Index: common/db/task.php
===================================================================
--- common/db/task.php	(revision 1094)
+++ common/db/task.php	(working copy)
@@ -172,4 +172,67 @@
     return array_values($rounds);
 }
 
+function task_get_authors($task_id, $no_cache = false) {
+    log_assert(is_task_id($task_id), 'Invalid task_id');
+    
+    $authors = false;
+    if (!$no_cache) {
+        $authors = mem_cache_get("task-authors-by-id:".$task_id);
+    }
+
+    if ($authors === false) {
+        $authors = tag_get("task", $task_id, "author");
+        mem_cache_set("task-authors-by-id:".$task_id, $authors);
+    }
+    
+    return $authors;
+}
+
+// Task filter
+// Returns only tasks that contain all the tags
+// and are in 'arhiva' or in 'arhiva-educationala'
+// Task from 'arhiva-educationala' are shown first
+function task_filter_by_tags($tag_ids, $scores = true, $user_id = null) {
+    log_assert(is_array($tag_ids), "tag_ids must be an array");
+    foreach ($tag_ids as $tag_id) {
+        log_assert(is_tag_id($tag_id), "invalid tag id");
+    }
+
+    if (count($tag_ids) > 0) {
+        $tag_filter = "AND ".tag_build_where('task', $tag_ids);
+    } else {
+        $tag_filter = "";
+    }
+
+    if ($user_id == null || $scores == false) {
+        $join_score = "";
+        $score_fields = "";
+    } else {
+        $join_score = "LEFT JOIN ia_score ON ia_score.user_id = ".db_quote($user_id)." AND
+                            ia_score.round_id = round.id AND
+                            ia_score.task_id = ia_task.id AND 
+                            ia_score.name = 'score'";
+        $score_fields = "ia_score.score,";
+    }
+
+    $query = "SELECT ia_task.id AS task_id,
+                ia_task.title AS task_title,
+                ia_task.order AS 'order',
+                ia_task.page_name AS page_name,
+                ia_task.open_source AS open_source,
+                ia_task.open_tests AS open_tests,
+                round.id AS round_id,
+                $score_fields
+                round.title AS round_title
+    FROM ia_task
+    LEFT JOIN ia_round_task AS round_task ON round_task.task_id = ia_task.id
+    LEFT JOIN ia_round AS round ON round.id = round_task.round_id
+    $join_score
+    WHERE (round.id = 'arhiva' OR round.id = 'arhiva-educationala')
+        AND ia_task.hidden = '0' $tag_filter
+    ORDER BY round.id DESC, ia_task.order";
+    $tasks = db_fetch_all($query);
+
+    return $tasks;
+}
 ?>
Index: www/controllers/task.php
===================================================================
--- www/controllers/task.php	(revision 1094)
+++ www/controllers/task.php	(working copy)
@@ -329,4 +329,40 @@
     execute_view_die('views/task_tag_edit.php', $view);
 }
 
+// Gets a list of tags from request
+// Prints a list of tasks that contain all those tags
+// Tasks must be in 'arhiva' or in 'arhiva educationala'
+function controller_task_search() {
+    $tags = request('tag_id', null);
+    if (is_null($tags)) {
+        $tags = Array();
+    }
+
+    if (!is_array($tags)) {
+        flash_error("Url invalid");
+        redirect(url_home());
+    }
+
+    foreach ($tags as $tag) {
+        if (!is_tag_id($tag)) {
+            flash_error("Url invalid");
+            redirect(url_home());
+        }
+    }
+
+    if (identity_is_anonymous()) {
+        $user_id = null;
+    } else {
+        $user_id = identity_get_user_id();
+    }
+    $tasks = task_filter_by_tags($tags, true, $user_id);
+    foreach ($tasks as &$task) {
+        $task['authors'] = task_get_authors($task['task_id']);
+    }
+    
+    $view['title'] = "Rezultatele filtrării";
+    $view['tasks'] = $tasks;
+    execute_view_die('views/task_filter_results.php', $view);
+}
+
 ?>
Index: www/index.php
===================================================================
--- www/index.php	(revision 1094)
+++ www/index.php	(working copy)
@@ -82,6 +82,12 @@
     controller_task_delete(request("task_id"));
 }
 
+// Task search
+else if ($page == 'cauta-probleme') {
+    require_once(IA_ROOT_DIR.'www/controllers/task.php');
+    controller_task_search();
+}
+
 // Task detail editor
 else if ($urlstart == 'admin' && getattr($pagepath, 1) == 'problema') {
     require_once(IA_ROOT_DIR.'www/controllers/task.php');
Index: www/macros/macro_algorithmtags.php
===================================================================
--- www/macros/macro_algorithmtags.php	(revision 1094)
+++ www/macros/macro_algorithmtags.php	(working copy)
@@ -50,13 +50,16 @@
 
         $subtags_html = Array();
         foreach ($tag['sub_tags'] as $subtag) {
-            $subtags_html[] = '<div class="sub_tag_name">'.$subtag['name'].'</div>';
+            $tag_link = format_link(url_task_search(array($tag_id)), $subtag['name'], true, 
+                            array('class' => "sub_tag_search_anchor"));
+            $subtags_html[] = '<div class="sub_tag_name">'.$tag_link.'</div>';
         }
 
         $color_scheme = $tag_id % 6;
+        $tag_link = format_link(url_task_search(array($tag_id)), $tag_name, true, array('class' => 'tag_search_anchor'));
         $html_code .= '
         <li style="display: none;" class="tags_list_item">
-            <span class="tag_name color_scheme_'.$color_scheme.'">'.html_escape($tag_name).'</span>
+            <span class="tag_name color_scheme_'.$color_scheme.'">'.$tag_link.'</span>
             <a href="javascript:show_tag_list('.html_escape($tag_id).')"
                     id="tag_anchor_'.html_escape($tag_id).'"
                     class="show_tag_anchor"
@@ -65,8 +68,8 @@
             </a>
             <div style="display: none;"
                 id="tag_list_'.html_escape($tag_id).'"
-            >:
-                '.implode(' ', $subtags_html).'
+            >&nbsp;
+                '.implode('&nbsp;', $subtags_html).'
             </div>
         </li>';
     }
Index: www/macros/macro_taskparam.php
===================================================================
--- www/macros/macro_taskparam.php	(revision 1094)
+++ www/macros/macro_taskparam.php	(working copy)
@@ -51,11 +51,7 @@
             return html_escape($task['title']);
 
         case 'author':
-            $authors = mem_cache_get("task-authors-by-id:".$task["id"]);
-            if ($authors === false) {
-                $authors = tag_get("task", $task["id"], "author");
-                mem_cache_set("task-authors-by-id:".$task["id"], $authors);
-            }
+            $authors = task_get_authors($task['id']);
             function format_author($tag) {
                 return format_link(url_task_search(array($tag["id"])), $tag["name"]);
             }
Index: www/macros/macro_tasks.php
===================================================================
--- www/macros/macro_tasks.php	(revision 1094)
+++ www/macros/macro_tasks.php	(working copy)
@@ -4,6 +4,7 @@
 require_once(IA_ROOT_DIR . "www/format/table.php");
 require_once(IA_ROOT_DIR . "www/format/pager.php");
 require_once(IA_ROOT_DIR . "common/db/round.php");
+require_once(IA_ROOT_DIR . "common/db/task.php");
 require_once(IA_ROOT_DIR . "common/round.php");
 
 function format_score_column($val) {
@@ -27,12 +28,9 @@
 function format_single_author($tag) {
     return format_link(url_task_search(array($tag["id"])), $tag["name"]);
 }
+
 function format_author($row) {
-    $authors = mem_cache_get("task-authors-by-id:".$row["id"]);
-    if ($authors === false) {
-        $authors = tag_get("task", $row["id"], "author");
-        mem_cache_set("task-authors-by-id:".$row["id"], $authors);
-    }
+    $authors = task_get_authors($row['id']);
     return implode(", ", array_map('format_single_author', $authors));
 }
 
Index: www/static/css/sitewide.css
===================================================================
--- www/static/css/sitewide.css	(revision 1094)
+++ www/static/css/sitewide.css	(working copy)
@@ -309,6 +309,24 @@
     padding-left: 0.4em;
 }
 
+a.sub_tag_search_anchor {
+    color: #000000;
+    outline-style: none;
+}
+
+a.sub_tag_search_anchor:hover {
+    text-decoration: none;
+}
+
+a.tag_search_anchor {
+    color: #FFF0E1;
+    outline-style: none;
+}
+
+a.tag_search_anchor:hover {
+    text-decoration: none;
+}
+
 .tag_name.color_scheme_0 {
     background-color: rgb(204, 0, 0);
 }
@@ -336,3 +354,7 @@
 .show_tag_anchor {
     font-size: 10px;
 }
+
+table.filter_results {
+    width: 99%;
+}
Index: www/url.php
===================================================================
--- www/url.php	(revision 1094)
+++ www/url.php	(working copy)
@@ -51,12 +51,19 @@
             continue;
         }
         if ($k != 'page') {
-            $url .= ($first ? "?" : "&");
-            $first = false;
-            $url .= $k . '=' . urlencode($v);
+            if (is_array($v)) {
+                foreach ($v as $sv) {
+                    $url .= ($first ? "?" : "&");
+                    $first = false;
+                    $url .= $k. '[]=' . urlencode($sv);
+                }
+            } else {
+                $url .= ($first ? "?" : "&");
+                $first = false;
+                $url .= $k . '=' . urlencode($v);
+            }
         }
     }
-
     return $url;
 }
 
@@ -266,8 +273,8 @@
 }
 
 function url_task_search($tag_ids) {
-    // STUB
-    return "#" . implode("#", array_map('html_escape', $tag_ids));
+    log_assert(is_array($tag_ids), "Tag ids must be an array");
+    return url_complex("cauta-probleme", array("tag_id" => $tag_ids));
 }
 
 function url_task_list($page_name, $filter = null) {
Index: www/views/task_filter_results.php
===================================================================
--- www/views/task_filter_results.php	(revision 0)
+++ www/views/task_filter_results.php	(revision 0)
@@ -0,0 +1,94 @@
+<?php
+include('header.php');
+include('format/table.php');
+
+function format_title($row) {
+    $title = "<span style=\"float:left;\">".format_link(url_textblock($row["page_name"]), $row["task_title"])."</span>";
+    if ($row['open_source'] || $row['open_tests']) {
+        $title .= "<span style=\"float:right;\">";
+        $title .= format_link(url_task($row['task_id']), format_img(url_static("images/open_small.png"), ""), false);
+        $title .= "</span>";
+    }
+    return $title;
+}
+
+function format_score_column($val) {
+    if (is_null($val)) {
+        return 'N/A';
+    } else {
+        return round($val);
+    }
+}
+
+function format_single_author($tag) {
+    return format_link(url_task_search(array($tag["id"])), $tag["name"]);
+}
+
+function format_authors($row) {
+    $authors = $row['authors'];
+    return implode(", ", array_map('format_single_author', $authors));
+}
+
+function task_row_style($row) {
+    $score = getattr($row, 'score');
+    if (is_null($score)) {
+        return '';
+    }
+
+    log_assert(is_numeric($score));
+    $score = (int)$score;
+
+    if (100 == $score) {
+        return 'solved';
+    }
+    else {
+        return 'tried';
+    }
+}
+
+echo "<h1>Rezultatele Filtrarii</h1>";
+$tasks = $view['tasks'];
+$options = pager_init_options();
+$options['total_entries'] = count($tasks);
+$options['row_style'] = 'task_row_style';
+$options['css_class'] = 'tasks filter_results';
+$options['show_count'] = true;
+$options['show_display_entries'] = false;
+
+if (identity_is_anonymous()) {
+    $user_id = null;
+} else {
+    $user_id = identity_get_user_id();
+}
+
+$column_infos = array();
+$column_infos[] = array(
+        'title' => 'Numar',
+        'css_class' => 'number',
+        'rowform' => create_function_cached('$row',
+        'return str_pad($row["order"] - 1, 3, \'0\', STR_PAD_LEFT);'));
+ 
+$column_infos[] = array(
+        'title' => 'Titlul problemei',
+        'css_class' => 'task',
+        'rowform' => 'format_title');
+$column_infos[] = array(
+        'title' => 'Autor(i)',
+        'rowform' => 'format_authors');
+$column_infos[] = array(
+        'title' => 'Sursa',
+        'css_class' => 'source',
+        'key' => 'round_title',);
+if (!is_null($user_id)) {
+    $column_infos[] = array (
+            'title' => 'Scorul tau',
+            'css_class' => 'number score',
+            'key' => 'score',
+            'valform' => 'format_score_column');
+}
+
+$task_chunks = array_chunk($tasks, $options['display_entries']);
+$chunk = $task_chunks[$options['first_entry'] / $options['display_entries']];
+echo format_table($chunk, $column_infos, $options);
+include('footer.php');
+?>
