diff --git a/include/Entity.php b/include/Entity.php
new file mode 100644
index 0000000..4edcd23
--- /dev/null
+++ b/include/Entity.php
@@ -0,0 +1,27 @@
+<?php
+class Entity {
+    protected function __construct() {
+        
+    }
+    
+    protected function specify_search($searchterms, $searchfields) {
+        if(array_key_exists('fritext', $searchterms)) {
+            $freeterm = $searchterms['fritext'];
+            unset($searchterms['fritext']);
+            foreach($searchfields as $field) {
+                if(array_key_exists($field, $searchterms)) {
+                    $term = $searchterms[$field];
+                    if(is_array($term)) {
+                        $term[] = $freeterm;
+                    } else {
+                        $searchterms[$field] = array($term, $freeterm);
+                    }
+                } else {
+                    $searchterms[$field] = $freeterm;
+                }
+            }
+        }
+        return $searchterms;
+    }
+}
+?>
diff --git a/include/Product.php b/include/Product.php
index 7c0a0e6..c4f342b 100644
--- a/include/Product.php
+++ b/include/Product.php
@@ -1,5 +1,5 @@
 <?php
-class Product {
+class Product extends Entity {
     private $id = 0;
     private $brand = '';
     private $name = '';
@@ -43,6 +43,7 @@ class Product {
     }
     
     public function __construct($clue, $type = 'id') {
+        parent::__construct();
         $search = null;
         switch($type) {
             case 'id':
@@ -110,34 +111,36 @@ class Product {
     }
 
     public function matches($terms) {
+        $terms = $this->specify_search($terms, array('brand',
+                                                     'name',
+                                                     'serial',
+                                                     'invoice',
+                                                     'status',
+                                                     'tag'));
+        $matches = array();
         foreach($terms as $field => $values) {
-            $matchvalues = array();
             if(property_exists($this, $field)) {
-                $matchvalues[] = $this->$field;
+                if(match($values, $this->$field)) {
+                    $matches[$field] = $this->$field;
+                }
             } else if(array_key_exists($field, $this->get_info())) {
-                $matchvalues[] = $this->get_info()[$field];
-            } else {
-                switch($field) {
-                    case 'tag':
-                        $matchvalues = $this->get_tags();
-                    case 'status':
-                        $matchvalues[] = $this->get_status();
-                    case 'fritext':
-                        $matchvalues[] = $this->brand;
-                        $matchvalues[] = $this->name;
-                        $matchvalues[] = $this->serial;
-                        $matchvalues[] = $this->invoice;
-                        $matchvalues = array_merge($matchvalues,
-                                                   $this->get_tags(),
-                                                   array_values(
-                                                       $this->get_info()));
+                if(match($values, $this->get_info()[$field])) {
+                    $matches[$field] = $this->get_info()[$field];
+                }
+            } else if($field == 'tag') {
+                foreach($this->get_tags() as $tag) {
+                    if(match($values, $tag)) {
+                        $matches['tags'] = $this->get_tags();
+                        break;
+                    }
+                }
+            } else if($field == 'status') {
+                if(match($values, $this->get_status())) {
+                    $matches['status'] = $this->get_status();
                 }
             }
-            if(!match($values, $matchvalues)) {
-                return false;
-            }
         }
-        return true;
+        return $matches;
     }
 
     public function get_id() {
diff --git a/include/SearchPage.php b/include/SearchPage.php
index e89111f..e1a3f8e 100644
--- a/include/SearchPage.php
+++ b/include/SearchPage.php
@@ -132,8 +132,9 @@ class SearchPage extends Page {
         $items = get_items($type);
         $out = array();
         foreach($items as $item) {
-            if($item->matches($terms)) {
-                $out[] = $item;
+            $result = $item->matches($terms);
+            if($result) {
+                $out[] = array($item, $result);
             }
         }
         return $out;
@@ -158,11 +159,17 @@ class SearchPage extends Page {
         }
         $products = 'Inga artiklar hittade.';
         if($this->product_hits) {
-            $products = $this->build_product_table($this->product_hits);
+            $products = '';
+            foreach($this->product_hits as $hit) {
+                $products .= $this->render_product($hit[0], $hit[1]);
+            }
         }
         $users = 'Inga användare hittade.';
         if($this->user_hits) {
-            $users = $this->build_user_table($this->user_hits);
+            $users = '';
+            foreach($this->user_hits as $hit) {
+                $users .= $this->render_user($hit[0], $hit[1]);
+            }
         }
         print(replace(array('terms' => $terms,
                             'hidden' => $hidden,
@@ -170,5 +177,29 @@ class SearchPage extends Page {
                             'user_results' => $users),
                       $this->fragments['search_form']));
     }
+
+    private function render_product($product, $matches) {
+        $link = replace(array('id' => $product->get_id(),
+                              'name' => $product->get_name(),
+                              'page' => 'products'),
+                        $this->fragments['item_link']);
+
+        $data =  print_r($matches, true);
+        
+        return $link . '<br/>'
+             . $data . '<br/>';
+    }
+
+    private function render_user($user, $matches) {
+        $link = replace(array('id' => $user->get_id(),
+                              'name' => $user->get_name(),
+                              'page' => 'users'),
+                        $this->fragments['item_link']);
+
+        $data =  print_r($matches, true);
+        
+        return $link . '<br/>'
+             . $data . '<br/>';
+    }
 }
 ?>
diff --git a/include/User.php b/include/User.php
index 80ed297..aee33f5 100644
--- a/include/User.php
+++ b/include/User.php
@@ -1,5 +1,5 @@
 <?php
-class User {
+class User extends Entity {
     private $id = 0;
     private $name = '';
     private $notes = '';
@@ -13,6 +13,7 @@ class User {
     }
 
     public function __construct($clue, $type = 'id') {
+        parent::__construct();
         $find = null;
         switch($type) {
             case 'id':
@@ -47,25 +48,34 @@ class User {
     }
 
     public function matches($terms) {
+        $terms = $this->specify_search($terms, array('name',
+                                                     'email',
+                                                     'notes'));
+        $matches = array();
         foreach($terms as $field => $values) {
-            $matchvalues = array();
-            if($field == 'name') {
-                $matchvalues[] = $this->name;
-                $matchvalues[] = $this->get_displayname();
-            } else if(property_exists($this, $field)) {
-                $matchvalues[] = $this->$field;
-            } else if($field == 'fritext') {
-                $matchvalues[] = $this->name;
-                $matchvalues[] = $this->get_displayname();
-                $matchvalues[] = $this->notes;
-            } else {
-                return false;
-            }
-            if(!match($values, $matchvalues)) {
-                return false;
+            switch($field) {
+                case 'name':
+                    if(match($values, $this->name)) {
+                        $matches['name'] = $this->name;
+                    }
+                    if(match($values, $this->get_displayname())) {
+                        $matches['displayname'] = $this->get_displayname();
+                    }
+                    break;
+                case 'email':
+                    if($this->get_email(false) && match($values,
+                                                        $this->get_email())) {
+                        $matches['email'] = $this->get_email();
+                    }
+                    break;
+                case 'notes':
+                    if(match($values, $this->notes)) {
+                        $matches['notes'] = $this->notes;
+                    }
+                    break;
             }
         }
-        return true;
+        return $matches;
     }
 
     public function get_displayname() {
@@ -76,11 +86,14 @@ class User {
         }
     }
 
-    public function get_email() {
+    public function get_email($format = true) {
         try {
             return $this->ldap->get_user_email($this->name);
         } catch(Exception $e) {
-            return 'Mailadress saknas';
+            if($format) {
+                return 'Mailadress saknas';
+            }
+            return false;
         }
     }
 
diff --git a/include/functions.php b/include/functions.php
index 712ee91..099b4bb 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -253,19 +253,13 @@ function suggest_content($fieldname) {
     return $out;
 }
 
-function match($testvalues, $matchvalues) {
-    # match only presence of field (if no value given)
-    if(!$testvalues && $matchvalues) {
-        return true;
+function match($searchterms, $subject) {
+    if(!is_array($searchterms)) {
+        $searchterms = array($searchterms);
     }
-    if(!is_array($testvalues)) {
-        $testvalues = array($testvalues);
-    }
-    foreach($testvalues as $value) {
-        foreach($matchvalues as $candidate) {
-            if(fnmatch('*'.$value.'*', $candidate, FNM_CASEFOLD)) {
-                return true;
-            }
+    foreach($searchterms as $term) {
+        if(fnmatch('*'.$term.'*', $subject, FNM_CASEFOLD)) {
+            return true;
         }
     }
     return false;