diff --git a/tippingpoint/tpToIdea.py b/tippingpoint/tpToIdea.py
index 1d723790f1ce7fcbc3db5ea0461d75ea5b7fb034..52b9bacb46e477a368945a52650772d2d15bc961 100644
--- a/tippingpoint/tpToIdea.py
+++ b/tippingpoint/tpToIdea.py
@@ -1,5 +1,8 @@
-# python ./tpToIdea.py --origdata --oneshot -d /root/Dokumenty/PycharmProjects/TippingPoint/IdeaLogTest -n cz.cesnet.server.tippingpoint /root/Dokumenty/PycharmProjects/TippingPoint/tp-test-log.txt /root/Dokumenty/PycharmProjects/TippingPoint/tp-log2.txt --test
-
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2017-2018 Cesnet z.s.p.o
+# Use of this source is governed by a 3-clause BSD-style license, see LICENSE file.
 
 import json
 from uuid import uuid4
@@ -13,6 +16,7 @@ import resource
 import os.path as pth
 import atexit
 import time
+from datetime import datetime
 import logging
 
 
@@ -134,91 +138,251 @@ class Filer(object):
 
 
 class IdeaGen(object):
-    idea_categories = {'Malware.Worm': re.compile("^Exploits: .*?Worm"),
-                       'Attempt.Login': re.compile("SipVicious Brute Force"),
-                       'Attempt.Exploit': re.compile("^Exploits: .*?Attempt"),
-                       'Other': re.compile("P2P"),
-                       'Recon.Scanning': re.compile("^Reconnaissance"),
-                       'Vulnerable.Open': re.compile("(^Vulnerabilities: [0-9]{5}|^Network Equipment: [0-9]{4} SNMP)"),
-                       'Vulnerable.Config': re.compile("^Vulnerabilities: [0-9]{4} ICMP")}
-    anomaly_re = re.compile("(^Network Equipment: [0-9]{4} IP|^Traffic Normalization: [0-9]{4} (?!Tunneling))")
-    availability_ddos_re = re.compile("^Traffic Normalization: ")
-
-    def __init__(self, name, test=False):
+
+    tp_tax_to_idea = {
+        1: {
+              1: ["Attempt.Exploit"],
+              2: ["Attempt.Exploit"],
+              3: ["Attempt.Exploit"],
+              4: ["Attempt.Exploit"],
+              5: ["Attempt.Exploit"],
+              6: ["Attempt.Exploit"],
+            255: ["Attempt.Exploit"]
+        },
+
+        2: {
+              1: ["Malware.Worm"],
+              2: ["Malware.Virus"],
+              3: ["Malware.Trojan"],
+              4: ["Intrusion.Botnet"],
+              5: ["Fraud.Phishing"],
+            255: ["Malware"]
+        },
+
+        3: {
+              1: ["Availability.DDoS"],
+              2: ["Availability.DDoS"],
+              3: ["Availability.DDoS"],
+            255: ["Availability.DDoS"]
+        },
+
+        4: {
+              1: ["Other"],
+              2: ["Other"],
+              3: ["Other"],
+              4: ["Other"],
+              5: ["Other"],
+              6: ["Attempt.Login"],
+              7: ["Malware.Spyware"],
+            255: ["Other"]
+        },
+
+        5: {
+              1: ["Recon.Scanning"],
+              2: ["Attempt.Exploit"],
+              3: ["Attempt.Exploit"],
+              4: ["Recon.Scanning", "Attempt.Exploit"],
+            255: ["Attempt.Exploit"]
+        },
+
+        6: {
+              1: ["Anomaly.Protocol"],
+              2: ["Anomaly.Traffic"],
+              3: ["Anomaly.Application"],
+            255: ["Anomaly"]
+        },
+
+        7: {
+              1: ["Anomaly.Traffic"],
+              2: ["Anomaly.Application"],
+            255: ["Anomaly.Traffic"]
+        },
+
+        8: {
+              1: ["Other"],
+              2: ["Other"],
+            255: ["Other"]
+        },
+    }
+
+    tp_prot_to_idea = {
+        1: "appletalk",
+        2: "auth",
+        3: "bgp",
+        4: "cdp",
+        5: "clns",
+        6: "dhcp",
+        7: "domain",
+        8: "finger",
+        9: "ftp",
+        10: "hsrp",
+        11: "http",
+        12: "icmp",
+        13: "igmp",
+        14: "eigrp",
+        15: "ipv6",
+        16: "ipx",
+        17: "irc",
+        18: "isis",
+        19: "isakmp",
+        20: "ldap",
+        21: "mpls",
+        22: "ms-rpc",
+        23: "ms-sql",
+        24: "nat",
+        25: "netbios",
+        26: "nntp",
+        27: "ntp",
+        28: "oracle",
+        29: "ospf",
+        30: "pop-imap",
+        31: "sunrpc",
+        32: "qos",
+        33: "rip",
+        34: "sunrpc",
+        35: "smb",
+        36: "smtp",
+        37: "snmp",
+        38: "sql",
+        39: "ssh",
+        40: "ssl-tls",
+        41: "tacacs",
+        42: "tcp",
+        43: "telnet",
+        45: "udp",
+        46: "uucp",
+        48: "x11",
+        49: "tftp",
+        50: "ip",
+        51: "nfs",
+        52: "wins",
+        80: "h323",
+        81: "megaco",
+        82: "mgcp",
+        83: "sip",
+        84: "rtp",
+        99: "voip",
+        100: "aim",
+        101: "msn",
+        102: "yahoo",
+        103: "icq",
+        119: "im",
+        120: "musicmatch",
+        121: "winamp",
+        122: "shoutcast",
+        123: "windows",
+        124: "quicktime",
+        125: "rtsp",
+        149: "streaming",
+        150: "bittorrent",
+        151: "manolito",
+        152: "directconnect",
+        153: "earthstation5",
+        154: "p2p",
+        155: "fasttrack",
+        156: "gnutella",
+        157: "twister",
+        158: "winmx",
+        180: "p2p",
+        190: "scada-dnp3",
+        191: "scada-iccp",
+        192: "scada-iec",
+        193: "scada-modbus",
+        194: "scada-opc",
+        199: "scada",
+        254: "multi-protocol",
+    }
+
+    def __init__(self, name, test=False, other=False):
         self.name = name
         self.test = test
+        self.other = other
 
-    def convert_category(self, category, incident, examples_of_incident):
+    def convert_category_and_protocol(self, category, id_taxonomy):
         '''
         converts category from record to IDEA category
         :param category: TippingPoint category description
-        :param incident: TippingPoint incident description
-        :param examples_of_incident: some TippingPoing incident descriptions has examples
+        :param id_taxonomy: TippingPoint taxonomy id
         :return: if category or incident is empty or is not important for saving it return None, otherwise return
                  converted category
         '''
-        if not (category and incident):
+        if not (category and id_taxonomy):
             return None
-        tp_category = category + ": " + incident
-        if IdeaGen.anomaly_re.search(tp_category) and not examples_of_incident:
-            return "Anomaly.Traffic"
-        if IdeaGen.availability_ddos_re.search(tp_category) and examples_of_incident:
-            return "Availability.DoS"
-        for category, pattern in IdeaGen.idea_categories.items():
-            if pattern.search(tp_category):
-               return category
-        return None
-
-    def gen_event_idea(self, timestamp, category, id_taxonomy, cve, examples_of_incident, proto, src_ip, src_port,
-                       dest_ip, dest_port, conn_count, url, orig_data, incident_desription):
+        tp_cat_maj = id_taxonomy >> 24
+        tp_cat_min = id_taxonomy >> 16 & 0b11111111
+        tp_prot = id_taxonomy >> 8 & 0b11111111
+        tp_platf = id_taxonomy & 0b11111111
+        try:
+            category = IdeaGen.tp_tax_to_idea[tp_cat_maj][tp_cat_min]
+        except KeyError:
+            category = ["Other"]
+
+        try:
+            protocol = IdeaGen.tp_prot_to_idea[tp_prot]
+        except KeyError:
+            protocol = None
+
+        return { 'category': category, 'protocol': protocol }
+
+    def gen_event_idea(self, timestamp, category, id_taxonomy, cve, filter_name, proto, src_ip, src_port,
+                       dest_ip, dest_port, conn_count, url, severity, orig_data):
         '''
         put every piece of record together into IDEA message
         :return: new IDEA message
         '''
+
+        if (category == ["Other"]) and not self.other:
+            return None
+
         event = {
             'Format': "IDEA0",
             'ID': str(uuid4()),
-            'DetectTime': time.strftime("%y-%m-%dT%H:%M:%S", time.localtime(timestamp)),
-            'Category': [category] + (["Test"] if self.test else []),
-            'Note': incident_desription,
-            'Ref': []
+            'DetectTime': datetime.utcfromtimestamp(timestamp / 1000).isoformat() + 'Z',
+            'Category': category + (["Test"] if self.test else [])
         }
         if cve:
-            event['Ref'].append("cve:"+cve)
-        if id_taxonomy:
-            event['Ref'].append("tipping_point_taxonomy:%d" % int(id_taxonomy))
-        if conn_count:
-            event['ConnCount'] = conn_count
+            event['Ref'] = ['urn:cve:'.format(i) for i in cve]
+        if conn_count and int(conn_count):
+            event['ConnCount'] = int(conn_count)
         source = {}
         target = {}
         if src_ip:
+            # TippingPoint vSMS bugfix: Remove excessive spaces occasionally included inside the IPv6 address
+            src_ip = src_ip.replace(" ", "")
             af = "IP4" if not ':' in src_ip else "IP6"
             source[af] = [src_ip]
-        if src_port:
-            source['Port'] = [src_port]
-        if proto:
-            source['Proto'] = [proto]
-        if url:
-            source['url'] = url
-        if dest_ip:
+            if src_port and int(src_port):
+                source['Port'] = [int(src_port)]
+            if proto:
+                source['Proto'] = proto
+        if dest_ip and (dest_ip != "0.0.0.0"):
+            # TippingPoint vSMS bugfix: Remove excessive spaces occasionally included inside the IPv6 address
+            dest_ip = dest_ip.replace(" ", "")
             af = "IP4" if not ':' in dest_ip else "IP6"
             target[af] = [dest_ip]
-        if dest_port:
-            target['Port'] = [dest_port]
+            if dest_port and int(dest_port):
+                target['Port'] = [int(dest_port)]
+            if proto:
+                target['Proto'] = proto
+            if url:
+                target['URL'] = url
+
         if source:
             event['Source'] = [source]
         if target:
-            event['Target'] = [target]
-        if examples_of_incident:
-            event['Note'] += ", examples of event:" + examples_of_incident[6:]
+            if category and category == "Reputation":
+                event['Source'].append(target)
+            else:
+                event['Target'] = [target]
         if orig_data:
-            event['Attach'] = {'Handle': "att1",
-                               'Note': "original data",
-                               'Content': orig_data}
+            event['Attach'] = [{
+                               'Type': ["OrigData"],
+                               'Content': orig_data.strip()
+            }]
         event['Node'] = [{
                             'Name': self.name,
-                            'Type': ["Connection", "Honeypot", "Recon"],
-                            'SW': ["HP Tipping Point"],
+                            'Type': ["Datagram", "Content", "Protocol", "Signature", "Policy", "Heuristic"],
+                            'SW': ["TippingPoint_NX_NGIPS"]
                         }]
         return event
 
@@ -284,7 +448,7 @@ def daemonize(
 def get_args():
     optp = optparse.OptionParser(
         usage="usage: %prog [options] logfile ...",
-        description="Watch HP-Tipping_Point logfiles and generate Idea events into directory")
+        description="Watch TippingPoint logfiles and generate Idea events into directory")
     optp.add_option(
         "-n", "--name",
         default=None,
@@ -297,7 +461,13 @@ def get_args():
         default=False,
         dest="test",
         action="store_true",
-        help="Add Test category")
+        help="Add \"Test\" category")
+    optp.add_option(
+        "--other",
+        default=False,
+        dest="other",
+        action="store_true",
+        help="Send events having \"Other\" category (usually nonmalicious)")
     optp.add_option(
         "-o", "--oneshot",
         default=False,
@@ -367,23 +537,43 @@ def process_data(line, filer, origdata, idea_gen):
     :param idea_file: where output goes
     :param origdata: if true, write original record to IDEA message
     '''
-    row = line.split(",")
-    while re.search("^CVE-.*$", row[4]):
-        row[3] += ", " + row[4]
-        del row[4]
-    examples_of_incident = []
-    while not re.search("(UDP|IP|ICMP|DNS|IP6)", row[5]):
-        examples_of_incident.append(row[5])
-        del row[5]
-    examples_of_incident = " ".join(examples_of_incident)
-    category = idea_gen.convert_category(category=row[1], incident=row[4], examples_of_incident=examples_of_incident)
-    if category and not_empty(row[0][-14:-3]):
-        idea_event = idea_gen.gen_event_idea(timestamp=int(row[0][-14:-3]), category=category, id_taxonomy=not_empty(row[2]), cve=not_empty(row[3]),
-                                             examples_of_incident=not_empty(examples_of_incident), proto=not_empty(row[5]),
+
+    ll_prot_str = [" ip:", " ipv6:", " udp:", " tcp:", "(ip)", "(ipv6)", "(udp)", "(tcp)", " ip ", " ipv6 ", " udp ", " tcp "]
+
+    row = line.split("|")
+
+    catprot = idea_gen.convert_category_and_protocol(category=row[1], id_taxonomy=int(row[2]))
+    proto = []
+    if not_empty(row[5]).lower() in ['ip', 'ip6', 'udp', 'tcp']:
+        proto.append(row[5].lower())
+
+    flt_proto = [pstr for pstr in ll_prot_str if(pstr in not_empty(row[4]).lower())]
+    if flt_proto:
+        proto.append(flt_proto[0].translate(None, " ():v"))
+
+    if catprot['protocol']:
+        proto.append(catprot['protocol'])
+    if set(proto).intersection({"ip", "ip6"}):
+        try:
+            proto.remove("ip")
+            proto.remove("ip6")
+        except ValueError:
+            pass
+        if not "udp" in proto:
+            proto.append("tcp")
+    proto = list(set(proto))
+
+    timestamp = row[0].split(" ")[-1]
+    cve = [i for i in row[3].split(",") if i not in ("null", "")]
+    odata = "|".join([timestamp] + row[1:])
+    if catprot['category'] and not_empty(row[0][-14:-3]):
+        idea_event = idea_gen.gen_event_idea(timestamp=int(timestamp), category=catprot['category'], id_taxonomy=int(row[2]),
+                                             cve=cve, filter_name=not_empty(row[4]), proto=proto,
                                              src_ip=not_empty(row[6]), src_port=not_empty(row[7]), dest_ip=not_empty(row[8]), dest_port=not_empty(row[9]),
-                                             conn_count=not_empty(row[10]), url=not_empty(row[12]),
-                                             orig_data=str(line) if origdata else False, incident_desription=row[4])
-        save_events(idea_event, filer)
+                                             conn_count=not_empty(row[10]), severity=not_empty(row[11]), url=not_empty(row[12]),
+                                             orig_data=odata if origdata else False)
+        if idea_event:
+            save_events(idea_event, filer)
 
 
 running_flag = True
@@ -425,7 +615,7 @@ def main():
             })
         files = [FileWatcher(arg) for arg in args]
     filer = Filer(opts.dir)
-    idea_gen = IdeaGen(opts.name, opts.test)
+    idea_gen = IdeaGen(opts.name, opts.test, opts.other)
     while running_flag:
         for log_file in files:
             while True: