diff --git a/src/main/java/com/gitblit/wicket/pages/MyTicketsPage.java b/src/main/java/com/gitblit/wicket/pages/MyTicketsPage.java
index 4da1dcd..7b85b14 100644
--- a/src/main/java/com/gitblit/wicket/pages/MyTicketsPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/MyTicketsPage.java
@@ -17,6 +17,10 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.wicket.PageParameters;
@@ -53,271 +57,288 @@
  */
 public class MyTicketsPage extends RootPage {
 
-	public MyTicketsPage() {
-		this(null);
-	}
+    public MyTicketsPage() {
+        this(null);
+    }
 
-	public MyTicketsPage(PageParameters params)	{
-		super(params);
-		setupPage("", getString("gb.myTickets"));
+    public MyTicketsPage(PageParameters params) {
+        super(params);
+        setupPage("", getString("gb.myTickets"));
 
-		UserModel currentUser = GitBlitWebSession.get().getUser();
-		if (currentUser == null || UserModel.ANONYMOUS.equals(currentUser)) {
-			setRedirect(true);
-			setResponsePage(getApplication().getHomePage());
-			return;
-		}
+        UserModel currentUser = GitBlitWebSession.get().getUser();
+        if (currentUser == null || UserModel.ANONYMOUS.equals(currentUser)) {
+            setRedirect(true);
+            setResponsePage(getApplication().getHomePage());
+            return;
+        }
 
-		final String username = currentUser.getName();
-		final String[] statiiParam = (params == null) ? TicketsUI.openStatii : params.getStringArray(Lucene.status.name());
-		final String assignedToParam = (params == null) ? "" : params.getString(Lucene.responsible.name(), null);
-		final String milestoneParam = (params == null) ? "" : params.getString(Lucene.milestone.name(), null);
-		final String queryParam = (params == null || StringUtils.isEmpty(params.getString("q", null))) ? "watchedby:" + username : params.getString("q", null);
-		final String searchParam = (params == null) ? "" : params.getString("s", null);
-		final String sortBy = (params == null) ? "" : Lucene.fromString(params.getString("sort", Lucene.created.name())).name();
-		final String repositoryId = (params == null) ? "" : params.getString(Lucene.rid.name(), null);
-		final boolean desc = (params == null) ? true : !"asc".equals(params.getString("direction", "desc"));
+        final String username = currentUser.getName();
+        final String defaultQueryParam = "watchedby:"+username;
 
-		// add the user title panel
-		add(new UserTitlePanel("userTitlePanel", currentUser, getString("gb.myTickets")));
+        final String[] statiiParam = (params == null) ? TicketsUI.openStatii : params.getStringArray(Lucene.status.name());
+        final String assignedToParam = (params == null) ? "" : params.getString(Lucene.responsible.name(), null);
+        final String milestoneParam = (params == null) ? "" : params.getString(Lucene.milestone.name(), null);
+        final String queryParam = (params == null || StringUtils.isEmpty(params.getString("q", null))) ? defaultQueryParam : params.getString("q", null);
+        final String searchParam = (params == null) ? "" : params.getString("s", null);
+        final String sortBy = (params == null) ? "" : Lucene.fromString(params.getString("sort", Lucene.created.name())).name();
+        final String repositoryId = (params == null) ? "" : params.getString(Lucene.rid.name(), null);
+        final boolean desc = (params == null) ? true : !"asc".equals(params.getString("direction", "desc"));
 
-		// add search form
-		add(new TicketSearchForm("ticketSearchForm", null, searchParam, getClass(), params));
 
-		// standard queries
-		add(new BookmarkablePageLink<Void>("changesQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Proposal.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        // add the user title panel
+        add(new UserTitlePanel("userTitlePanel", currentUser, getString("gb.myTickets")));
+
+        // add search form
+        add(new TicketSearchForm("ticketSearchForm", null, searchParam, getClass(), params));
+
+        // standard queries
+        add(new BookmarkablePageLink<Void>("changesQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Proposal.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("bugsQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Bug.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new BookmarkablePageLink<Void>("bugsQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Bug.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("enhancementsQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Enhancement.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new BookmarkablePageLink<Void>("enhancementsQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Enhancement.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("tasksQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Task.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new BookmarkablePageLink<Void>("tasksQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Task.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("questionsQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Question.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new BookmarkablePageLink<Void>("questionsQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Question.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
-		
-		add(new BookmarkablePageLink<Void>("maintenanceQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.type.matches(TicketModel.Type.Maintenance.name()),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+                        1)));
+        
+        add(new BookmarkablePageLink<Void>("maintenanceQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.type.matches(TicketModel.Type.Maintenance.name()),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("resetQuery", MyTicketsPage.class,
-				queryParameters(
-						null,
-						milestoneParam,
-						TicketsUI.openStatii,
-						null,
-						null,
-						true,
+        add(new BookmarkablePageLink<Void>("resetQuery", MyTicketsPage.class,
+                queryParameters(
                         null,
-						1)));
+                        milestoneParam,
+                        TicketsUI.openStatii,
+                        null,
+                        null,
+                        true,
+                        null,
+                        1)));
 
-		add(new Label("userDivider"));
-		add(new BookmarkablePageLink<Void>("createdQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.createdby.matches(username),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new Label("userDivider"));
+        add(new BookmarkablePageLink<Void>("createdQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.createdby.matches(username),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		add(new BookmarkablePageLink<Void>("watchedQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.watchedby.matches(username),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+        add(new BookmarkablePageLink<Void>("watchedQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.watchedby.matches(username),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
-		add(new BookmarkablePageLink<Void>("mentionsQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.mentions.matches(username),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+                        1)));
+        add(new BookmarkablePageLink<Void>("mentionsQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.mentions.matches(username),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
-		add(new BookmarkablePageLink<Void>("responsibleQuery", MyTicketsPage.class,
-				queryParameters(
-						Lucene.responsible.matches(username),
-						milestoneParam,
-						statiiParam,
-						assignedToParam,
-						sortBy,
-						desc,
+                        1)));
+        add(new BookmarkablePageLink<Void>("responsibleQuery", MyTicketsPage.class,
+                queryParameters(
+                        Lucene.responsible.matches(username),
+                        milestoneParam,
+                        statiiParam,
+                        assignedToParam,
+                        sortBy,
+                        desc,
                         repositoryId,
-						1)));
+                        1)));
 
-		// states
-		if (ArrayUtils.isEmpty(statiiParam)) {
-			add(new Label("selectedStatii", getString("gb.all")));
-		} else {
-			add(new Label("selectedStatii", StringUtils.flattenStrings(Arrays.asList(statiiParam), ",")));
-		}
-		add(new BookmarkablePageLink<Void>("openTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.openStatii, assignedToParam, sortBy, desc, repositoryId, 1)));
-		add(new BookmarkablePageLink<Void>("closedTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.closedStatii, assignedToParam, sortBy, desc, repositoryId, 1)));
-		add(new BookmarkablePageLink<Void>("allTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, null, assignedToParam, sortBy, desc, repositoryId, 1)));
+        // states
+        if (ArrayUtils.isEmpty(statiiParam)) {
+            add(new Label("selectedStatii", getString("gb.all")));
+        } else {
+            add(new Label("selectedStatii", StringUtils.flattenStrings(Arrays.asList(statiiParam), ",")));
+        }
+        add(new BookmarkablePageLink<Void>("openTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.openStatii, assignedToParam, sortBy, desc, repositoryId, 1)));
+        add(new BookmarkablePageLink<Void>("closedTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, TicketsUI.closedStatii, assignedToParam, sortBy, desc, repositoryId, 1)));
+        add(new BookmarkablePageLink<Void>("allTickets", MyTicketsPage.class, queryParameters(queryParam, milestoneParam, null, assignedToParam, sortBy, desc, repositoryId, 1)));
 
-		// by status
-		List<Status> statii = new ArrayList<Status>(Arrays.asList(Status.values()));
-		statii.remove(Status.Closed);
-		ListDataProvider<Status> resolutionsDp = new ListDataProvider<Status>(statii);
-		DataView<Status> statiiLinks = new DataView<Status>("statii", resolutionsDp) {
-			private static final long serialVersionUID = 1L;
+        // by status
+        List<Status> statii = new ArrayList<Status>(Arrays.asList(Status.values()));
+        statii.remove(Status.Closed);
+        ListDataProvider<Status> resolutionsDp = new ListDataProvider<Status>(statii);
+        DataView<Status> statiiLinks = new DataView<Status>("statii", resolutionsDp) {
+            private static final long serialVersionUID = 1L;
 
-			@Override
-			public void populateItem(final Item<Status> item) {
-				final Status status = item.getModelObject();
-				PageParameters p = queryParameters(queryParam, milestoneParam, new String [] { status.name().toLowerCase() }, assignedToParam, sortBy, desc, repositoryId, 1);
-				String css = TicketsUI.getStatusClass(status);
-				item.add(new LinkPanel("statusLink", css, status.toString(), MyTicketsPage.class, p).setRenderBodyOnly(true));
-			}
-		};
-		add(statiiLinks);
+            @Override
+            public void populateItem(final Item<Status> item) {
+                final Status status = item.getModelObject();
+                PageParameters p = queryParameters(queryParam, milestoneParam, new String [] { status.name().toLowerCase() }, assignedToParam, sortBy, desc, repositoryId, 1);
+                String css = TicketsUI.getStatusClass(status);
+                item.add(new LinkPanel("statusLink", css, status.toString(), MyTicketsPage.class, p).setRenderBodyOnly(true));
+            }
+        };
+        add(statiiLinks);
 
         // by sort
-		List<TicketSort> sortChoices = new ArrayList<TicketSort>();
-		sortChoices.add(new TicketSort(getString("gb.sortNewest"), Lucene.created.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortOldest"), Lucene.created.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortMostRecentlyUpdated"), Lucene.updated.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLeastRecentlyUpdated"), Lucene.updated.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortMostComments"), Lucene.comments.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLeastComments"), Lucene.comments.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortMostPatchsetRevisions"), Lucene.patchsets.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLeastPatchsetRevisions"), Lucene.patchsets.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortMostVotes"), Lucene.votes.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLeastVotes"), Lucene.votes.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortHighestPriority"), Lucene.priority.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLowestPriority"), Lucene.priority.name(), false));
-		sortChoices.add(new TicketSort(getString("gb.sortHighestSeverity"), Lucene.severity.name(), true));
-		sortChoices.add(new TicketSort(getString("gb.sortLowestSeverity"), Lucene.severity.name(), false));
+        List<TicketSort> sortChoices = new ArrayList<TicketSort>();
+        sortChoices.add(new TicketSort(getString("gb.sortNewest"), Lucene.created.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortOldest"), Lucene.created.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortMostRecentlyUpdated"), Lucene.updated.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLeastRecentlyUpdated"), Lucene.updated.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortMostComments"), Lucene.comments.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLeastComments"), Lucene.comments.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortMostPatchsetRevisions"), Lucene.patchsets.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLeastPatchsetRevisions"), Lucene.patchsets.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortMostVotes"), Lucene.votes.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLeastVotes"), Lucene.votes.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortHighestPriority"), Lucene.priority.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLowestPriority"), Lucene.priority.name(), false));
+        sortChoices.add(new TicketSort(getString("gb.sortHighestSeverity"), Lucene.severity.name(), true));
+        sortChoices.add(new TicketSort(getString("gb.sortLowestSeverity"), Lucene.severity.name(), false));
 
-		TicketSort currentSort = sortChoices.get(0);
-		for (TicketSort ts : sortChoices) {
-			if (ts.sortBy.equals(sortBy) && desc == ts.desc) {
-				currentSort = ts;
-				break;
-			}
-		}
-		add(new Label("currentSort", currentSort.name));
+        TicketSort currentSort = sortChoices.get(0);
+        for (TicketSort ts : sortChoices) {
+            if (ts.sortBy.equals(sortBy) && desc == ts.desc) {
+                currentSort = ts;
+                break;
+            }
+        }
+        add(new Label("currentSort", currentSort.name));
 
-		ListDataProvider<TicketSort> sortChoicesDp = new ListDataProvider<TicketSort>(sortChoices);
-		DataView<TicketSort> sortMenu = new DataView<TicketSort>("sort", sortChoicesDp) {
-			private static final long serialVersionUID = 1L;
+        ListDataProvider<TicketSort> sortChoicesDp = new ListDataProvider<TicketSort>(sortChoices);
+        DataView<TicketSort> sortMenu = new DataView<TicketSort>("sort", sortChoicesDp) {
+            private static final long serialVersionUID = 1L;
 
-			@Override
-			public void populateItem(final Item<TicketSort> item) {
-				final TicketSort ts = item.getModelObject();
-				PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, assignedToParam, ts.sortBy, ts.desc, repositoryId, 1);
-				item.add(new LinkPanel("sortLink", null, ts.name, MyTicketsPage.class, params).setRenderBodyOnly(true));
-			}
-		};
-		add(sortMenu);
+            @Override
+            public void populateItem(final Item<TicketSort> item) {
+                final TicketSort ts = item.getModelObject();
+                PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, assignedToParam, ts.sortBy, ts.desc, repositoryId, 1);
+                item.add(new LinkPanel("sortLink", null, ts.name, MyTicketsPage.class, params).setRenderBodyOnly(true));
+            }
+        };
+        add(sortMenu);
 
         // by repository
-		List<RepositoryModel> repositoryChoices = getRepositoryModels();
-        RepositoryModel noneChoice = new RepositoryModel();
+        final List<QueryResult> tickets =
+            query(initializeQueryBuilder(defaultQueryParam, username), 1, Integer.MAX_VALUE, sortBy, desc);
+        final List<RepositoryModel> repositoryChoices = correspondingRepositories(tickets);
+        Collections.sort(repositoryChoices, new Comparator<RepositoryModel>() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public int compare(RepositoryModel repository1, RepositoryModel repository2) {
+                return repository1.toString().compareTo(repository2.toString());
+            }
+        });
+
+        final RepositoryModel noneChoice = new RepositoryModel();
         noneChoice.name = getString("gb.all");
         repositoryChoices.add(0, noneChoice);
-		RepositoryModel currentRepository = repositoryChoices.size() > 0 ? repositoryChoices.get(0) : null;
-		for (RepositoryModel r : repositoryChoices) {
-			if (r.getRID().equals(repositoryId)) {
-				currentRepository = r;
-				break;
-			}
-		}
-		add(new Label("currentRepository", currentRepository == null ? "none" : currentRepository.toString()));
 
-		ListDataProvider<RepositoryModel> repositoryChoicesDp = new ListDataProvider<RepositoryModel>(repositoryChoices);
-		DataView<RepositoryModel> repositoryMenu = new DataView<RepositoryModel>("repository", repositoryChoicesDp) {
-			private static final long serialVersionUID = 1L;
+        RepositoryModel currentRepository = repositoryChoices.size() > 0 ? repositoryChoices.get(0) : null;
+        for (RepositoryModel r : repositoryChoices) {
+            if (r.getRID().equals(repositoryId)) {
+                currentRepository = r;
+                break;
+            }
+        }
+        add(new Label("currentRepository", currentRepository == null ? "none" : currentRepository.toString()));
 
-			@Override
-			public void populateItem(final Item<RepositoryModel> item) {
-				final RepositoryModel r = item.getModelObject();
-				PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, assignedToParam, sortBy, desc, r.getRID(), 1);
-				item.add(new LinkPanel("repositoryLink", null, r.toString(), MyTicketsPage.class, params).setRenderBodyOnly(true));
-			}
-		};
-		add(repositoryMenu);
+        ListDataProvider<RepositoryModel> repositoryChoicesDp = new ListDataProvider<RepositoryModel>(repositoryChoices);
+        DataView<RepositoryModel> repositoryMenu = new DataView<RepositoryModel>("repository", repositoryChoicesDp) {
+            private static final long serialVersionUID = 1L;
 
-		// Build Query here
-		QueryBuilder qb = new QueryBuilder(queryParam);
-		if (!qb.containsField(Lucene.status.name()) && !ArrayUtils.isEmpty(statiiParam)) {
-			// specify the states
-			boolean not = false;
-			QueryBuilder q = new QueryBuilder();
-			for (String state : statiiParam) {
-				if (state.charAt(0) == '!') {
-					not = true;
-					q.and(Lucene.status.doesNotMatch(state.substring(1)));
-				} else {
-					q.or(Lucene.status.matches(state));
-				}
-			}
-			if (not) {
-				qb.and(q.toString());
-			} else {
-				qb.and(q.toSubquery().toString());
-			}
-		}
+            @Override
+            public void populateItem(final Item<RepositoryModel> item) {
+                final RepositoryModel r = item.getModelObject();
+                PageParameters params = queryParameters(queryParam, milestoneParam, statiiParam, assignedToParam, sortBy, desc, r.getRID(), 1);
+                item.add(new LinkPanel("repositoryLink", null, r.toString(), MyTicketsPage.class, params).setRenderBodyOnly(true));
+            }
+        };
+        add(repositoryMenu);
+
+        // Update query with filter criteria
+        final QueryBuilder qb = initializeQueryBuilder(queryParam, username);
+
+        if (!qb.containsField(Lucene.status.name()) && !ArrayUtils.isEmpty(statiiParam)) {
+            // specify the states
+            boolean not = false;
+            QueryBuilder q = new QueryBuilder();
+            for (String state : statiiParam) {
+                if (state.charAt(0) == '!') {
+                    not = true;
+                    q.and(Lucene.status.doesNotMatch(state.substring(1)));
+                } else {
+                    q.or(Lucene.status.matches(state));
+                }
+            }
+
+            if (not) {
+                qb.and(q.toString());
+            } else {
+                qb.and(q.toSubquery().toString());
+            }
+        }
 
         if (noneChoice != currentRepository && !qb.containsField(Lucene.rid.name())) {
             QueryBuilder q1 = new QueryBuilder();
@@ -325,134 +346,153 @@
             qb.and(q1.toSubquery().toString());
         }
 
-		final String luceneQuery;
-		if (qb.containsField(Lucene.createdby.name())
-				|| qb.containsField(Lucene.responsible.name())
-				|| qb.containsField(Lucene.watchedby.name())) {
-			// focused "my tickets" query
-			luceneQuery = qb.build();
-		} else {
-			// general "my tickets" query
-			QueryBuilder myQuery = new QueryBuilder();
-			myQuery.or(Lucene.createdby.matches(username));
-			myQuery.or(Lucene.responsible.matches(username));
-			myQuery.or(Lucene.watchedby.matches(username));
-			myQuery.and(qb.toSubquery().toString());
-			luceneQuery = myQuery.build();
-		}
+        // paging links
+        int page = (params != null) ? Math.max(1, WicketUtils.getPage(params)) : 1;
+        int pageSize = app().settings().getInteger(Keys.tickets.perPage, 25);
 
-		// paging links
-		int page = (params != null) ? Math.max(1, WicketUtils.getPage(params)) : 1;
-		int pageSize = app().settings().getInteger(Keys.tickets.perPage, 25);
+        final List<QueryResult> results = 
+            StringUtils.isEmpty(searchParam) ? query(qb, page, pageSize, sortBy, desc) : search(searchParam, page, pageSize);
 
-		List<QueryResult> results;
-		if(StringUtils.isEmpty(searchParam)) {
-			results = app().tickets().queryFor(luceneQuery, page, pageSize, sortBy, desc);
-		} else {
-			results = app().tickets().searchFor(null, searchParam, page, pageSize);
-		}
+        int totalResults = results.size() == 0 ? 0 : results.get(0).totalResults;
+        buildPager(queryParam, milestoneParam, statiiParam, assignedToParam, sortBy, desc, repositoryId, page, pageSize, results.size(), totalResults);
 
-		int totalResults = results.size() == 0 ? 0 : results.get(0).totalResults;
-		buildPager(queryParam, milestoneParam, statiiParam, assignedToParam, sortBy, desc, repositoryId, page, pageSize, results.size(), totalResults);
+        final boolean showSwatch = app().settings().getBoolean(Keys.web.repositoryListSwatches, true);
+        add(new TicketListPanel("ticketList", results, showSwatch, true));
+    }
 
-		final boolean showSwatch = app().settings().getBoolean(Keys.web.repositoryListSwatches, true);
-		add(new TicketListPanel("ticketList", results, showSwatch, true));
-	}
+    protected PageParameters queryParameters(
+            String query,
+            String milestone,
+            String[] states,
+            String assignedTo,
+            String sort,
+            boolean descending,
+            String repositoryId,
+            int page) {
 
-	protected PageParameters queryParameters(
-			String query,
-			String milestone,
-			String[] states,
-			String assignedTo,
-			String sort,
-			boolean descending,
-			String repositoryId,
-			int page) {
+        PageParameters params = WicketUtils.newRepositoryParameter("");
+        if (!StringUtils.isEmpty(query)) {
+            params.add("q", query);
+        }
+        if (!StringUtils.isEmpty(milestone)) {
+            params.add(Lucene.milestone.name(), milestone);
+        }
+        if (!ArrayUtils.isEmpty(states)) {
+            for (String state : states) {
+                params.add(Lucene.status.name(), state);
+            }
+        }
+        if (!StringUtils.isEmpty(assignedTo)) {
+            params.add(Lucene.responsible.name(), assignedTo);
+        }
+        if (!StringUtils.isEmpty(sort)) {
+            params.add("sort", sort);
+        }
+        if (!descending) {
+            params.add("direction", "asc");
+        }
+        if (!StringUtils.isEmpty(repositoryId)) {
+            params.add(Lucene.rid.name(), repositoryId);
+        }
+        if (page > 1) {
+            params.add("pg", "" + page);
+        }
+        return params;
+    }
 
-		PageParameters params = WicketUtils.newRepositoryParameter("");
-		if (!StringUtils.isEmpty(query)) {
-			params.add("q", query);
-		}
-		if (!StringUtils.isEmpty(milestone)) {
-			params.add(Lucene.milestone.name(), milestone);
-		}
-		if (!ArrayUtils.isEmpty(states)) {
-			for (String state : states) {
-				params.add(Lucene.status.name(), state);
-			}
-		}
-		if (!StringUtils.isEmpty(assignedTo)) {
-			params.add(Lucene.responsible.name(), assignedTo);
-		}
-		if (!StringUtils.isEmpty(sort)) {
-			params.add("sort", sort);
-		}
-		if (!descending) {
-			params.add("direction", "asc");
-		}
-		if (!StringUtils.isEmpty(repositoryId)) {
-			params.add(Lucene.rid.name(), repositoryId);
-		}
-		if (page > 1) {
-			params.add("pg", "" + page);
-		}
-		return params;
-	}
+    protected void buildPager(
+            final String query,
+            final String milestone,
+            final String [] states,
+            final String assignedTo,
+            final String sort,
+            final boolean desc,
+            final String repositoryId,
+            final int page,
+            int pageSize,
+            int count,
+            int total) {
 
-	protected void buildPager(
-			final String query,
-			final String milestone,
-			final String [] states,
-			final String assignedTo,
-			final String sort,
-			final boolean desc,
-			final String repositoryId,
-			final int page,
-			int pageSize,
-			int count,
-			int total) {
+        boolean showNav = total > (2 * pageSize);
+        boolean allowPrev = page > 1;
+        boolean allowNext = (pageSize * (page - 1) + count) < total;
+        add(new BookmarkablePageLink<Void>("prevLink", MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, page - 1)).setEnabled(allowPrev).setVisible(showNav));
+        add(new BookmarkablePageLink<Void>("nextLink", MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, page + 1)).setEnabled(allowNext).setVisible(showNav));
 
-		boolean showNav = total > (2 * pageSize);
-		boolean allowPrev = page > 1;
-		boolean allowNext = (pageSize * (page - 1) + count) < total;
-		add(new BookmarkablePageLink<Void>("prevLink", MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, page - 1)).setEnabled(allowPrev).setVisible(showNav));
-		add(new BookmarkablePageLink<Void>("nextLink", MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, page + 1)).setEnabled(allowNext).setVisible(showNav));
+        if (total <= pageSize) {
+            add(new Label("pageLink").setVisible(false));
+            return;
+        }
 
-		if (total <= pageSize) {
-			add(new Label("pageLink").setVisible(false));
-			return;
-		}
+        // determine page numbers to display
+        int pages = count == 0 ? 0 : ((total / pageSize) + (total % pageSize == 0 ? 0 : 1));
+        // preferred number of pagelinks
+        int segments = 5;
+        if (pages < segments) {
+            // not enough data for preferred number of page links
+            segments = pages;
+        }
+        int minpage = Math.min(Math.max(1, page - 2), pages - (segments - 1));
+        int maxpage = Math.min(pages, minpage + (segments - 1));
+        List<Integer> sequence = new ArrayList<Integer>();
+        for (int i = minpage; i <= maxpage; i++) {
+            sequence.add(i);
+        }
 
-		// determine page numbers to display
-		int pages = count == 0 ? 0 : ((total / pageSize) + (total % pageSize == 0 ? 0 : 1));
-		// preferred number of pagelinks
-		int segments = 5;
-		if (pages < segments) {
-			// not enough data for preferred number of page links
-			segments = pages;
-		}
-		int minpage = Math.min(Math.max(1, page - 2), pages - (segments - 1));
-		int maxpage = Math.min(pages, minpage + (segments - 1));
-		List<Integer> sequence = new ArrayList<Integer>();
-		for (int i = minpage; i <= maxpage; i++) {
-			sequence.add(i);
-		}
+        ListDataProvider<Integer> pagesDp = new ListDataProvider<Integer>(sequence);
+        DataView<Integer> pagesView = new DataView<Integer>("pageLink", pagesDp) {
+            private static final long serialVersionUID = 1L;
 
-		ListDataProvider<Integer> pagesDp = new ListDataProvider<Integer>(sequence);
-		DataView<Integer> pagesView = new DataView<Integer>("pageLink", pagesDp) {
-			private static final long serialVersionUID = 1L;
+            @Override
+            public void populateItem(final Item<Integer> item) {
+                final Integer i = item.getModelObject();
+                LinkPanel link = new LinkPanel("page", null, "" + i, MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, i));
+                link.setRenderBodyOnly(true);
+                if (i == page) {
+                    WicketUtils.setCssClass(item, "active");
+                }
+                item.add(link);
+            }
+        };
+        add(pagesView);
+    }
 
-			@Override
-			public void populateItem(final Item<Integer> item) {
-				final Integer i = item.getModelObject();
-				LinkPanel link = new LinkPanel("page", null, "" + i, MyTicketsPage.class, queryParameters(query, milestone, states, assignedTo, sort, desc, repositoryId, i));
-				link.setRenderBodyOnly(true);
-				if (i == page) {
-					WicketUtils.setCssClass(item, "active");
-				}
-				item.add(link);
-			}
-		};
-		add(pagesView);
-	}
+    private QueryBuilder initializeQueryBuilder(String queryparam, String username) {
+        final QueryBuilder qb = new QueryBuilder(queryparam);
+
+        // focused "my tickets"
+        if (qb.containsField(Lucene.createdby.name())
+                || qb.containsField(Lucene.responsible.name())
+                || qb.containsField(Lucene.watchedby.name())) {
+
+            return qb;
+        }
+
+        // general "my tickets"
+        return qb.andSubquery()
+                 .or(Lucene.createdby.matches(username))
+                 .or(Lucene.responsible.matches(username))
+                 .or(Lucene.watchedby.matches(username))
+                 .endSubquery();
+    }
+
+    private List<QueryResult> query(QueryBuilder qb, int page, int pageSize, String sortBy, boolean descending) {
+        return app().tickets().queryFor(qb.build(), page, pageSize, sortBy, descending);
+    }
+
+    private List<QueryResult> search(String searchParam, int page, int pageSize) {
+        return app().tickets().searchFor(null, searchParam, page, pageSize);
+    }
+
+    private List<RepositoryModel> correspondingRepositories(Collection<QueryResult> tickets) { 
+        final HashMap<String, RepositoryModel> result = new HashMap<>();
+        for (QueryResult ticket : tickets) {
+            RepositoryModel repository = app().repositories().getRepositoryModel(ticket.repository);
+            if (!result.containsKey(repository.getRID())) {
+                result.put(repository.getRID(), repository);
+            }
+        }
+
+        return new ArrayList<>(result.values());
+    }
 }
