diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
index d3bf7cf..c429abe 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/GitilesView.java
@@ -460,6 +460,14 @@
     this.anchor = anchor;
   }
 
+  public Builder copyFrom(GitilesView other) {
+    return new Builder(other.type).copyFrom(this);
+  }
+
+  public Builder toBuilder() {
+    return copyFrom(this);
+  }
+
   public String getHostName() {
     return hostName;
   }
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/TestViewFilter.java b/gitiles-servlet/src/test/java/com/google/gitiles/TestViewFilter.java
new file mode 100644
index 0000000..4f1e5ba
--- /dev/null
+++ b/gitiles-servlet/src/test/java/com/google/gitiles/TestViewFilter.java
@@ -0,0 +1,114 @@
+// Copyright (C) 2014 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gitiles;
+
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.gitiles.GitilesFilter.REPO_PATH_REGEX;
+import static com.google.gitiles.GitilesFilter.REPO_REGEX;
+import static com.google.gitiles.GitilesFilter.ROOT_REGEX;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+
+import org.eclipse.jgit.http.server.glue.MetaFilter;
+import org.eclipse.jgit.http.server.glue.MetaServlet;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
+import org.eclipse.jgit.junit.TestRepository;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/** Run {@link ViewFilter} in a test environment. */
+class TestViewFilter {
+  static class Result {
+    private final GitilesView view;
+    private final FakeHttpServletResponse res;
+
+    private Result(GitilesView view, FakeHttpServletResponse res) {
+      this.view = view;
+      this.res = res;
+    }
+
+    GitilesView getView() {
+      return view;
+    }
+
+    FakeHttpServletResponse getResponse() {
+      return res;
+    }
+  }
+
+  static Result service(TestRepository<? extends DfsRepository> repo, String pathAndQuery)
+      throws IOException, ServletException {
+    TestServlet servlet = new TestServlet();
+    ViewFilter vf = new ViewFilter(
+        new TestGitilesAccess(repo.getRepository()),
+        TestGitilesUrls.URLS,
+        new VisibilityCache(false));
+    MetaFilter mf = new MetaFilter();
+
+    for (Pattern p : ImmutableList.of(ROOT_REGEX, REPO_REGEX, REPO_PATH_REGEX)) {
+      mf.serveRegex(p)
+          .through(vf)
+          .with(servlet);
+    }
+    FakeHttpServletResponse res = new FakeHttpServletResponse();
+    dummyServlet(mf).service(newRequest(repo, pathAndQuery), res);
+    if (servlet.view != null && servlet.view.getRepositoryName() != null) {
+      assertEquals(repo.getRepository().getDescription().getRepositoryName(),
+          servlet.view.getRepositoryName());
+    }
+    return new Result(servlet.view, res);
+  }
+
+  private static class TestServlet extends HttpServlet {
+    private static final long serialVersionUID = 1L;
+
+    private GitilesView view;
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse res) {
+      checkState(view == null);
+      view = ViewFilter.getView(req);
+    }
+  }
+
+  private static FakeHttpServletRequest newRequest(TestRepository<? extends DfsRepository> repo,
+      String pathAndQuery) {
+    FakeHttpServletRequest req = FakeHttpServletRequest.newRequest(repo.getRepository());
+    int q = pathAndQuery.indexOf('?');
+    if (q > 0) {
+      req.setPathInfo(pathAndQuery.substring(0, q));
+      req.setQueryString(pathAndQuery.substring(q + 1));
+    } else {
+      req.setPathInfo(pathAndQuery);
+    }
+    return req;
+  }
+
+  private static MetaServlet dummyServlet(MetaFilter mf) {
+    return new MetaServlet(mf) {
+      private static final long serialVersionUID = 1L;
+    };
+  }
+
+  private TestViewFilter() {
+  }
+}
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java b/gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java
index 581bee0..ed6cc79 100644
--- a/gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java
+++ b/gitiles-servlet/src/test/java/com/google/gitiles/ViewFilterTest.java
@@ -14,21 +14,13 @@
 
 package com.google.gitiles;
 
-import static com.google.gitiles.FakeHttpServletRequest.newRequest;
-import static com.google.gitiles.GitilesFilter.REPO_PATH_REGEX;
-import static com.google.gitiles.GitilesFilter.REPO_REGEX;
-import static com.google.gitiles.GitilesFilter.ROOT_REGEX;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.net.HttpHeaders;
-import com.google.common.util.concurrent.Atomics;
 import com.google.gitiles.GitilesView.Type;
 
-import org.eclipse.jgit.http.server.glue.MetaFilter;
-import org.eclipse.jgit.http.server.glue.MetaServlet;
 import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@@ -38,13 +30,8 @@
 import org.junit.Test;
 
 import java.io.IOException;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Pattern;
 
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 /** Tests for the view filter. */
 public class ViewFilterTest {
@@ -53,7 +40,7 @@
   @Before
   public void setUp() throws Exception {
     repo = new TestRepository<DfsRepository>(
-        new InMemoryRepository(new DfsRepositoryDescription("test")));
+        new InMemoryRepository(new DfsRepositoryDescription("repo")));
   }
 
   @Test
@@ -479,57 +466,16 @@
   }
 
   private String getRedirectUrl(String pathAndQuery) throws ServletException, IOException {
-    FakeHttpServletResponse res = new FakeHttpServletResponse();
-    service(pathAndQuery, Atomics.<GitilesView> newReference(), res);
-    assertEquals(302, res.getStatus());
-    return res.getHeader(HttpHeaders.LOCATION);
+    TestViewFilter.Result result = TestViewFilter.service(repo, pathAndQuery);
+    assertEquals(302, result.getResponse().getStatus());
+    return result.getResponse().getHeader(HttpHeaders.LOCATION);
   }
 
   private GitilesView getView(String pathAndQuery) throws ServletException, IOException {
-    AtomicReference<GitilesView> view = Atomics.newReference();
-    FakeHttpServletResponse res = new FakeHttpServletResponse();
-    service(pathAndQuery, view, res);
-    assertTrue("expected non-redirect status, got " + res.getStatus(),
-        res.getStatus() < 300 || res.getStatus() >= 400);
-    return view.get();
-  }
-
-  private void service(String pathAndQuery, final AtomicReference<GitilesView> view,
-      FakeHttpServletResponse res) throws ServletException, IOException {
-    HttpServlet testServlet = new HttpServlet() {
-      private static final long serialVersionUID = 1L;
-      @Override
-      protected void doGet(HttpServletRequest req, HttpServletResponse res) {
-        view.set(ViewFilter.getView(req));
-      }
-    };
-
-    ViewFilter vf = new ViewFilter(
-        new TestGitilesAccess(repo.getRepository()),
-        TestGitilesUrls.URLS,
-        new VisibilityCache(false));
-    MetaFilter mf = new MetaFilter();
-
-    for (Pattern p : ImmutableList.of(ROOT_REGEX, REPO_REGEX, REPO_PATH_REGEX)) {
-      mf.serveRegex(p)
-          .through(vf)
-          .with(testServlet);
-    }
-
-    FakeHttpServletRequest req = newRequest(repo.getRepository());
-    int q = pathAndQuery.indexOf('?');
-    if (q > 0) {
-      req.setPathInfo(pathAndQuery.substring(0, q));
-      req.setQueryString(pathAndQuery.substring(q + 1));
-    } else {
-      req.setPathInfo(pathAndQuery);
-    }
-    dummyServlet(mf).service(req, res);
-  }
-
-  private MetaServlet dummyServlet(MetaFilter mf) {
-    return new MetaServlet(mf) {
-      private static final long serialVersionUID = 1L;
-    };
+    TestViewFilter.Result result = TestViewFilter.service(repo, pathAndQuery);
+    FakeHttpServletResponse resp = result.getResponse();
+    assertTrue("expected non-redirect status, got " + resp.getStatus(),
+        resp.getStatus() < 300 || resp.getStatus() >= 400);
+    return result.getView();
   }
 }
