History Sync cleanup: Delete TypedUrlSyncBridge

TYPED_URLS has been replaced by HISTORY, so this bridge was now unused.

Bug: 1365291
Change-Id: I8d55dc01ec8c56265b76843a93e8062a0f5c1eee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4855981
Reviewed-by: Sophie Chang <sophiechang@chromium.org>
Commit-Queue: Marc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1195896}
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn
index fcd97b9..63259f1 100644
--- a/components/history/core/browser/BUILD.gn
+++ b/components/history/core/browser/BUILD.gn
@@ -63,8 +63,6 @@
     "sync/history_sync_bridge.h",
     "sync/history_sync_metadata_database.cc",
     "sync/history_sync_metadata_database.h",
-    "sync/typed_url_sync_bridge.cc",
-    "sync/typed_url_sync_bridge.h",
     "sync/typed_url_sync_metadata_database.cc",
     "sync/typed_url_sync_metadata_database.h",
     "sync/visit_id_remapper.cc",
@@ -176,7 +174,6 @@
     "sync/history_sync_metadata_database_unittest.cc",
     "sync/test_history_backend_for_sync.cc",
     "sync/test_history_backend_for_sync.h",
-    "sync/typed_url_sync_bridge_unittest.cc",
     "sync/typed_url_sync_metadata_database_unittest.cc",
     "sync/visit_id_remapper_unittest.cc",
     "top_sites_database_unittest.cc",
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc
index fc3b2e8..62e8af1b 100644
--- a/components/history/core/browser/history_backend.cc
+++ b/components/history/core/browser/history_backend.cc
@@ -56,7 +56,6 @@
 #include "components/history/core/browser/keyword_search_term_util.h"
 #include "components/history/core/browser/page_usage_data.h"
 #include "components/history/core/browser/sync/history_sync_bridge.h"
-#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #include "components/history/core/browser/url_row.h"
 #include "components/history/core/browser/url_utils.h"
 #include "components/sync/base/features.h"
@@ -413,14 +412,6 @@
     InitImpl(history_database_params);
   delegate_->DBLoaded();
 
-  typed_url_sync_bridge_ = std::make_unique<TypedURLSyncBridge>(
-      this, db_ ? db_->GetTypedURLMetadataDB() : nullptr,
-      std::make_unique<ClientTagBasedModelTypeProcessor>(
-          syncer::TYPED_URLS,
-          base::BindRepeating(&syncer::ReportUnrecoverableError,
-                              history_database_params.channel)));
-  typed_url_sync_bridge_->Init();
-
   history_sync_bridge_ = std::make_unique<HistorySyncBridge>(
       this, db_ ? db_->GetHistoryMetadataDB() : nullptr,
       std::make_unique<ClientTagBasedModelTypeProcessor>(
@@ -1542,11 +1533,6 @@
   ScheduleCommit();
 }
 
-void HistoryBackend::SetTypedURLSyncBridgeForTest(
-    std::unique_ptr<TypedURLSyncBridge> bridge) {
-  typed_url_sync_bridge_ = std::move(bridge);
-}
-
 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) const {
   return time < expirer_.GetCurrentExpirationTime();
 }
@@ -2019,12 +2005,6 @@
 }
 
 base::WeakPtr<syncer::ModelTypeControllerDelegate>
-HistoryBackend::GetTypedURLSyncControllerDelegate() {
-  DCHECK(typed_url_sync_bridge_);
-  return typed_url_sync_bridge_->change_processor()->GetControllerDelegate();
-}
-
-base::WeakPtr<syncer::ModelTypeControllerDelegate>
 HistoryBackend::GetHistorySyncControllerDelegate() {
   DCHECK(history_sync_bridge_);
   return history_sync_bridge_->change_processor()->GetControllerDelegate();
@@ -3556,10 +3536,8 @@
   if (!db_)
     return;
 
-  // Notify the sync bridges about storage error. They'll report failures to the
+  // Notify the sync bridge about storage error. It'll report failures to the
   // sync engine and stop accepting remote updates.
-  if (typed_url_sync_bridge_)
-    typed_url_sync_bridge_->OnDatabaseError();
   if (history_sync_bridge_)
     history_sync_bridge_->OnDatabaseError();
 
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h
index 87c35c3..2a7fcca 100644
--- a/components/history/core/browser/history_backend.h
+++ b/components/history/core/browser/history_backend.h
@@ -73,7 +73,6 @@
 class HistoryDBTask;
 class HistorySyncBridge;
 class InMemoryHistoryBackend;
-class TypedURLSyncBridge;
 class URLDatabase;
 
 // Returns a formatted version of `url` with the HTTP/HTTPS scheme, port,
@@ -626,9 +625,15 @@
   // For each element in `urls`, updates the pre-existing URLRow in the database
   // with the same ID; or ignores the element if no such row exists. Returns the
   // number of records successfully updated.
+  // TODO(crbug.com/1365291): This method is only used in tests. Ideally migrate
+  // those tests to other APIs and delete this, or failing that, at least
+  // rename it to *ForTest.
   size_t UpdateURLs(const URLRows& urls);
 
   // While adding visits in batch, the source needs to be provided.
+  // TODO(crbug.com/1365291): This method is only used in tests. Ideally migrate
+  // those tests to other APIs and delete this, or failing that, at least
+  // rename it to *ForTest.
   bool AddVisits(const GURL& url,
                  const std::vector<VisitInfo>& visits,
                  VisitSource visit_source);
@@ -707,11 +712,6 @@
   // redirect chain.
   bool GetLastVisitByTime(base::Time visit_time, VisitRow* visit_row) override;
 
-  // Returns the sync controller delegate for syncing typed urls. The returned
-  // delegate is owned by `this` object.
-  base::WeakPtr<syncer::ModelTypeControllerDelegate>
-  GetTypedURLSyncControllerDelegate();
-
   // Returns the sync controller delegate for syncing history. The returned
   // delegate is owned by `this` object.
   base::WeakPtr<syncer::ModelTypeControllerDelegate>
@@ -786,6 +786,9 @@
   // added for each given URL at the last visit time in the URLRow if the
   // passed visit type != SOURCE_SYNCED (the sync code manages visits itself).
   // Each visit will have the visit_source type set.
+  // TODO(crbug.com/1365291): This method is only used in tests. Ideally migrate
+  // those tests to other APIs and delete this, or failing that, at least
+  // rename it to *ForTest.
   void AddPagesWithDetails(const URLRows& info, VisitSource visit_source);
 
 #if defined(UNIT_TEST)
@@ -794,8 +797,6 @@
   ExpireHistoryBackend* expire_backend() { return &expirer_; }
 #endif
 
-  void SetTypedURLSyncBridgeForTest(std::unique_ptr<TypedURLSyncBridge> bridge);
-
   // Returns true if the passed visit time is already expired (used by the sync
   // code to avoid syncing visits that would immediately be expired).
   bool IsExpiredVisitTime(const base::Time& time) const override;
@@ -1111,11 +1112,6 @@
   // List of observers
   base::ObserverList<HistoryBackendObserver>::Unchecked observers_;
 
-  // Used to manage syncing of the typed urls datatype. It will be null before
-  // HistoryBackend::Init() is called. Defined after `observers_` because
-  // it unregisters itself as observer during destruction.
-  std::unique_ptr<TypedURLSyncBridge> typed_url_sync_bridge_;
-
   // Used to manage syncing of the history datatype. It will be null before
   // HistoryBackend::Init() is called. Defined after `observers_` because
   // it unregisters itself as observer during destruction.
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc
index a1b8efd..36b18a0 100644
--- a/components/history/core/browser/history_backend_unittest.cc
+++ b/components/history/core/browser/history_backend_unittest.cc
@@ -45,7 +45,6 @@
 #include "components/history/core/browser/keyword_search_term.h"
 #include "components/history/core/browser/keyword_search_term_util.h"
 #include "components/history/core/browser/page_usage_data.h"
-#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #include "components/history/core/test/database_test_utils.h"
 #include "components/history/core/test/history_client_fake_bookmarks.h"
 #include "components/history/core/test/test_history_database.h"
@@ -3367,7 +3366,6 @@
 TEST_F(HistoryBackendTest, DatabaseError) {
   base::HistogramTester histogram_tester;
 
-  backend_->SetTypedURLSyncBridgeForTest(nullptr);
   backend_->DatabaseErrorCallback(SQLITE_CANTOPEN, nullptr);
   // Run loop to let any posted callbacks run before TearDown().
   base::RunLoop().RunUntilIdle();
diff --git a/components/history/core/browser/history_service.cc b/components/history/core/browser/history_service.cc
index 71c86b4..898406b5 100644
--- a/components/history/core/browser/history_service.cc
+++ b/components/history/core/browser/history_service.cc
@@ -1459,18 +1459,6 @@
 }
 
 std::unique_ptr<syncer::ModelTypeControllerDelegate>
-HistoryService::GetTypedURLSyncControllerDelegate() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // Note that a callback is bound for GetTypedURLSyncControllerDelegate()
-  // because this getter itself must also run in the backend sequence, and the
-  // proxy object below will take care of that.
-  return std::make_unique<syncer::ProxyModelTypeControllerDelegate>(
-      backend_task_runner_,
-      base::BindRepeating(&HistoryBackend::GetTypedURLSyncControllerDelegate,
-                          base::Unretained(history_backend_.get())));
-}
-
-std::unique_ptr<syncer::ModelTypeControllerDelegate>
 HistoryService::GetHistorySyncControllerDelegate() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Note that a callback is bound for GetHistorySyncControllerDelegate()
diff --git a/components/history/core/browser/history_service.h b/components/history/core/browser/history_service.h
index 0e14e7a..d445938f 100644
--- a/components/history/core/browser/history_service.h
+++ b/components/history/core/browser/history_service.h
@@ -765,11 +765,6 @@
   base::WeakPtr<syncer::SyncableService> GetDeleteDirectivesSyncableService();
 
   // For sync codebase only: instantiates a controller delegate to interact with
-  // TypedURLSyncBridge. Must be called from the UI thread.
-  std::unique_ptr<syncer::ModelTypeControllerDelegate>
-  GetTypedURLSyncControllerDelegate();
-
-  // For sync codebase only: instantiates a controller delegate to interact with
   // HistorySyncBridge. Must be called from the UI thread.
   std::unique_ptr<syncer::ModelTypeControllerDelegate>
   GetHistorySyncControllerDelegate();
diff --git a/components/history/core/browser/history_service_observer.h b/components/history/core/browser/history_service_observer.h
index 968af2b1..c88bd94c 100644
--- a/components/history/core/browser/history_service_observer.h
+++ b/components/history/core/browser/history_service_observer.h
@@ -54,9 +54,7 @@
   //
   // These metadata-only updates happen in these scenarios:
   //  1. When the Page Title is updated shortly after the page loads.
-  //  2. When `TypedURLSyncBridge` updates the `URLRow` data. This often happens
-  //     in addition to adding new visits, so `OnURLVisited` will be called too.
-  //  3. When History expiration expires some, but not all visits related to
+  //  2. When History expiration expires some, but not all visits related to
   //     a URL. In that case, the URL's metadata is updated.
   //
   // `changed_urls` lists the information for each of the URLs affected. The
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.cc b/components/history/core/browser/sync/typed_url_sync_bridge.cc
deleted file mode 100644
index ecd3234..0000000
--- a/components/history/core/browser/sync/typed_url_sync_bridge.cc
+++ /dev/null
@@ -1,1294 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
-
-#include "base/auto_reset.h"
-#include "base/big_endian.h"
-#include "base/functional/bind.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/ranges/algorithm.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "components/sync/model/metadata_batch.h"
-#include "components/sync/model/mutable_data_batch.h"
-#include "components/sync/model/sync_metadata_store_change_list.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "net/base/url_util.h"
-
-namespace history {
-
-namespace {
-
-// The server backend can't handle arbitrarily large node sizes, so to keep
-// the size under control we limit the visit array.
-static const int kMaxTypedUrlVisits = 100;
-
-// There's no limit on how many visits the history DB could have for a given
-// typed URL, so we limit how many we fetch from the DB to avoid crashes due to
-// running out of memory (http://crbug.com/89793). This value is different
-// from kMaxTypedUrlVisits, as some of the visits fetched from the DB may be
-// RELOAD visits, which will be stripped.
-static const int kMaxVisitsToFetch = 1000;
-
-// This is the threshold at which we start throttling sync updates for typed
-// URLs - any URLs with a typed_count >= this threshold will be throttled.
-static const int kTypedUrlVisitThrottleThreshold = 10;
-
-// This is the multiple we use when throttling sync updates. If the multiple is
-// N, we sync up every Nth update (i.e. when typed_count % N == 0).
-static const int kTypedUrlVisitThrottleMultiple = 10;
-
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused.
-enum class SyncTypedUrlDatabaseError {
-  kMergeFullSyncDataRead = 0,
-  kMergeFullSyncDataWriteData = 1,
-  kMergeFullSyncDataWriteMetadata = 2,
-  kApplyIncrementalSyncChangesWriteData = 3,
-  kApplyIncrementalSyncChangesWriteMetadata = 4,
-  kOnURLsDeletedReadMetadata = 5,
-  kOnDatabaseError = 6,
-  kLoadMetadataOpen = 7,
-  kLoadMetadataRead = 8,
-  kMaxValue = kLoadMetadataRead
-};
-
-static bool VisitsAreSorted(const std::vector<VisitRow>& visits) {
-  return base::ranges::is_sorted(visits, /*comp=*/{}, &VisitRow::visit_time);
-}
-
-std::string GetStorageKeyFromURLRow(const URLRow& row) {
-  DCHECK_NE(row.id(), 0);
-  std::string storage_key(sizeof(row.id()), 0);
-  base::WriteBigEndian<URLID>(&storage_key[0], row.id());
-  return storage_key;
-}
-
-bool HasTypedUrl(const std::vector<VisitRow>& visits) {
-  return base::ranges::any_of(visits, [](const VisitRow& visit) {
-    return ui::PageTransitionCoreTypeIs(visit.transition,
-                                        ui::PAGE_TRANSITION_TYPED);
-  });
-}
-
-void RecordDatabaseError(SyncTypedUrlDatabaseError error) {
-  base::UmaHistogramEnumeration("Sync.TypedURLDatabaseError", error);
-}
-
-}  // namespace
-
-TypedURLSyncBridge::URLWithVisits::URLWithVisits(
-    const GURL& url,
-    const std::vector<VisitInfo>& visits)
-    : url(url), visits(visits) {}
-
-TypedURLSyncBridge::URLWithVisits::~URLWithVisits() = default;
-
-TypedURLSyncBridge::URLWithVisits::URLWithVisits(URLWithVisits&&) = default;
-
-TypedURLSyncBridge::TypedURLSyncBridge(
-    HistoryBackend* history_backend,
-    TypedURLSyncMetadataDatabase* sync_metadata_database,
-    std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor)
-    : ModelTypeSyncBridge(std::move(change_processor)),
-      history_backend_(history_backend),
-      sync_metadata_database_(sync_metadata_database) {
-  DCHECK(history_backend_);
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-TypedURLSyncBridge::~TypedURLSyncBridge() = default;
-
-std::unique_ptr<syncer::MetadataChangeList>
-TypedURLSyncBridge::CreateMetadataChangeList() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return std::make_unique<syncer::SyncMetadataStoreChangeList>(
-      sync_metadata_database_, syncer::TYPED_URLS,
-      base::BindRepeating(&syncer::ModelTypeChangeProcessor::ReportError,
-                          change_processor()->GetWeakPtr()));
-}
-
-absl::optional<syncer::ModelError> TypedURLSyncBridge::MergeFullSyncData(
-    std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-    syncer::EntityChangeList entity_data) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  // Create a mapping of all local data by URL. These will be narrowed down
-  // by MergeURLWithSync() to include only the entries different from sync
-  // server data.
-  std::map<GURL, URLRow> new_db_urls;
-  std::map<GURL, std::vector<VisitRow>> local_visit_vectors;
-
-  if (!GetValidURLsAndVisits(&local_visit_vectors, &new_db_urls)) {
-    RecordDatabaseError(SyncTypedUrlDatabaseError::kMergeFullSyncDataRead);
-    return syncer::ModelError(
-        FROM_HERE, "Could not get the typed_url entries from HistoryBackend.");
-  }
-
-  // New sync data organized for different write operations to history backend.
-  std::vector<URLRow> new_synced_urls;
-  std::vector<URLRow> updated_synced_urls;
-  std::vector<URLWithVisits> new_synced_visits;
-
-  // Iterate through entity_data and check for all the urls that
-  // sync already knows about. MergeURLWithSync() will remove urls that
-  // are the same as the synced ones from `new_db_urls`.
-  for (const std::unique_ptr<syncer::EntityChange>& entity_change :
-       entity_data) {
-    DCHECK(entity_change->data().specifics.has_typed_url());
-    const sync_pb::TypedUrlSpecifics& specifics =
-        entity_change->data().specifics.typed_url();
-    if (ShouldIgnoreUrl(GURL(specifics.url()))) {
-      continue;
-    }
-
-    // Ignore old sync urls that don't have any transition data stored with
-    // them, or transition data that does not match the visit data (will be
-    // deleted later by GarbageCollectionDirective).
-    if (specifics.visit_transitions_size() == 0 ||
-        specifics.visit_transitions_size() != specifics.visits_size()) {
-      DCHECK_EQ(specifics.visits_size(), specifics.visit_transitions_size());
-      DLOG(WARNING)
-          << "Ignoring obsolete sync url with no visit transition info.";
-
-      continue;
-    }
-    MergeURLWithSync(specifics, &new_db_urls, &local_visit_vectors,
-                     &new_synced_urls, &new_synced_visits,
-                     &updated_synced_urls);
-  }
-
-  absl::optional<syncer::ModelError> error =
-      WriteToHistoryBackend(&new_synced_urls, &updated_synced_urls, nullptr,
-                            &new_synced_visits, nullptr);
-  if (error) {
-    RecordDatabaseError(SyncTypedUrlDatabaseError::kMergeFullSyncDataWriteData);
-    return error;
-  }
-
-  // Update storage key here first, and then send updated typed URL to sync
-  // below, otherwise processor will have duplicate entries.
-  for (const std::unique_ptr<syncer::EntityChange>& entity_change :
-       entity_data) {
-    DCHECK(entity_change->data().specifics.has_typed_url());
-    std::string storage_key = GetStorageKeyInternal(
-        entity_change->data().specifics.typed_url().url());
-    if (storage_key.empty()) {
-      // ignore entity change
-      change_processor()->UntrackEntityForClientTagHash(
-          entity_change->data().client_tag_hash);
-    } else {
-      change_processor()->UpdateStorageKey(entity_change->data(), storage_key,
-                                           metadata_change_list.get());
-    }
-  }
-
-  // Send new/updated typed URL to sync.
-  for (const auto& [url, url_row] : new_db_urls) {
-    SendTypedURLToProcessor(url_row, local_visit_vectors[url],
-                            metadata_change_list.get());
-  }
-
-  absl::optional<syncer::ModelError> metadata_error =
-      change_processor()->GetError();
-  if (metadata_error) {
-    RecordDatabaseError(
-        SyncTypedUrlDatabaseError::kMergeFullSyncDataWriteMetadata);
-  }
-  return metadata_error;
-}
-
-absl::optional<syncer::ModelError>
-TypedURLSyncBridge::ApplyIncrementalSyncChanges(
-    std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-    syncer::EntityChangeList entity_changes) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  std::vector<GURL> pending_deleted_urls;
-  std::vector<URLWithVisits> new_synced_visits;
-  std::vector<VisitRow> deleted_visits;
-  std::vector<URLRow> updated_synced_urls;
-  std::vector<URLRow> new_synced_urls;
-
-  for (const std::unique_ptr<syncer::EntityChange>& entity_change :
-       entity_changes) {
-    if (entity_change->type() == syncer::EntityChange::ACTION_DELETE) {
-      URLRow url_row;
-      int64_t url_id = TypedURLSyncMetadataDatabase::StorageKeyToURLID(
-          entity_change->storage_key());
-      if (!history_backend_->GetURLByID(url_id, &url_row)) {
-        // Ignoring the case that there is no matching URLRow with URLID
-        // `url_id`.
-        continue;
-      }
-
-      pending_deleted_urls.push_back(url_row.url());
-      continue;
-    }
-
-    DCHECK(entity_change->data().specifics.has_typed_url());
-    const sync_pb::TypedUrlSpecifics& specifics =
-        entity_change->data().specifics.typed_url();
-
-    GURL url(specifics.url());
-
-    if (ShouldIgnoreUrl(url)) {
-      continue;
-    }
-
-    DCHECK(specifics.visits_size());
-    sync_pb::TypedUrlSpecifics filtered_url = FilterExpiredVisits(specifics);
-    if (filtered_url.visits_size() == 0) {
-      continue;
-    }
-
-    UpdateFromSync(filtered_url, &new_synced_visits, &deleted_visits,
-                   &updated_synced_urls, &new_synced_urls);
-  }
-
-  absl::optional<syncer::ModelError> error = WriteToHistoryBackend(
-      &new_synced_urls, &updated_synced_urls, &pending_deleted_urls,
-      &new_synced_visits, &deleted_visits);
-  if (error) {
-    RecordDatabaseError(
-        SyncTypedUrlDatabaseError::kApplyIncrementalSyncChangesWriteData);
-    return error;
-  }
-
-  // New entities were either ignored or written to history DB and assigned a
-  // storage key. Notify processor about updated storage keys.
-  for (const std::unique_ptr<syncer::EntityChange>& entity_change :
-       entity_changes) {
-    if (entity_change->type() == syncer::EntityChange::ACTION_ADD) {
-      std::string storage_key = GetStorageKeyInternal(
-          entity_change->data().specifics.typed_url().url());
-      if (storage_key.empty()) {
-        // ignore entity change
-        change_processor()->UntrackEntityForClientTagHash(
-            entity_change->data().client_tag_hash);
-      } else {
-        change_processor()->UpdateStorageKey(entity_change->data(), storage_key,
-                                             metadata_change_list.get());
-      }
-    }
-  }
-
-  absl::optional<syncer::ModelError> metadata_error =
-      change_processor()->GetError();
-  if (metadata_error) {
-    RecordDatabaseError(
-        SyncTypedUrlDatabaseError::kApplyIncrementalSyncChangesWriteMetadata);
-  }
-  return metadata_error;
-}
-
-void TypedURLSyncBridge::GetData(StorageKeyList storage_keys,
-                                 DataCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  auto batch = std::make_unique<syncer::MutableDataBatch>();
-  for (const std::string& key : storage_keys) {
-    URLRow url_row;
-    URLID url_id = TypedURLSyncMetadataDatabase::StorageKeyToURLID(key);
-
-    if (!history_backend_->GetURLByID(url_id, &url_row)) {
-      // Ignoring the case which no matching URLRow with URLID `url_id`.
-      DLOG(ERROR) << "Could not find URL for id: " << url_id;
-      continue;
-    }
-
-    std::vector<VisitRow> visits_vector;
-    if (!FixupURLAndGetVisits(&url_row, &visits_vector) ||
-        visits_vector.empty()) {
-      continue;
-    }
-    std::unique_ptr<syncer::EntityData> entity_data =
-        CreateEntityData(url_row, visits_vector);
-    if (!entity_data) {
-      // Cannot create EntityData, ex. no TYPED visits.
-      continue;
-    }
-
-    batch->Put(key, std::move(entity_data));
-  }
-
-  std::move(callback).Run(std::move(batch));
-}
-
-void TypedURLSyncBridge::GetAllDataForDebugging(DataCallback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  std::vector<URLRow> typed_urls;
-  if (!history_backend_->GetAllTypedURLs(&typed_urls)) {
-    change_processor()->ReportError(
-        {FROM_HERE, "Could not get the typed_url entries."});
-    return;
-  }
-
-  auto batch = std::make_unique<syncer::MutableDataBatch>();
-  for (URLRow& url : typed_urls) {
-    std::vector<VisitRow> visits_vector;
-    if (!FixupURLAndGetVisits(&url, &visits_vector) || visits_vector.empty()) {
-      continue;
-    }
-    std::unique_ptr<syncer::EntityData> entity_data =
-        CreateEntityData(url, visits_vector);
-    if (!entity_data) {
-      // Cannot create EntityData, ex. no TYPED visits.
-      continue;
-    }
-
-    batch->Put(GetStorageKeyFromURLRow(url), std::move(entity_data));
-  }
-
-  std::move(callback).Run(std::move(batch));
-}
-
-// Must be exactly the value of GURL::spec() for backwards comparability with
-// the previous (Directory + SyncableService) iteration of sync integration.
-// This can be large but it is assumed that this is not held in memory at steady
-// state.
-std::string TypedURLSyncBridge::GetClientTag(
-    const syncer::EntityData& entity_data) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(entity_data.specifics.has_typed_url())
-      << "EntityData does not have typed urls specifics.";
-
-  return entity_data.specifics.typed_url().url();
-}
-
-// Prefer to use URLRow::id() to uniquely identify entities when coordinating
-// with sync because it has a significantly low memory cost than a URL.
-std::string TypedURLSyncBridge::GetStorageKey(
-    const syncer::EntityData& entity_data) {
-  NOTREACHED() << "TypedURLSyncBridge do not support GetStorageKey.";
-  return std::string();
-}
-
-bool TypedURLSyncBridge::SupportsGetStorageKey() const {
-  return false;
-}
-
-void TypedURLSyncBridge::OnURLVisited(HistoryBackend* history_backend,
-                                      const URLRow& url_row,
-                                      const VisitRow& visit_row) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(sync_metadata_database_);
-  DCHECK_GE(url_row.typed_count(), 0);
-
-  if (processing_syncer_changes_) {
-    return;  // These are changes originating from us, ignore.
-  }
-
-  if (!change_processor()->IsTrackingMetadata()) {
-    return;  // Sync processor not yet ready, don't sync.
-  }
-  if (!ShouldSyncVisit(url_row.typed_count(), visit_row.transition)) {
-    return;
-  }
-
-  std::unique_ptr<syncer::MetadataChangeList> metadata_change_list =
-      CreateMetadataChangeList();
-
-  UpdateSyncFromLocal(url_row, /*is_from_expiration=*/false,
-                      metadata_change_list.get());
-}
-
-void TypedURLSyncBridge::OnURLsModified(HistoryBackend* history_backend,
-                                        const std::vector<URLRow>& changed_urls,
-                                        bool is_from_expiration) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(sync_metadata_database_);
-
-  if (processing_syncer_changes_) {
-    return;  // These are changes originating from us, ignore.
-  }
-
-  if (!change_processor()->IsTrackingMetadata()) {
-    return;  // Sync processor not yet ready, don't sync.
-  }
-
-  std::unique_ptr<syncer::MetadataChangeList> metadata_change_list =
-      CreateMetadataChangeList();
-
-  for (const URLRow& row : changed_urls) {
-    DCHECK_GE(row.typed_count(), 0);
-    // If there were any errors updating the sync node, just ignore them and
-    // continue on to process the next URL.
-    UpdateSyncFromLocal(row, is_from_expiration, metadata_change_list.get());
-  }
-}
-
-void TypedURLSyncBridge::OnURLsDeleted(HistoryBackend* history_backend,
-                                       bool all_history,
-                                       bool expired,
-                                       const std::vector<URLRow>& deleted_rows,
-                                       const std::set<GURL>& favicon_urls) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(sync_metadata_database_);
-
-  if (processing_syncer_changes_) {
-    return;  // These are changes originating from us, ignore.
-  }
-
-  if (!change_processor()->IsTrackingMetadata()) {
-    return;  // Sync processor not yet ready, don't sync.
-  }
-
-  // Ignore URLs expired due to old age (we don't want to sync them as deletions
-  // to avoid extra traffic up to the server, and also to make sure that a
-  // client with a bad clock setting won't go on an expiration rampage and
-  // delete all history from every client). The server will gracefully age out
-  // the sync DB entries when they've been idle for long enough.
-  if (expired) {
-    // Delete metadata from the DB and ask the processor to untrack the entries.
-    for (const URLRow& row : deleted_rows) {
-      ExpireMetadataForURL(row);
-    }
-    return;
-  }
-
-  std::unique_ptr<syncer::MetadataChangeList> metadata_change_list =
-      CreateMetadataChangeList();
-
-  if (all_history) {
-    auto batch = std::make_unique<syncer::MetadataBatch>();
-    if (!sync_metadata_database_->GetAllSyncMetadata(batch.get())) {
-      RecordDatabaseError(
-          SyncTypedUrlDatabaseError::kOnURLsDeletedReadMetadata);
-      change_processor()->ReportError({FROM_HERE,
-                                       "Failed reading typed url metadata from "
-                                       "TypedURLSyncMetadataDatabase."});
-      return;
-    }
-
-    syncer::EntityMetadataMap metadata_map(batch->TakeAllMetadata());
-    for (const auto& [storage_key, metadata] : metadata_map) {
-      change_processor()->Delete(storage_key, metadata_change_list.get());
-    }
-  } else {
-    // Delete rows.
-    for (const URLRow& row : deleted_rows) {
-      std::string storage_key = GetStorageKeyFromURLRow(row);
-      change_processor()->Delete(storage_key, metadata_change_list.get());
-    }
-  }
-}
-
-void TypedURLSyncBridge::OnVisitUpdated(const VisitRow& visit,
-                                        VisitUpdateReason reason) {}
-
-void TypedURLSyncBridge::OnVisitDeleted(const VisitRow& visit) {}
-
-void TypedURLSyncBridge::Init() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  history_backend_observation_.Observe(history_backend_.get());
-  LoadMetadata();
-}
-
-void TypedURLSyncBridge::OnDatabaseError() {
-  sync_metadata_database_ = nullptr;
-  RecordDatabaseError(SyncTypedUrlDatabaseError::kOnDatabaseError);
-  change_processor()->ReportError(
-      {FROM_HERE, "HistoryDatabase encountered error"});
-}
-
-// static
-bool TypedURLSyncBridge::WriteToTypedUrlSpecifics(
-    const URLRow& url,
-    const std::vector<VisitRow>& visits,
-    sync_pb::TypedUrlSpecifics* typed_url) {
-  DCHECK(!url.last_visit().is_null());
-  DCHECK(!visits.empty());
-  DCHECK_EQ(url.last_visit().ToInternalValue(),
-            visits.back().visit_time.ToInternalValue());
-
-  typed_url->set_url(url.url().spec());
-  typed_url->set_title(base::UTF16ToUTF8(url.title()));
-  typed_url->set_hidden(url.hidden());
-
-  DCHECK(VisitsAreSorted(visits));
-
-  bool only_typed = false;
-  int skip_count = 0;
-
-  if (!HasTypedUrl(visits)) {
-    // This URL has no TYPED visits, don't sync it
-    return false;
-  }
-
-  if (visits.size() > static_cast<size_t>(kMaxTypedUrlVisits)) {
-    int typed_count = 0;
-    int total = 0;
-    // Walk the passed-in visit vector and count the # of typed visits.
-    for (const VisitRow& visit : visits) {
-      // We ignore reload visits.
-      if (PageTransitionCoreTypeIs(visit.transition,
-                                   ui::PAGE_TRANSITION_RELOAD)) {
-        continue;
-      }
-      ++total;
-      if (PageTransitionCoreTypeIs(visit.transition,
-                                   ui::PAGE_TRANSITION_TYPED)) {
-        ++typed_count;
-      }
-    }
-
-    // We should have at least one typed visit. This can sometimes happen if
-    // the history DB has an inaccurate count for some reason (there's been
-    // bugs in the history code in the past which has left users in the wild
-    // with incorrect counts - http://crbug.com/84258).
-    DCHECK_GT(typed_count, 0);
-
-    if (typed_count > kMaxTypedUrlVisits) {
-      only_typed = true;
-      skip_count = typed_count - kMaxTypedUrlVisits;
-    } else if (total > kMaxTypedUrlVisits) {
-      skip_count = total - kMaxTypedUrlVisits;
-    }
-  }
-
-  for (const VisitRow& visit : visits) {
-    // Skip reload visits.
-    if (PageTransitionCoreTypeIs(visit.transition,
-                                 ui::PAGE_TRANSITION_RELOAD)) {
-      continue;
-    }
-
-    // If we only have room for typed visits, then only add typed visits.
-    if (only_typed && !PageTransitionCoreTypeIs(visit.transition,
-                                                ui::PAGE_TRANSITION_TYPED)) {
-      continue;
-    }
-
-    if (skip_count > 0) {
-      // We have too many entries to fit, so we need to skip the oldest ones.
-      // Only skip typed URLs if there are too many typed URLs to fit.
-      if (only_typed || !PageTransitionCoreTypeIs(visit.transition,
-                                                  ui::PAGE_TRANSITION_TYPED)) {
-        --skip_count;
-        continue;
-      }
-    }
-    typed_url->add_visits(visit.visit_time.ToInternalValue());
-    typed_url->add_visit_transitions(visit.transition);
-  }
-  DCHECK_EQ(skip_count, 0);
-
-  CHECK_GT(typed_url->visits_size(), 0);
-  CHECK_LE(typed_url->visits_size(), kMaxTypedUrlVisits);
-  CHECK_EQ(typed_url->visits_size(), typed_url->visit_transitions_size());
-
-  return true;
-}
-
-// static
-TypedURLSyncBridge::MergeResult TypedURLSyncBridge::MergeUrls(
-    const sync_pb::TypedUrlSpecifics& sync_url,
-    const URLRow& url,
-    std::vector<VisitRow>* visits,
-    URLRow* new_url,
-    std::vector<VisitInfo>* new_visits) {
-  DCHECK(new_url);
-  DCHECK_EQ(sync_url.url(), url.url().spec());
-  DCHECK_EQ(sync_url.url(), new_url->url().spec());
-  DCHECK(visits->size());
-  DCHECK_GT(sync_url.visits_size(), 0);
-  CHECK_EQ(sync_url.visits_size(), sync_url.visit_transitions_size());
-
-  // Convert these values only once.
-  std::u16string sync_url_title(base::UTF8ToUTF16(sync_url.title()));
-  base::Time sync_url_last_visit = base::Time::FromInternalValue(
-      sync_url.visits(sync_url.visits_size() - 1));
-
-  // This is a bitfield representing what we'll need to update with the output
-  // value.
-  MergeResult different = DIFF_NONE;
-
-  // Check if the non-incremented values changed.
-  if ((sync_url_title != url.title()) || (sync_url.hidden() != url.hidden())) {
-    // Use the values from the most recent visit.
-    if (sync_url_last_visit >= url.last_visit()) {
-      new_url->set_title(sync_url_title);
-      new_url->set_hidden(sync_url.hidden());
-      different |= DIFF_LOCAL_ROW_CHANGED;
-    } else {
-      new_url->set_title(url.title());
-      new_url->set_hidden(url.hidden());
-      different |= DIFF_UPDATE_NODE;
-    }
-  } else {
-    // No difference.
-    new_url->set_title(url.title());
-    new_url->set_hidden(url.hidden());
-  }
-
-  size_t sync_url_num_visits = sync_url.visits_size();
-  size_t history_num_visits = visits->size();
-  size_t sync_url_visit_index = 0;
-  size_t history_visit_index = 0;
-  base::Time earliest_history_time = (*visits)[0].visit_time;
-  // Walk through the two sets of visits and figure out if any new visits were
-  // added on either side.
-  while (sync_url_visit_index < sync_url_num_visits ||
-         history_visit_index < history_num_visits) {
-    // Time objects are initialized to "earliest possible time".
-    base::Time sync_url_time, history_time;
-    if (sync_url_visit_index < sync_url_num_visits) {
-      sync_url_time =
-          base::Time::FromInternalValue(sync_url.visits(sync_url_visit_index));
-    }
-    if (history_visit_index < history_num_visits) {
-      history_time = (*visits)[history_visit_index].visit_time;
-    }
-    if (sync_url_visit_index >= sync_url_num_visits ||
-        (history_visit_index < history_num_visits &&
-         sync_url_time > history_time)) {
-      // We found a visit in the history DB that doesn't exist in the sync DB,
-      // so mark the sync_url as modified so the caller will update the sync
-      // node.
-      different |= DIFF_UPDATE_NODE;
-      ++history_visit_index;
-    } else if (history_visit_index >= history_num_visits ||
-               sync_url_time < history_time) {
-      // Found a visit in the sync node that doesn't exist in the history DB, so
-      // add it to our list of new visits and set the appropriate flag so the
-      // caller will update the history DB.
-      // If the sync_url visit is older than any existing visit in the history
-      // DB, don't re-add it - this keeps us from resurrecting visits that were
-      // aged out locally.
-      //
-      // TODO(sync): This extra check should be unnecessary now that filtering
-      // expired visits is performed separately. Non-expired visits older than
-      // the earliest existing history visits should still be synced, so this
-      // check should be removed.
-      if (sync_url_time > earliest_history_time) {
-        different |= DIFF_LOCAL_VISITS_ADDED;
-        new_visits->push_back(VisitInfo(
-            sync_url_time, ui::PageTransitionFromInt(sync_url.visit_transitions(
-                               sync_url_visit_index))));
-      }
-      // This visit is added to visits below.
-      ++sync_url_visit_index;
-    } else {
-      // Same (already synced) entry found in both DBs - no need to do anything.
-      ++sync_url_visit_index;
-      ++history_visit_index;
-    }
-  }
-
-  DCHECK(VisitsAreSorted(*visits));
-  if (different & DIFF_LOCAL_VISITS_ADDED) {
-    // If the server does not have the same visits as the local db, then the
-    // new visits from the server need to be added to the vector containing
-    // local visits. These visits will be passed to the server.
-    // Insert new visits into the appropriate place in the visits vector.
-    auto visit_ix = visits->begin();
-    for (const auto& [new_visit_time, new_page_transition] : *new_visits) {
-      while (visit_ix != visits->end() &&
-             new_visit_time > visit_ix->visit_time) {
-        ++visit_ix;
-      }
-      visit_ix = visits->insert(
-          visit_ix,
-          VisitRow(url.id(), new_visit_time, /*arg_referring_visit=*/0,
-                   new_page_transition, /*arg_segment_id=*/0,
-                   HistoryBackend::IsTypedIncrement(new_page_transition),
-                   /*arg_opener_visit=*/0));
-      ++visit_ix;
-    }
-  }
-  DCHECK(VisitsAreSorted(*visits));
-
-  new_url->set_last_visit(visits->back().visit_time);
-  return different;
-}
-
-// static
-void TypedURLSyncBridge::DiffVisits(
-    const std::vector<VisitRow>& history_visits,
-    const sync_pb::TypedUrlSpecifics& sync_specifics,
-    std::vector<VisitInfo>* new_visits,
-    std::vector<VisitRow>* removed_visits) {
-  DCHECK(new_visits);
-  size_t old_visit_count = history_visits.size();
-  size_t new_visit_count = sync_specifics.visits_size();
-  size_t old_index = 0;
-  size_t new_index = 0;
-  while (old_index < old_visit_count && new_index < new_visit_count) {
-    base::Time new_visit_time =
-        base::Time::FromInternalValue(sync_specifics.visits(new_index));
-    if (history_visits[old_index].visit_time < new_visit_time) {
-      if (new_index > 0 && removed_visits) {
-        // If there are visits missing from the start of the node, that
-        // means that they were probably clipped off due to our code that
-        // limits the size of the sync nodes - don't delete them from our
-        // local history.
-        removed_visits->push_back(history_visits[old_index]);
-      }
-      ++old_index;
-    } else if (history_visits[old_index].visit_time > new_visit_time) {
-      new_visits->push_back(VisitInfo(
-          new_visit_time, ui::PageTransitionFromInt(
-                              sync_specifics.visit_transitions(new_index))));
-      ++new_index;
-    } else {
-      ++old_index;
-      ++new_index;
-    }
-  }
-
-  if (removed_visits) {
-    for (; old_index < old_visit_count; ++old_index) {
-      removed_visits->push_back(history_visits[old_index]);
-    }
-  }
-
-  for (; new_index < new_visit_count; ++new_index) {
-    new_visits->push_back(VisitInfo(
-        base::Time::FromInternalValue(sync_specifics.visits(new_index)),
-        ui::PageTransitionFromInt(
-            sync_specifics.visit_transitions(new_index))));
-  }
-}
-
-// static
-void TypedURLSyncBridge::UpdateURLRowFromTypedUrlSpecifics(
-    const sync_pb::TypedUrlSpecifics& typed_url,
-    URLRow* new_url) {
-  DCHECK_GT(typed_url.visits_size(), 0);
-  CHECK_EQ(typed_url.visit_transitions_size(), typed_url.visits_size());
-  if (!new_url->url().is_valid()) {
-    new_url->set_url(GURL(typed_url.url()));
-  }
-  new_url->set_title(base::UTF8ToUTF16(typed_url.title()));
-  new_url->set_hidden(typed_url.hidden());
-  // Only provide the initial value for the last_visit field - after that, let
-  // the history code update the last_visit field on its own.
-  if (new_url->last_visit().is_null()) {
-    new_url->set_last_visit(base::Time::FromInternalValue(
-        typed_url.visits(typed_url.visits_size() - 1)));
-  }
-}
-
-void TypedURLSyncBridge::LoadMetadata() {
-  if (!history_backend_ || !sync_metadata_database_) {
-    RecordDatabaseError(SyncTypedUrlDatabaseError::kLoadMetadataOpen);
-    change_processor()->ReportError(
-        {FROM_HERE, "Failed to load TypedURLSyncMetadataDatabase."});
-    return;
-  }
-
-  auto batch = std::make_unique<syncer::MetadataBatch>();
-  if (!sync_metadata_database_->GetAllSyncMetadata(batch.get())) {
-    RecordDatabaseError(SyncTypedUrlDatabaseError::kLoadMetadataRead);
-    change_processor()->ReportError({FROM_HERE,
-                                     "Failed reading typed url metadata from "
-                                     "TypedURLSyncMetadataDatabase."});
-    return;
-  }
-  change_processor()->ModelReadyToSync(std::move(batch));
-}
-
-void TypedURLSyncBridge::MergeURLWithSync(
-    const sync_pb::TypedUrlSpecifics& server_typed_url,
-    std::map<GURL, URLRow>* local_typed_urls,
-    std::map<GURL, std::vector<VisitRow>>* local_visit_vectors,
-    std::vector<URLRow>* new_synced_urls,
-    std::vector<URLWithVisits>* new_synced_visits,
-    std::vector<URLRow>* updated_synced_urls) {
-  DCHECK_NE(0, server_typed_url.visits_size());
-  DCHECK_EQ(server_typed_url.visits_size(),
-            server_typed_url.visit_transitions_size());
-
-  // Ignore empty urls.
-  if (server_typed_url.url().empty()) {
-    DVLOG(1) << "Ignoring empty URL in sync DB";
-    return;
-  }
-  // Now, get rid of the expired visits. If there are no un-expired visits
-  // left, ignore this url - any local data should just replace it.
-  sync_pb::TypedUrlSpecifics sync_url = FilterExpiredVisits(server_typed_url);
-  if (sync_url.visits_size() == 0) {
-    DVLOG(1) << "Ignoring expired URL in sync DB: " << sync_url.url();
-    return;
-  }
-
-  // Check if local db already has the url from sync.
-  auto it = local_typed_urls->find(GURL(sync_url.url()));
-  if (it == local_typed_urls->end()) {
-    // There are no matching typed urls from the local db, check for untyped
-    URLRow untyped_url(GURL(sync_url.url()));
-
-    // The URL may still exist in the local db if it is an untyped url.
-    // An untyped url will transition to a typed url after receiving visits
-    // from sync, and sync should receive any visits already existing locally
-    // for the url, so the full list of visits is consistent.
-    bool is_existing_url =
-        history_backend_->GetURL(untyped_url.url(), &untyped_url);
-    if (is_existing_url) {
-      // Add a new entry to `local_typed_urls`, and set the iterator to it.
-      std::vector<VisitRow> untyped_visits;
-      // TODO(crbug.com/1075573): We early return on urls with all visits
-      // expired. It does not feel right as we might get new non-expired visits
-      // through sync.
-      if (!FixupURLAndGetVisits(&untyped_url, &untyped_visits) ||
-          untyped_visits.empty()) {
-        return;
-      }
-      (*local_visit_vectors)[untyped_url.url()] = untyped_visits;
-
-      // Store row info that will be used to update sync's visits.
-      (*local_typed_urls)[untyped_url.url()] = untyped_url;
-
-      // Set iterator `it` to point to this entry.
-      it = local_typed_urls->find(untyped_url.url());
-      DCHECK(it != local_typed_urls->end());
-      // Continue with merge below.
-    } else {
-      // The url is new to the local history DB.
-      // Create new db entry for url.
-      URLRow new_url(GURL(sync_url.url()));
-      UpdateURLRowFromTypedUrlSpecifics(sync_url, &new_url);
-      new_synced_urls->push_back(new_url);
-
-      // Add entries for url visits.
-      std::vector<VisitInfo> added_visits;
-      size_t visit_count = sync_url.visits_size();
-
-      for (size_t index = 0; index < visit_count; ++index) {
-        base::Time visit_time =
-            base::Time::FromInternalValue(sync_url.visits(index));
-        ui::PageTransition transition =
-            ui::PageTransitionFromInt(sync_url.visit_transitions(index));
-        added_visits.emplace_back(visit_time, transition);
-      }
-      new_synced_visits->emplace_back(new_url.url(), added_visits);
-      return;
-    }
-  }
-
-  // Same URL exists in sync data and in history data - compare the
-  // entries to see if there's any difference.
-  auto& [url, url_row] = *it;
-  std::vector<VisitRow>& visits = (*local_visit_vectors)[url];
-  std::vector<VisitInfo> added_visits;
-
-  // Empty URLs should be filtered out by ShouldIgnoreUrl() previously.
-  DCHECK(!url_row.url().spec().empty());
-
-  // Initialize fields in `new_url` to the same values as the fields in
-  // the existing URLRow in the history DB. This is needed because we
-  // overwrite the existing value in WriteToHistoryBackend(), but some of
-  // the values in that structure are not synced (like typed_count).
-  URLRow new_url(url_row);
-
-  MergeResult difference =
-      MergeUrls(sync_url, url_row, &visits, &new_url, &added_visits);
-
-  if (difference != DIFF_NONE) {
-    url_row = new_url;
-    if (difference & DIFF_UPDATE_NODE) {
-      // We don't want to resurrect old visits that have been aged out by
-      // other clients, so remove all visits that are older than the
-      // earliest existing visit in the sync node.
-      //
-      // TODO(sync): This logic should be unnecessary now that filtering of
-      // expired visits is performed separately. Non-expired visits older than
-      // the earliest existing sync visits should still be synced, so this
-      // logic should be removed.
-      if (sync_url.visits_size() > 0) {
-        base::Time earliest_visit =
-            base::Time::FromInternalValue(sync_url.visits(0));
-        for (auto i = visits.begin();
-             i != visits.end() && i->visit_time < earliest_visit;) {
-          i = visits.erase(i);
-        }
-        // Should never be possible to delete all the items, since the
-        // visit vector contains newer local visits it will keep and/or the
-        // visits in typed_url.visits newer than older local visits.
-        DCHECK_GT(visits.size(), 0U);
-      }
-      DCHECK_EQ(new_url.last_visit().ToInternalValue(),
-                visits.back().visit_time.ToInternalValue());
-    }
-    if (difference & DIFF_LOCAL_ROW_CHANGED) {
-      // Add entry to updated_synced_urls to update the local db.
-      DCHECK_EQ(url_row.id(), new_url.id());
-      updated_synced_urls->push_back(new_url);
-    }
-    if (difference & DIFF_LOCAL_VISITS_ADDED) {
-      // Add entry with new visits to new_synced_visits to update the local db.
-      new_synced_visits->emplace_back(url, added_visits);
-    }
-  } else {
-    // No difference in urls, erase from map
-    local_typed_urls->erase(it);
-  }
-}
-
-void TypedURLSyncBridge::UpdateFromSync(
-    const sync_pb::TypedUrlSpecifics& typed_url,
-    std::vector<URLWithVisits>* visits_to_add,
-    std::vector<VisitRow>* visits_to_remove,
-    std::vector<URLRow>* updated_urls,
-    std::vector<URLRow>* new_urls) {
-  URLRow new_url(GURL(typed_url.url()));
-  std::vector<VisitRow> existing_visits;
-  bool existing_url = history_backend_->GetURL(new_url.url(), &new_url);
-  if (existing_url) {
-    // This URL already exists locally - fetch the visits so we can
-    // merge them below.
-    // TODO(crbug.com/1075573): We early return on urls with all visits
-    // expired. It does not feel right as we might get new non-expired visits
-    // through sync.
-    if (!FixupURLAndGetVisits(&new_url, &existing_visits) ||
-        existing_visits.empty()) {
-      return;
-    }
-  }
-  visits_to_add->emplace_back(new_url.url(), std::vector<VisitInfo>());
-
-  // Update the URL with information from the typed URL.
-  UpdateURLRowFromTypedUrlSpecifics(typed_url, &new_url);
-
-  // Figure out which visits we need to add.
-  DiffVisits(existing_visits, typed_url, &visits_to_add->back().visits,
-             visits_to_remove);
-
-  if (existing_url) {
-    updated_urls->push_back(new_url);
-  } else {
-    new_urls->push_back(new_url);
-  }
-}
-
-void TypedURLSyncBridge::UpdateSyncFromLocal(
-    URLRow row,
-    bool is_from_expiration,
-    syncer::MetadataChangeList* metadata_change_list) {
-  if (ShouldIgnoreUrl(row.url())) {
-    return;
-  }
-
-  // Get the visits for this node.
-  std::vector<VisitRow> visit_vector;
-  if (!FixupURLAndGetVisits(&row, &visit_vector)) {
-    return;
-  }
-
-  // We want to also deal with URLs that have all visits expired (that return
-  // empty `visit_vector` from FixupURLAndGetVisits()) so that these get expired
-  // or deleted.
-  if (HasTypedUrl(visit_vector)) {
-    SendTypedURLToProcessor(row, visit_vector, metadata_change_list);
-  } else {
-    std::string storage_key = GetStorageKeyFromURLRow(row);
-    // If the URL has no typed visits any more we should get rid of it. It is
-    // possible that this URL never had typed visits and thus it has no sync
-    // entity and no sync metadata. We do not need to check for this case
-    // as all the code below is no-op if there is no sync metadata for `row`.
-    if (is_from_expiration) {
-      // Only remove its metadata as we do not sync up deletions for expired
-      // entities (see the comment in OnURLsDeleted()).
-      ExpireMetadataForURL(row);
-    } else {
-      // This change is caused by the user explicitly removing some visits, we
-      // should also remove the entity from sync.
-      change_processor()->Delete(storage_key, metadata_change_list);
-    }
-  }
-}
-
-void TypedURLSyncBridge::ExpireMetadataForURL(const URLRow& row) {
-  std::string storage_key = GetStorageKeyFromURLRow(row);
-  // The following functions need to tolerate if there exists no metadata
-  // for `storage_key` as we might call this function multiple times for a given
-  // url.
-  sync_metadata_database_->ClearEntityMetadata(syncer::TYPED_URLS, storage_key);
-  change_processor()->UntrackEntityForStorageKey(storage_key);
-}
-
-absl::optional<syncer::ModelError> TypedURLSyncBridge::WriteToHistoryBackend(
-    const std::vector<URLRow>* new_urls,
-    const std::vector<URLRow>* updated_urls,
-    const std::vector<GURL>* deleted_urls,
-    const std::vector<URLWithVisits>* new_visits,
-    const std::vector<VisitRow>* deleted_visits) {
-  DCHECK_EQ(processing_syncer_changes_, false);
-  // Set flag to stop accepting history change notifications from backend.
-  base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
-
-  if (deleted_urls && !deleted_urls->empty()) {
-    history_backend_->DeleteURLs(*deleted_urls);
-  }
-
-  if (new_urls) {
-    history_backend_->AddPagesWithDetails(*new_urls, SOURCE_SYNCED);
-  }
-
-  if (updated_urls) {
-    // This is an existing entry in the URL database. We don't verify the
-    // visit_count or typed_count values here, because either one (or both)
-    // could be zero in the case of bookmarks, or in the case of a URL
-    // transitioning from non-typed to typed as a result of this sync.
-    // In the field we sometimes run into errors on specific URLs. It's OK
-    // to just continue on (we can try writing again on the next model
-    // association).
-    history_backend_->UpdateURLs(*updated_urls);
-  }
-
-  if (new_visits) {
-    for (const auto& [url, visit_infos] : *new_visits) {
-      // If there are no visits to add, just skip this.
-      if (visit_infos.empty()) {
-        continue;
-      }
-      if (!history_backend_->AddVisits(url, visit_infos, SOURCE_SYNCED)) {
-        return syncer::ModelError(FROM_HERE,
-                                  "Could not add visits to HistoryBackend.");
-      }
-    }
-  }
-
-  if (deleted_visits) {
-    if (!history_backend_->RemoveVisits(*deleted_visits,
-                                        DeletionInfo::Reason::kOther)) {
-      return syncer::ModelError(FROM_HERE,
-                                "Could not remove visits from HistoryBackend.");
-      // This is bad news, since it means we may end up resurrecting history
-      // entries on the next reload. It's unavoidable so we'll just keep on
-      // syncing.
-    }
-  }
-
-  return {};
-}
-
-sync_pb::TypedUrlSpecifics TypedURLSyncBridge::FilterExpiredVisits(
-    const sync_pb::TypedUrlSpecifics& source) {
-  // Make a copy of the source, then regenerate the visits.
-  sync_pb::TypedUrlSpecifics specifics(source);
-  specifics.clear_visits();
-  specifics.clear_visit_transitions();
-  for (int i = 0; i < source.visits_size(); ++i) {
-    base::Time time = base::Time::FromInternalValue(source.visits(i));
-    if (!history_backend_->IsExpiredVisitTime(time)) {
-      specifics.add_visits(source.visits(i));
-      specifics.add_visit_transitions(source.visit_transitions(i));
-    }
-  }
-  DCHECK(specifics.visits_size() == specifics.visit_transitions_size());
-  return specifics;
-}
-
-bool TypedURLSyncBridge::ShouldIgnoreUrl(const GURL& url) {
-  // Ignore empty URLs. Not sure how this can happen (maybe import from other
-  // busted browsers, or misuse of the history API, or just plain bugs) but we
-  // can't deal with them.
-  if (url.spec().empty()) {
-    return true;
-  }
-
-  // Ignore local file URLs.
-  if (url.SchemeIsFile()) {
-    return true;
-  }
-
-  // Ignore localhost URLs.
-  if (net::IsLocalhost(url)) {
-    return true;
-  }
-
-  // Ignore username and password, since history backend will remove user name
-  // and password in database_utils::GurlToDatabaseUrl and send
-  // username/password removed url to sync later.
-  if (url.has_username() || url.has_password()) {
-    return true;
-  }
-
-  return false;
-}
-
-bool TypedURLSyncBridge::ShouldIgnoreVisits(
-    const std::vector<VisitRow>& visits) {
-  // We ignore URLs that were imported, but have never been visited by
-  // chromium.
-  static const int kFirstImportedSource = SOURCE_FIREFOX_IMPORTED;
-  VisitSourceMap map;
-  if (!history_backend_->GetVisitsSource(visits, &map)) {
-    return false;  // If we can't read the visit, assume it's not imported.
-  }
-
-  // Walk the list of visits and look for a non-imported item.
-  for (const VisitRow& visit : visits) {
-    if (map.count(visit.visit_id) == 0 ||
-        map[visit.visit_id] < kFirstImportedSource) {
-      return false;
-    }
-  }
-  // We only saw imported visits, so tell the caller to ignore them.
-  return true;
-}
-
-bool TypedURLSyncBridge::ShouldSyncVisit(int typed_count,
-                                         ui::PageTransition transition) {
-  // Just use an ad-hoc criteria to determine whether to ignore this
-  // notification. For most users, the distribution of visits is roughly a bell
-  // curve with a long tail - there are lots of URLs with < 5 visits so we want
-  // to make sure we sync up every visit to ensure the proper ordering of
-  // suggestions. But there are relatively few URLs with > 10 visits, and those
-  // tend to be more broadly distributed such that there's no need to sync up
-  // every visit to preserve their relative ordering.
-  return (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) &&
-          (typed_count < kTypedUrlVisitThrottleThreshold ||
-           (typed_count % kTypedUrlVisitThrottleMultiple) == 0));
-}
-
-bool TypedURLSyncBridge::FixupURLAndGetVisits(URLRow* url,
-                                              std::vector<VisitRow>* visits) {
-  if (!history_backend_->GetMostRecentVisitsForURL(url->id(), kMaxVisitsToFetch,
-                                                   visits)) {
-    // Couldn't load the visits for this URL due to some kind of DB error.
-    // Don't bother writing this URL to the history DB (if we ignore the
-    // error and continue, we might end up duplicating existing visits).
-    DLOG(ERROR) << "Could not load visits for url: " << url->url();
-    return false;
-  }
-
-  // Sometimes (due to a bug elsewhere in the history or sync code, or due to
-  // a crash between adding a URL to the history database and updating the
-  // visit DB) the visit vector for a URL can be empty. If this happens, just
-  // create a new visit whose timestamp is the same as the last_visit time.
-  // This is a workaround for http://crbug.com/84258.
-  if (visits->empty()) {
-    DVLOG(1) << "Found empty visits for URL: " << url->url();
-    if (url->last_visit().is_null()) {
-      // If modified URL is bookmarked, history backend treats it as modified
-      // even if all its visits are deleted. Return empty visits to stop further
-      // processing.
-      return true;
-    }
-
-    VisitRow visit(url->id(), url->last_visit(), /*arg_referring_visit=*/0,
-                   ui::PAGE_TRANSITION_TYPED,
-                   /*arg_segment_id=*/0,
-                   /*arg_incremented_omnibox_typed_score=*/true,
-                   /*arg_opener_visit=*/0);
-    visits->push_back(visit);
-  }
-
-  // GetMostRecentVisitsForURL() returns the data in the opposite order that
-  // we need it, so reverse it.
-  base::ranges::reverse(*visits);
-
-  // Sometimes, the last_visit field in the URL doesn't match the timestamp of
-  // the last visit in our visit array (they come from different tables, so
-  // crashes/bugs can cause them to mismatch), so just set it here.
-  url->set_last_visit(visits->back().visit_time);
-  DCHECK(VisitsAreSorted(*visits));
-
-  // Removes all visits that are older than the current expiration time. Visits
-  // are in ascending order now, so we can check from beginning to check how
-  // many expired visits.
-  size_t num_expired_visits = 0;
-  for (const VisitRow& visit : *visits) {
-    base::Time time = visit.visit_time;
-    if (history_backend_->IsExpiredVisitTime(time)) {
-      ++num_expired_visits;
-    } else {
-      break;
-    }
-  }
-  if (num_expired_visits != 0) {
-    if (num_expired_visits == visits->size()) {
-      DVLOG(1) << "All visits are expired for url: " << url->url();
-      visits->clear();
-      return true;
-    }
-    visits->erase(visits->begin(), visits->begin() + num_expired_visits);
-  }
-  DCHECK(VisitsAreSorted(*visits));
-
-  return true;
-}
-
-std::unique_ptr<syncer::EntityData> TypedURLSyncBridge::CreateEntityData(
-    const URLRow& row,
-    const std::vector<VisitRow>& visits) {
-  auto entity_data = std::make_unique<syncer::EntityData>();
-  sync_pb::TypedUrlSpecifics* specifics =
-      entity_data->specifics.mutable_typed_url();
-
-  if (!WriteToTypedUrlSpecifics(row, visits, specifics)) {
-    // Cannot write to specifics, ex. no TYPED visits.
-    return nullptr;
-  }
-  entity_data->name = row.url().spec();
-  return entity_data;
-}
-
-bool TypedURLSyncBridge::GetValidURLsAndVisits(
-    std::map<GURL, std::vector<VisitRow>>* url_to_visit,
-    std::map<GURL, URLRow>* url_to_urlrow) {
-  DCHECK(url_to_visit);
-  DCHECK(url_to_urlrow);
-
-  std::vector<URLRow> local_typed_urls;
-  if (!history_backend_->GetAllTypedURLs(&local_typed_urls)) {
-    return false;
-  }
-  for (URLRow& url : local_typed_urls) {
-    DCHECK_EQ(0U, url_to_visit->count(url.url()));
-    if (!FixupURLAndGetVisits(&url, &((*url_to_visit)[url.url()])) ||
-        ShouldIgnoreUrl(url.url()) ||
-        ShouldIgnoreVisits((*url_to_visit)[url.url()])) {
-      // Ignore this URL if we couldn't load the visits or if there's some
-      // other problem with it (it was empty, or imported and never visited).
-    } else {
-      // Add url to url_to_urlrow.
-      (*url_to_urlrow)[url.url()] = url;
-    }
-  }
-  return true;
-}
-
-std::string TypedURLSyncBridge::GetStorageKeyInternal(const std::string& url) {
-  DCHECK(history_backend_);
-
-  URLRow existing_url;
-  bool is_existing_url = history_backend_->GetURL(GURL(url), &existing_url);
-
-  if (!is_existing_url) {
-    // The typed url did not save to local history database, so return empty
-    // string.
-    return std::string();
-  }
-
-  return GetStorageKeyFromURLRow(existing_url);
-}
-
-void TypedURLSyncBridge::SendTypedURLToProcessor(
-    const URLRow& row,
-    const std::vector<VisitRow>& visits,
-    syncer::MetadataChangeList* metadata_change_list) {
-  DCHECK(!visits.empty());
-  DCHECK(metadata_change_list);
-
-  std::unique_ptr<syncer::EntityData> entity_data =
-      CreateEntityData(row, visits);
-  if (!entity_data) {
-    // Cannot create EntityData, ex. no TYPED visits.
-    return;
-  }
-
-  std::string storage_key = GetStorageKeyFromURLRow(row);
-  change_processor()->Put(storage_key, std::move(entity_data),
-                          metadata_change_list);
-}
-
-}  // namespace history
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.h b/components/history/core/browser/sync/typed_url_sync_bridge.h
deleted file mode 100644
index 2810519f..0000000
--- a/components/history/core/browser/sync/typed_url_sync_bridge.h
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_HISTORY_CORE_BROWSER_SYNC_TYPED_URL_SYNC_BRIDGE_H_
-#define COMPONENTS_HISTORY_CORE_BROWSER_SYNC_TYPED_URL_SYNC_BRIDGE_H_
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/memory/raw_ptr.h"
-#include "base/scoped_observation.h"
-#include "components/history/core/browser/history_backend.h"
-#include "components/history/core/browser/history_backend_observer.h"
-#include "components/history/core/browser/sync/typed_url_sync_metadata_database.h"
-#include "components/sync/model/metadata_change_list.h"
-#include "components/sync/model/model_type_change_processor.h"
-#include "components/sync/model/model_type_sync_bridge.h"
-#include "components/sync/model/sync_error.h"
-
-namespace history {
-
-class TypedURLSyncBridge : public syncer::ModelTypeSyncBridge,
-                           public HistoryBackendObserver {
- public:
-  // `sync_metadata_store` is owned by `history_backend`, and must outlive
-  // TypedURLSyncBridge.
-  TypedURLSyncBridge(
-      HistoryBackend* history_backend,
-      TypedURLSyncMetadataDatabase* sync_metadata_store,
-      std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor);
-
-  TypedURLSyncBridge(const TypedURLSyncBridge&) = delete;
-  TypedURLSyncBridge& operator=(const TypedURLSyncBridge&) = delete;
-
-  ~TypedURLSyncBridge() override;
-
-  // syncer::ModelTypeSyncBridge implementation.
-  std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
-      override;
-  absl::optional<syncer::ModelError> MergeFullSyncData(
-      std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-      syncer::EntityChangeList entity_data) override;
-  absl::optional<syncer::ModelError> ApplyIncrementalSyncChanges(
-      std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
-      syncer::EntityChangeList entity_changes) override;
-  void GetData(StorageKeyList storage_keys, DataCallback callback) override;
-  void GetAllDataForDebugging(DataCallback callback) override;
-  std::string GetClientTag(const syncer::EntityData& entity_data) override;
-  std::string GetStorageKey(const syncer::EntityData& entity_data) override;
-  bool SupportsGetStorageKey() const override;
-
-  // HistoryBackendObserver:
-  void OnURLVisited(HistoryBackend* history_backend,
-                    const URLRow& row,
-                    const VisitRow& visit_row) override;
-  void OnURLsModified(HistoryBackend* history_backend,
-                      const std::vector<URLRow>& changed_urls,
-                      bool is_from_expiration) override;
-  void OnURLsDeleted(HistoryBackend* history_backend,
-                     bool all_history,
-                     bool expired,
-                     const std::vector<URLRow>& deleted_rows,
-                     const std::set<GURL>& favicon_urls) override;
-  void OnVisitUpdated(const VisitRow& visit, VisitUpdateReason reason) override;
-  void OnVisitDeleted(const VisitRow& visit) override;
-
-  // Must be called after creation and before any operations.
-  void Init();
-
-  // Called by HistoryBackend when database error is reported through
-  // DatabaseErrorCallback.
-  void OnDatabaseError();
-
-  // Return true if this function successfully converts the passed URL
-  // information to a TypedUrlSpecifics structure for writing to the sync DB.
-  [[nodiscard]] static bool WriteToTypedUrlSpecifics(
-      const URLRow& url,
-      const std::vector<VisitRow>& visits,
-      sync_pb::TypedUrlSpecifics* specifics);
-
- private:
-  friend class TypedURLSyncBridgeTest;
-
-  struct URLWithVisits {
-    URLWithVisits(const GURL& url, const std::vector<VisitInfo>& visits);
-    ~URLWithVisits();
-
-    URLWithVisits(URLWithVisits&&);
-
-    GURL url;
-    std::vector<VisitInfo> visits;
-  };
-
-  // Bitfield returned from MergeUrls to specify the result of a merge.
-  typedef uint32_t MergeResult;
-  static const MergeResult DIFF_NONE = 0;
-  static const MergeResult DIFF_UPDATE_NODE = 1 << 0;
-  static const MergeResult DIFF_LOCAL_ROW_CHANGED = 1 << 1;
-  static const MergeResult DIFF_LOCAL_VISITS_ADDED = 1 << 2;
-
-  // Merges the URL information in `typed_url` with the URL information from the
-  // history database in `url` and `visits`, and returns a bitmask with the
-  // results of the merge:
-  // DIFF_UPDATE_NODE - changes have been made to `new_url` and `visits` which
-  //   should be persisted to the sync node.
-  // DIFF_LOCAL_ROW_CHANGED - The history data in `new_url` should be persisted
-  //   to the history DB.
-  // DIFF_LOCAL_VISITS_ADDED - `new_visits` contains a list of visits that
-  //   should be written to the history DB for this URL. Deletions are not
-  //   written to the DB - each client is left to age out visits on their own.
-  static MergeResult MergeUrls(const sync_pb::TypedUrlSpecifics& typed_url,
-                               const URLRow& url,
-                               std::vector<VisitRow>* visits,
-                               URLRow* new_url,
-                               std::vector<VisitInfo>* new_visits);
-
-  // Diffs the set of visits between the history DB and the sync DB, using the
-  // sync DB as the canonical copy. Result is the set of `new_visits` and
-  // `removed_visits` that can be applied to the history DB to make it match
-  // the sync DB version. `removed_visits` can be null if the caller does not
-  // care about which visits to remove.
-  static void DiffVisits(const std::vector<VisitRow>& history_visits,
-                         const sync_pb::TypedUrlSpecifics& sync_specifics,
-                         std::vector<VisitInfo>* new_visits,
-                         std::vector<VisitRow>* removed_visits);
-
-  // Fills `new_url` with formatted data from `typed_url`.
-  static void UpdateURLRowFromTypedUrlSpecifics(
-      const sync_pb::TypedUrlSpecifics& typed_url,
-      URLRow* new_url);
-
-  // Synchronously load sync metadata from the TypedURLSyncMetadataDatabase and
-  // pass it to the processor so that it can start tracking changes.
-  void LoadMetadata();
-
-  // Compares `server_typed_url` from the server against local history to decide
-  // how to merge any existing data, and updates appropriate data containers to
-  // write to server and backend.
-  void MergeURLWithSync(const sync_pb::TypedUrlSpecifics& server_typed_url,
-                        std::map<GURL, URLRow>* local_typed_urls,
-                        std::map<GURL, std::vector<VisitRow>>* visit_vectors,
-                        std::vector<URLRow>* new_synced_urls,
-                        std::vector<URLWithVisits>* new_synced_visits,
-                        std::vector<URLRow>* updated_synced_urls);
-
-  // Given a typed URL in the sync DB, looks for an existing entry in the
-  // local history DB and generates a list of visits to add to the
-  // history DB to bring it up to date (avoiding duplicates).
-  // Updates the passed `visits_to_add` and `visits_to_remove` vectors with the
-  // visits to add to/remove from the history DB, and adds a new entry to either
-  // `updated_urls` or `new_urls` depending on whether the URL already existed
-  // in the history DB.
-  void UpdateFromSync(const sync_pb::TypedUrlSpecifics& typed_url,
-                      std::vector<URLWithVisits>* visits_to_add,
-                      std::vector<VisitRow>* visits_to_remove,
-                      std::vector<URLRow>* updated_urls,
-                      std::vector<URLRow>* new_urls);
-
-  // Utility routine that (a) updates an existing sync node or (b) creates a
-  // new one for the passed `typed_url` if one does not already exist or (c)
-  // removes metadata for `row` if `is_from_expiration` is true and the `row`
-  // has no more typed visits.
-  void UpdateSyncFromLocal(URLRow row,
-                           bool is_from_expiration,
-                           syncer::MetadataChangeList* metadata_change_list);
-
-  // Deletes metadata for an expired URL `row` but does not send up the deletion
-  // to the server (each client expires them independently). It is an no-op when
-  // called on an url with already expired metadata.
-  void ExpireMetadataForURL(const URLRow& row);
-
-  // Writes new typed url data from sync server to history backend.
-  absl::optional<syncer::ModelError> WriteToHistoryBackend(
-      const std::vector<URLRow>* new_urls,
-      const std::vector<URLRow>* updated_urls,
-      const std::vector<GURL>* deleted_urls,
-      const std::vector<URLWithVisits>* new_visits,
-      const std::vector<VisitRow>* deleted_visits);
-
-  // Given a TypedUrlSpecifics object, removes all visits that are older than
-  // the current expiration time. Note that this can result in having no visits
-  // at all.
-  sync_pb::TypedUrlSpecifics FilterExpiredVisits(
-      const sync_pb::TypedUrlSpecifics& specifics);
-
-  // Helper function that determines if we should ignore a URL for the purposes
-  // of sync, because it contains invalid data.
-  bool ShouldIgnoreUrl(const GURL& url);
-
-  // Helper function that determines if we should ignore a URL for the purposes
-  // of sync, based on the visits the URL had.
-  bool ShouldIgnoreVisits(const std::vector<VisitRow>& visits);
-
-  // Returns true if the caller should sync as a result of the passed visit
-  // notification. We use this to throttle the number of sync changes we send
-  // to the server so we don't hit the server for every
-  // single typed URL visit.
-  bool ShouldSyncVisit(int typed_count, ui::PageTransition transition);
-
-  // Fetches visits from the history DB corresponding to the passed URL. This
-  // function compensates for the fact that the history DB has rather poor data
-  // integrity (duplicate visits, visit timestamps that don't match the
-  // last_visit timestamp, huge data sets that exhaust memory when fetched,
-  // expired visits that are not deleted by `ExpireHistoryBackend`, etc) by
-  // modifying the passed `url` object and `visits` vector. The order of
-  // `visits` will be from the oldest to the newest order.
-  // Returns false if we could not fetch the visits for the passed URL, DB
-  // error. If there are no visits for the passed url, or all the visits are
-  // expired, it returns true but `visits` is empty.
-  bool FixupURLAndGetVisits(URLRow* url, std::vector<VisitRow>* visits);
-
-  // Create an EntityData by URL `row` and its visits `visits`.
-  std::unique_ptr<syncer::EntityData> CreateEntityData(
-      const URLRow& row,
-      const std::vector<VisitRow>& visits);
-
-  // Get all the typed urls and visits from the history db, after filtering
-  // them, put them into `url_to_visit` and `url_to_urlrow`.
-  // Return false if cannot get urls from HistoryBackend.
-  bool GetValidURLsAndVisits(
-      std::map<GURL, std::vector<VisitRow>>* url_to_visit,
-      std::map<GURL, URLRow>* url_to_urlrow);
-
-  // Get URLID from HistoryBackend, and return URLID as storage key.
-  std::string GetStorageKeyInternal(const std::string& url);
-
-  // Send local typed url to processor().
-  void SendTypedURLToProcessor(
-      const URLRow& row,
-      const std::vector<VisitRow>& visits,
-      syncer::MetadataChangeList* metadata_change_list);
-
-  // A non-owning pointer to the backend, which we're syncing local changes from
-  // and sync changes to.
-  const raw_ptr<HistoryBackend, DanglingUntriaged> history_backend_;
-
-  // Whether we're currently processing changes from the syncer. While this is
-  // true, we ignore any local url changes, since we triggered them.
-  bool processing_syncer_changes_ = false;
-
-  // A non-owning pointer to the database, which is for storing typed urls sync
-  // metadata and state.
-  raw_ptr<TypedURLSyncMetadataDatabase, AcrossTasksDanglingUntriaged>
-      sync_metadata_database_;
-
-  // Since HistoryBackend use SequencedTaskRunner, so should use SequenceChecker
-  // here.
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  // Tracks observed history backend, for receiving updates from history
-  // backend.
-  base::ScopedObservation<HistoryBackend, HistoryBackendObserver>
-      history_backend_observation_{this};
-};
-
-}  // namespace history
-
-#endif  // COMPONENTS_HISTORY_CORE_BROWSER_SYNC_TYPED_URL_SYNC_BRIDGE_H_
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
deleted file mode 100644
index b396a2d..0000000
--- a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
+++ /dev/null
@@ -1,1818 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/history/core/browser/sync/typed_url_sync_bridge.h"
-
-#include <algorithm>
-#include <memory>
-
-#include "base/big_endian.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/functional/bind.h"
-#include "base/memory/raw_ptr.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task/single_thread_task_runner.h"
-#include "base/test/task_environment.h"
-#include "base/time/time.h"
-#include "components/history/core/browser/history_backend.h"
-#include "components/history/core/browser/history_backend_client.h"
-#include "components/history/core/browser/history_database_params.h"
-#include "components/history/core/browser/in_memory_history_backend.h"
-#include "components/history/core/test/test_history_database.h"
-#include "components/sync/model/data_batch.h"
-#include "components/sync/protocol/entity_metadata.pb.h"
-#include "components/sync/protocol/entity_specifics.pb.h"
-#include "components/sync/protocol/typed_url_specifics.pb.h"
-#include "components/sync/test/mock_model_type_change_processor.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace history {
-
-namespace {
-
-using base::Time;
-using sync_pb::TypedUrlSpecifics;
-using syncer::DataBatch;
-using syncer::EntityChange;
-using syncer::EntityChangeList;
-using syncer::EntityData;
-using syncer::MetadataBatch;
-using syncer::MetadataChangeList;
-using syncer::MockModelTypeChangeProcessor;
-using testing::_;
-using testing::AllOf;
-using testing::DoAll;
-using testing::IsEmpty;
-using testing::Mock;
-using testing::NiceMock;
-using testing::Pointee;
-using testing::Return;
-using testing::UnorderedElementsAre;
-
-// Constants used to limit size of visits processed. See
-// equivalent constants in typed_url_sync_bridge.cc for descriptions.
-const int kMaxTypedUrlVisits = 100;
-const int kVisitThrottleThreshold = 10;
-const int kVisitThrottleMultiple = 10;
-
-// Visits with this timestamp are treated as expired.
-const int kExpiredVisit = -1;
-
-// Helper constants for tests.
-const char kTitle[] = "pie";
-const char kTitle2[] = "cookie";
-const char kURL[] = "http://pie.com/";
-const char kURL2[] = "http://cookie.com/";
-
-// Action SaveArgPointeeMove<k>(pointer) saves the value pointed to by the k-th
-// (0-based) argument of the mock function by moving it to *pointer.
-ACTION_TEMPLATE(SaveArgPointeeMove,
-                HAS_1_TEMPLATE_PARAMS(int, k),
-                AND_1_VALUE_PARAMS(pointer)) {
-  *pointer = std::move(*testing::get<k>(args));
-}
-
-// Matches that TypedUrlSpecifics has expected URL.
-MATCHER_P(HasURLInSpecifics, url, "") {
-  return arg.specifics.typed_url().url() == url;
-}
-
-// Matches that TypedUrlSpecifics has expected title.
-MATCHER_P(HasTitleInSpecifics, title, "") {
-  return arg.specifics.typed_url().title() == title;
-}
-
-MATCHER(HasTypedUrlInSpecifics, "") {
-  return arg.specifics.has_typed_url();
-}
-
-MATCHER(IsValidStorageKey, "") {
-  return TypedURLSyncMetadataDatabase::StorageKeyToURLID(arg) > 0;
-}
-
-Time SinceEpoch(int64_t microseconds_since_epoch) {
-  return Time::FromDeltaSinceWindowsEpoch(
-      base::Microseconds(microseconds_since_epoch));
-}
-
-bool URLsEqual(const URLRow& row, const sync_pb::TypedUrlSpecifics& specifics) {
-  return ((row.url().spec().compare(specifics.url()) == 0) &&
-          (base::UTF16ToUTF8(row.title()).compare(specifics.title()) == 0) &&
-          (row.hidden() == specifics.hidden()));
-}
-
-bool URLsEqual(const URLRow& lhs, const URLRow& rhs) {
-  // Only compare synced fields (ignore typed_count and visit_count as those
-  // are maintained by the history subsystem).
-  return (lhs.url().spec().compare(rhs.url().spec()) == 0) &&
-         (lhs.title().compare(rhs.title()) == 0) &&
-         (lhs.hidden() == rhs.hidden());
-}
-
-void AddNewestVisit(ui::PageTransition transition,
-                    int64_t visit_time,
-                    URLRow* url,
-                    std::vector<VisitRow>* visits) {
-  Time time = SinceEpoch(visit_time);
-  visits->insert(visits->begin(),
-                 VisitRow(url->id(), time, 0, transition, 0,
-                          HistoryBackend::IsTypedIncrement(transition), 0));
-
-  if (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED)) {
-    url->set_typed_count(url->typed_count() + 1);
-  }
-
-  url->set_last_visit(time);
-  url->set_visit_count(visits->size());
-}
-
-void AddOldestVisit(ui::PageTransition transition,
-                    int visit_time,
-                    URLRow* url,
-                    std::vector<VisitRow>* visits) {
-  Time time = SinceEpoch(visit_time);
-  visits->push_back(VisitRow(url->id(), time, 0, transition, 0,
-                             HistoryBackend::IsTypedIncrement(transition), 0));
-
-  if (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED)) {
-    url->set_typed_count(url->typed_count() + 1);
-  }
-
-  url->set_visit_count(visits->size());
-}
-
-// Create a new row object and the typed visit corresponding with the time at
-// `last_visit` in the `visits` vector.
-URLRow MakeTypedUrlRow(const std::string& url,
-                       const std::string& title,
-                       int typed_count,
-                       int64_t last_visit,
-                       bool hidden,
-                       std::vector<VisitRow>* visits) {
-  // Give each URL a unique ID, to mimic the behavior of the real database.
-  GURL gurl(url);
-  URLRow history_url(gurl);
-  history_url.set_title(base::UTF8ToUTF16(title));
-  history_url.set_typed_count(typed_count);
-  history_url.set_hidden(hidden);
-
-  Time last_visit_time = SinceEpoch(last_visit);
-  history_url.set_last_visit(last_visit_time);
-
-  ui::PageTransition transition = ui::PAGE_TRANSITION_RELOAD;
-  bool incremented_omnibox_typed_score = false;
-  if (typed_count > 0) {
-    transition = ui::PAGE_TRANSITION_TYPED;
-    incremented_omnibox_typed_score = true;
-  }
-  visits->push_back(VisitRow(history_url.id(), last_visit_time, 0, transition,
-                             0, incremented_omnibox_typed_score, 0));
-
-  history_url.set_visit_count(visits->size());
-  return history_url;
-}
-
-// Create a new row object and a typed and a reload visit with appropriate
-// times.
-URLRow MakeTypedUrlRowWithTwoVisits(const std::string& url,
-                                    const std::string& title,
-                                    int64_t typed_visit,
-                                    int64_t reload_visit,
-                                    std::vector<VisitRow>* visits) {
-  // Give each URL a unique ID, to mimic the behavior of the real database.
-  GURL gurl(url);
-  URLRow history_url(gurl);
-  history_url.set_title(base::UTF8ToUTF16(title));
-  history_url.set_typed_count(1);
-  history_url.set_visit_count(2);
-  history_url.set_hidden(false);
-
-  Time typed_visit_time = SinceEpoch(typed_visit);
-  Time reload_visit_time = SinceEpoch(reload_visit);
-
-  history_url.set_last_visit(std::max(typed_visit_time, reload_visit_time));
-
-  visits->push_back(VisitRow(history_url.id(), typed_visit_time, 0,
-                             ui::PAGE_TRANSITION_TYPED, 0, true, 0));
-  // Add a non-typed visit for time `last_visit`.
-  visits->push_back(VisitRow(history_url.id(), reload_visit_time, 0,
-                             ui::PAGE_TRANSITION_RELOAD, 0, false, 0));
-  return history_url;
-}
-
-void VerifyEqual(const TypedUrlSpecifics& s1, const TypedUrlSpecifics& s2) {
-  // Instead of just comparing serialized strings, manually check fields to show
-  // differences on failure.
-  EXPECT_EQ(s1.url(), s2.url());
-  EXPECT_EQ(s1.title(), s2.title());
-  EXPECT_EQ(s1.hidden(), s2.hidden());
-  EXPECT_EQ(s1.visits_size(), s2.visits_size());
-  EXPECT_EQ(s1.visit_transitions_size(), s2.visit_transitions_size());
-  EXPECT_EQ(s1.visits_size(), s1.visit_transitions_size());
-  int size = s1.visits_size();
-  for (int i = 0; i < size; ++i) {
-    EXPECT_EQ(s1.visits(i), s2.visits(i)) << "visits differ at index " << i;
-    EXPECT_EQ(s1.visit_transitions(i), s2.visit_transitions(i))
-        << "visit_transitions differ at index " << i;
-  }
-}
-
-void VerifyDataBatch(std::map<std::string, TypedUrlSpecifics> expected,
-                     std::unique_ptr<DataBatch> batch) {
-  while (batch->HasNext()) {
-    auto [key, data] = batch->Next();
-    auto iter = expected.find(key);
-    ASSERT_NE(iter, expected.end());
-    VerifyEqual(iter->second, data->specifics.typed_url());
-    // Removing allows us to verify we don't see the same item multiple times,
-    // and that we saw everything we expected.
-    expected.erase(iter);
-  }
-  EXPECT_TRUE(expected.empty());
-}
-
-std::string IntToStorageKey(int id) {
-  std::string storage_key(sizeof(URLID), 0);
-  base::WriteBigEndian<URLID>(&storage_key[0], id);
-  return storage_key;
-}
-
-void StoreMetadata(const std::string& storage_key,
-                   std::unique_ptr<EntityData> entity_data,
-                   MetadataChangeList* metadata_change_list) {
-  sync_pb::EntityMetadata metadata;
-  metadata.set_sequence_number(1);
-  metadata_change_list->UpdateMetadata(storage_key, metadata);
-}
-
-class TestHistoryBackendDelegate : public HistoryBackend::Delegate {
- public:
-  TestHistoryBackendDelegate() = default;
-
-  TestHistoryBackendDelegate(const TestHistoryBackendDelegate&) = delete;
-  TestHistoryBackendDelegate& operator=(const TestHistoryBackendDelegate&) =
-      delete;
-
-  bool CanAddURL(const GURL& url) const override { return true; }
-  void NotifyProfileError(sql::InitStatus init_status,
-                          const std::string& diagnostics) override {}
-  void SetInMemoryBackend(
-      std::unique_ptr<InMemoryHistoryBackend> backend) override {}
-  void NotifyFaviconsChanged(const std::set<GURL>& page_urls,
-                             const GURL& icon_url) override {}
-  void NotifyURLVisited(const URLRow& url_row,
-                        const VisitRow& visit_row,
-                        absl::optional<int64_t> local_navigation_id) override {}
-  void NotifyURLsModified(const std::vector<URLRow>& changed_urls) override {}
-  void NotifyURLsDeleted(DeletionInfo deletion_info) override {}
-  void NotifyKeywordSearchTermUpdated(const URLRow& row,
-                                      KeywordID keyword_id,
-                                      const std::u16string& term) override {}
-  void NotifyKeywordSearchTermDeleted(URLID url_id) override {}
-  void DBLoaded() override {}
-};
-
-class TestHistoryBackendForSync : public HistoryBackend {
- public:
-  explicit TestHistoryBackendForSync(
-      std::unique_ptr<HistoryBackendClient> backend_client)
-      : HistoryBackend(std::make_unique<TestHistoryBackendDelegate>(),
-                       std::move(backend_client),
-                       base::SingleThreadTaskRunner::GetCurrentDefault()) {}
-
-  bool IsExpiredVisitTime(const Time& time) const override {
-    return time.ToDeltaSinceWindowsEpoch().InMicroseconds() == kExpiredVisit;
-  }
-
-  URLID GetIdByUrl(const GURL& gurl) {
-    return db()->GetRowForURL(gurl, nullptr);
-  }
-
-  void SetVisitsForUrl(URLRow* new_url, const std::vector<VisitRow> visits) {
-    if (!GetURL(new_url->url(), nullptr)) {
-      URLRow to_insert = *new_url;
-      // AddVisits() increments counts so we should decrement it now to get a
-      // consistent result in the end.
-      for (const auto& visit : visits) {
-        to_insert.set_visit_count(to_insert.visit_count() - 1);
-        if (ui::PageTransitionCoreTypeIs(visit.transition,
-                                         ui::PAGE_TRANSITION_TYPED)) {
-          to_insert.set_typed_count(to_insert.typed_count() - 1);
-        }
-      }
-      AddPagesWithDetails({to_insert}, SOURCE_SYNCED);
-    }
-
-    std::vector<VisitInfo> added_visits;
-    for (const auto& visit : visits) {
-      added_visits.emplace_back(visit.visit_time, visit.transition);
-    }
-    AddVisits(new_url->url(), added_visits, SOURCE_SYNCED);
-    new_url->set_id(GetIdByUrl(new_url->url()));
-  }
-
- private:
-  ~TestHistoryBackendForSync() override = default;
-};
-
-class MockHistoryBackendClient : public HistoryBackendClient {
- public:
-  MOCK_METHOD(bool, IsPinnedURL, (const GURL& url), (override));
-  MOCK_METHOD(std::vector<URLAndTitle>, GetPinnedURLs, (), (override));
-  MOCK_METHOD(bool, IsWebSafe, (const GURL& url), (override));
-};
-
-}  // namespace
-
-class TypedURLSyncBridgeTest : public testing::Test {
- public:
-  void SetUp() override {
-    auto history_backend_client =
-        std::make_unique<NiceMock<MockHistoryBackendClient>>();
-    history_backend_client_ = history_backend_client.get();
-    ON_CALL(*history_backend_client_, IsPinnedURL).WillByDefault(Return(false));
-
-    fake_history_backend_ =
-        new TestHistoryBackendForSync(std::move(history_backend_client));
-    ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
-    fake_history_backend_->Init(
-        false, TestHistoryDatabaseParamsForPath(test_dir_.GetPath()));
-    auto bridge = std::make_unique<TypedURLSyncBridge>(
-        fake_history_backend_.get(),
-        fake_history_backend_->db()->GetTypedURLMetadataDB(),
-        mock_processor_.CreateForwardingProcessor());
-    typed_url_sync_bridge_ = bridge.get();
-    typed_url_sync_bridge_->Init();
-    typed_url_sync_bridge_->history_backend_observation_.Reset();
-    fake_history_backend_->SetTypedURLSyncBridgeForTest(std::move(bridge));
-  }
-
-  void TearDown() override { fake_history_backend_->Closing(); }
-
-  // Starts sync for `typed_url_sync_bridge_` with `initial_data` as the
-  // initial sync data.
-  void StartSyncing(const std::vector<TypedUrlSpecifics>& specifics) {
-    ON_CALL(mock_processor_, IsTrackingMetadata()).WillByDefault(Return(true));
-    // Set change processor.
-    const auto error =
-        bridge()->MergeFullSyncData(bridge()->CreateMetadataChangeList(),
-                                    CreateEntityChangeList(specifics));
-
-    EXPECT_FALSE(error);
-  }
-
-  void BuildAndPushLocalChanges(
-      size_t num_typed_urls,
-      size_t num_reload_urls,
-      const std::vector<std::string>& urls,
-      std::vector<URLRow>* rows,
-      std::vector<std::vector<VisitRow>>* visit_vectors) {
-    const size_t total_urls = num_typed_urls + num_reload_urls;
-    DCHECK(urls.size() >= total_urls);
-    DCHECK(bridge());
-
-    if (total_urls) {
-      // Create new URL rows, populate the mock backend with its visits, and
-      // send to the sync service.
-      std::vector<URLRow> changed_urls;
-
-      for (size_t i = 0; i < total_urls; ++i) {
-        const int typed = i < num_typed_urls ? 1 : 0;
-        std::vector<VisitRow> visits;
-        visit_vectors->push_back(visits);
-        rows->push_back(MakeTypedUrlRow(urls[i], kTitle, typed, i + 3, false,
-                                        &visit_vectors->back()));
-        fake_history_backend_->SetVisitsForUrl(&rows->back(),
-                                               visit_vectors->back());
-        changed_urls.push_back(rows->back());
-      }
-
-      bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls,
-                               /*is_from_expiration=*/false);
-    }
-  }
-
-  std::vector<VisitRow> ApplyUrlAndVisitsChange(
-      const std::string& url,
-      const std::string& title,
-      int typed_count,
-      int64_t last_visit,
-      bool hidden,
-      EntityChange::ChangeType change_type) {
-    std::vector<VisitRow> visits;
-    URLRow row =
-        MakeTypedUrlRow(url, title, typed_count, last_visit, hidden, &visits);
-    sync_pb::TypedUrlSpecifics typed_url_specifics;
-    WriteToTypedUrlSpecifics(row, visits, &typed_url_specifics);
-    std::string storage_key = GetStorageKey(typed_url_specifics.url());
-
-    EntityChangeList entity_changes;
-    switch (change_type) {
-      case EntityChange::ACTION_ADD:
-        entity_changes.push_back(EntityChange::CreateAdd(
-            std::string(), SpecificsToEntity(typed_url_specifics)));
-        break;
-      case EntityChange::ACTION_UPDATE:
-        entity_changes.push_back(EntityChange::CreateUpdate(
-            storage_key, SpecificsToEntity(typed_url_specifics)));
-        break;
-      case EntityChange::ACTION_DELETE:
-        entity_changes.push_back(EntityChange::CreateDelete(storage_key));
-        break;
-    }
-
-    std::unique_ptr<MetadataChangeList> metadata_changes =
-        bridge()->CreateMetadataChangeList();
-
-    bridge()->ApplyIncrementalSyncChanges(std::move(metadata_changes),
-                                          std::move(entity_changes));
-    return visits;
-  }
-
-  void AddObserver() {
-    bridge()->history_backend_observation_.Observe(fake_history_backend_.get());
-  }
-
-  void RemoveObserver() { bridge()->history_backend_observation_.Reset(); }
-
-  // Fills `specifics` with the sync data for `url` and `visits`.
-  static bool WriteToTypedUrlSpecifics(const URLRow& url,
-                                       const std::vector<VisitRow>& visits,
-                                       TypedUrlSpecifics* specifics) {
-    return TypedURLSyncBridge::WriteToTypedUrlSpecifics(url, visits, specifics);
-  }
-
-  std::string GetStorageKey(const std::string& url) {
-    return bridge()->GetStorageKeyInternal(url);
-  }
-
-  std::set<std::string> GetAllSyncMetadataKeys() {
-    MetadataBatch metadata_batch;
-    metadata_store()->GetAllSyncMetadata(&metadata_batch);
-    std::set<std::string> keys;
-    for (const auto& [storage_key, metadata] :
-         metadata_batch.GetAllMetadata()) {
-      keys.insert(storage_key);
-    }
-    return keys;
-  }
-
-  EntityData SpecificsToEntity(const TypedUrlSpecifics& specifics) {
-    EntityData data;
-    *data.specifics.mutable_typed_url() = specifics;
-    return data;
-  }
-
-  EntityChangeList CreateEntityChangeList(
-      const std::vector<TypedUrlSpecifics>& specifics_vector) {
-    EntityChangeList entity_change_list;
-    for (const auto& specifics : specifics_vector) {
-      entity_change_list.push_back(EntityChange::CreateAdd(
-          GetStorageKey(specifics.url()), SpecificsToEntity(specifics)));
-    }
-    return entity_change_list;
-  }
-
-  std::map<std::string, TypedUrlSpecifics> ExpectedMap(
-      const std::vector<TypedUrlSpecifics>& specifics_vector) {
-    std::map<std::string, TypedUrlSpecifics> map;
-    for (const auto& specifics : specifics_vector) {
-      map[GetStorageKey(specifics.url())] = specifics;
-    }
-    return map;
-  }
-
-  void VerifyAllLocalHistoryData(
-      const std::vector<TypedUrlSpecifics>& expected) {
-    bridge()->GetAllDataForDebugging(
-        base::BindOnce(&VerifyDataBatch, ExpectedMap(expected)));
-  }
-
-  void VerifyGetData(TypedURLSyncBridge::StorageKeyList storage_keys,
-                     const std::vector<TypedUrlSpecifics>& expected) {
-    bridge()->GetData(storage_keys,
-                      base::BindOnce(&VerifyDataBatch, ExpectedMap(expected)));
-  }
-
-  static void DiffVisits(const std::vector<VisitRow>& history_visits,
-                         const sync_pb::TypedUrlSpecifics& sync_specifics,
-                         std::vector<VisitInfo>* new_visits,
-                         std::vector<VisitRow>* removed_visits) {
-    TypedURLSyncBridge::DiffVisits(history_visits, sync_specifics, new_visits,
-                                   removed_visits);
-  }
-
-  static VisitRow CreateVisit(ui::PageTransition type, int64_t timestamp) {
-    return VisitRow(0, SinceEpoch(timestamp), 0, type, 0,
-                    HistoryBackend::IsTypedIncrement(type), 0);
-  }
-
-  static TypedURLSyncBridge::MergeResult MergeUrls(
-      const sync_pb::TypedUrlSpecifics& typed_url,
-      const URLRow& url,
-      std::vector<VisitRow>* visits,
-      URLRow* new_url,
-      std::vector<VisitInfo>* new_visits) {
-    return TypedURLSyncBridge::MergeUrls(typed_url, url, visits, new_url,
-                                         new_visits);
-  }
-
-  static sync_pb::TypedUrlSpecifics MakeTypedUrlSpecifics(const char* url,
-                                                          const char* title,
-                                                          int64_t last_visit,
-                                                          bool hidden) {
-    sync_pb::TypedUrlSpecifics typed_url;
-    typed_url.set_url(url);
-    typed_url.set_title(title);
-    typed_url.set_hidden(hidden);
-    typed_url.add_visits(last_visit);
-    typed_url.add_visit_transitions(ui::PAGE_TRANSITION_TYPED);
-    return typed_url;
-  }
-
-  static const TypedURLSyncBridge::MergeResult DIFF_NONE =
-      TypedURLSyncBridge::DIFF_NONE;
-  static const TypedURLSyncBridge::MergeResult DIFF_UPDATE_NODE =
-      TypedURLSyncBridge::DIFF_UPDATE_NODE;
-  static const TypedURLSyncBridge::MergeResult DIFF_LOCAL_ROW_CHANGED =
-      TypedURLSyncBridge::DIFF_LOCAL_ROW_CHANGED;
-  static const TypedURLSyncBridge::MergeResult DIFF_LOCAL_VISITS_ADDED =
-      TypedURLSyncBridge::DIFF_LOCAL_VISITS_ADDED;
-
-  TypedURLSyncBridge* bridge() { return typed_url_sync_bridge_; }
-
-  TypedURLSyncMetadataDatabase* metadata_store() {
-    return bridge()->sync_metadata_database_;
-  }
-
- protected:
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  base::ScopedTempDir test_dir_;
-  raw_ptr<MockHistoryBackendClient, DanglingUntriaged> history_backend_client_;
-  scoped_refptr<TestHistoryBackendForSync> fake_history_backend_;
-  raw_ptr<TypedURLSyncBridge> typed_url_sync_bridge_ = nullptr;
-  NiceMock<MockModelTypeChangeProcessor> mock_processor_;
-};
-
-// Add two typed urls locally and verify bridge can get them from GetAllData.
-TEST_F(TypedURLSyncBridgeTest, GetAllData) {
-  // Add two urls to backend.
-  std::vector<VisitRow> visits1, visits2, visits3;
-  URLRow row1 = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, 2, 4, false, &visits2);
-  URLRow expired_row = MakeTypedUrlRow("http://expired.com/", kTitle, 1,
-                                       kExpiredVisit, false, &visits3);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-  fake_history_backend_->SetVisitsForUrl(&expired_row, visits3);
-
-  // Create the same data in sync.
-  TypedUrlSpecifics typed_url1, typed_url2;
-  WriteToTypedUrlSpecifics(row1, visits1, &typed_url1);
-  WriteToTypedUrlSpecifics(row2, visits2, &typed_url2);
-
-  // Check that the local cache is still correct, expired row is filtered out.
-  VerifyAllLocalHistoryData({typed_url1, typed_url2});
-}
-
-// Add two typed urls locally and verify bridge can get them from GetData.
-TEST_F(TypedURLSyncBridgeTest, GetData) {
-  // Add two urls to backend.
-  std::vector<VisitRow> visits1, visits2;
-  URLRow row1 = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, 2, 4, false, &visits2);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-
-  // Create the same data in sync.
-  TypedUrlSpecifics typed_url1, typed_url2;
-  WriteToTypedUrlSpecifics(row1, visits1, &typed_url1);
-  WriteToTypedUrlSpecifics(row2, visits2, &typed_url2);
-
-  // Check that the local cache is still correct.
-  VerifyGetData({IntToStorageKey(1)}, {typed_url1});
-  VerifyGetData({IntToStorageKey(2)}, {typed_url2});
-}
-
-// Add a typed url locally and one to sync with the same data. Starting sync
-// should result in no changes.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlNoChange) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&row, visits);
-
-  // Create the same data in sync.
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(row, visits, typed_url);
-
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-
-  // Even Sync already know the url, bridge still need to tell sync about
-  // storage keys.
-  const std::string expected_storage_key = IntToStorageKey(1);
-  EXPECT_CALL(mock_processor_,
-              UpdateStorageKey(
-                  AllOf(HasURLInSpecifics(kURL), HasTitleInSpecifics(kTitle)),
-                  expected_storage_key, _));
-  StartSyncing({*typed_url});
-
-  // Check that the local cache was is still correct.
-  VerifyAllLocalHistoryData({*typed_url});
-}
-
-// Add a corrupted typed url locally, has typed url count 1, but no real typed
-// url visit. Starting sync should not pick up this url.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlNoTypedUrl) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow row = MakeTypedUrlRow(kURL, kTitle, 0, 3, false, &visits);
-
-  // Mark typed_count to 1 even when there is no typed url visit.
-  row.set_typed_count(1);
-  fake_history_backend_->SetVisitsForUrl(&row, visits);
-
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // There's also no metadata written as there's no call to Put() (where the
-  // test could mock storing metadata).
-  EXPECT_THAT(GetAllSyncMetadataKeys(), IsEmpty());
-}
-
-// Starting sync with no sync data should just push the local url to sync.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlEmptySync) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&row, visits);
-
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(DoAll(SaveArgPointeeMove<1>(&entity_data), StoreMetadata));
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Check that the local cache is still correct.
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(row, visits, typed_url);
-  VerifyAllLocalHistoryData({*typed_url});
-
-  EXPECT_THAT(GetAllSyncMetadataKeys(),
-              UnorderedElementsAre(GetStorageKey(kURL)));
-
-  // Check that the server was updated correctly.
-  const TypedUrlSpecifics& committed_specifics =
-      entity_data.specifics.typed_url();
-
-  ASSERT_EQ(1, committed_specifics.visits_size());
-  EXPECT_EQ(3, committed_specifics.visits(0));
-  ASSERT_EQ(1, committed_specifics.visit_transitions_size());
-  EXPECT_EQ(static_cast<const int>(visits[0].transition),
-            committed_specifics.visit_transitions(0));
-}
-
-// Starting sync with no local data should just push the synced url into the
-// backend.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlEmptyLocal) {
-  // Create the sync data.
-  std::vector<VisitRow> visits;
-  URLRow row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(row, visits, typed_url);
-
-  // Verify processor receive correct update storage key.
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  EXPECT_CALL(mock_processor_,
-              UpdateStorageKey(
-                  AllOf(HasURLInSpecifics(kURL), HasTitleInSpecifics(kTitle)),
-                  IntToStorageKey(1), _));
-  StartSyncing({*typed_url});
-
-  // Check that the backend was updated correctly.
-  std::vector<VisitRow> all_visits;
-  Time server_time = SinceEpoch(3);
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  ASSERT_EQ(1U, all_visits.size());
-  EXPECT_EQ(server_time, all_visits[0].visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[0].transition, visits[0].transition));
-}
-
-// Add a url to the local and sync data before sync begins, with the sync data
-// having more recent visits. Check that starting sync updates the backend
-// with the sync visit, while the older local visit is not pushed to sync.
-// The title should be updated to the sync version due to the more recent
-// timestamp.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlOldLocal) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow local_row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&local_row, visits);
-
-  // Create sync data for the same url with a more recent visit.
-  std::vector<VisitRow> server_visits;
-  URLRow server_row =
-      MakeTypedUrlRow(kURL, kTitle2, 1, 6, false, &server_visits);
-  server_row.set_id(fake_history_backend_->GetIdByUrl(GURL(kURL)));
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(server_row, server_visits, typed_url);
-
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(DoAll(SaveArgPointeeMove<1>(&entity_data), StoreMetadata));
-  StartSyncing({*typed_url});
-
-  // Check that the backend was updated correctly.
-  std::vector<VisitRow> all_visits;
-  Time server_time = SinceEpoch(6);
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  ASSERT_EQ(2U, all_visits.size());
-  EXPECT_EQ(server_time, all_visits.back().visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits.back().transition, server_visits[0].transition));
-  URLRow url_row;
-  EXPECT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  EXPECT_EQ(kTitle2, base::UTF16ToUTF8(url_row.title()));
-
-  EXPECT_THAT(GetAllSyncMetadataKeys(),
-              UnorderedElementsAre(GetStorageKey(kURL)));
-
-  // Check that the sync was updated correctly.
-  // The local history visit should not be added to sync because it is older
-  // than sync's oldest visit.
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-  ASSERT_EQ(1, url_specifics.visits_size());
-  EXPECT_EQ(6, url_specifics.visits(0));
-  ASSERT_EQ(1, url_specifics.visit_transitions_size());
-  EXPECT_EQ(static_cast<const int>(visits[0].transition),
-            url_specifics.visit_transitions(0));
-}
-
-// Add a url to the local and sync data before sync begins, with the local data
-// having more recent visits. Check that starting sync updates the sync
-// with the local visits, while the older sync visit is not pushed to the
-// backend. Sync's title should be updated to the local version due to the more
-// recent timestamp.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlOldSync) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow local_row = MakeTypedUrlRow(kURL, kTitle2, 1, 3, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&local_row, visits);
-
-  // Create sync data for the same url with an older visit.
-  std::vector<VisitRow> server_visits;
-  URLRow server_row =
-      MakeTypedUrlRow(kURL, kTitle, 1, 2, false, &server_visits);
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(server_row, server_visits, typed_url);
-
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  StartSyncing({*typed_url});
-
-  // Check that the backend was not updated.
-  std::vector<VisitRow> all_visits;
-  Time local_visit_time = SinceEpoch(3);
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  ASSERT_EQ(1U, all_visits.size());
-  EXPECT_EQ(local_visit_time, all_visits[0].visit_time);
-
-  // Check that the server was updated correctly.
-  // The local history visit should not be added to sync because it is older
-  // than sync's oldest visit.
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-  ASSERT_EQ(1, url_specifics.visits_size());
-  EXPECT_EQ(3, url_specifics.visits(0));
-  EXPECT_EQ(kTitle2, url_specifics.title());
-  ASSERT_EQ(1, url_specifics.visit_transitions_size());
-  EXPECT_EQ(static_cast<const int>(visits[0].transition),
-            url_specifics.visit_transitions(0));
-}
-
-// Check that there is no crash during start sync, if history backend and sync
-// have same url, but sync has username/password in it.
-// Also check sync will not accept url with username and password.
-TEST_F(TypedURLSyncBridgeTest, MergeUrlsWithUsernameAndPassword) {
-  const char kURLWithUsernameAndPassword[] =
-      "http://username:password@pie.com/";
-
-  // Add a url to backend.
-  std::vector<VisitRow> visits;
-  URLRow local_row = MakeTypedUrlRow(kURL, kTitle2, 1, 3, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&local_row, visits);
-
-  // Create sync data for the same url but contain username and password.
-  std::vector<VisitRow> server_visits;
-  URLRow server_row = MakeTypedUrlRow(kURLWithUsernameAndPassword, kTitle, 1, 3,
-                                      false, &server_visits);
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(server_row, server_visits, typed_url);
-
-  // Check username/password url is not synced.
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _));
-
-  // Make sure there is no crash when merge two urls.
-  StartSyncing({*typed_url});
-
-  // Notify typed url sync service of the update.
-  bridge()->OnURLVisited(fake_history_backend_.get(), server_row,
-                         server_visits.front());
-}
-
-// Starting sync with both local and sync have same typed URL, but different
-// visit. After merge, both local and sync should have two same visits.
-TEST_F(TypedURLSyncBridgeTest, SimpleMerge) {
-  // Add a url to backend.
-  std::vector<VisitRow> visits1;
-  URLRow row1 = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits1);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-
-  // Create the sync data.
-  std::vector<VisitRow> visits2;
-  URLRow row2 = MakeTypedUrlRow(kURL, kTitle, 1, 4, false, &visits2);
-  sync_pb::EntitySpecifics entity_specifics;
-  sync_pb::TypedUrlSpecifics* typed_url = entity_specifics.mutable_typed_url();
-  WriteToTypedUrlSpecifics(row2, visits2, typed_url);
-
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _));
-  StartSyncing({*typed_url});
-
-  // Check that the backend was updated correctly.
-  std::vector<VisitRow> all_visits;
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  ASSERT_EQ(2U, all_visits.size());
-  EXPECT_EQ(SinceEpoch(3), all_visits[0].visit_time);
-  EXPECT_EQ(SinceEpoch(4), all_visits[1].visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[0].transition, visits1[0].transition));
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[1].transition, visits2[0].transition));
-}
-
-// Create a local typed URL with one TYPED visit after sync has started. Check
-// that sync is sent an ADD change for the new URL.
-TEST_F(TypedURLSyncBridgeTest, AddLocalTypedUrl) {
-  // Create a local typed URL (simulate a typed visit) that is not already
-  // in sync. Check that sync is sent an ADD change for the existing URL.
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(IsValidStorageKey(), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  BuildAndPushLocalChanges(1, 0, urls, &url_rows, &visit_vectors);
-
-  URLRow url_row = url_rows.front();
-  std::vector<VisitRow> visits = visit_vectors.front();
-
-  // Get typed url specifics.
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-
-  EXPECT_TRUE(URLsEqual(url_row, url_specifics));
-  ASSERT_EQ(1, url_specifics.visits_size());
-  ASSERT_EQ(static_cast<const int>(visits.size()), url_specifics.visits_size());
-  EXPECT_EQ(visits[0].visit_time.ToInternalValue(), url_specifics.visits(0));
-  EXPECT_EQ(static_cast<const int>(visits[0].transition),
-            url_specifics.visit_transitions(0));
-}
-
-// Update a local typed URL that is already synced. Check that sync is sent an
-// UPDATE for the existing url, but RELOAD visits aren't synced.
-TEST_F(TypedURLSyncBridgeTest, UpdateLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Update the URL row, adding another typed visit to the visit vector.
-  std::vector<URLRow> changed_urls;
-  std::vector<VisitRow> visits;
-  URLRow url_row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  AddNewestVisit(ui::PAGE_TRANSITION_TYPED, 7, &url_row, &visits);
-  AddNewestVisit(ui::PAGE_TRANSITION_RELOAD, 8, &url_row, &visits);
-  AddNewestVisit(ui::PAGE_TRANSITION_LINK, 9, &url_row, &visits);
-  fake_history_backend_->SetVisitsForUrl(&url_row, visits);
-  changed_urls.push_back(url_row);
-
-  // Notify typed url sync service of the update.
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls,
-                           /*is_from_expiration=*/false);
-
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-  EXPECT_TRUE(URLsEqual(url_row, url_specifics));
-  ASSERT_EQ(3, url_specifics.visits_size());
-
-  // Check that each visit has been translated/communicated correctly.
-  // Note that the specifics record visits in chronological order, and the
-  // visits from the db are in reverse chronological order.
-  EXPECT_EQ(visits[0].visit_time.ToInternalValue(), url_specifics.visits(2));
-  EXPECT_EQ(static_cast<const int>(visits[0].transition),
-            url_specifics.visit_transitions(2));
-  EXPECT_EQ(visits[2].visit_time.ToInternalValue(), url_specifics.visits(1));
-  EXPECT_EQ(static_cast<const int>(visits[2].transition),
-            url_specifics.visit_transitions(1));
-  EXPECT_EQ(visits[3].visit_time.ToInternalValue(), url_specifics.visits(0));
-  EXPECT_EQ(static_cast<const int>(visits[3].transition),
-            url_specifics.visit_transitions(0));
-}
-
-// Append a RELOAD visit to a typed url that is already synced. Check that sync
-// does not receive any updates.
-TEST_F(TypedURLSyncBridgeTest, ReloadVisitLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _));
-  BuildAndPushLocalChanges(1, 0, {kURL}, &url_rows, &visit_vectors);
-
-  // Check that Put method has been already called.
-  Mock::VerifyAndClearExpectations(&mock_processor_);
-
-  // Update the URL row, adding another typed visit to the visit vector.
-  URLRow url_row = url_rows.front();
-  std::vector<URLRow> changed_urls;
-  std::vector<VisitRow> new_visits;
-  AddNewestVisit(ui::PAGE_TRANSITION_RELOAD, 7, &url_row, &new_visits);
-  fake_history_backend_->SetVisitsForUrl(&url_row, new_visits);
-  changed_urls.push_back(url_row);
-
-  // Notify typed url sync service of the update.
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row,
-                         new_visits.front());
-  // No change pass to processor
-}
-
-// Appends a LINK visit to an existing typed url. Check that sync does not
-// receive any changes.
-TEST_F(TypedURLSyncBridgeTest, LinkVisitLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _));
-  BuildAndPushLocalChanges(1, 0, urls, &url_rows, &visit_vectors);
-
-  // Check that Put method has been already called.
-  Mock::VerifyAndClearExpectations(&mock_processor_);
-
-  // Update the URL row, adding a non-typed visit to the visit vector.
-  URLRow url_row = url_rows.front();
-  std::vector<VisitRow> new_visits;
-  AddNewestVisit(ui::PAGE_TRANSITION_LINK, 6, &url_row, &new_visits);
-  fake_history_backend_->SetVisitsForUrl(&url_row, new_visits);
-
-  // Notify typed url sync service of non-typed visit, expect no change.
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row,
-                         new_visits.front());
-  // No change pass to processor
-}
-
-// Appends a series of LINK visits followed by a TYPED one to an existing typed
-// url. Check that sync receives an UPDATE with the newest visit data.
-TEST_F(TypedURLSyncBridgeTest, TypedVisitLocalTypedUrl) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Update the URL row, adding another typed visit to the visit vector.
-  std::vector<VisitRow> visits;
-  URLRow url_row = MakeTypedUrlRow(kURL, kTitle, 1, 3, false, &visits);
-  AddOldestVisit(ui::PAGE_TRANSITION_LINK, 1, &url_row, &visits);
-  AddNewestVisit(ui::PAGE_TRANSITION_LINK, 6, &url_row, &visits);
-  AddNewestVisit(ui::PAGE_TRANSITION_TYPED, 7, &url_row, &visits);
-  fake_history_backend_->SetVisitsForUrl(&url_row, visits);
-
-  // Notify typed url sync service of typed visit.
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row, visits.front());
-
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-
-  EXPECT_TRUE(URLsEqual(url_row, url_specifics));
-  EXPECT_EQ(4, url_specifics.visits_size());
-
-  // Check that each visit has been translated/communicated correctly.
-  // Note that the specifics record visits in chronological order, and the
-  // visits from the db are in reverse chronological order.
-  int r = url_specifics.visits_size() - 1;
-  for (int i = 0; i < url_specifics.visits_size(); ++i, --r) {
-    EXPECT_EQ(visits[i].visit_time.ToInternalValue(), url_specifics.visits(r));
-    EXPECT_EQ(static_cast<const int>(visits[i].transition),
-              url_specifics.visit_transitions(r));
-  }
-}
-
-// Delete several (but not all) local typed urls. Check that sync receives the
-// DELETE changes, and the non-deleted urls remain synced.
-TEST_F(TypedURLSyncBridgeTest, DeleteLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back("http://pie.com/");
-  urls.push_back("http://cake.com/");
-  urls.push_back("http://google.com/");
-  urls.push_back("http://foo.com/");
-
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _))
-      .Times(4);
-  BuildAndPushLocalChanges(4, 0, urls, &url_rows, &visit_vectors);
-
-  // Delete some urls from backend and create deleted row vector.
-  std::vector<URLRow> rows;
-  std::set<std::string> deleted_storage_keys;
-  for (size_t i = 0; i < 3u; ++i) {
-    const std::string storage_key = GetStorageKey(url_rows[i].url().spec());
-    deleted_storage_keys.insert(storage_key);
-    fake_history_backend_->DeleteURL(url_rows[i].url());
-    rows.push_back(url_rows[i]);
-  }
-
-  // Notify typed url sync service.
-  for (const std::string& storage_key : deleted_storage_keys) {
-    EXPECT_CALL(mock_processor_, Delete(storage_key, _));
-  }
-  bridge()->OnURLsDeleted(fake_history_backend_.get(), false, false, rows,
-                          std::set<GURL>());
-}
-
-// Delete the last typed visit for one (but not all) local typed urls. Check
-// that sync receives the DELETE changes, and the non-deleted urls remain
-// synced.
-TEST_F(TypedURLSyncBridgeTest, DeleteLocalTypedUrlVisit) {
-  std::vector<VisitRow> visits1, visits2;
-  URLRow row1 = MakeTypedUrlRowWithTwoVisits(kURL, kTitle,
-                                             /*typed_visit=*/2,
-                                             /*reload_visit=*/4, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, /*typed_count=*/2,
-                                /*last_visit=*/10, false, &visits2);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-
-  StartSyncing({});
-
-  // Simulate deletion of the last typed visit (e.g. by clearing browsing data),
-  // the deletion must get synced up.
-  fake_history_backend_->ExpireHistoryBetween({},
-                                              /*begin_time=*/SinceEpoch(1),
-                                              /*end_time=*/SinceEpoch(3),
-                                              /*user_initiated*/ true);
-  URLRow row1_updated;
-  ASSERT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &row1_updated));
-  std::vector<URLRow> changed_urls{row1_updated};
-  EXPECT_CALL(mock_processor_, Delete(GetStorageKey(kURL), _));
-  bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls,
-                           /*is_from_expiration=*/false);
-}
-
-// Expire a local typed url (but not all). This has only impact on local store
-// (metadata in the db and in-memory maps), nothing gets synced up.
-TEST_F(TypedURLSyncBridgeTest, ExpireLocalTypedUrl) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Add two URLs into the history db and notify the bridge to get it synced up
-  // and thus also metadata written into the DB.
-  std::vector<VisitRow> visits1, visits2;
-  URLRow row1 = MakeTypedUrlRow(kURL, kTitle, /*typed_count=*/1,
-                                /*last_visit=*/2, /*hidden=*/false, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, /*typed_count=*/1,
-                                /*last_visit=*/3, /*hidden=*/false, &visits2);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _))
-      .Times(2u)
-      .WillRepeatedly(StoreMetadata);
-  bridge()->OnURLsModified(fake_history_backend_.get(), {row1, row2},
-                           /*is_from_expiration=*/false);
-
-  std::string storage_key1 = GetStorageKey(kURL);
-  std::string storage_key2 = GetStorageKey(kURL2);
-  EXPECT_THAT(GetAllSyncMetadataKeys(),
-              UnorderedElementsAre(storage_key1, storage_key2));
-
-  // Simulate expiration - delete a url from the backend.
-  fake_history_backend_->DeleteURL(GURL(kURL));
-
-  // Notify typed url bridge of these URLs getting expired.
-  EXPECT_CALL(mock_processor_, Delete).Times(0);
-  EXPECT_CALL(mock_processor_, UntrackEntityForStorageKey(storage_key1));
-  bridge()->OnURLsDeleted(fake_history_backend_.get(), /*all_history=*/false,
-                          /*expired=*/true, {row1}, std::set<GURL>());
-
-  // The urls are removed from the metadata store.
-  EXPECT_THAT(GetAllSyncMetadataKeys(), UnorderedElementsAre(storage_key2));
-}
-
-// Expire the last local typed visit for a URL (with some non-typed visits
-// remaining). This results in the sync entity getting untracked. This has only
-// impact on local store (metadata in the db and in-memory maps), nothing gets
-// synced up.
-TEST_F(TypedURLSyncBridgeTest, ExpireLocalTypedVisit) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Add two URLs into the history db and notify the bridge to get it synced up
-  // and thus also metadata written into the DB.
-  std::vector<VisitRow> visits1, visits2;
-  URLRow row1 = MakeTypedUrlRowWithTwoVisits(kURL, kTitle, /*typed_visit=*/2,
-                                             /*reload_visit=*/5, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, /*typed_count=*/1,
-                                /*last_visit=*/4, /*hidden=*/false, &visits2);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _))
-      .Times(2u)
-      .WillRepeatedly(StoreMetadata);
-  bridge()->OnURLsModified(fake_history_backend_.get(), {row1, row2},
-                           /*is_from_expiration=*/false);
-
-  std::string storage_key1 = GetStorageKey(kURL);
-  std::string storage_key2 = GetStorageKey(kURL2);
-  EXPECT_THAT(GetAllSyncMetadataKeys(),
-              UnorderedElementsAre(storage_key1, storage_key2));
-
-  // Simulate expiration of all visits before time 3.
-  fake_history_backend_->ExpireHistoryBeforeForTesting(SinceEpoch(3));
-  URLRow row1_updated;
-  ASSERT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &row1_updated));
-  EXPECT_EQ(row1_updated.typed_count(), 0);
-  EXPECT_NE(row1_updated.last_visit(), base::Time());
-
-  // Notify typed url sync service of these URLs getting expired (it does not
-  // matter that we pass in the old version of row1, the bridge will fix it up).
-  EXPECT_CALL(mock_processor_, Delete).Times(0);
-  EXPECT_CALL(mock_processor_, UntrackEntityForStorageKey(storage_key1));
-  bridge()->OnURLsModified(fake_history_backend_.get(), {row1},
-                           /*is_from_expiration=*/true);
-
-  // The urls are removed from the metadata store.
-  EXPECT_THAT(GetAllSyncMetadataKeys(), UnorderedElementsAre(storage_key2));
-}
-
-// Expire the last local typed visit (with no other visits left in the DB but
-// keeping the url in the DB which happens e.g. for bookmarked urls). This
-// results in the sync entity getting untracked. This has only impact on local
-// store (metadata in the db and in-memory maps), nothing gets synced up.
-TEST_F(TypedURLSyncBridgeTest, ExpireLastLocalVisit) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Add two URLs into the history db and notify the bridge to get it synced up
-  // and thus also metadata written into the DB.
-  std::vector<VisitRow> visits1, visits2;
-  URLRow row1 = MakeTypedUrlRow(kURL, kTitle, /*typed_count=*/1,
-                                /*last_visit=*/1, /*hidden=*/false, &visits1);
-  URLRow row2 = MakeTypedUrlRow(kURL2, kTitle2, /*typed_count=*/1,
-                                /*last_visit=*/3, /*hidden=*/false, &visits2);
-  fake_history_backend_->SetVisitsForUrl(&row1, visits1);
-  fake_history_backend_->SetVisitsForUrl(&row2, visits2);
-
-  URLRow row1_original;
-  ASSERT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &row1_original));
-
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _))
-      .Times(2u)
-      .WillRepeatedly(StoreMetadata);
-  bridge()->OnURLsModified(fake_history_backend_.get(), {row1, row2},
-                           /*is_from_expiration=*/false);
-
-  std::string storage_key1 = GetStorageKey(kURL);
-  std::string storage_key2 = GetStorageKey(kURL2);
-  EXPECT_THAT(GetAllSyncMetadataKeys(),
-              UnorderedElementsAre(storage_key1, storage_key2));
-
-  // Simulate expiration of all visits before time 2. Simulate kURL is
-  // bookmarked so that it does not get deleted despite there's no visit left.
-  EXPECT_CALL(*history_backend_client_, IsPinnedURL(GURL(kURL)))
-      .WillOnce(Return(true));
-  fake_history_backend_->ExpireHistoryBeforeForTesting(SinceEpoch(2));
-  URLRow row1_updated;
-  ASSERT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &row1_updated));
-  EXPECT_EQ(row1_updated.typed_count(), 0);
-  EXPECT_EQ(row1_updated.last_visit(), base::Time());
-
-  // Notify typed url sync service of these URLs getting expired (it does not
-  // matter that we pass in the old version of row1, the bridge will fix it up).
-  EXPECT_CALL(mock_processor_, Delete).Times(0);
-  EXPECT_CALL(mock_processor_, UntrackEntityForStorageKey(storage_key1));
-  bridge()->OnURLsModified(fake_history_backend_.get(), {row1_updated},
-                           /*is_from_expiration=*/true);
-
-  // The urls are removed from the metadata store.
-  EXPECT_THAT(GetAllSyncMetadataKeys(), UnorderedElementsAre(storage_key2));
-}
-
-// Saturate the visits for a typed url with both TYPED and LINK navigations.
-// Check that no more than kMaxTypedURLVisits are synced, and that LINK visits
-// are dropped rather than TYPED ones.
-TEST_F(TypedURLSyncBridgeTest, MaxVisitLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  BuildAndPushLocalChanges(0, 1, urls, &url_rows, &visit_vectors);
-
-  URLRow url_row = url_rows.front();
-  std::vector<VisitRow> visits;
-
-  // Add `kMaxTypedUrlVisits` + 10 visits to the url. The 10 oldest
-  // non-typed visits are expected to be skipped.
-  int i = 1;
-  for (; i <= kMaxTypedUrlVisits - 20; ++i) {
-    AddNewestVisit(ui::PAGE_TRANSITION_TYPED, i, &url_row, &visits);
-  }
-  for (; i <= kMaxTypedUrlVisits; ++i) {
-    AddNewestVisit(ui::PAGE_TRANSITION_LINK, i, &url_row, &visits);
-  }
-  for (; i <= kMaxTypedUrlVisits + 10; ++i) {
-    AddNewestVisit(ui::PAGE_TRANSITION_TYPED, i, &url_row, &visits);
-  }
-
-  fake_history_backend_->SetVisitsForUrl(&url_row, visits);
-
-  // Notify typed url sync service of typed visit.
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row, visits.front());
-
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-  ASSERT_EQ(kMaxTypedUrlVisits, url_specifics.visits_size());
-
-  // Check that each visit has been translated/communicated correctly.
-  // Note that the specifics records visits in chronological order, and the
-  // visits from the db are in reverse chronological order.
-  int num_typed_visits_synced = 0;
-  int num_other_visits_synced = 0;
-  int r = url_specifics.visits_size() - 1;
-  for (int j = 0; j < url_specifics.visits_size(); ++j, --r) {
-    if (url_specifics.visit_transitions(j) ==
-        static_cast<int32_t>(ui::PAGE_TRANSITION_TYPED)) {
-      ++num_typed_visits_synced;
-    } else {
-      ++num_other_visits_synced;
-    }
-  }
-  EXPECT_EQ(kMaxTypedUrlVisits - 10, num_typed_visits_synced);
-  EXPECT_EQ(10, num_other_visits_synced);
-}
-
-// Add enough visits to trigger throttling of updates to a typed url. Check that
-// sync does not receive an update until the proper throttle interval has been
-// reached.
-TEST_F(TypedURLSyncBridgeTest, ThrottleVisitLocalTypedUrl) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  BuildAndPushLocalChanges(0, 1, urls, &url_rows, &visit_vectors);
-
-  URLRow url_row = url_rows.front();
-  std::vector<VisitRow> visits;
-
-  // Add enough visits to the url so that typed count is above the throttle
-  // limit, and not right on the interval that gets synced.
-  int i = 1;
-  for (; i < kVisitThrottleThreshold + kVisitThrottleMultiple / 2; ++i) {
-    AddNewestVisit(ui::PAGE_TRANSITION_TYPED, i, &url_row, &visits);
-  }
-  fake_history_backend_->SetVisitsForUrl(&url_row, visits);
-
-  // Notify typed url sync service of typed visit.
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row, visits.front());
-
-  visits.clear();
-  for (; i % kVisitThrottleMultiple != 1; ++i) {
-    AddNewestVisit(ui::PAGE_TRANSITION_TYPED, i, &url_row, &visits);
-  }
-  --i;  // Account for the increment before the condition ends.
-  fake_history_backend_->SetVisitsForUrl(&url_row, visits);
-
-  // Notify typed url sync service of typed visit.
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  bridge()->OnURLVisited(fake_history_backend_.get(), url_row, visits.front());
-
-  ASSERT_EQ(i, entity_data.specifics.typed_url().visits_size());
-}
-
-// Create a remote typed URL and visit, then send to sync bridge after sync
-// has started. Check that local DB is received the new URL and visit.
-TEST_F(TypedURLSyncBridgeTest, AddUrlAndVisits) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  EXPECT_CALL(mock_processor_, UntrackEntityForStorageKey).Times(0);
-
-  EXPECT_CALL(mock_processor_,
-              UpdateStorageKey(
-                  AllOf(HasURLInSpecifics(kURL), HasTitleInSpecifics(kTitle)),
-                  IntToStorageKey(1), _));
-  std::vector<VisitRow> visits =
-      ApplyUrlAndVisitsChange(kURL, kTitle, /*typed_count=*/1, /*last_visit=*/3,
-                              /*hidden=*/false, EntityChange::ACTION_ADD);
-
-  Time visit_time = SinceEpoch(3);
-  std::vector<VisitRow> all_visits;
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  EXPECT_EQ(1U, all_visits.size());
-  EXPECT_EQ(visit_time, all_visits[0].visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[0].transition, visits[0].transition));
-  URLRow url_row;
-  EXPECT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  EXPECT_EQ(kTitle, base::UTF16ToUTF8(url_row.title()));
-}
-
-// Create a remote typed URL with expired visit, then send to sync bridge after
-// sync has started. Check that local DB did not receive the expired URL and
-// visit.
-TEST_F(TypedURLSyncBridgeTest, AddExpiredUrlAndVisits) {
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  EXPECT_CALL(mock_processor_, UpdateStorageKey).Times(0);
-
-  EXPECT_CALL(mock_processor_, UntrackEntityForClientTagHash);
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  ApplyUrlAndVisitsChange(kURL, kTitle, /*typed_count=*/1,
-                          /*last_visit=*/kExpiredVisit,
-                          /*hidden=*/false, EntityChange::ACTION_ADD);
-
-  ASSERT_EQ(0, fake_history_backend_->GetIdByUrl(GURL(kURL)));
-}
-
-// Update a remote typed URL and create a new visit that is already synced, then
-// send the update to sync bridge. Check that local DB is received an
-// UPDATE for the existing url and new visit.
-TEST_F(TypedURLSyncBridgeTest, UpdateUrlAndVisits) {
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  std::vector<VisitRow> visits =
-      ApplyUrlAndVisitsChange(kURL, kTitle, /*typed_count=*/1, /*last_visit=*/3,
-                              /*hidden=*/false, EntityChange::ACTION_ADD);
-  Time visit_time = SinceEpoch(3);
-  std::vector<VisitRow> all_visits;
-  URLRow url_row;
-
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-
-  EXPECT_EQ(1U, all_visits.size());
-  EXPECT_EQ(visit_time, all_visits[0].visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[0].transition, visits[0].transition));
-  EXPECT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  EXPECT_EQ(kTitle, base::UTF16ToUTF8(url_row.title()));
-
-  std::vector<VisitRow> new_visits = ApplyUrlAndVisitsChange(
-      kURL, kTitle2, /*typed_count=*/2, /*last_visit=*/6,
-      /*hidden=*/false, EntityChange::ACTION_UPDATE);
-
-  Time new_visit_time = SinceEpoch(6);
-  url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-
-  EXPECT_EQ(2U, all_visits.size());
-  EXPECT_EQ(new_visit_time, all_visits.back().visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits.back().transition, new_visits[0].transition));
-  EXPECT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  EXPECT_EQ(kTitle2, base::UTF16ToUTF8(url_row.title()));
-}
-
-// Delete a typed urls which already synced. Check that local DB receives the
-// DELETE changes.
-TEST_F(TypedURLSyncBridgeTest, DeleteUrlAndVisits) {
-  std::vector<URLRow> url_rows;
-  std::vector<std::vector<VisitRow>> visit_vectors;
-  std::vector<std::string> urls;
-  urls.push_back(kURL);
-
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-  EXPECT_CALL(mock_processor_,
-              Put(IsValidStorageKey(), Pointee(HasTypedUrlInSpecifics()), _));
-  BuildAndPushLocalChanges(1, 0, urls, &url_rows, &visit_vectors);
-
-  Time visit_time = SinceEpoch(3);
-  std::vector<VisitRow> all_visits;
-  URLID url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_NE(0, url_id);
-  fake_history_backend_->GetVisitsForURL(url_id, &all_visits);
-  EXPECT_EQ(1U, all_visits.size());
-  EXPECT_EQ(visit_time, all_visits[0].visit_time);
-  EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-      all_visits[0].transition, visit_vectors[0][0].transition));
-  URLRow url_row;
-  EXPECT_TRUE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  EXPECT_EQ(kTitle, base::UTF16ToUTF8(url_row.title()));
-
-  // Add observer back to check if TypedUrlSyncBridge receive delete
-  // changes back from fake_history_backend_.
-  AddObserver();
-
-  ApplyUrlAndVisitsChange(kURL, kTitle, /*typed_count=*/1, /*last_visit=*/3,
-                          /*hidden=*/false, EntityChange::ACTION_DELETE);
-
-  EXPECT_FALSE(fake_history_backend_->GetURL(GURL(kURL), &url_row));
-  url_id = fake_history_backend_->GetIdByUrl(GURL(kURL));
-  ASSERT_EQ(0, url_id);
-}
-
-// Create two set of visits for history DB and sync DB, two same set of visits
-// are same. Check DiffVisits will return empty set of diff visits.
-TEST_F(TypedURLSyncBridgeTest, DiffVisitsSame) {
-  std::vector<VisitRow> old_visits;
-  sync_pb::TypedUrlSpecifics new_url;
-
-  const int64_t visits[] = {1024, 2065, 65534, 1237684};
-
-  for (int64_t visit : visits) {
-    old_visits.emplace_back(0, SinceEpoch(visit), 0, ui::PAGE_TRANSITION_TYPED,
-                            0, true, 0);
-    new_url.add_visits(visit);
-    new_url.add_visit_transitions(ui::PAGE_TRANSITION_TYPED);
-  }
-
-  std::vector<VisitInfo> new_visits;
-  std::vector<VisitRow> removed_visits;
-
-  DiffVisits(old_visits, new_url, &new_visits, &removed_visits);
-  EXPECT_TRUE(new_visits.empty());
-  EXPECT_TRUE(removed_visits.empty());
-}
-
-// Create two set of visits for history DB and sync DB. Check DiffVisits will
-// return correct set of diff visits.
-TEST_F(TypedURLSyncBridgeTest, DiffVisitsRemove) {
-  std::vector<VisitRow> old_visits;
-  sync_pb::TypedUrlSpecifics new_url;
-
-  const int64_t visits_left[] = {1,    2,     1024,    1500,   2065,
-                                 6000, 65534, 1237684, 2237684};
-  const int64_t visits_right[] = {1024, 2065, 65534, 1237684};
-
-  // DiffVisits will not remove the first visit, because we never delete visits
-  // from the start of the array (since those visits can get truncated by the
-  // size-limiting code).
-  const int64_t visits_removed[] = {1500, 6000, 2237684};
-
-  for (int64_t visit : visits_left) {
-    old_visits.emplace_back(0, SinceEpoch(visit), 0, ui::PAGE_TRANSITION_TYPED,
-                            0, true, 0);
-  }
-
-  for (int64_t visit : visits_right) {
-    new_url.add_visits(visit);
-    new_url.add_visit_transitions(ui::PAGE_TRANSITION_TYPED);
-  }
-
-  std::vector<VisitInfo> new_visits;
-  std::vector<VisitRow> removed_visits;
-
-  DiffVisits(old_visits, new_url, &new_visits, &removed_visits);
-  EXPECT_TRUE(new_visits.empty());
-  ASSERT_EQ(removed_visits.size(), std::size(visits_removed));
-  for (size_t i = 0; i < std::size(visits_removed); ++i) {
-    EXPECT_EQ(removed_visits[i].visit_time.ToInternalValue(),
-              visits_removed[i]);
-  }
-}
-
-// Create two set of visits for history DB and sync DB. Check DiffVisits will
-// return correct set of diff visits.
-TEST_F(TypedURLSyncBridgeTest, DiffVisitsAdd) {
-  std::vector<VisitRow> old_visits;
-  sync_pb::TypedUrlSpecifics new_url;
-
-  const int64_t visits_left[] = {1024, 2065, 65534, 1237684};
-  const int64_t visits_right[] = {1,    1024,  1500,    2065,
-                                  6000, 65534, 1237684, 2237684};
-
-  const int64_t visits_added[] = {1, 1500, 6000, 2237684};
-
-  for (int64_t visit : visits_left) {
-    old_visits.emplace_back(0, SinceEpoch(visit), 0, ui::PAGE_TRANSITION_TYPED,
-                            0, true, 0);
-  }
-
-  for (int64_t visit : visits_right) {
-    new_url.add_visits(visit);
-    new_url.add_visit_transitions(ui::PAGE_TRANSITION_TYPED);
-  }
-
-  std::vector<VisitInfo> new_visits;
-  std::vector<VisitRow> removed_visits;
-
-  DiffVisits(old_visits, new_url, &new_visits, &removed_visits);
-  EXPECT_TRUE(removed_visits.empty());
-  ASSERT_TRUE(new_visits.size() == std::size(visits_added));
-  for (size_t i = 0; i < std::size(visits_added); ++i) {
-    EXPECT_EQ(new_visits[i].first.ToInternalValue(), visits_added[i]);
-    EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs(
-        new_visits[i].second, ui::PAGE_TRANSITION_TYPED));
-  }
-}
-
-// Create three visits, check RELOAD visit is removed by
-// WriteToTypedUrlSpecifics so it won't apply to sync DB.
-TEST_F(TypedURLSyncBridgeTest, WriteTypedUrlSpecifics) {
-  std::vector<VisitRow> visits;
-  visits.push_back(CreateVisit(ui::PAGE_TRANSITION_TYPED, 1));
-  visits.push_back(CreateVisit(ui::PAGE_TRANSITION_RELOAD, 2));
-  visits.push_back(CreateVisit(ui::PAGE_TRANSITION_LINK, 3));
-
-  URLRow url(MakeTypedUrlRow(kURL, kTitle, 0, 100, false, &visits));
-  sync_pb::TypedUrlSpecifics typed_url;
-  WriteToTypedUrlSpecifics(url, visits, &typed_url);
-  // RELOAD visits should be removed.
-  EXPECT_EQ(2, typed_url.visits_size());
-  EXPECT_EQ(typed_url.visit_transitions_size(), typed_url.visits_size());
-  EXPECT_EQ(1, typed_url.visits(0));
-  EXPECT_EQ(3, typed_url.visits(1));
-  EXPECT_EQ(static_cast<int32_t>(ui::PAGE_TRANSITION_TYPED),
-            typed_url.visit_transitions(0));
-  EXPECT_EQ(static_cast<int32_t>(ui::PAGE_TRANSITION_LINK),
-            typed_url.visit_transitions(1));
-}
-
-// Create 101 visits, check WriteToTypedUrlSpecifics will only keep 100 visits.
-TEST_F(TypedURLSyncBridgeTest, TooManyVisits) {
-  std::vector<VisitRow> visits;
-  int64_t timestamp = 1000;
-  visits.push_back(CreateVisit(ui::PAGE_TRANSITION_TYPED, timestamp++));
-  for (int i = 0; i < 100; ++i) {
-    visits.push_back(CreateVisit(ui::PAGE_TRANSITION_LINK, timestamp++));
-  }
-  URLRow url(MakeTypedUrlRow(kURL, kTitle, 0, timestamp++, false, &visits));
-  sync_pb::TypedUrlSpecifics typed_url;
-  WriteToTypedUrlSpecifics(url, visits, &typed_url);
-  // # visits should be capped at 100.
-  EXPECT_EQ(100, typed_url.visits_size());
-  EXPECT_EQ(typed_url.visit_transitions_size(), typed_url.visits_size());
-  EXPECT_EQ(1000, typed_url.visits(0));
-  // Visit with timestamp of 1001 should be omitted since we should have
-  // skipped that visit to stay under the cap.
-  EXPECT_EQ(1002, typed_url.visits(1));
-  EXPECT_EQ(static_cast<int32_t>(ui::PAGE_TRANSITION_TYPED),
-            typed_url.visit_transitions(0));
-  EXPECT_EQ(static_cast<int32_t>(ui::PAGE_TRANSITION_LINK),
-            typed_url.visit_transitions(1));
-}
-
-// Create 306 visits, check WriteToTypedUrlSpecifics will only keep 100 typed
-// visits.
-TEST_F(TypedURLSyncBridgeTest, TooManyTypedVisits) {
-  std::vector<VisitRow> visits;
-  int64_t timestamp = 1000;
-  for (int i = 0; i < 102; ++i) {
-    visits.push_back(CreateVisit(ui::PAGE_TRANSITION_TYPED, timestamp++));
-    visits.push_back(CreateVisit(ui::PAGE_TRANSITION_LINK, timestamp++));
-    visits.push_back(CreateVisit(ui::PAGE_TRANSITION_RELOAD, timestamp++));
-  }
-  URLRow url(MakeTypedUrlRow(kURL, kTitle, 0, timestamp++, false, &visits));
-  sync_pb::TypedUrlSpecifics typed_url;
-  WriteToTypedUrlSpecifics(url, visits, &typed_url);
-  // # visits should be capped at 100.
-  EXPECT_EQ(100, typed_url.visits_size());
-  EXPECT_EQ(typed_url.visit_transitions_size(), typed_url.visits_size());
-  // First two typed visits should be skipped.
-  EXPECT_EQ(1006, typed_url.visits(0));
-
-  // Ensure there are no non-typed visits since that's all that should fit.
-  for (int i = 0; i < typed_url.visits_size(); ++i) {
-    EXPECT_EQ(static_cast<int32_t>(ui::PAGE_TRANSITION_TYPED),
-              typed_url.visit_transitions(i));
-  }
-}
-
-// Create a typed url without visit, check WriteToTypedUrlSpecifics will return
-// false for it.
-TEST_F(TypedURLSyncBridgeTest, NoTypedVisits) {
-  std::vector<VisitRow> visits;
-  URLRow url(MakeTypedUrlRow(kURL, kTitle, 0, 1000, false, &visits));
-  sync_pb::TypedUrlSpecifics typed_url;
-  EXPECT_FALSE(WriteToTypedUrlSpecifics(url, visits, &typed_url));
-  // URLs with no typed URL visits should not been written to specifics.
-  EXPECT_EQ(0, typed_url.visits_size());
-}
-
-TEST_F(TypedURLSyncBridgeTest, MergeUrls) {
-  std::vector<VisitRow> visits1;
-  URLRow row1(MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &visits1));
-  sync_pb::TypedUrlSpecifics specs1(
-      MakeTypedUrlSpecifics(kURL, kTitle, 3, false));
-  URLRow new_row1((GURL(kURL)));
-  std::vector<VisitInfo> new_visits1;
-  EXPECT_TRUE(TypedURLSyncBridgeTest::MergeUrls(specs1, row1, &visits1,
-                                                &new_row1, &new_visits1) ==
-              TypedURLSyncBridgeTest::DIFF_NONE);
-
-  std::vector<VisitRow> visits2;
-  URLRow row2(MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &visits2));
-  sync_pb::TypedUrlSpecifics specs2(
-      MakeTypedUrlSpecifics(kURL, kTitle, 3, true));
-  std::vector<VisitRow> expected_visits2;
-  URLRow expected2(
-      MakeTypedUrlRow(kURL, kTitle, 2, 3, true, &expected_visits2));
-  URLRow new_row2((GURL(kURL)));
-  std::vector<VisitInfo> new_visits2;
-  EXPECT_TRUE(TypedURLSyncBridgeTest::MergeUrls(specs2, row2, &visits2,
-                                                &new_row2, &new_visits2) ==
-              TypedURLSyncBridgeTest::DIFF_LOCAL_ROW_CHANGED);
-  EXPECT_TRUE(URLsEqual(new_row2, expected2));
-
-  std::vector<VisitRow> visits3;
-  URLRow row3(MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &visits3));
-  sync_pb::TypedUrlSpecifics specs3(
-      MakeTypedUrlSpecifics(kURL, kTitle2, 3, true));
-  std::vector<VisitRow> expected_visits3;
-  URLRow expected3(
-      MakeTypedUrlRow(kURL, kTitle2, 2, 3, true, &expected_visits3));
-  URLRow new_row3((GURL(kURL)));
-  std::vector<VisitInfo> new_visits3;
-  EXPECT_EQ(TypedURLSyncBridgeTest::DIFF_LOCAL_ROW_CHANGED |
-                TypedURLSyncBridgeTest::DIFF_NONE,
-            TypedURLSyncBridgeTest::MergeUrls(specs3, row3, &visits3, &new_row3,
-                                              &new_visits3));
-  EXPECT_TRUE(URLsEqual(new_row3, expected3));
-
-  // Create one node in history DB with timestamp of 3, and one node in sync
-  // DB with timestamp of 4. Result should contain one new item (4).
-  std::vector<VisitRow> visits4;
-  URLRow row4(MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &visits4));
-  sync_pb::TypedUrlSpecifics specs4(
-      MakeTypedUrlSpecifics(kURL, kTitle2, 4, false));
-  std::vector<VisitRow> expected_visits4;
-  URLRow expected4(
-      MakeTypedUrlRow(kURL, kTitle2, 2, 4, false, &expected_visits4));
-  URLRow new_row4((GURL(kURL)));
-  std::vector<VisitInfo> new_visits4;
-  EXPECT_EQ(TypedURLSyncBridgeTest::DIFF_UPDATE_NODE |
-                TypedURLSyncBridgeTest::DIFF_LOCAL_ROW_CHANGED |
-                TypedURLSyncBridgeTest::DIFF_LOCAL_VISITS_ADDED,
-            TypedURLSyncBridgeTest::MergeUrls(specs4, row4, &visits4, &new_row4,
-                                              &new_visits4));
-  EXPECT_EQ(1U, new_visits4.size());
-  EXPECT_EQ(specs4.visits(0), new_visits4[0].first.ToInternalValue());
-  EXPECT_TRUE(URLsEqual(new_row4, expected4));
-  EXPECT_EQ(2U, visits4.size());
-
-  std::vector<VisitRow> visits5;
-  URLRow row5(MakeTypedUrlRow(kURL, kTitle, 1, 4, false, &visits5));
-  sync_pb::TypedUrlSpecifics specs5(
-      MakeTypedUrlSpecifics(kURL, kTitle, 3, false));
-  std::vector<VisitRow> expected_visits5;
-  URLRow expected5(
-      MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &expected_visits5));
-  URLRow new_row5((GURL(kURL)));
-  std::vector<VisitInfo> new_visits5;
-
-  // UPDATE_NODE should be set because row5 has a newer last_visit timestamp.
-  EXPECT_EQ(TypedURLSyncBridgeTest::DIFF_UPDATE_NODE |
-                TypedURLSyncBridgeTest::DIFF_NONE,
-            TypedURLSyncBridgeTest::MergeUrls(specs5, row5, &visits5, &new_row5,
-                                              &new_visits5));
-  EXPECT_TRUE(URLsEqual(new_row5, expected5));
-  EXPECT_EQ(0U, new_visits5.size());
-}
-
-// Tests to ensure that we don't resurrect expired URLs (URLs that have been
-// deleted from the history DB but still exist in the sync DB).
-TEST_F(TypedURLSyncBridgeTest, MergeUrlsAfterExpiration) {
-  // First, create a history row that has two visits, with timestamps 2 and 3.
-  std::vector<VisitRow>(history_visits);
-  history_visits.push_back(
-      VisitRow(0, SinceEpoch(2), 0, ui::PAGE_TRANSITION_TYPED, 0, true, 0));
-  URLRow history_url(
-      MakeTypedUrlRow(kURL, kTitle, 2, 3, false, &history_visits));
-
-  // Now, create a sync node with visits at timestamps 1, 2, 3, 4.
-  sync_pb::TypedUrlSpecifics node(
-      MakeTypedUrlSpecifics(kURL, kTitle, 1, false));
-  node.add_visits(2);
-  node.add_visits(3);
-  node.add_visits(4);
-  node.add_visit_transitions(2);
-  node.add_visit_transitions(3);
-  node.add_visit_transitions(4);
-  URLRow new_history_url(history_url.url());
-  std::vector<VisitInfo> new_visits;
-  EXPECT_EQ(
-      TypedURLSyncBridgeTest::DIFF_NONE |
-          TypedURLSyncBridgeTest::DIFF_LOCAL_VISITS_ADDED,
-      TypedURLSyncBridgeTest::MergeUrls(node, history_url, &history_visits,
-                                        &new_history_url, &new_visits));
-  EXPECT_TRUE(URLsEqual(history_url, new_history_url));
-  EXPECT_EQ(1U, new_visits.size());
-  EXPECT_EQ(4U, new_visits[0].first.ToInternalValue());
-  // We should not sync the visit with timestamp #1 since it is earlier than
-  // any other visit for this URL in the history DB. But we should sync visit
-  // #4.
-  EXPECT_EQ(3U, history_visits.size());
-  EXPECT_EQ(2U, history_visits[0].visit_time.ToInternalValue());
-  EXPECT_EQ(3U, history_visits[1].visit_time.ToInternalValue());
-  EXPECT_EQ(4U, history_visits[2].visit_time.ToInternalValue());
-}
-
-// Create a local typed URL with one expired TYPED visit,
-// MergeFullSyncData should not pass it to sync. And then add a non
-// expired visit, OnURLsModified should only send the non expired visit to sync.
-TEST_F(TypedURLSyncBridgeTest, LocalExpiredTypedUrlDoNotSync) {
-  URLRow row;
-  std::vector<URLRow> changed_urls;
-  std::vector<VisitRow> visits;
-
-  // Add an expired typed URL to local.
-  row = MakeTypedUrlRow(kURL, kTitle, 1, kExpiredVisit, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&row, visits);
-
-  // Check change processor did not receive expired typed URL.
-  EXPECT_CALL(mock_processor_, Put).Times(0);
-  StartSyncing(std::vector<TypedUrlSpecifics>());
-
-  // Add a non expired typed URL to local.
-  row = MakeTypedUrlRow(kURL, kTitle, 2, 1, false, &visits);
-  fake_history_backend_->SetVisitsForUrl(&row, visits);
-
-  changed_urls.push_back(row);
-  // Check change processor did not receive expired typed URL.
-  EntityData entity_data;
-  EXPECT_CALL(mock_processor_, Put(GetStorageKey(kURL), _, _))
-      .WillOnce(SaveArgPointeeMove<1>(&entity_data));
-  // Notify typed url sync service of the update.
-  bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls,
-                           /*is_from_expiration=*/false);
-
-  // Get typed url specifics. Verify only a non-expired visit received.
-  const sync_pb::TypedUrlSpecifics& url_specifics =
-      entity_data.specifics.typed_url();
-
-  EXPECT_TRUE(URLsEqual(row, url_specifics));
-  ASSERT_EQ(1, url_specifics.visits_size());
-  ASSERT_EQ(static_cast<const int>(visits.size() - 1),
-            url_specifics.visits_size());
-  EXPECT_EQ(visits[1].visit_time.ToInternalValue(), url_specifics.visits(0));
-  EXPECT_EQ(static_cast<const int>(visits[1].transition),
-            url_specifics.visit_transitions(0));
-}
-
-// Tests that database error gets reported to processor as model type error.
-TEST_F(TypedURLSyncBridgeTest, DatabaseError) {
-  EXPECT_CALL(mock_processor_, ReportError);
-  bridge()->OnDatabaseError();
-}
-
-}  // namespace history
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
index b2db5f8..91eb5d8 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -21,7 +21,6 @@
 #import "components/consent_auditor/consent_auditor.h"
 #import "components/dom_distiller/core/dom_distiller_service.h"
 #import "components/history/core/browser/history_service.h"
-#import "components/history/core/browser/sync/typed_url_sync_bridge.h"
 #import "components/keyed_service/core/service_access_type.h"
 #import "components/metrics/demographics/user_demographics.h"
 #import "components/password_manager/core/browser/password_store_interface.h"