diff --git a/src/main/java/com/android/vts/util/DatastoreHelper.java b/src/main/java/com/android/vts/util/DatastoreHelper.java
index 3764c7a..782887b 100644
--- a/src/main/java/com/android/vts/util/DatastoreHelper.java
+++ b/src/main/java/com/android/vts/util/DatastoreHelper.java
@@ -166,372 +166,6 @@
   }
 
   /**
-   * Upload data from a test report message
-   *
-   * @param report The test report containing data to upload.
-   */
-  public static void insertTestReport(TestReportMessage report) {
-
-    List<Entity> testEntityList = new ArrayList<>();
-    List<Entity> branchEntityList = new ArrayList<>();
-    List<Entity> buildTargetEntityList = new ArrayList<>();
-    List<Entity> coverageEntityList = new ArrayList<>();
-    List<Entity> profilingPointRunEntityList = new ArrayList<>();
-
-    if (!report.hasStartTimestamp()
-            || !report.hasEndTimestamp()
-            || !report.hasTest()
-            || !report.hasHostInfo()
-            || !report.hasBuildInfo()) {
-      // missing information
-      return;
-    }
-    long startTimestamp = report.getStartTimestamp();
-    long endTimestamp = report.getEndTimestamp();
-    String testName = report.getTest().toStringUtf8();
-    String testBuildId = report.getBuildInfo().getId().toStringUtf8();
-    String hostName = report.getHostInfo().getHostname().toStringUtf8();
-
-    TestEntity testEntity = new TestEntity(testName);
-
-    Key testRunKey =
-            KeyFactory.createKey(
-                    testEntity.getOldKey(), TestRunEntity.KIND, report.getStartTimestamp());
-
-    long passCount = 0;
-    long failCount = 0;
-    long coveredLineCount = 0;
-    long totalLineCount = 0;
-
-    Set<Key> buildTargetKeys = new HashSet<>();
-    Set<Key> branchKeys = new HashSet<>();
-    List<TestCaseRunEntity> testCases = new ArrayList<>();
-    List<Key> profilingPointKeys = new ArrayList<>();
-    List<String> links = new ArrayList<>();
-
-    // Process test cases
-    for (TestCaseReportMessage testCase : report.getTestCaseList()) {
-      String testCaseName = testCase.getName().toStringUtf8();
-      TestCaseResult result = testCase.getTestResult();
-      // Track global pass/fail counts
-      if (result == TestCaseResult.TEST_CASE_RESULT_PASS) {
-        ++passCount;
-      } else if (result != TestCaseResult.TEST_CASE_RESULT_SKIP) {
-        ++failCount;
-      }
-      if (testCase.getSystraceCount() > 0
-              && testCase.getSystraceList().get(0).getUrlCount() > 0) {
-        String systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8();
-        links.add(systraceLink);
-      }
-
-      // Process coverage data for test case
-      for (CoverageReportMessage coverage : testCase.getCoverageList()) {
-        CoverageEntity coverageEntity =
-                CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage);
-        if (coverageEntity == null) {
-          logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
-        } else {
-          coveredLineCount += coverageEntity.getCoveredCount();
-          totalLineCount += coverageEntity.getTotalCount();
-          coverageEntityList.add(coverageEntity.toEntity());
-        }
-      }
-
-      // Process profiling data for test case
-      for (ProfilingReportMessage profiling : testCase.getProfilingList()) {
-        ProfilingPointRunEntity profilingPointRunEntity =
-                ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
-        if (profilingPointRunEntity == null) {
-          logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
-        } else {
-          profilingPointRunEntityList.add(profilingPointRunEntity.toEntity());
-          profilingPointKeys.add(profilingPointRunEntity.getKey());
-          testEntity.setHasProfilingData(true);
-        }
-      }
-
-      int lastIndex = testCases.size() - 1;
-      if (lastIndex < 0 || testCases.get(lastIndex).isFull()) {
-        testCases.add(new TestCaseRunEntity());
-        ++lastIndex;
-      }
-      TestCaseRunEntity testCaseEntity = testCases.get(lastIndex);
-      testCaseEntity.addTestCase(testCaseName, result.getNumber());
-    }
-
-    List<Entity> testCasePuts = new ArrayList<>();
-    for (TestCaseRunEntity testCaseEntity : testCases) {
-      testCasePuts.add(testCaseEntity.toEntity());
-    }
-    List<Key> testCaseKeys = datastore.put(testCasePuts);
-
-    List<Long> testCaseIds = new ArrayList<>();
-    for (Key key : testCaseKeys) {
-      testCaseIds.add(key.getId());
-    }
-
-    // Process device information
-    long testRunType = 0;
-    for (AndroidDeviceInfoMessage device : report.getDeviceInfoList()) {
-      DeviceInfoEntity deviceInfoEntity =
-              DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device);
-      if (deviceInfoEntity == null) {
-        logger.log(Level.WARNING, "Invalid device info in test run " + testRunKey);
-      } else {
-        // Run type on devices must be the same, else set to OTHER
-        TestRunType runType = TestRunType.fromBuildId(deviceInfoEntity.getBuildId());
-        if (runType == null) {
-          testRunType = TestRunType.OTHER.getNumber();
-        } else {
-          testRunType = runType.getNumber();
-        }
-        testEntityList.add(deviceInfoEntity.toEntity());
-        BuildTargetEntity target = new BuildTargetEntity(deviceInfoEntity.getBuildFlavor());
-        if (buildTargetKeys.add(target.key)) {
-          buildTargetEntityList.add(target.toEntity());
-        }
-        BranchEntity branch = new BranchEntity(deviceInfoEntity.getBranch());
-        if (branchKeys.add(branch.key)) {
-          branchEntityList.add(branch.toEntity());
-        }
-      }
-    }
-
-    // Overall run type should be determined by the device builds unless test build is OTHER
-    if (testRunType == TestRunType.OTHER.getNumber()) {
-      testRunType = TestRunType.fromBuildId(testBuildId).getNumber();
-    } else if (TestRunType.fromBuildId(testBuildId) == TestRunType.OTHER) {
-      testRunType = TestRunType.OTHER.getNumber();
-    }
-
-    // Process global coverage data
-    for (CoverageReportMessage coverage : report.getCoverageList()) {
-      CoverageEntity coverageEntity =
-              CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage);
-      if (coverageEntity == null) {
-        logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey);
-      } else {
-        coveredLineCount += coverageEntity.getCoveredCount();
-        totalLineCount += coverageEntity.getTotalCount();
-        coverageEntityList.add(coverageEntity.toEntity());
-      }
-    }
-
-    // Process global API coverage data
-    for (ApiCoverageReportMessage apiCoverage : report.getApiCoverageList()) {
-      HalInterfaceMessage halInterfaceMessage = apiCoverage.getHalInterface();
-      List<String> halApiList = apiCoverage.getHalApiList().stream().map(h -> h.toStringUtf8())
-              .collect(
-                      Collectors.toList());
-      List<String> coveredHalApiList = apiCoverage.getCoveredHalApiList().stream()
-              .map(h -> h.toStringUtf8()).collect(
-                      Collectors.toList());
-      ApiCoverageEntity apiCoverageEntity = new ApiCoverageEntity(
-              testRunKey,
-              halInterfaceMessage.getHalPackageName().toStringUtf8(),
-              halInterfaceMessage.getHalVersionMajor(),
-              halInterfaceMessage.getHalVersionMinor(),
-              halInterfaceMessage.getHalInterfaceName().toStringUtf8(),
-              halApiList,
-              coveredHalApiList
-      );
-      com.googlecode.objectify.Key apiCoverageEntityKey = apiCoverageEntity.save();
-      if (apiCoverageEntityKey == null) {
-        logger.log(Level.WARNING, "Invalid API coverage report in test run " + testRunKey);
-      }
-    }
-
-    // Process global profiling data
-    for (ProfilingReportMessage profiling : report.getProfilingList()) {
-      ProfilingPointRunEntity profilingPointRunEntity =
-              ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling);
-      if (profilingPointRunEntity == null) {
-        logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey);
-      } else {
-        profilingPointRunEntityList.add(profilingPointRunEntity.toEntity());
-        profilingPointKeys.add(profilingPointRunEntity.getKey());
-        testEntity.setHasProfilingData(true);
-      }
-    }
-
-    // Process log data
-    for (LogMessage log : report.getLogList()) {
-      if (log.hasUrl()) {
-        links.add(log.getUrl().toStringUtf8());
-      }
-    }
-    // Process url resource
-    for (UrlResourceMessage resource : report.getLinkResourceList()) {
-      if (resource.hasUrl()) {
-        links.add(resource.getUrl().toStringUtf8());
-      }
-    }
-
-    boolean hasCodeCoverage = totalLineCount > 0 && coveredLineCount >= 0;
-    TestRunEntity testRunEntity =
-            new TestRunEntity(
-                    testEntity.getOldKey(),
-                    testRunType,
-                    startTimestamp,
-                    endTimestamp,
-                    testBuildId,
-                    hostName,
-                    passCount,
-                    failCount,
-                    hasCodeCoverage,
-                    testCaseIds,
-                    links);
-    testEntityList.add(testRunEntity.toEntity());
-
-    CodeCoverageEntity codeCoverageEntity = new CodeCoverageEntity(
-            testRunEntity.getKey(),
-            coveredLineCount,
-            totalLineCount);
-    testEntityList.add(codeCoverageEntity.toEntity());
-
-    Entity test = testEntity.toEntity();
-
-    if (datastoreTransactionalRetry(test, testEntityList)) {
-      List<List<Entity>> auxiliaryEntityList =
-              Arrays.asList(
-                      profilingPointRunEntityList,
-                      coverageEntityList,
-                      branchEntityList,
-                      buildTargetEntityList);
-      int indexCount = 0;
-      for (List<Entity> entityList : auxiliaryEntityList) {
-        switch (indexCount) {
-          case 0:
-          case 1:
-            if (entityList.size() > MAX_ENTITY_SIZE_PER_TRANSACTION) {
-              List<List<Entity>> partitionedList =
-                      Lists.partition(entityList, MAX_ENTITY_SIZE_PER_TRANSACTION);
-              partitionedList.forEach(
-                      subEntityList -> {
-                        datastoreTransactionalRetry(
-                                new Entity(NULL_ENTITY_KIND), subEntityList);
-                      });
-            } else {
-              datastoreTransactionalRetry(new Entity(NULL_ENTITY_KIND), entityList);
-            }
-            break;
-          case 2:
-          case 3:
-            datastoreTransactionalRetryWithXG(
-                    new Entity(NULL_ENTITY_KIND), entityList, true);
-            break;
-          default:
-            break;
-        }
-        indexCount++;
-      }
-
-      if (testRunEntity.getType() == TestRunType.POSTSUBMIT.getNumber()) {
-        VtsAlertJobServlet.addTask(testRunKey);
-        if (testRunEntity.getHasCodeCoverage()) {
-          VtsCoverageAlertJobServlet.addTask(testRunKey);
-        }
-        if (profilingPointKeys.size() > 0) {
-          VtsProfilingStatsJobServlet.addTasks(profilingPointKeys);
-        }
-      } else {
-        logger.log(
-                Level.WARNING,
-                "The alert email was not sent as testRunEntity type is not POSTSUBMIT!" +
-                        " \n " + " testRunEntity type => " + testRunEntity.getType());
-      }
-    }
-  }
-
-  /**
-   * Upload data from a test plan report message
-   *
-   * @param report The test plan report containing data to upload.
-   */
-  public static void insertTestPlanReport(TestPlanReportMessage report) {
-    List<Entity> testEntityList = new ArrayList<>();
-
-    List<String> testModules = report.getTestModuleNameList();
-    List<Long> testTimes = report.getTestModuleStartTimestampList();
-    if (testModules.size() != testTimes.size() || !report.hasTestPlanName()) {
-      logger.log(Level.WARNING, "TestPlanReportMessage is missing information.");
-      return;
-    }
-
-    String testPlanName = report.getTestPlanName();
-    Entity testPlanEntity = new TestPlanEntity(testPlanName).toEntity();
-    List<Key> testRunKeys = new ArrayList<>();
-    for (int i = 0; i < testModules.size(); i++) {
-      String test = testModules.get(i);
-      long time = testTimes.get(i);
-      Key parentKey = KeyFactory.createKey(TestEntity.KIND, test);
-      Key testRunKey = KeyFactory.createKey(parentKey, TestRunEntity.KIND, time);
-      testRunKeys.add(testRunKey);
-    }
-    Map<Key, Entity> testRuns = datastore.get(testRunKeys);
-    long passCount = 0;
-    long failCount = 0;
-    long startTimestamp = -1;
-    long endTimestamp = -1;
-    String testBuildId = null;
-    long type = 0;
-    Set<DeviceInfoEntity> deviceInfoEntitySet = new HashSet<>();
-    for (Key testRunKey : testRuns.keySet()) {
-      TestRunEntity testRun = TestRunEntity.fromEntity(testRuns.get(testRunKey));
-      if (testRun == null) {
-        continue; // not a valid test run
-      }
-      passCount += testRun.getPassCount();
-      failCount += testRun.getFailCount();
-      if (startTimestamp < 0 || testRunKey.getId() < startTimestamp) {
-        startTimestamp = testRunKey.getId();
-      }
-      if (endTimestamp < 0 || testRun.getEndTimestamp() > endTimestamp) {
-        endTimestamp = testRun.getEndTimestamp();
-      }
-      type = testRun.getType();
-      testBuildId = testRun.getTestBuildId();
-      Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRunKey);
-      for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) {
-        DeviceInfoEntity device = DeviceInfoEntity.fromEntity(deviceInfoEntity);
-        if (device == null) {
-          continue; // invalid entity
-        }
-        deviceInfoEntitySet.add(device);
-      }
-    }
-    if (startTimestamp < 0 || testBuildId == null || type == 0) {
-      logger.log(Level.WARNING, "Couldn't infer test run information from runs.");
-      return;
-    }
-    TestPlanRunEntity testPlanRun =
-            new TestPlanRunEntity(
-                    testPlanEntity.getKey(),
-                    testPlanName,
-                    type,
-                    startTimestamp,
-                    endTimestamp,
-                    testBuildId,
-                    passCount,
-                    failCount,
-                    0L,
-                    0L,
-                    testRunKeys);
-
-    // Create the device infos.
-    for (DeviceInfoEntity device : deviceInfoEntitySet) {
-      testEntityList.add(device.copyWithParent(testPlanRun.key).toEntity());
-    }
-    testEntityList.add(testPlanRun.toEntity());
-
-    // Add the task to calculate total number API list.
-    testPlanRun.addCoverageApiTask();
-
-    datastoreTransactionalRetry(testPlanEntity, testEntityList);
-  }
-
-  /**
    * Datastore Transactional process for data insertion with MAX_WRITE_RETRIES times and withXG of
    * false value
    *
