diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9ea526d9f710326c7b98267b30624635e1090305
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+**.swp
+wiser-wcs-reports/.idea/*
+wiser-wcs-reports/env/*
+wiser-wcs-reports/example_nmap_output/*
+
diff --git a/Dockerfile b/Dockerfile
index 5fcc1c9628417abf0cada75532ae17ab383e7a55..df6977cb0fcdb56bd6846bc6b9d6304beee0bc55 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,10 +14,13 @@ COPY install/zap-plugin.patch install/w3af-plugin.patch install/cscan.patch /tmp
 COPY install/cscan.sh /tmp/install/
 RUN chmod +x /tmp/install/cscan.sh && /tmp/install/cscan.sh
 
+COPY wiser-wcs-reports /service/wiser-wcs-reports/
+COPY install/wiser-wcs.sh /tmp/install/
+RUN chmod +x /tmp/install/wiser-wcs.sh && /tmp/install/wiser-wcs.sh
+
 COPY install/cleanup.sh /tmp/install/
 RUN chmod +x /tmp/install/cleanup.sh && /tmp/install/cleanup.sh
 
-COPY wiser-wcs-reports /service/wiser-wcs-reports/
 COPY run-cscan.sh configure.py config-example.json /service/
 RUN chmod +x /service/run-cscan.sh
 
diff --git a/MANIFEST b/MANIFEST
index e40de4a6b598f9a44da8a48446ab31c3465ecd78..63404cf9c776af5c408cfd53b4e326701fafb8d0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,3 @@
-VERSION=v1.3.2
+VERSION=v1.3.3
 SERVICE=vat-genscan
 
diff --git a/install/wiser-wcs.sh b/install/wiser-wcs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..38e5129ec8fde162eb2a992e4265e09358d3bc99
--- /dev/null
+++ b/install/wiser-wcs.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+
+pip3 install -r /service/wiser-wcs-reports/requirements.txt
+
diff --git a/run-cscan.sh b/run-cscan.sh
index abaf1b537ebfca45f0995b30815904f8712fbaa2..86d8999a588da1c960442e846752f5197fe3449b 100644
--- a/run-cscan.sh
+++ b/run-cscan.sh
@@ -20,7 +20,7 @@ if [ $RESULT -ne 0 ]; then
 fi
 
 cd /service/wiser-wcs-reports
-python wiser-wcs.py | tail -n 1 > /root/out/genscan-out.json
+python3 wiser-wcs.py | tail -n 1 > /root/out/genscan-out.json
 
 # outputting the scan result
 cat /root/out/genscan-out.json
diff --git a/wiser-wcs-reports/requirements.py b/wiser-wcs-reports/requirements.py
deleted file mode 100644
index 0e710fc5785dcca707e400bcdf116794f89980b0..0000000000000000000000000000000000000000
--- a/wiser-wcs-reports/requirements.py
+++ /dev/null
@@ -1,4 +0,0 @@
-argparse==1.2.1
-simplejson==3.8.0
-wsgiref==0.1.2
-xml2json==0.1
diff --git a/wiser-wcs-reports/requirements.txt b/wiser-wcs-reports/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3ed018b26028451bb38c1266215486b01f7c15d6
--- /dev/null
+++ b/wiser-wcs-reports/requirements.txt
@@ -0,0 +1,2 @@
+configparser==4.0.2
+xmljson==0.2.0
diff --git a/wiser-wcs-reports/wiser-wcs.py b/wiser-wcs-reports/wiser-wcs.py
index f4dc5b5f04ad9f308b421c3e5e7f7800a30e926c..f5027ebcb82e3e9214a52412d7f1e46bac7066b1 100644
--- a/wiser-wcs-reports/wiser-wcs.py
+++ b/wiser-wcs-reports/wiser-wcs.py
@@ -1,262 +1,266 @@
-from xml2json import json2xml, xml2json
+from xmljson import badgerfish
+from xml.etree.ElementTree import fromstring
 from os import listdir
 from os.path import isfile, join
-import ConfigParser
+from collections import OrderedDict
+import configparser
 import json
 import re
 
 
 class Options(object):
-    """
-    Dummy class
-    """
-    pass
+	"""
+	Dummy class
+	"""
+	pass
 
 
 class IterMixin(object):
-    def __iter__(self):
-        for attr, value in self.__dict__.iteritems():
-            yield attr, value
+	def __iter__(self):
+		for attr, value in self.__dict__.iteritems():
+			yield attr, value
 
 
 class WiserVulnerability(IterMixin):
-    """
-    Super class of WISER vulnerabilities.
-    """
-
-    """ short description of the vulnerability """
-    short_desc = dict()
-    """ long description """
-    desc = dict()
-    """ reference url """
-    reference = dict()
-    """ how to solve """
-    solution = dict()
-    """ risk level """
-    risk_level = dict()
-    """ WISER risk level """
-    w_risk_level = dict()
-    """id of the vuln """
-    wascid = dict()
-    """  Source pen_test  """
-    source_pentest = dict()
-
-    def __init__(self):
-        pass
-
-    def parse_from_alert(self, alert_dict, type):
-        pass
-
-    def parse_report(self, report_dict):
-        pass
-
-    """
-    Sets WISER risk level to the Vulnerability.
-    """
-    def set_wiser_risk_level(self):
-        pass
-
-    def __str__(self):
-        return json.dumps(dict(self))
+	"""
+	Super class of WISER vulnerabilities.
+	"""
+
+	""" short description of the vulnerability """
+	short_desc = dict()
+	""" long description """
+	desc = dict()
+	""" reference url """
+	reference = dict()
+	""" how to solve """
+	solution = dict()
+	""" risk level """
+	risk_level = dict()
+	""" WISER risk level """
+	w_risk_level = dict()
+	"""id of the vuln """
+	wascid = dict()
+	"""  Source pen_test  """
+	source_pentest = dict()
+
+	def __init__(self):
+		pass
+
+	def parse_from_alert(self, alert_dict, type):
+		pass
+
+	def parse_report(self, report_dict):
+		pass
+
+	"""
+	Sets WISER risk level to the Vulnerability.
+	"""
+	def set_wiser_risk_level(self):
+		pass
+
+	def __str__(self):
+		return json.dumps(self.__dict__)
 
 
 class WiserReport(IterMixin):
 
-    report = list()
-    report_json = dict()
+	report = list()
+	report_json = dict()
 
-    def __init__(self):
-        pass
+	def __init__(self):
+		pass
 
-    def parse_report(self, report_dict):
-        pass
+	def parse_report(self, report_dict):
+		pass
 
-    """ Gets the report from the parsed list of vulnerabilities.
-    """
-    def get_report(self):
-        return self.report
+	""" Gets the report from the parsed list of vulnerabilities.
+	"""
+	def get_report(self):
+		return self.report
 
 
 class WiserZapVulnerability(WiserVulnerability):
 
-    def __init__(self, alert):
-        self.parse_report(alert)
-
-    def parse_report(self, alert):
-        self.short_desc = alert['alert']['#text']
-        self.desc = alert['desc']['#text']
-        self.reference = alert['reference']['#text']
-        self.risk_level = alert['riskdesc']['#text']
-        self.solution = alert['solution']['#text']
-        if 'wascid' in alert:
-            self.wascid = alert['wascid']['#text']
-        self.source_pentest="OWASP ZAP"
-        self.set_wiser_risk_level()
-
-    def set_wiser_risk_level(self):
-        if self.risk_level == "Low (Low)":
-            self.w_risk_level = 10
-        if self.risk_level == "Low (Medium)":
-            self.w_risk_level = 20
-        if self.risk_level == "Low (High)":
-            self.w_risk_level = 50
-        if self.risk_level == "Medium (Low)":
-            self.w_risk_level = 20
-        if self.risk_level == "Medium (Medium)":
-            self.w_risk_level = 50
-        if self.risk_level == "Medium (High)":
-            self.w_risk_level = 80
-        if self.risk_level == "High (Low)":
-            self.w_risk_level = 50
-        if self.risk_level == "High (Medium)":
-            self.w_risk_level = 80
-        if self.risk_level == "High (High)":
-            self.w_risk_level = 100
+	def __init__(self, alert):
+		super().__init__()
+		self.parse_report(alert)
+	
+	@staticmethod
+	def _pretty(text):
+		return re.sub('(</?p>)+', '\n', text).strip()
+
+	def parse_report(self, alert):
+		self.short_desc = self._pretty(alert['alert']['$'])
+		self.desc = self._pretty(alert['desc']['$'])
+		self.reference = self._pretty(alert['reference']['$'])
+		self.risk_level = self._pretty(alert['riskdesc']['$'])
+		self.solution = self._pretty(alert['solution']['$'])
+		if 'wascid' in alert:
+			self.wascid = alert['wascid']['$']
+		self.source_pentest="OWASP ZAP"
+		self.set_wiser_risk_level()
+
+	def set_wiser_risk_level(self):
+		if self.risk_level == "Low (Low)":
+			self.w_risk_level = 10
+		if self.risk_level == "Low (Medium)":
+			self.w_risk_level = 20
+		if self.risk_level == "Low (High)":
+			self.w_risk_level = 50
+		if self.risk_level == "Medium (Low)":
+			self.w_risk_level = 20
+		if self.risk_level == "Medium (Medium)":
+			self.w_risk_level = 50
+		if self.risk_level == "Medium (High)":
+			self.w_risk_level = 80
+		if self.risk_level == "High (Low)":
+			self.w_risk_level = 50
+		if self.risk_level == "High (Medium)":
+			self.w_risk_level = 80
+		if self.risk_level == "High (High)":
+			self.w_risk_level = 100
 
 
 class WiserW3afVulnerability(WiserVulnerability):
 
-    def __init__(self, alert):
-        self.parse_report(alert)
-
-    def parse_report(self, alert):
-        self.short_desc = alert['@name']
-        self.desc = alert['description']['#text']
-        if 'references' in alert:
-            if 'reference' in alert['references']:
-                if alert['references']['reference'] is dict:
-                    self.reference = alert['references']['reference']['@url']
-                if alert['references']['reference'] is list:
-                    self.reference = alert['references']['reference'][0]['@url']
-        self.risk_level = alert['@severity']
-        if 'long-description' in alert:
-            self.solution = alert['long-description']['#text']
-        if '@id' in alert:
-            if 'references' in alert:
-                if 'reference' in alert['references']:
-                    if '@title' in alert['references']['reference']:
-                        if alert['references']['reference']['@title'] == 'WASC':
-                            #self.wascid = alert['@id']
-                            self.wascid = re.sub('[\[\]]', '', alert['@id'])
-        self.source_pentest="W3af"
-        self.set_wiser_risk_level()
-
-    def set_wiser_risk_level(self):
-        if self.risk_level == "Information":
-            self.w_risk_level = 25
-        if self.risk_level == "Low":
-            self.w_risk_level = 50
-        if self.risk_level == "Medium":
-            self.w_risk_level = 75
-        if self.risk_level == "High":
-            self.w_risk_level = 100
+	def __init__(self, alert):
+		super().__init__()
+		self.parse_report(alert)
+
+	def parse_report(self, alert):
+		self.short_desc = alert['@name']
+		self.desc = alert['description']['$']
+		if 'references' in alert:
+			if 'reference' in alert['references']:
+				if isinstance(alert['references']['reference'], OrderedDict):
+					self.reference = alert['references']['reference']['@url']
+				if alert['references']['reference'] is list:
+					self.reference = alert['references']['reference'][0]['@url']
+		self.risk_level = alert['@severity']
+		if 'long-description' in alert:
+			self.solution = alert['long-description']['$']
+		if '@id' in alert:
+			if 'references' in alert:
+				if 'reference' in alert['references']:
+					if '@title' in alert['references']['reference']:
+						if alert['references']['reference']['@title'] == 'WASC':
+							self.wascid = re.sub('[\[\]]', '', alert['@id'])
+		self.source_pentest="W3af"
+		self.set_wiser_risk_level()
+
+	def set_wiser_risk_level(self):
+		if self.risk_level == "Information":
+			self.w_risk_level = 25
+		if self.risk_level == "Low":
+			self.w_risk_level = 50
+		if self.risk_level == "Medium":
+			self.w_risk_level = 75
+		if self.risk_level == "High":
+			self.w_risk_level = 100
 
 
 class WiserZapReport(WiserReport):
 
-    def __init__(self, report):
-        self.parse_report(report)
-
-    def parse_report(self, report_dict):
-        """
-        Parses OWASP ZAP report
-        :param report:
-        :return:
-        """
-        self.report = list()
-        print report_dict
-        if 'site' in report_dict:
-            if 'alerts' in report_dict['site'] and report_dict['site']['alerts'] is not None:
-                if 'alertitem' in report_dict['site']['alerts']:
-                    if type(report_dict['site']['alerts']['alertitem'])==list:
-                        for i in range(0, len(report_dict['site']['alerts']['alertitem'])):
-                            alert = report_dict['site']['alerts']['alertitem'][i]
-                            vulnerability = WiserZapVulnerability(alert)
-                            self.report.append(vulnerability)
-                    else:
-                        alert = report_dict['site']['alerts']['alertitem']
-                        vulnerability = WiserZapVulnerability(alert)
-                        self.report.append(vulnerability)
+	def __init__(self, report):
+		super().__init__()
+		self.parse_report(report)
+
+	def parse_report(self, report_dict):
+		"""
+		Parses OWASP ZAP report
+		:param report:
+		:return:
+		"""
+		self.report = list()
+		if 'site' in report_dict:
+			if 'alerts' in report_dict['site'] and report_dict['site']['alerts'] is not None:
+				if 'alertitem' in report_dict['site']['alerts']:
+					if type(report_dict['site']['alerts']['alertitem'])==list:
+						for i in range(0, len(report_dict['site']['alerts']['alertitem'])):
+							alert = report_dict['site']['alerts']['alertitem'][i]
+							vulnerability = WiserZapVulnerability(alert)
+							self.report.append(vulnerability)
+					else:
+						alert = report_dict['site']['alerts']['alertitem']
+						vulnerability = WiserZapVulnerability(alert)
+						self.report.append(vulnerability)
 
 class WiserW3afReport(WiserReport):
 
-    def __init__(self, report):
-        self.parse_report(report)
-
-    def parse_report(self, report_dict):
-        """
-        Parses W3af report
-        :param report:
-        :return:
-        """
-        self.report = list()
-        if 'vulnerability' in report_dict:
-            if type(report_dict['vulnerability'])==list:
-                for alert in report_dict['vulnerability']:
-                    vulnerability = WiserW3afVulnerability(alert)
-                    self.report.append(vulnerability)
-            else:
-                alert = report_dict['vulnerability']
-                vulnerability = WiserW3afVulnerability(alert)
-                self.report.append(vulnerability)
+	def __init__(self, report):
+		super().__init__()
+		self.parse_report(report)
+
+	def parse_report(self, report_dict):
+		"""
+		Parses W3af report
+		:param report:
+		:return:
+		"""
+		self.report = list()
+		if 'vulnerability' in report_dict:
+			if type(report_dict['vulnerability'])==list:
+				for alert in report_dict['vulnerability']:
+					vulnerability = WiserW3afVulnerability(alert)
+					self.report.append(vulnerability)
+			else:
+				alert = report_dict['vulnerability']
+				vulnerability = WiserW3afVulnerability(alert)
+				self.report.append(vulnerability)
 
 
 def parse_config_file(filename):
-    """
-    Parse the config file.
+	"""
+	Parse the config file.
 
-    :param filename: the config file
-    :return:
-    """
-    config = ConfigParser.ConfigParser()
-    config.read(filename)
-    return config
+	:param filename: the config file
+	:return:
+	"""
+	config = configparser.ConfigParser()
+	config.read(filename)
+	return config
 
 
 def reports_json(dir):
-    """
-    Iterate through directory.
-    :param dir:
-    :return:
-    """
-    options = Options
-    setattr(options, 'pretty', False)
-    strip_ns = 0
-    strip = 0
-    onlyfiles = [f for f in listdir(dir) if isfile(join(dir,f))]
-    reports = dict()
-    for f in onlyfiles:
-        inputstream = open(join(dir,f))
-        input = inputstream.read()
-        out = xml2json(input, options, strip_ns, strip)
-        reports[f] = out
-    return reports
+	"""
+	Iterate through directory.
+	:param dir:
+	:return:
+	"""
+	onlyfiles = [f for f in listdir(dir) if isfile(join(dir,f))]
+	reports = dict()
+	for f in onlyfiles:
+		inputstream = open(join(dir,f))
+		input = inputstream.read()
+		out = badgerfish.data(fromstring(input))
+		reports[f] = out
+	return reports
 
 
 def list_vulnerabilities(reports):
-    """
-    List all vulnerabilities based on the reports given.
-    :return:
-    """
-    vulnerabilities = list()
-    for report in reports.values():
-        report_dict = json.loads(report)
-        if "OWASPZAPReport" in report_dict:
-            vulnerabilities.extend(WiserZapReport(report_dict['OWASPZAPReport']).get_report())
-        if "w3af-run" in report_dict:
-            vulnerabilities.extend(WiserW3afReport(report_dict['w3af-run']).get_report())
-    return vulnerabilities
+	"""
+	List all vulnerabilities based on the reports given.
+	:return:
+	"""
+	vulnerabilities = list()
+	for report in reports.values():
+		report_dict = report
+		if "OWASPZAPReport" in report_dict:
+			vulnerabilities.extend(WiserZapReport(report_dict['OWASPZAPReport']).get_report())
+		if "w3af-run" in report_dict:
+			vulnerabilities.extend(WiserW3afReport(report_dict['w3af-run']).get_report())
+	return vulnerabilities
 
 if __name__ == "__main__":
-    config = parse_config_file('wiser-wcs.cfg')
-    reports = reports_json(config._sections['cscan_config']['cscan_output'])
-    print "printing vulnerabilities: "
-    vulnerabilities = list_vulnerabilities(reports)
-    vulnerabilities_list = list()
-    for vulnerability in vulnerabilities:
-        print vulnerability
-        vulnerabilities_list.append(vulnerability.__dict__)
-
-    vulnerabilities_json = json.dumps({ "reports": vulnerabilities_list})
-    print "printing vulnerabilities JSON: "
-    print vulnerabilities_json
+	config = parse_config_file('wiser-wcs.cfg')
+	reports = reports_json(config['cscan_config']['cscan_output'])
+	print("printing vulnerabilities: ")
+	vulnerabilities = list_vulnerabilities(reports)
+	vulnerabilities_list = list()
+	for vulnerability in vulnerabilities:
+		print(vulnerability)
+		vulnerabilities_list.append(vulnerability.__dict__)
+
+	vulnerabilities_json = json.dumps({ "reports": vulnerabilities_list})
+	print("printing vulnerabilities JSON: ")
+	print(vulnerabilities_json)