diff --git a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java b/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
deleted file mode 100644
index 9dec435..0000000
--- a/src/test/java/com/googlesource/gerrit/plugins/its/phabricator/conduit/ConduitTest.java
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// 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.googlesource.gerrit.plugins.its.phabricator.conduit;
-
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.resetToStrict;
-import static org.powermock.api.easymock.PowerMock.expectNew;
-
-import com.google.gson.JsonObject;
-import com.google.gson.JsonPrimitive;
-import com.googlesource.gerrit.plugins.its.base.testutil.LoggingMockingTestCase;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ConduitPing;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ManiphestEdit;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ManiphestInfo;
-import com.googlesource.gerrit.plugins.its.phabricator.conduit.results.ProjectInfo;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import org.easymock.Capture;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(Conduit.class)
-public class ConduitTest extends LoggingMockingTestCase {
-  private static final String URL = "urlFoo";
-  private static final String TOKEN = "tokenFoo";
-
-  private ConduitConnection connection;
-
-  public void testConduitPingPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(new JsonPrimitive("foo"))
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ConduitPing actual = conduit.conduitPing();
-
-    assertEquals("Hostname does not match", "foo", actual.getHostname());
-  }
-
-  public void testConduitPingConnectionFail() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("conduit.ping"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.conduitPing();
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestInfoPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
-  }
-
-  public void testManiphestInfoFailConnect() throws Exception {
-    mockConnection();
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestInfo(42);
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestInfoFailRelevant() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestInfo(42);
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-  }
-
-  public void testManiphestEditPassComment() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.update"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit = conduit.maniphestEdit(42, "foo");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditPassProjects() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit =
-        conduit.maniphestEdit(42, Arrays.asList("foo", "bar"), Conduit.ACTION_PROJECT_ADD);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-    assertEquals(
-        "Task projects are not set",
-        Arrays.asList("foo", "bar"),
-        paramsRelevant.get("projectPHIDs"));
-
-    assertEquals("ManiphestEdit's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditPassCommentAndProjects() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestEdit maniphestEdit =
-        conduit.maniphestEdit(
-            42, "baz", Arrays.asList("foo", "bar"), Conduit.ACTION_PROJECT_REMOVE);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-    assertEquals("Task comment is not set", "baz", paramsRelevant.get("comments"));
-    assertEquals(
-        "Task projects are not set",
-        Arrays.asList("foo", "bar"),
-        paramsRelevant.get("projectPHIDs"));
-
-    assertEquals("ManiphestUpdate's id does not match", 42, maniphestEdit.getId());
-  }
-
-  public void testManiphestEditFailConnect() throws Exception {
-    mockConnection();
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCapture = new Capture<>();
-
-    expect(connection.call(eq("conduit.connect"), capture(paramsCapture), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, null);
-
-    try {
-      conduit.maniphestEdit(42, "foo");
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-  }
-
-  public void testManiphestEditFailRelevant() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    ConduitException conduitException = new ConduitException();
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.edit"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andThrow(conduitException)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    try {
-      conduit.maniphestEdit(42, "foo");
-      fail("no exception got thrown");
-    } catch (ConduitException e) {
-      assertSame(conduitException, e);
-    }
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("id"));
-  }
-
-  public void testConnectionReuse() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("id", new JsonPrimitive(42));
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("maniphest.info"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ManiphestInfo maniphestInfo = conduit.maniphestInfo(42);
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    assertEquals("Task id is not set", 42, paramsRelevant.get("task_id"));
-
-    assertEquals("ManiphestInfo's id does not match", 42, maniphestInfo.getId());
-  }
-
-  public void testProjectQueryPass() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject projectInfoJson = new JsonObject();
-    projectInfoJson.addProperty("name", "foo");
-    projectInfoJson.addProperty("phid", "PHID-PROJ-bar");
-
-    JsonObject queryDataJson = new JsonObject();
-    queryDataJson.add("PHID-PROJ-bar", projectInfoJson);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("data", queryDataJson);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ProjectInfo projectInfo = conduit.projectQuery("foo");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    List<String> expectedNames = Arrays.asList("foo");
-    assertEquals("Project name does not match", expectedNames, paramsRelevant.get("names"));
-
-    assertEquals("ProjectInfo's name does not match", "foo", projectInfo.getName());
-  }
-
-  public void testProjectQueryPassMultipleResults() throws Exception {
-    mockConnection();
-
-    resetToStrict(connection);
-
-    JsonObject projectInfoJson1 = new JsonObject();
-    projectInfoJson1.addProperty("name", "foo1");
-    projectInfoJson1.addProperty("phid", "PHID-PROJ-bar1");
-
-    JsonObject projectInfoJson2 = new JsonObject();
-    projectInfoJson2.addProperty("name", "foo2");
-    projectInfoJson2.addProperty("phid", "PHID-PROJ-bar2");
-
-    JsonObject projectInfoJson3 = new JsonObject();
-    projectInfoJson3.addProperty("name", "foo3");
-    projectInfoJson3.addProperty("phid", "PHID-PROJ-bar3");
-
-    JsonObject queryDataJson = new JsonObject();
-    queryDataJson.add("PHID-PROJ-bar1", projectInfoJson1);
-    queryDataJson.add("PHID-PROJ-bar2", projectInfoJson2);
-    queryDataJson.add("PHID-PROJ-bar3", projectInfoJson3);
-
-    JsonObject retRelevant = new JsonObject();
-    retRelevant.add("data", queryDataJson);
-
-    Capture<Map<String, Object>> paramsCaptureRelevant = new Capture<>();
-
-    expect(connection.call(eq("project.query"), capture(paramsCaptureRelevant), eq(TOKEN)))
-        .andReturn(retRelevant)
-        .once();
-
-    replayMocks();
-
-    Conduit conduit = new Conduit(URL, TOKEN);
-
-    ProjectInfo projectInfo = conduit.projectQuery("foo2");
-
-    Map<String, Object> paramsRelevant = paramsCaptureRelevant.getValue();
-    List<String> expectedNames = Arrays.asList("foo2");
-    assertEquals("Project name does not match", expectedNames, paramsRelevant.get("names"));
-
-    assertEquals("ProjectInfo's name does not match", "foo2", projectInfo.getName());
-  }
-
-  private void mockConnection() throws Exception {
-    connection = createMock(ConduitConnection.class);
-    expectNew(ConduitConnection.class, URL).andReturn(connection).once();
-  }
-}
