diff --git a/zenmap/zenmapCore/NetworkInventory.py b/zenmap/zenmapCore/NetworkInventory.py
index dc28662..90bd9e5 100644
--- a/zenmap/zenmapCore/NetworkInventory.py
+++ b/zenmap/zenmapCore/NetworkInventory.py
@@ -455,14 +455,29 @@ class FilteredNetworkInventory(NetworkInventory):
     def get_host_count(self):
         return len(self.network_inventory.hosts)
     def match_keyword(self, host, keyword):
-        return self.match_os(host, keyword) or\
+        found = True
+        if keyword != "" and keyword[0] == "!":
+            keyword = keyword[1:]
+            found = False
+
+        if self.match_os(host, keyword) or\
                self.match_target(host, keyword) or\
-               self.match_service(host, keyword)
+               self.match_service(host, keyword):
+            return found
+        else:
+            return not found
     def match_target(self, host, name):
         return HostSearch.match_target(host, name)
     def match_in_route(self, host, hop):
+        found = True
+        if hop != "" and hop[0] == "!":
+            hop = hop[1:]
+            found = False
         hops = host.get_trace().get('hops', [])
-        return hop in hops
+        if hop in hops:
+            return found
+        else:
+            return not found
     def match_hostname(self, host, hostname):
         return HostSearch.match_hostname(host, hostname)
     def match_service(self, host, service):
diff --git a/zenmap/zenmapCore/SearchResult.py b/zenmap/zenmapCore/SearchResult.py
index 75c023f..b41a58a 100644
--- a/zenmap/zenmapCore/SearchResult.py
+++ b/zenmap/zenmapCore/SearchResult.py
@@ -106,31 +106,47 @@ from zenmapCore.UmitLogging import log
 class HostSearch(object):
     @staticmethod
     def match_target(host, name):
-        addrs = []
+        found = True
+        if name != "" and name[0] == "!":
+            name = name[1:]
+            found = False
+        name = name.lower()
+
         mac = host.get_mac()
         ip = host.get_ip()
         ipv6 = host.get_ipv6()
 
         if mac and mac.has_key('addr'):
-            if name in mac['addr'].lower(): return True
+            if name in mac['addr'].lower(): return found
         if ip and ip.has_key('addr'):
-            if name in ip['addr'].lower(): return True
+            if name in ip['addr'].lower(): return found
         if ipv6 and ipv6.has_key('addr'):
-            if name in ipv6['addr'].lower(): return True
+            if name in ipv6['addr'].lower(): return found
 
         if HostSearch.match_hostname(host, name):
-            return True
-        return False
+            return found
+        return not found
     @staticmethod
     def match_hostname(host, hostname):
+        found = True
+        if hostname != "" and hostname[0] == "!":
+            hostname = hostname[1:]
+            found = False
+        hostname = hostname.lower()
+
         hostnames = host.get_hostnames()
         for hn in hostnames:
             if hostname in hn['hostname'].lower():
-                return True
+                return found
         else:
-            return False
+            return not found
     @staticmethod
     def match_service(host, service):
+        found = True
+        if service != "" and service[0] == "!":
+            service = service[1:]
+            found = False
+        service = service.lower()
         for port in host.get_ports():
             # We concatenate all useful fields and add them to the list
             if port['port_state'] not in ['open','open|filtered']:
@@ -140,11 +156,15 @@ class HostSearch(object):
                       port.get("service_version", "") + " " + \
                       port.get("service_extrainfo", "")
             if service in version.lower():
-                return True
+                return found
         else:
-            return False
+            return not found
     @staticmethod
     def match_os(host, os):
+        found = True
+        if os != "" and os[0] == "!":
+            os = os[1:]
+            found = False
         os = os.lower()
         os_str = ""
 
@@ -158,19 +178,22 @@ class HostSearch(object):
                           osclass['type'].lower()
 
         if os in os_str:
-            return True
-        return False
+            return found
+        return not found
     @staticmethod
     def match_port(host_ports, port, port_state):
+        found = True
+        if port != "" and port[0] == "!":
+            port = port[1:]
+            found = False
         # Check if the port is parsable, if not return False silently
         if re.match("^\d+$", port) == None:
             return False
 
         for hp in host_ports:
             if hp['portid'] == port and hp['port_state'] == port_state:
-                return True
-        else:
-            return False
+                return found
+        return not found
 
 class SearchResult(object):
     def __init__(self):
@@ -212,32 +235,54 @@ class SearchResult(object):
         pass
 
     def basic_match(self, keyword, property):
+        found = True
+        if keyword != "" and keyword[0] == "!":
+            keyword = keyword[1:]
+            found = False
         if keyword == "*" or keyword == "":
-            return True
+            return found
 
-        return keyword.lower() in str(self.parsed_scan.__getattribute__(property)).lower()
+        if keyword.lower() in str(self.parsed_scan.__getattribute__(property)).lower():
+            return found
+        else:
+            return not found
 
     def match_keyword(self, keyword):
         log.debug("Match keyword: %s" % keyword)
+        found = True
+        if keyword != "" and keyword[0] == "!":
+            keyword = keyword[1:]
+            found = False
 
-        return self.basic_match(keyword, "nmap_output") or \
+        if self.basic_match(keyword, "nmap_output") or \
                self.match_profile(keyword) or \
-               self.match_target(keyword)
+               self.match_target(keyword):
+            return found
+        else:
+            return not found
 
     def match_profile(self, profile):
         log.debug("Match profile: %s" % profile)
         log.debug("Comparing: %s == %s ??" % (str(self.parsed_scan.profile_name).lower(),
                                               "*%s*" % profile.lower()))
+        found = True
+        if profile != "" and profile[0] == "!":
+            profile = profile[1:]
+            found = False
         if profile == "*" or profile == "" or \
            profile.lower() in str(self.parsed_scan.profile_name).lower():
-            return True
-        return False
+            return found
+        return not found
 
     def match_option(self, option):
         log.debug("Match option: %s" % option)
 
+        found = True
+        if option != "" and option[0] == "!":
+            option = option[1:]
+            found = False
         if option == "*" or option == "":
-            return True
+            return found
 
         # NOTE: Option matching treats "_" and "-" the same, just like the optcmp
         #       function in utils.cc . Also, option matching is case-sensitive.
@@ -256,10 +301,16 @@ class SearchResult(object):
             if val is None:
                 val = ops["-" + optname]
             if val is None:
-                return False
-            return str(val) == optval or str(val) == optval
+                return not found
+            if str(val) == optval or str(val) == optval:
+                return found
+            else:
+                return not found
         else:
-            return ops["--" + option] is not None or ops["-" + option] is not None
+            if ops["--" + option] is not None or ops["-" + option] is not None:
+                return found
+            else:
+                return not found
 
     def match_date(self, date_arg, operator="date"):
         # The parsed scan's get_date() returns a time.struct_time, so we
@@ -305,15 +356,20 @@ class SearchResult(object):
     def match_target(self, target):
         log.debug("Match target: %s" % target)
 
+        found = True
+        if target != "" and target[0] == "!":
+            target = target[1:]
+            found = False
+
         for spec in self.parsed_scan.get_targets():
             if target in spec:
-                return True
+                return found
         else:
             # We search the (rDNS) hostnames list
             for host in self.parsed_scan.get_hosts():
                 if HostSearch.match_target(host, target):
-                    return True
-        return False
+                    return found
+        return not found
 
     def match_os(self, os):
         # If you have lots of big scans in your DB (with a lot of hosts scanned),
@@ -321,15 +377,22 @@ class SearchResult(object):
         # search just greps through the nmap output, while this function iterates
         # through all parsed OS-related values for every host in every scan!
         hosts = self.parsed_scan.get_hosts()
-        os = os.lower()
+        found = True
+        if os != "" and os[0] == "!":
+            os = os[1:]
+            found = False
         for host in hosts:
             if HostSearch.match_os(host, os):
-                return True
-        return False
+                return found
+        return not found
 
     def match_scanned(self, ports):
+        found = True
+        if ports != "" and ports[0] == "!":
+            ports = ports[1:]
+            found = False
         if ports == "":
-            return True
+            return found
 
         # Transform a comma-delimited string containing ports into a list
         ports = filter(lambda not_empty: not_empty, ports.split(","))
@@ -358,14 +421,18 @@ class SearchResult(object):
                 elif port == service:
                     break
             else:
-                return False
+                return not found
         else:
             # The ports loop finished for all ports, which means the search was successful.
-            return True
+            return found
 
     def match_port(self, ports, port_state):
         log.debug("Match port:%s" % ports)
 
+        found = True
+        if ports != "" and ports[0] == "!":
+            ports = ports[1:]
+            found = False
         # Transform a comma-delimited string containing ports into a list
         ports = filter(lambda not_empty: not_empty, ports.split(","))
 
@@ -374,9 +441,9 @@ class SearchResult(object):
                 if not HostSearch.match_port(host.get_ports(), port, port_state):
                     break
             else:
-                return True
+                return found
         else:
-            return False
+            return not found
 
     def match_open(self, port):
         return self.match_port(port, "open")
@@ -397,19 +464,26 @@ class SearchResult(object):
         return self.match_port(port, "closed|filtered")
 
     def match_service(self, sversion):
+        found = True
+        if sversion != "" and sversion[0] == "!":
+            sversion = sversion[1:]
+            found = False
         if sversion == "" or sversion == "*":
-            return True
+            return found
 
-        versions = []
         for host in self.parsed_scan.get_hosts():
             if HostSearch.match_service(host, sversion):
-                return True
+                return found
         else:
-            return False
+            return not found
 
     def match_in_route(self, host):
+        found = True
+        if host != "" and host[0] == "!":
+            host = host[1:]
+            found = False
         if host == "" or host == "*":
-            return True
+            return found
 
         # Since the parser doesn't parse traceroute output, we need to cheat and look
         # the host up in the Nmap output, in the Traceroute section of the scan.
@@ -426,9 +500,9 @@ class SearchResult(object):
 
         for tr in traceroutes:
             if host.lower() in tr.lower():
-                return True
+                return found
         else:
-            return False
+            return not found
 
     def match_dir(self, dir):
         # The dir: operator is handled by the SearchParser class, we ignore it here.
