diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart
index b57d352..c81cae0 100644
--- a/packages/flutter/lib/src/widgets/navigator.dart
+++ b/packages/flutter/lib/src/widgets/navigator.dart
@@ -36,11 +36,6 @@
 ///  * [Navigator], which is where all the [Route]s end up.
 typedef RouteFactory = Route<dynamic> Function(RouteSettings settings);
 
-/// Creates a route for the given context and route settings.
-///
-/// Used by [CustomBuilderPage.routeBuilder].
-typedef RouteBuilder<T> = Route<T> Function(BuildContext context, RouteSettings settings);
-
 /// Creates a series of one or more routes.
 ///
 /// Used by [Navigator.onGenerateInitialRoutes].
@@ -55,15 +50,6 @@
 /// [ModalRoute.removeScopedWillPopCallback], and [WillPopScope].
 typedef WillPopCallback = Future<bool> Function();
 
-/// Signature for the [Navigator.onPopPage] callback.
-///
-/// This callback must call [Route.didPop] on the specified route and must
-/// properly update the pages list the next time it is passed into
-/// [Navigator.pages] so that it no longer includes the corresponding [Page].
-/// (Otherwise, the page will be interpreted as a new page to show when the
-/// [Navigator.pages] list is next updated.)
-typedef PopPageCallback = bool Function(Route<dynamic> route, dynamic result);
-
 /// Indicates whether the current route should be popped.
 ///
 /// Used as the return value for [Route.willPop].
@@ -104,13 +90,6 @@
 /// See [MaterialPageRoute] for a route that replaces the entire screen with a
 /// platform-adaptive transition.
 ///
-/// A route can belong to a page if the [settings] are a subclass of [Page]. A
-/// page-based route, as opposite to pageless route, is created from
-/// [Page.createRoute] during [Navigator.pages] updates. The page associated
-/// with this route may change during the lifetime of the route. If the
-/// [Navigator] updates the page of this route, it calls [changedInternalState]
-/// to notify the route that the page has been updated.
-///
 /// The type argument `T` is the route's return type, as used by
 /// [currentResult], [popped], and [didPop]. The type `void` may be used if the
 /// route does not return a value.
@@ -119,7 +98,7 @@
   ///
   /// If the [settings] are not provided, an empty [RouteSettings] object is
   /// used instead.
-  Route({ RouteSettings settings }) : _settings = settings ?? const RouteSettings();
+  Route({ RouteSettings settings }) : settings = settings ?? const RouteSettings();
 
   /// The navigator that the route is in, if any.
   NavigatorState get navigator => _navigator;
@@ -128,26 +107,7 @@
   /// The settings for this route.
   ///
   /// See [RouteSettings] for details.
-  ///
-  /// The settings can change during the route's lifetime. If the settings
-  /// change, the route's overlays will be marked dirty (see
-  /// [changedInternalState]).
-  ///
-  /// If the route is created from a [Page] in the [Navigator.pages] list, then
-  /// this will be a [Page] subclass, and it will be updated each time its
-  /// corresponding [Page] in the [Navigator.pages] has changed. Once the
-  /// [Route] is removed from the history, this value stops updating (and
-  /// remains with its last value).
-  RouteSettings get settings => _settings;
-  RouteSettings _settings;
-
-  void _updateSettings(RouteSettings newSettings) {
-    assert(newSettings != null);
-    if (_settings != newSettings) {
-      _settings = newSettings;
-      changedInternalState();
-    }
-  }
+  final RouteSettings settings;
 
   /// The overlay entries of this route.
   ///
@@ -287,6 +247,7 @@
   ///
   /// See [popped], [didComplete], and [currentResult] for a discussion of the
   /// `result` argument.
+  @protected
   @mustCallSuper
   bool didPop(T result) {
     didComplete(result);
@@ -486,82 +447,6 @@
   String toString() => '${objectRuntimeType(this, 'RouteSettings')}("$name", $arguments)';
 }
 
-/// Describes the configuration of a [Route].
-///
-/// The type argument `T` is the corresponding [Route]'s return type, as
-/// used by [Route.currentResult], [Route.popped], and [Route.didPop].
-///
-/// See also:
-///
-///  * [Navigator.pages], which accepts a list of [Page]s and updates its routes
-///    history.
-///  * [CustomBuilderPage], a [Page] subclass that provides the API to build a
-///    customized route.
-abstract class Page<T> extends RouteSettings {
-  /// Creates a page and initializes [key] for subclasses.
-  ///
-  /// The [arguments] argument must not be null.
-  const Page({
-    this.key,
-    String name,
-    Object arguments,
-  }) : super(name: name, arguments: arguments);
-
-  /// The key associated with this page.
-  ///
-  /// This key will be used for comparing pages in [canUpdate].
-  final LocalKey key;
-
-  /// Whether this page can be updated with the [other] page.
-  ///
-  /// Two pages are consider updatable if they have same the [runtimeType] and
-  /// [key].
-  bool canUpdate(Page<dynamic> other) {
-    return other.runtimeType == runtimeType &&
-           other.key == key;
-  }
-
-  /// Creates the [Route] that corresponds to this page.
-  ///
-  /// The created [Route] must have its [Route.settings] property set to this [Page].
-  Route<T> createRoute(BuildContext context);
-
-  @override
-  String toString() => '${objectRuntimeType(this, 'Page')}("$name", $key, $arguments)';
-}
-
-/// A [Page] that builds a customized [Route] based on the [routeBuilder].
-///
-/// The type argument `T` is the corresponding [Route]'s return type, as
-/// used by [Route.currentResult], [Route.popped], and [Route.didPop].
-class CustomBuilderPage<T> extends Page<T> {
-  /// Creates a page with a custom route builder.
-  ///
-  /// Use [routeBuilder] to specify the route that will be created from this
-  /// page.
-  const CustomBuilderPage({
-    @required LocalKey key,
-    @required this.routeBuilder,
-    String name,
-    Object arguments,
-  }) : assert(key != null),
-       assert(routeBuilder != null),
-       super(key: key, name: name, arguments: arguments);
-
-  /// A builder that will be called during [createRoute] to create a [Route].
-  ///
-  /// The routes returned from this builder must have their settings equal to
-  /// the input `settings`.
-  final RouteBuilder<T> routeBuilder;
-
-  @override
-  Route<T> createRoute(BuildContext context) {
-    final Route<T> route = routeBuilder(context, this);
-    assert(route.settings == this);
-    return route;
-  }
-}
-
 /// An interface for observing the behavior of a [Navigator].
 class NavigatorObserver {
   /// The navigator that the observer is observing, if any.
@@ -606,336 +491,6 @@
   void didStopUserGesture() { }
 }
 
-/// A [Route] wrapper interface that can be staged for [TransitionDelegate] to
-/// decide how its underlying [Route] should transition on or off screen.
-abstract class RouteTransitionRecord {
-  /// Retrieves the wrapped [Route].
-  Route<dynamic> get route;
-
-  /// Whether this route is entering the screen.
-  ///
-  /// If this property is true, this route requires an explicit decision on how
-  /// to transition into the screen. Such a decision should be made in the
-  /// [TransitionDelegate.resolve].
-  bool get isEntering;
-
-  bool _debugWaitingForExitDecision = false;
-
-  /// Marks the [route] to be pushed with transition.
-  ///
-  /// During [TransitionDelegate.resolve], this can be called on an entering
-  /// route (where [RouteTransitionRecord.isEntering] is true) in indicate that the
-  /// route should be pushed onto the [Navigator] with an animated transition.
-  void markForPush();
-
-  /// Marks the [route] to be added without transition.
-  ///
-  /// During [TransitionDelegate.resolve], this can be called on an entering
-  /// route (where [RouteTransitionRecord.isEntering] is true) in indicate that the
-  /// route should be added onto the [Navigator] without an animated transition.
-  void markForAdd();
-
-  /// Marks the [route] to be popped with transition.
-  ///
-  /// During [TransitionDelegate.resolve], this can be called on an exiting
-  /// route to indicate that the route should be popped off the [Navigator] with
-  /// an animated transition.
-  void markForPop([dynamic result]);
-
-  /// Marks the [route] to be completed without transition.
-  ///
-  /// During [TransitionDelegate.resolve], this can be called on an exiting
-  /// route to indicate that the route should be completed with the provided
-  /// result and removed from the [Navigator] without an animated transition.
-  void markForComplete([dynamic result]);
-
-  /// Marks the [route] to be removed without transition.
-  ///
-  /// During [TransitionDelegate.resolve], this can be called on an exiting
-  /// route to indicate that the route should be removed from the [Navigator]
-  /// without completing and without an animated transition.
-  void markForRemove();
-}
-
-/// The delegate that decides how pages added and removed from [Navigator.pages]
-/// transition in or out of the screen.
-///
-/// This abstract class implements the API to be called by [Navigator] when it
-/// requires explicit decisions on how the routes transition on or off the screen.
-///
-/// To make route transition decisions, subclass must implement [resolve].
-///
-/// {@tool sample --template=freeform}
-/// The following example demonstrates how to implement a subclass that always
-/// removes or adds routes without animated transitions and puts the removed
-/// routes at the top of the list.
-///
-/// ```dart imports
-/// import 'package:flutter/widgets.dart';
-/// ```
-///
-/// ```dart
-/// class NoAnimationTransitionDelegate extends TransitionDelegate<void> {
-///   @override
-///   Iterable<RouteTransitionRecord> resolve({
-///     List<RouteTransitionRecord> newPageRouteHistory,
-///     Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
-///     Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
-///   }) {
-///     final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
-///
-///     for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
-///       if (pageRoute.isEntering) {
-///         pageRoute.markForAdd();
-///       }
-///       results.add(pageRoute);
-///
-///     }
-///     for (final RouteTransitionRecord exitingPageRoute in locationToExitingPageRoute.values) {
-///       exitingPageRoute.markForRemove();
-///       final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
-///       if (pagelessRoutes != null) {
-///         for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
-///           pagelessRoute.markForRemove();
-///         }
-///       }
-///       results.add(exitingPageRoute);
-///
-///     }
-///     return results;
-///   }
-/// }
-///
-/// ```
-/// {@end-tool}
-///
-/// See also:
-///
-///  * [Navigator.transitionDelegate], which uses this class to make route
-///    transition decisions.
-///  * [DefaultTransitionDelegate], which implements the default way to decide
-///    how routes transition in or out of the screen.
-abstract class TransitionDelegate<T> {
-  /// Creates a delegate and enables subclass to create a constant class.
-  const TransitionDelegate();
-
-  Iterable<RouteTransitionRecord> _transition({
-    List<RouteTransitionRecord> newPageRouteHistory,
-    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
-    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
-  }) {
-    final Iterable<RouteTransitionRecord> results = resolve(
-      newPageRouteHistory: newPageRouteHistory,
-      locationToExitingPageRoute: locationToExitingPageRoute,
-      pageRouteToPagelessRoutes: pageRouteToPagelessRoutes,
-    );
-    // Verifies the integrity after the decisions have been made.
-    //
-    // Here are the rules:
-    // - All the entering routes in newPageRouteHistory must either be pushed or
-    //   added.
-    // - All the exiting routes in locationToExitingPageRoute must either be
-    //   popped, completed or removed.
-    // - All the pageless routes that belong to exiting routes must either be
-    //   popped, completed or removed.
-    // - All the entering routes in the result must preserve the same order as
-    //   the entering routes in newPageRouteHistory, and the result must contain
-    //   all exiting routes.
-    //     ex:
-    //
-    //     newPageRouteHistory = [A, B, C]
-    //
-    //     locationToExitingPageRoute = {A -> D, C -> E}
-    //
-    //     results = [A, B ,C ,D ,E] is valid
-    //     results = [D, A, B ,C ,E] is also valid because exiting route can be
-    //     inserted in any place
-    //
-    //     results = [B, A, C ,D ,E] is invalid because B must be after A.
-    //     results = [A, B, C ,E] is invalid because results must include D.
-    assert(() {
-      final List<RouteTransitionRecord> resultsToVerify = results.toList(growable: false);
-      final Set<RouteTransitionRecord> exitingPageRoutes = locationToExitingPageRoute.values.toSet();
-      // Firstly, verifies all exiting routes have been marked.
-      for (final RouteTransitionRecord exitingPageRoute in exitingPageRoutes) {
-        assert(!exitingPageRoute._debugWaitingForExitDecision);
-        if (pageRouteToPagelessRoutes.containsKey(exitingPageRoute)) {
-          for (final RouteTransitionRecord pagelessRoute in pageRouteToPagelessRoutes[exitingPageRoute]) {
-            assert(!pagelessRoute._debugWaitingForExitDecision);
-          }
-        }
-      }
-      // Secondly, verifies the order of results matches the newPageRouteHistory
-      // and contains all the exiting routes.
-      int indexOfNextRouteInNewHistory = 0;
-
-      for (final _RouteEntry routeEntry in resultsToVerify.cast<_RouteEntry>()) {
-        assert(routeEntry != null);
-        assert(!routeEntry.isEntering && !routeEntry._debugWaitingForExitDecision);
-        if (
-          indexOfNextRouteInNewHistory >= newPageRouteHistory.length ||
-          routeEntry != newPageRouteHistory[indexOfNextRouteInNewHistory]
-        ) {
-          assert(exitingPageRoutes.contains(routeEntry));
-          exitingPageRoutes.remove(routeEntry);
-        } else {
-          indexOfNextRouteInNewHistory += 1;
-        }
-      }
-
-      assert(
-        indexOfNextRouteInNewHistory == newPageRouteHistory.length &&
-        exitingPageRoutes.isEmpty
-      );
-      return true;
-    }());
-
-    return results;
-  }
-
-  /// A method that will be called by the [Navigator] to decide how routes
-  /// transition in or out of the screen when [Navigator.pages] is updated.
-  ///
-  /// The `newPageRouteHistory` list contains all page-based routes in the order
-  /// that will be on the [Navigator]'s history stack after this update
-  /// completes. If a route in `newPageRouteHistory` has its
-  /// [RouteTransitionRecord.isEntering] set to true, this route requires explicit
-  /// decision on how it should transition onto the Navigator. To make a
-  /// decision, call [RouteTransitionRecord.markForPush] or
-  /// [RouteTransitionRecord.markForAdd].
-  ///
-  /// The `locationToExitingPageRoute` contains the pages-based routes that
-  /// are removed from the routes history after page update and require explicit
-  /// decision on how to transition off the screen. This map records page-based
-  /// routes to be removed with the location of the route in the original route
-  /// history before the update. The keys are the locations represented by the
-  /// page-based routes that are directly below the removed routes, and the value
-  /// are the page-based routes to be removed. The location is null if the route
-  /// to be removed is the bottom most route. To make a decision for a removed
-  /// route, call [RouteTransitionRecord.markForPop],
-  /// [RouteTransitionRecord.markForComplete] or
-  /// [RouteTransitionRecord.markForRemove].
-  ///
-  /// The `pageRouteToPagelessRoutes` records the page-based routes and their
-  /// associated pageless routes. If a page-based route is to be removed, its
-  /// associated pageless routes also require explicit decisions on how to
-  /// transition off the screen.
-  ///
-  /// Once all the decisions have been made, this method must merge the removed
-  /// routes and the `newPageRouteHistory` and return the merged result. The
-  /// order in the result will be the order the [Navigator] uses for updating
-  /// the route history. The return list must preserve the same order of routes
-  /// in `newPageRouteHistory`. The removed routes, however, can be inserted
-  /// into the return list freely as long as all of them are included.
-  ///
-  /// For example, consider the following case.
-  ///
-  ///    newPageRouteHistory = [A, B, C]
-  ///
-  ///    locationToExitingPageRoute = {A -> D, C -> E}
-  ///
-  /// The following outputs are valid.
-  ///
-  ///    result = [A, B ,C ,D ,E] is valid
-  ///    result = [D, A, B ,C ,E] is also valid because exiting route can be
-  ///    inserted in any place
-  ///
-  /// The following outputs are invalid.
-  ///
-  ///    result = [B, A, C ,D ,E] is invalid because B must be after A.
-  ///    result = [A, B, C ,E] is invalid because results must include D.
-  ///
-  /// See also:
-  ///
-  ///  * [RouteTransitionRecord.markForPush], which makes route enter the screen
-  ///    with an animated transition.
-  ///  * [RouteTransitionRecord.markForAdd], which makes route enter the screen
-  ///    without an animated transition.
-  ///  * [RouteTransitionRecord.markForPop], which makes route exit the screen
-  ///    with an animated transition.
-  ///  * [RouteTransitionRecord.markForRemove], which does not complete the
-  ///    route and makes it exit the screen without an animated transition.
-  ///  * [RouteTransitionRecord.markForComplete], which completes the route and
-  ///    makes it exit the screen without an animated transition.
-  ///  * [DefaultTransitionDelegate.resolve], which implements the default way
-  ///    to decide how routes transition in or out of the screen.
-  Iterable<RouteTransitionRecord> resolve({
-    List<RouteTransitionRecord> newPageRouteHistory,
-    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
-    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
-  });
-}
-
-/// The default implementation of [TransitionDelegate] that the [Navigator] will
-/// use if its [Navigator.transitionDelegate] is not specified.
-///
-/// This transition delegate follows two rules. Firstly, all the entering routes
-/// are placed on top of the exiting routes if they are at the same location.
-/// Secondly, the top most route will always transition with an animated transition.
-/// All the other routes below will either be completed with
-/// [Route.currentResult] or added without an animated transition.
-class DefaultTransitionDelegate<T> extends TransitionDelegate<T> {
-  /// Creates a default transition delegate.
-  const DefaultTransitionDelegate() : super();
-
-  @override
-  Iterable<RouteTransitionRecord> resolve({
-    List<RouteTransitionRecord> newPageRouteHistory,
-    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
-    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
-  }) {
-    final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
-    // This method will handle the exiting route and its corresponding pageless
-    // route at this location. It will also recursively check if there is any
-    // other exiting routes above it and handle them accordingly.
-    void handleExitingRoute(RouteTransitionRecord location, bool isLast) {
-      final RouteTransitionRecord exitingPageRoute = locationToExitingPageRoute[location];
-      if (exitingPageRoute == null)
-        return;
-      assert(exitingPageRoute._debugWaitingForExitDecision);
-      final bool hasPagelessRoute = pageRouteToPagelessRoutes.containsKey(exitingPageRoute);
-      final bool isLastExitingPageRoute = isLast && !locationToExitingPageRoute.containsKey(exitingPageRoute);
-      if (isLastExitingPageRoute && !hasPagelessRoute) {
-        exitingPageRoute.markForPop(exitingPageRoute.route.currentResult);
-      } else {
-        exitingPageRoute.markForComplete(exitingPageRoute.route.currentResult);
-      }
-      results.add(exitingPageRoute);
-
-      if (hasPagelessRoute) {
-        final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
-        for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
-          assert(pagelessRoute._debugWaitingForExitDecision);
-          if (isLastExitingPageRoute && pagelessRoute == pagelessRoutes.last) {
-            pagelessRoute.markForPop(pagelessRoute.route.currentResult);
-          } else {
-            pagelessRoute.markForComplete(pagelessRoute.route.currentResult);
-          }
-        }
-      }
-      // It is possible there is another exiting route above this exitingPageRoute.
-      handleExitingRoute(exitingPageRoute, isLast);
-    }
-
-    // Handles exiting route in the beginning of list.
-    handleExitingRoute(null, newPageRouteHistory.isEmpty);
-
-    for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
-      final bool isLastIteration = newPageRouteHistory.last == pageRoute;
-      if (pageRoute.isEntering) {
-        if (!locationToExitingPageRoute.containsKey(pageRoute) && isLastIteration) {
-          pageRoute.markForPush();
-        } else {
-          pageRoute.markForAdd();
-        }
-      }
-      results.add(pageRoute);
-      handleExitingRoute(pageRoute, isLastIteration);
-    }
-    return results;
-  }
-}
-
 /// A widget that manages a set of child widgets with a stack discipline.
 ///
 /// Many apps have a navigator near the top of their widget hierarchy in order
@@ -950,9 +505,8 @@
 /// Mobile apps typically reveal their contents via full-screen elements
 /// called "screens" or "pages". In Flutter these elements are called
 /// routes and they're managed by a [Navigator] widget. The navigator
-/// manages a stack of [Route] objects and provides two ways for managing
-/// the stack, the declarative API [Navigator.pages] or imperative API
-/// [Navigator.push] and [Navigator.pop].
+/// manages a stack of [Route] objects and provides methods for managing
+/// the stack, like [Navigator.push] and [Navigator.pop].
 ///
 /// When your user interface fits this paradigm of a stack, where the user
 /// should be able to _navigate_ back to an earlier element in the stack,
@@ -964,21 +518,6 @@
 /// used in the [Scaffold.appBar] property) can automatically add a back
 /// button for user navigation.
 ///
-/// ## Using the Pages API
-///
-/// The [Navigator] will convert its [Navigator.pages] into a stack of [Route]s
-/// if it is provided. A change in [Navigator.pages] will trigger an update to
-/// the stack of [Route]s. The [Navigator] will update its routes to match the
-/// new configuration of its [Navigator.pages]. To use this API, one can use
-/// [CustomBuilderPage] or create a [Page] subclass and defines a list of
-/// [Page]s for [Navigator.pages]. A [Navigator.onPopPage] callback is also
-/// required to properly clean up the input pages in case of a pop.
-///
-/// By Default, the [Navigator] will use [DefaultTransitionDelegate] to decide
-/// how routes transition in or out of the screen. To customize it, define a
-/// [TransitionDelegate] subclass and provide it to the
-/// [Navigator.transitionDelegate].
-///
 /// ### Displaying a full-screen route
 ///
 /// Although you can create a navigator directly, it's most common to use the
@@ -1194,7 +733,7 @@
 /// ```
 ///
 /// ```dart main
-/// void main() => runApp(MyApp());
+/// void main() => runApp(new MyApp());
 /// ```
 ///
 /// ```dart
@@ -1320,77 +859,17 @@
 class Navigator extends StatefulWidget {
   /// Creates a widget that maintains a stack-based history of child widgets.
   ///
-  /// The [onGenerateRoute], [pages], [onGenerateInitialRoutes],
-  /// [transitionDelegate], [observers]  arguments must not be null.
-  ///
-  /// If the [pages] is not empty, the [onPopPage] must not be null.
+  /// The [onGenerateRoute] argument must not be null.
   const Navigator({
     Key key,
-    this.pages = const <Page<dynamic>>[],
-    this.onPopPage,
     this.initialRoute,
     this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
     this.onGenerateRoute,
     this.onUnknownRoute,
-    this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
     this.observers = const <NavigatorObserver>[],
-  }) : assert(pages != null),
-       assert(onGenerateInitialRoutes != null),
-       assert(transitionDelegate != null),
-       assert(observers != null),
+  }) : assert(onGenerateInitialRoutes != null),
        super(key: key);
 
-  /// The list of pages with which to populate the history.
-  ///
-  /// Pages are turned into routes using [Page.createRoute] in a manner
-  /// analogous to how [Widget]s are turned into [Element]s (and [State]s or
-  /// [RenderObject]s) using [Widget.createElement] (and
-  /// [StatefulWidget.createState] or [RenderObjectWidget.createRenderObject]).
-  ///
-  /// When this list is updated, the new list is compared to the previous
-  /// list and the set of routes is updated accordingly.
-  ///
-  /// Some [Route]s do not correspond to [Page] objects, namely, those that are
-  /// added to the history using the [Navigator] API ([push] and friends). A
-  /// [Route] that does not correspond to a [Page] object is called a pageless
-  /// route and is tied to the [Route] that _does_ correspond to a [Page] object
-  /// that is below it in the history.
-  ///
-  /// Pages that are added or removed may be animated as controlled by the
-  /// [transitionDelegate]. If a page is removed that had other pageless routes
-  /// pushed on top of it using [push] and friends, those pageless routes are
-  /// also removed with or without animation as determined by the
-  /// [transitionDelegate].
-  ///
-  /// To use this API, an [onPopPage] callback must also be provided to properly
-  /// clean up this list if a page has been popped.
-  ///
-  /// If [initialRoute] is non-null when the widget is first created, then
-  /// [onGenerateInitialRoutes] is used to generate routes that are above those
-  /// corresponding to [pages] in the initial history.
-  final List<Page<dynamic>> pages;
-
-  /// Called when [pop] is invoked but the current [Route] corresponds to a
-  /// [Page] found in the [pages] list.
-  ///
-  /// The `result` argument is the value with which the route is to complete
-  /// (e.g. the value returned from a dialog).
-  ///
-  /// This callback is responsible for calling [Route.didPop] and returning
-  /// whether this pop is successful.
-  ///
-  /// The [Navigator] widget should be rebuilt with a [pages] list that does not
-  /// contain the [Page] for the given [Route]. The next time the [pages] list
-  /// is updated, if the [Page] corresponding to this [Route] is still present,
-  /// it will be interpreted as a new route to display.
-  final PopPageCallback onPopPage;
-
-  /// The delegate used for deciding how routes transition in or off the screen
-  /// during the [pages] updates.
-  ///
-  /// Defaults to [DefaultTransitionDelegate] if not specified, cannot be null.
-  final TransitionDelegate<dynamic> transitionDelegate;
-
   /// The name of the first route to show.
   ///
   /// Defaults to [Navigator.defaultRouteName].
@@ -2201,14 +1680,6 @@
 // The _RouteLifecycle state machine (only goes down):
 //
 //                    [creation of a _RouteEntry]
-//                                 |
-//                                 +
-//                                 |\
-//                                 | \
-//                                 | staging
-//                                 | /
-//                                 |/
-//                    +-+----------+--+-------+
 //                   /  |             |       |
 //                  /   |             |       |
 //                 /    |             |       |
@@ -2217,7 +1688,7 @@
 //      pushReplace   push*         add*   replace*
 //               \       |            |       |
 //                \      |            |      /
-//                 +--pushing#      adding  /
+//                 +--pushing#        |     /
 //                          \        /     /
 //                           \      /     /
 //                           idle--+-----+
@@ -2243,69 +1714,47 @@
 //   route entry will exit that state.
 // # These states await futures or other events, then transition automatically.
 enum _RouteLifecycle {
-  staging, // we will wait for transition delegate to decide what to do with this route.
-  //
-  // routes that are present:
-  //
+  // routes that are and will be present:
   add, // we'll want to run install, didAdd, etc; a route created by onGenerateInitialRoutes or by the initial widget.pages
-  adding, // we'll want to run install, didAdd, etc; a route created by onGenerateInitialRoutes or by the initial widget.pages
-  // routes that are ready for transition.
   push, // we'll want to run install, didPush, etc; a route added via push() and friends
   pushReplace, // we'll want to run install, didPush, etc; a route added via pushReplace() and friends
   pushing, // we're waiting for the future from didPush to complete
   replace, // we'll want to run install, didReplace, etc; a route added via replace() and friends
   idle, // route is being harmless
-  //
-  // routes that are not present:
-  //
-  // routes that should be included in route announcement and should still listen to transition changes.
+  // routes that are but will not present:
   pop, // we'll want to call didPop
   remove, // we'll want to run didReplace/didRemove etc
-  // routes should not be included in route announcement but should still listen to transition changes.
+  // routes that are not and will not present:
   popping, // we're waiting for the route to call finalizeRoute to switch to dispose
   removing, // we are waiting for subsequent routes to be done animating, then will switch to dispose
-  // routes that are completely removed from the navigator and overlay.
   dispose, // we will dispose the route momentarily
   disposed, // we have disposed the route
 }
 
 typedef _RouteEntryPredicate = bool Function(_RouteEntry entry);
 
-class _RouteEntry extends RouteTransitionRecord {
+class _RouteEntry {
   _RouteEntry(
     this.route, {
       @required _RouteLifecycle initialState,
     }) : assert(route != null),
          assert(initialState != null),
          assert(
-           initialState == _RouteLifecycle.staging ||
            initialState == _RouteLifecycle.add ||
            initialState == _RouteLifecycle.push ||
            initialState == _RouteLifecycle.pushReplace ||
            initialState == _RouteLifecycle.replace
          ),
-         currentState = initialState;
+         currentState = initialState; // ignore: prefer_initializing_formals
 
-  @override
   final Route<dynamic> route;
 
   _RouteLifecycle currentState;
+  Route<dynamic> lastAnnouncedNextRoute; // last argument to Route.didChangeNext
   Route<dynamic> lastAnnouncedPreviousRoute; // last argument to Route.didChangePrevious
   Route<dynamic> lastAnnouncedPoppedNextRoute; // last argument to Route.didPopNext
-  Route<dynamic> lastAnnouncedNextRoute; // last argument to Route.didChangeNext
 
-  bool get hasPage => route.settings is Page;
-
-  bool canUpdateFrom(Page<dynamic> page) {
-    if (currentState.index > _RouteLifecycle.idle.index)
-      return false;
-    if (!hasPage)
-      return false;
-    final Page<dynamic> routePage = route.settings as Page<dynamic>;
-    return page.canUpdate(routePage);
-  }
-
-  void handleAdd({ @required NavigatorState navigator}) {
+  void handleAdd({ @required NavigatorState navigator, @required bool isNewFirst, @required Route<dynamic> previous, @required Route<dynamic> previousPresent }) {
     assert(currentState == _RouteLifecycle.add);
     assert(navigator != null);
     assert(navigator._debugLocked);
@@ -2313,7 +1762,13 @@
     route._navigator = navigator;
     route.install();
     assert(route.overlayEntries.isNotEmpty);
-    currentState = _RouteLifecycle.adding;
+    route.didAdd();
+    currentState = _RouteLifecycle.idle;
+    if (isNewFirst) {
+      route.didChangeNext(null);
+    }
+    for (final NavigatorObserver observer in navigator.widget.observers)
+      observer.didPush(route, previousPresent);
   }
 
   void handlePush({ @required NavigatorState navigator, @required bool isNewFirst, @required Route<dynamic> previous, @required Route<dynamic> previousPresent }) {
@@ -2383,16 +1838,6 @@
 
   bool doingPop = false;
 
-  void didAdd({ @required NavigatorState navigator, @required bool isNewFirst, @required Route<dynamic> previous, @required Route<dynamic> previousPresent }) {
-    route.didAdd();
-    currentState = _RouteLifecycle.idle;
-    if (isNewFirst) {
-      route.didChangeNext(null);
-    }
-    for (final NavigatorObserver observer in navigator.widget.observers)
-      observer.didPush(route, previousPresent);
-  }
-
   void pop<T>(T result) {
     assert(isPresent);
     doingPop = true;
@@ -2406,11 +1851,6 @@
 
   // Route is removed without being completed.
   void remove({ bool isReplaced = false }) {
-    assert(
-      !hasPage || _debugWaitingForExitDecision,
-      'A page-based route cannot be completed using imperative api, provide a '
-      'new list without the corresponding Page to Navigator.pages instead. '
-    );
     if (currentState.index >= _RouteLifecycle.remove.index)
       return;
     assert(isPresent);
@@ -2420,11 +1860,6 @@
 
   // Route completes with `result` and is removed.
   void complete<T>(T result, { bool isReplaced = false }) {
-    assert(
-      !hasPage || _debugWaitingForExitDecision,
-      'A page-based route cannot be completed using imperative api, provide a '
-      'new list without the corresponding Page to Navigator.pages instead. '
-    );
     if (currentState.index >= _RouteLifecycle.remove.index)
       return;
     assert(isPresent);
@@ -2445,25 +1880,8 @@
     currentState = _RouteLifecycle.disposed;
   }
 
-  bool get willBePresent {
-    return currentState.index <= _RouteLifecycle.idle.index &&
-           currentState.index >= _RouteLifecycle.add.index;
-  }
-
-  bool get isPresent {
-    return currentState.index <= _RouteLifecycle.remove.index &&
-           currentState.index >= _RouteLifecycle.add.index;
-  }
-
-  bool get suitableForAnnouncement {
-    return currentState.index <= _RouteLifecycle.removing.index &&
-           currentState.index >= _RouteLifecycle.push.index;
-  }
-
-  bool get suitableForTransitionAnimation {
-    return currentState.index <= _RouteLifecycle.remove.index &&
-           currentState.index >= _RouteLifecycle.push.index;
-  }
+  bool get willBePresent => currentState.index <= _RouteLifecycle.idle.index;
+  bool get isPresent => currentState.index <= _RouteLifecycle.remove.index;
 
   bool shouldAnnounceChangeToNext(Route<dynamic> nextRoute) {
     assert(nextRoute != lastAnnouncedNextRoute);
@@ -2477,76 +1895,17 @@
   }
 
   static final _RouteEntryPredicate isPresentPredicate = (_RouteEntry entry) => entry.isPresent;
-  static final _RouteEntryPredicate suitableForTransitionAnimationPredicate = (_RouteEntry entry) => entry.suitableForTransitionAnimation;
   static final _RouteEntryPredicate willBePresentPredicate = (_RouteEntry entry) => entry.willBePresent;
 
   static _RouteEntryPredicate isRoutePredicate(Route<dynamic> route) {
     return (_RouteEntry entry) => entry.route == route;
   }
-
-  @override
-  bool get isEntering => currentState == _RouteLifecycle.staging;
-
-  @override
-  void markForPush() {
-    assert(
-      isEntering && !_debugWaitingForExitDecision,
-      'This route cannot be marked for push. Either a decision has already been '
-      'made or it does not require an explicit decision on how to transition in.'
-    );
-    currentState = _RouteLifecycle.push;
-  }
-
-  @override
-  void markForAdd() {
-    assert(
-      isEntering && !_debugWaitingForExitDecision,
-      'This route cannot be marked for add. Either a decision has already been '
-      'made or it does not require an explicit decision on how to transition in.'
-    );
-    currentState = _RouteLifecycle.add;
-  }
-
-  @override
-  void markForPop([dynamic result]) {
-    assert(
-      !isEntering && _debugWaitingForExitDecision,
-      'This route cannot be marked for pop. Either a decision has already been '
-      'made or it does not require an explicit decision on how to transition out.'
-    );
-    pop<dynamic>(result);
-    _debugWaitingForExitDecision = false;
-  }
-
-  @override
-  void markForComplete([dynamic result]) {
-    assert(
-      !isEntering && _debugWaitingForExitDecision,
-      'This route cannot be marked for complete. Either a decision has already '
-      'been made or it does not require an explicit decision on how to transition '
-      'out.'
-    );
-    complete<dynamic>(result);
-    _debugWaitingForExitDecision = false;
-  }
-
-  @override
-  void markForRemove() {
-    assert(
-      !isEntering && _debugWaitingForExitDecision,
-      'This route cannot be marked for remove. Either a decision has already '
-      'been made or it does not require an explicit decision on how to transition '
-      'out.'
-    );
-    remove();
-    _debugWaitingForExitDecision = false;
-  }
 }
 
 /// The state for a [Navigator] widget.
 class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
   final GlobalKey<OverlayState> _overlayKey = GlobalKey<OverlayState>();
-  List<_RouteEntry> _history = <_RouteEntry>[];
+  final List<_RouteEntry> _history = <_RouteEntry>[];
 
   /// The [FocusScopeNode] for the [FocusScope] that encloses the routes.
   final FocusScopeNode focusScopeNode = FocusScopeNode(debugLabel: 'Navigator Scope');
@@ -2556,40 +1915,20 @@
   @override
   void initState() {
     super.initState();
-    assert(
-      widget.pages.isEmpty || widget.onPopPage != null,
-      'The Navigator.onPopPage must be provided to use the Navigator.pages API',
-    );
     for (final NavigatorObserver observer in widget.observers) {
       assert(observer.navigator == null);
       observer._navigator = this;
     }
-    String initialRoute = widget.initialRoute;
-    if (widget.pages.isNotEmpty) {
-      _history.addAll(
-        widget.pages.map((Page<dynamic> page) => _RouteEntry(
-          page.createRoute(context),
+    // TODO(chunhtai): Uses pages after we add page api.
+    // https://github.com/flutter/flutter/issues/45938
+    _history.addAll(
+      widget.onGenerateInitialRoutes(this, widget.initialRoute ?? Navigator.defaultRouteName)
+        .map((Route<dynamic> route) => _RouteEntry(
+          route,
           initialState: _RouteLifecycle.add,
-        ))
-      );
-    } else {
-      // If there is no page provided, we will need to provide default route
-      // to initialize the navigator.
-      initialRoute = initialRoute ?? Navigator.defaultRouteName;
-    }
-    if (initialRoute != null) {
-      _history.addAll(
-        widget.onGenerateInitialRoutes(
-          this,
-          widget.initialRoute ?? Navigator.defaultRouteName
-        ).map((Route<dynamic> route) =>
-          _RouteEntry(
-            route,
-            initialState: _RouteLifecycle.add,
-          ),
         ),
-      );
-    }
+      ),
+    );
     assert(!_debugLocked);
     assert(() { _debugLocked = true; return true; }());
     _flushHistoryUpdates();
@@ -2599,10 +1938,6 @@
   @override
   void didUpdateWidget(Navigator oldWidget) {
     super.didUpdateWidget(oldWidget);
-    assert(
-      widget.pages.isEmpty || widget.onPopPage != null,
-      'The Navigator.onPopPage must be provided to use the Navigator.pages API',
-    );
     if (oldWidget.observers != widget.observers) {
       for (final NavigatorObserver observer in oldWidget.observers)
         observer._navigator = null;
@@ -2611,31 +1946,10 @@
         observer._navigator = this;
       }
     }
-    if (oldWidget.pages != widget.pages) {
-      assert(
-        widget.pages.isNotEmpty,
-        'To use the Navigator.pages, there must be at least one page in the list.'
-      );
-      _updatePages();
-    }
-
     for (final _RouteEntry entry in _history)
       entry.route.changedExternalState();
   }
 
-  void _debugCheckDuplicatedPageKeys() {
-    assert((){
-      final Set<Key> keyReservation = <Key>{};
-      for (final Page<dynamic> page in widget.pages) {
-        if (page.key != null) {
-          assert(!keyReservation.contains(page.key));
-          keyReservation.add(page.key);
-        }
-      }
-      return true;
-    }());
-  }
-
   @override
   void dispose() {
     assert(!_debugLocked);
@@ -2663,276 +1977,8 @@
 
   String _lastAnnouncedRouteName;
 
-  bool _debugUpdatingPage = false;
-  void _updatePages() {
-    assert(() {
-      assert(!_debugUpdatingPage);
-      _debugCheckDuplicatedPageKeys();
-      _debugUpdatingPage = true;
-      return true;
-    }());
-
-    // This attempts to diff the new pages list (widget.pages) with
-    // the old _RouteEntry[s] list (_history), and produces a new list of
-    // _RouteEntry[s] to be the new list of _history. This method roughly
-    // follows the same outline of RenderObjectElement.updateChildren.
-    //
-    // The cases it tries to optimize for are:
-    //  - the old list is empty
-    //  - All the pages in the new list can match the page-based routes in the old
-    //    list, and their orders are the same.
-    //  - there is an insertion or removal of one or more page-based route in
-    //    only one place in the list
-    // If a page-based route with a key is in both lists, it will be synced.
-    // Page-based routes without keys might be synced but there is no guarantee.
-
-    // The general approach is to sync the entire new list backwards, as follows:
-    // 1. Walk the lists from the bottom, syncing nodes, and record pageless routes,
-    //    until you no longer have matching nodes.
-    // 2. Walk the lists from the top, without syncing nodes, until you no
-    //    longer have matching nodes. We'll sync these nodes at the end. We
-    //    don't sync them now because we want to sync all the nodes in order
-    //    from beginning to end.
-    // At this point we narrowed the old and new lists to the point
-    // where the nodes no longer match.
-    // 3. Walk the narrowed part of the old list to get the list of
-    //    keys.
-    // 4. Walk the narrowed part of the new list forwards:
-    //     * Create a new _RouteEntry for non-keyed items and record them for
-    //       transitionDelegate.
-    //     * Sync keyed items with the source if it exists.
-    // 5. Walk the narrowed part of the old list again to records the
-    //    _RouteEntry[s], as well as pageless routes, needed to be removed for
-    //    transitionDelegate.
-    // 5. Walk the top of the list again, syncing the nodes and recording
-    //    pageless routes.
-    // 6. Use transitionDelegate for explicit decisions on how _RouteEntry[s]
-    //    transition in or off the screens.
-    // 7. Fill pageless routes back into the new history.
-
-    bool needsExplicitDecision = false;
-    int newPagesBottom = 0;
-    int oldEntriesBottom = 0;
-    int newPagesTop = widget.pages.length - 1;
-    int oldEntriesTop = _history.length - 1;
-
-    final List<_RouteEntry> newHistory = <_RouteEntry>[];
-    final Map<_RouteEntry, List<_RouteEntry>> pageRouteToPagelessRoutes = <_RouteEntry, List<_RouteEntry>>{};
-
-    // Updates the bottom of the list.
-    _RouteEntry previousOldPageRouteEntry;
-    while (oldEntriesBottom <= oldEntriesTop) {
-      final _RouteEntry oldEntry = _history[oldEntriesBottom];
-      assert(oldEntry != null && oldEntry.currentState != _RouteLifecycle.disposed);
-      // Records pageless route. The bottom most pageless routes will be
-      // stored in key = null.
-      if (!oldEntry.hasPage) {
-        final List<_RouteEntry> pagelessRoutes = pageRouteToPagelessRoutes.putIfAbsent(
-          previousOldPageRouteEntry,
-          () => <_RouteEntry>[],
-        );
-        pagelessRoutes.add(oldEntry);
-        oldEntriesBottom += 1;
-        continue;
-      }
-      if (newPagesBottom > newPagesTop)
-        break;
-      final Page<dynamic> newPage = widget.pages[newPagesBottom];
-      if (!oldEntry.canUpdateFrom(newPage))
-        break;
-      previousOldPageRouteEntry = oldEntry;
-      oldEntry.route._updateSettings(newPage);
-      newHistory.add(oldEntry);
-      newPagesBottom += 1;
-      oldEntriesBottom += 1;
-    }
-
-    int pagelessRoutesToSkip = 0;
-    // Scans the top of the list until we found a page-based route that cannot be
-    // updated.
-    while ((oldEntriesBottom <= oldEntriesTop) && (newPagesBottom <= newPagesTop)) {
-      final _RouteEntry oldEntry = _history[oldEntriesTop];
-      assert(oldEntry != null && oldEntry.currentState != _RouteLifecycle.disposed);
-      if (!oldEntry.hasPage) {
-        // This route might need to be skipped if we can not find a page above.
-        pagelessRoutesToSkip += 1;
-        oldEntriesTop -= 1;
-        continue;
-      }
-      final Page<dynamic> newPage = widget.pages[newPagesTop];
-      if (!oldEntry.canUpdateFrom(newPage))
-        break;
-      // We found the page for all the consecutive pageless routes below. Those
-      // pageless routes do not need to be skipped.
-      pagelessRoutesToSkip = 0;
-      oldEntriesTop -= 1;
-      newPagesTop -= 1;
-    }
-    // Reverts the pageless routes that cannot be updated.
-    oldEntriesTop += pagelessRoutesToSkip;
-
-    // Scans middle of the old entries and records the page key to old entry map.
-    int oldEntriesBottomToScan = oldEntriesBottom;
-    final Map<LocalKey, _RouteEntry> pageKeyToOldEntry = <LocalKey, _RouteEntry>{};
-    while (oldEntriesBottomToScan <= oldEntriesTop) {
-      final _RouteEntry oldEntry = _history[oldEntriesBottomToScan];
-      oldEntriesBottomToScan += 1;
-      assert(
-        oldEntry != null &&
-        oldEntry.currentState != _RouteLifecycle.disposed
-      );
-      // Pageless routes will be recorded when we update the middle of the old
-      // list.
-      if (!oldEntry.hasPage)
-        continue;
-
-      assert(oldEntry.hasPage);
-
-      final Page<dynamic> page = oldEntry.route.settings as Page<dynamic>;
-      if (page.key == null)
-        continue;
-
-      assert(!pageKeyToOldEntry.containsKey(page.key));
-      pageKeyToOldEntry[page.key] = oldEntry;
-    }
-
-    // Updates the middle of the list.
-    while (newPagesBottom <= newPagesTop) {
-      final Page<dynamic> nextPage = widget.pages[newPagesBottom];
-      newPagesBottom += 1;
-      if (
-        nextPage.key == null ||
-        !pageKeyToOldEntry.containsKey(nextPage.key) ||
-        !pageKeyToOldEntry[nextPage.key].canUpdateFrom(nextPage)
-      ) {
-        // There is no matching key in the old history, we need to create a new
-        // route and wait for the transition delegate to decide how to add
-        // it into the history.
-        final _RouteEntry newEntry = _RouteEntry(
-          nextPage.createRoute(context),
-          initialState: _RouteLifecycle.staging,
-        );
-        needsExplicitDecision = true;
-        assert(
-          newEntry.route.settings == nextPage,
-          'If a route is created from a page, its must have that page as its '
-          'settings.',
-        );
-        newHistory.add(newEntry);
-      } else {
-        // Removes the key from pageKeyToOldEntry to indicate it is taken.
-        final _RouteEntry matchingEntry = pageKeyToOldEntry.remove(nextPage.key);
-        assert(matchingEntry.canUpdateFrom(nextPage));
-        matchingEntry.route._updateSettings(nextPage);
-        newHistory.add(matchingEntry);
-      }
-    }
-
-    // Any remaining old routes that do not have a match will need to be removed.
-    final Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute = <RouteTransitionRecord, RouteTransitionRecord>{};
-    while (oldEntriesBottom <= oldEntriesTop) {
-      final _RouteEntry potentialEntryToRemove = _history[oldEntriesBottom];
-      oldEntriesBottom += 1;
-
-      if (!potentialEntryToRemove.hasPage) {
-        assert(previousOldPageRouteEntry != null);
-        final List<_RouteEntry> pagelessRoutes = pageRouteToPagelessRoutes
-          .putIfAbsent(
-          previousOldPageRouteEntry,
-            () => <_RouteEntry>[]
-        );
-        pagelessRoutes.add(potentialEntryToRemove);
-        assert(() {
-          potentialEntryToRemove._debugWaitingForExitDecision = previousOldPageRouteEntry._debugWaitingForExitDecision;
-          return true;
-        }());
-        continue;
-      }
-
-      final Page<dynamic> potentialPageToRemove = potentialEntryToRemove.route.settings as Page<dynamic>;
-      // Marks for transition delegate to remove if this old page does not have
-      // a key or was not taken during updating the middle of new page.
-      if (
-        potentialPageToRemove.key == null ||
-        pageKeyToOldEntry.containsKey(potentialPageToRemove.key)
-      ) {
-        locationToExitingPageRoute[previousOldPageRouteEntry] = potentialEntryToRemove;
-        assert(() {
-          potentialEntryToRemove._debugWaitingForExitDecision = true;
-          return true;
-        }());
-      }
-      previousOldPageRouteEntry = potentialEntryToRemove;
-    }
-
-    // We've scanned the whole list.
-    assert(oldEntriesBottom == oldEntriesTop + 1);
-    assert(newPagesBottom == newPagesTop + 1);
-    newPagesTop = widget.pages.length - 1;
-    oldEntriesTop = _history.length - 1;
-    // Verifies we either reach the bottom or the oldEntriesBottom must be updatable
-    // by newPagesBottom.
-    assert(() {
-      if (oldEntriesBottom <= oldEntriesTop)
-        return newPagesBottom <= newPagesTop &&
-          _history[oldEntriesBottom].hasPage &&
-          _history[oldEntriesBottom].canUpdateFrom(widget.pages[newPagesBottom]);
-      else
-        return newPagesBottom > newPagesTop;
-    }());
-
-    // Updates the top of the list.
-    while ((oldEntriesBottom <= oldEntriesTop) && (newPagesBottom <= newPagesTop)) {
-      final _RouteEntry oldEntry = _history[oldEntriesBottom];
-      assert(oldEntry != null && oldEntry.currentState != _RouteLifecycle.disposed);
-      if (!oldEntry.hasPage) {
-        assert(previousOldPageRouteEntry != null);
-        final List<_RouteEntry> pagelessRoutes = pageRouteToPagelessRoutes
-          .putIfAbsent(
-          previousOldPageRouteEntry,
-            () => <_RouteEntry>[]
-        );
-        pagelessRoutes.add(oldEntry);
-        continue;
-      }
-      previousOldPageRouteEntry = oldEntry;
-      final Page<dynamic> newPage = widget.pages[newPagesBottom];
-      assert(oldEntry.canUpdateFrom(newPage));
-      oldEntry.route._updateSettings(newPage);
-      newHistory.add(oldEntry);
-      oldEntriesBottom += 1;
-      newPagesBottom += 1;
-    }
-
-    // Finally, uses transition delegate to make explicit decision if needed.
-    needsExplicitDecision = needsExplicitDecision || locationToExitingPageRoute.isNotEmpty;
-    Iterable<_RouteEntry> results = newHistory;
-    if (needsExplicitDecision) {
-      results = widget.transitionDelegate._transition(
-        newPageRouteHistory: newHistory,
-        locationToExitingPageRoute: locationToExitingPageRoute,
-        pageRouteToPagelessRoutes: pageRouteToPagelessRoutes,
-      ).cast<_RouteEntry>();
-    }
-    _history = <_RouteEntry>[];
-    // Adds the leading pageless routes if there is any.
-    if (pageRouteToPagelessRoutes.containsKey(null)) {
-      _history.addAll(pageRouteToPagelessRoutes[null]);
-    }
-    for (final _RouteEntry result in results) {
-      _history.add(result);
-      if (pageRouteToPagelessRoutes.containsKey(result)) {
-        _history.addAll(pageRouteToPagelessRoutes[result]);
-      }
-    }
-    assert(() {_debugUpdatingPage = false; return true;}());
-    assert(() { _debugLocked = true; return true; }());
-    _flushHistoryUpdates();
-    assert(() { _debugLocked = false; return true; }());
-  }
-
   void _flushHistoryUpdates({bool rearrangeOverlay = true}) {
-    assert(_debugLocked && !_debugUpdatingPage);
+    assert(_debugLocked);
     // Clean up the list, sending updates to the routes that changed. Notably,
     // we don't send the didChangePrevious/didChangeNext updates to those that
     // did not change at this point, because we're not yet sure exactly what the
@@ -2941,7 +1987,7 @@
     _RouteEntry next;
     _RouteEntry entry = _history[index];
     _RouteEntry previous = index > 0 ? _history[index - 1] : null;
-    bool canRemoveOrAdd = false; // Whether there is a fully opaque route on top to silently remove or add route underneath.
+    bool canRemove = false;
     Route<dynamic> poppedRoute; // The route that should trigger didPopNext on the top active route.
     bool seenTopActiveRoute = false; // Whether we've seen the route that would get didPopNext.
     final List<_RouteEntry> toBeDisposed = <_RouteEntry>[];
@@ -2951,21 +1997,12 @@
           assert(rearrangeOverlay);
           entry.handleAdd(
             navigator: this,
+            previous: previous?.route,
+            previousPresent: _getRouteBefore(index - 1, _RouteEntry.isPresentPredicate)?.route,
+            isNewFirst: next == null,
           );
-          assert(entry.currentState == _RouteLifecycle.adding);
+          assert(entry.currentState == _RouteLifecycle.idle);
           continue;
-        case _RouteLifecycle.adding:
-          if (canRemoveOrAdd || next == null) {
-            entry.didAdd(
-              navigator: this,
-              previous: previous?.route,
-              previousPresent: _getRouteBefore(index - 1, _RouteEntry.isPresentPredicate)?.route,
-              isNewFirst: next == null
-            );
-            assert(entry.currentState == _RouteLifecycle.idle);
-            continue;
-          }
-          break;
         case _RouteLifecycle.push:
         case _RouteLifecycle.pushReplace:
         case _RouteLifecycle.replace:
@@ -2994,7 +2031,7 @@
           seenTopActiveRoute = true;
           // This route is idle, so we are allowed to remove subsequent (earlier)
           // routes that are waiting to be removed silently:
-          canRemoveOrAdd = true;
+          canRemove = true;
           break;
         case _RouteLifecycle.pop:
           if (!seenTopActiveRoute) {
@@ -3007,7 +2044,6 @@
             previousPresent: _getRouteBefore(index, _RouteEntry.willBePresentPredicate)?.route,
           );
           assert(entry.currentState == _RouteLifecycle.popping);
-          canRemoveOrAdd = true;
           break;
         case _RouteLifecycle.popping:
           // Will exit this state when animation completes.
@@ -3025,7 +2061,7 @@
           assert(entry.currentState == _RouteLifecycle.removing);
           continue;
         case _RouteLifecycle.removing:
-          if (!canRemoveOrAdd && next != null) {
+          if (!canRemove && next != null) {
             // We aren't allowed to remove this route yet.
             break;
           }
@@ -3037,7 +2073,6 @@
           entry = next;
           break;
         case _RouteLifecycle.disposed:
-        case _RouteLifecycle.staging:
           assert(false);
           break;
       }
@@ -3073,11 +2108,7 @@
     int index = _history.length - 1;
     while (index >= 0) {
       final _RouteEntry entry = _history[index];
-      if (!entry.suitableForAnnouncement) {
-        index -= 1;
-        continue;
-      }
-      final _RouteEntry next = _getRouteAfter(index + 1, _RouteEntry.suitableForTransitionAnimationPredicate);
+      final _RouteEntry next = _getRouteAfter(index + 1, _RouteEntry.isPresentPredicate);
 
       if (next?.route != entry.lastAnnouncedNextRoute) {
         if (entry.shouldAnnounceChangeToNext(next?.route)) {
@@ -3085,7 +2116,7 @@
         }
         entry.lastAnnouncedNextRoute = next?.route;
       }
-      final _RouteEntry previous = _getRouteBefore(index - 1, _RouteEntry.suitableForTransitionAnimationPredicate);
+      final _RouteEntry previous = _getRouteBefore(index - 1, _RouteEntry.isPresentPredicate);
       if (previous?.route != entry.lastAnnouncedPreviousRoute) {
         entry.route.didChangePrevious(previous?.route);
         entry.lastAnnouncedPreviousRoute = previous?.route;
@@ -3584,12 +2615,7 @@
       return true;
     }());
     final _RouteEntry entry = _history.lastWhere(_RouteEntry.isPresentPredicate);
-    if (entry.hasPage) {
-      if (widget.onPopPage(entry.route, result))
-        entry.currentState = _RouteLifecycle.pop;
-    } else {
-      entry.pop<T>(result);
-    }
+    entry.pop<T>(result);
     if (entry.currentState == _RouteLifecycle.pop) {
       // Flush the history if the route actually wants to be popped (the pop
       // wasn't handled internally).
diff --git a/packages/flutter/test/widgets/navigator_test.dart b/packages/flutter/test/widgets/navigator_test.dart
index 51855e6..cc01fdb 100644
--- a/packages/flutter/test/widgets/navigator_test.dart
+++ b/packages/flutter/test/widgets/navigator_test.dart
@@ -1708,666 +1708,6 @@
     await tester.pump(const Duration(seconds: 1));
     expect(tickCount, 4);
   });
-
-  group('Page api', (){
-    Widget buildNavigator(
-      List<Page<dynamic>> pages,
-      PopPageCallback onPopPage, [
-        GlobalKey<NavigatorState> key,
-        TransitionDelegate<dynamic> transitionDelegate
-      ]) {
-      return MediaQuery(
-        data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
-        child: Localizations(
-          locale: const Locale('en', 'US'),
-          delegates: const <LocalizationsDelegate<dynamic>>[
-            DefaultMaterialLocalizations.delegate,
-            DefaultWidgetsLocalizations.delegate
-          ],
-          child: Directionality(
-            textDirection: TextDirection.ltr,
-            child: Navigator(
-              key: key,
-              pages: pages,
-              onPopPage: onPopPage,
-              transitionDelegate: transitionDelegate ?? const DefaultTransitionDelegate<dynamic>(),
-            ),
-          ),
-        ),
-      );
-    }
-
-    testWidgets('can initialize with pages list', (WidgetTester tester) async {
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      final List<TestPage> myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name:'initial'),
-        const TestPage(key: ValueKey<String>('2'), name:'second'),
-        const TestPage(key: ValueKey<String>('3'), name:'third'),
-      ];
-
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      expect(find.text('third'), findsOneWidget);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('initial'), findsNothing);
-
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('third'), findsNothing);
-      expect(find.text('second'), findsOneWidget);
-      expect(find.text('initial'), findsNothing);
-
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('third'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('initial'), findsOneWidget);
-    });
-
-    testWidgets('can push and pop pages using page api', (WidgetTester tester) async {
-      Animation<double> secondaryAnimationOfRouteOne;
-      Animation<double> primaryAnimationOfRouteOne;
-      Animation<double> secondaryAnimationOfRouteTwo;
-      Animation<double> primaryAnimationOfRouteTwo;
-      Animation<double> secondaryAnimationOfRouteThree;
-      Animation<double> primaryAnimationOfRouteThree;
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      List<Page<dynamic>> myPages = <Page<dynamic>>[
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('1'),
-          name:'initial',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteOne = secondaryAnimation;
-                primaryAnimationOfRouteOne = animation;
-                return const Text('initial');
-              },
-            );
-          },
-        ),
-      ];
-
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      expect(find.text('initial'), findsOneWidget);
-
-      myPages = <Page<dynamic>>[
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('1'),
-          name:'initial',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteOne = secondaryAnimation;
-                primaryAnimationOfRouteOne = animation;
-                return const Text('initial');
-              },
-            );
-          },
-        ),
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('2'),
-          name:'second',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteTwo = secondaryAnimation;
-                primaryAnimationOfRouteTwo = animation;
-                return const Text('second');
-              },
-            );
-          },
-        ),
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('3'),
-          name:'third',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteThree = secondaryAnimation;
-                primaryAnimationOfRouteThree = animation;
-                return const Text('third');
-              },
-            );
-          },
-        )
-      ];
-
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      // The third page is transitioning, and the secondary animation of first
-      // page should chain with the third page. The animation of second page
-      // won't start until the third page finishes transition.
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.forward);
-
-      await tester.pump(const Duration(milliseconds: 30));
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.value, 0.1);
-      await tester.pumpAndSettle();
-      // After transition finishes, the routes' animations are correctly chained.
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(find.text('third'), findsOneWidget);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('initial'), findsNothing);
-      // Starts pops the pages using page api and verify the animations chain
-      // correctly.
-
-      myPages = <Page<dynamic>>[
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('1'),
-          name:'initial',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteOne = secondaryAnimation;
-                primaryAnimationOfRouteOne = animation;
-                return const Text('initial');
-              },
-            );
-          },
-        ),
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('2'),
-          name:'second',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteTwo = secondaryAnimation;
-                primaryAnimationOfRouteTwo = animation;
-                return const Text('second');
-              },
-            );
-          },
-        ),
-      ];
-
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      await tester.pump(const Duration(milliseconds: 30));
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.value, 0.9);
-      await tester.pumpAndSettle();
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-    });
-
-    testWidgets('can modify routes history and secondary animation still works', (WidgetTester tester) async {
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      Animation<double> secondaryAnimationOfRouteOne;
-      Animation<double> primaryAnimationOfRouteOne;
-      Animation<double> secondaryAnimationOfRouteTwo;
-      Animation<double> primaryAnimationOfRouteTwo;
-      Animation<double> secondaryAnimationOfRouteThree;
-      Animation<double> primaryAnimationOfRouteThree;
-      List<Page<dynamic>> myPages = <CustomBuilderPage<void>>[
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('1'),
-          name:'initial',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteOne = secondaryAnimation;
-                primaryAnimationOfRouteOne = animation;
-                return const Text('initial');
-              },
-            );
-          },
-        ),
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('2'),
-          name:'second',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteTwo = secondaryAnimation;
-                primaryAnimationOfRouteTwo = animation;
-                return const Text('second');
-              },
-            );
-          },
-        ),
-        CustomBuilderPage<void>(
-          key: const ValueKey<String>('3'),
-          name:'third',
-          routeBuilder: (BuildContext context, RouteSettings settings) {
-            return PageRouteBuilder<void>(
-              settings: settings,
-              pageBuilder: (_, Animation<double> animation, Animation<double> secondaryAnimation) {
-                secondaryAnimationOfRouteThree = secondaryAnimation;
-                primaryAnimationOfRouteThree = animation;
-                return const Text('third');
-              },
-            );
-          },
-        ),
-      ];
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      expect(find.text('third'), findsOneWidget);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('initial'), findsNothing);
-      expect(secondaryAnimationOfRouteOne.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteThree.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteThree.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-
-      myPages = myPages.reversed.toList();
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      // Reversed routes are still chained up correctly.
-      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.completed);
-
-      navigator.currentState.pop();
-      await tester.pump();
-      await tester.pump(const Duration(milliseconds: 30));
-      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteOne.value, 0.9);
-      await tester.pumpAndSettle();
-      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-
-      navigator.currentState.pop();
-      await tester.pump();
-      await tester.pump(const Duration(milliseconds: 30));
-      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
-      expect(primaryAnimationOfRouteTwo.value, 0.9);
-      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      await tester.pumpAndSettle();
-      expect(secondaryAnimationOfRouteThree.value, primaryAnimationOfRouteTwo.value);
-      expect(primaryAnimationOfRouteThree.status, AnimationStatus.completed);
-      expect(secondaryAnimationOfRouteTwo.value, primaryAnimationOfRouteOne.value);
-      expect(primaryAnimationOfRouteTwo.status, AnimationStatus.dismissed);
-      expect(secondaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-      expect(primaryAnimationOfRouteOne.status, AnimationStatus.dismissed);
-    });
-
-    testWidgets('can work with pageless route', (WidgetTester tester) async {
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      List<TestPage> myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name:'initial'),
-        const TestPage(key: ValueKey<String>('2'), name:'second'),
-      ];
-
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      expect(find.text('second'), findsOneWidget);
-      expect(find.text('initial'), findsNothing);
-      // Pushes two pageless routes to second page route
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless1'),
-          settings: null,
-        )
-      );
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless2'),
-          settings: null,
-        )
-      );
-      await tester.pumpAndSettle();
-      // Now the history should look like
-      // [initial, second, second-pageless1, second-pageless2].
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsOneWidget);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name:'initial'),
-        const TestPage(key: ValueKey<String>('2'), name:'second'),
-        const TestPage(key: ValueKey<String>('3'), name:'third'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(find.text('third'), findsOneWidget);
-
-      // Pushes one pageless routes to third page route
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('third-pageless1'),
-          settings: null,
-        )
-      );
-      await tester.pumpAndSettle();
-      // Now the history should look like
-      // [initial, second, second-pageless1, second-pageless2, third, third-pageless1].
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsOneWidget);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name:'initial'),
-        const TestPage(key: ValueKey<String>('3'), name:'third'),
-        const TestPage(key: ValueKey<String>('2'), name:'second'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      // Swaps the order without any adding or removing should not trigger any
-      // transition. The routes should update without a pumpAndSettle
-      // Now the history should look like
-      // [initial, third, third-pageless1, second, second-pageless1, second-pageless2].
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsOneWidget);
-      // Pops the route one by one to make sure the order is correct.
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsOneWidget);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(myPages.length, 3);
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsNothing);
-      expect(find.text('second'), findsOneWidget);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(myPages.length, 3);
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsOneWidget);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(myPages.length, 2);
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsNothing);
-      expect(find.text('third'), findsOneWidget);
-      expect(find.text('third-pageless1'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(myPages.length, 2);
-      navigator.currentState.pop();
-      await tester.pumpAndSettle();
-      expect(find.text('initial'), findsOneWidget);
-      expect(find.text('third'), findsNothing);
-      expect(find.text('third-pageless1'), findsNothing);
-      expect(find.text('second'), findsNothing);
-      expect(find.text('second-pageless1'), findsNothing);
-      expect(find.text('second-pageless2'), findsNothing);
-      expect(myPages.length, 1);
-    });
-
-    testWidgets('complex case 1', (WidgetTester tester) async {
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      List<TestPage> myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-      ];
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-
-      // Add initial page route with one pageless route.
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      bool initialPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('initial-pageless1'),
-          settings: null,
-        )
-      ).then((_) => initialPageless1Completed = true);
-      await tester.pumpAndSettle();
-
-      // Pushes second page route with two pageless routes.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      await tester.pumpAndSettle();
-      bool secondPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless1'),
-          settings: null,
-        )
-      ).then((_) => secondPageless1Completed = true);
-      await tester.pumpAndSettle();
-      bool secondPageless2Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless2'),
-          settings: null,
-        )
-      ).then((_) => secondPageless2Completed = true);
-      await tester.pumpAndSettle();
-
-      // Pushes third page route with one pageless route.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      await tester.pumpAndSettle();
-      bool thirdPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('third-pageless1'),
-          settings: null,
-        )
-      ).then((_) => thirdPageless1Completed = true);
-      await tester.pumpAndSettle();
-
-      // Nothing has been popped.
-      expect(initialPageless1Completed, false);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-
-      // Switches order and removes the initial page route.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      // The pageless route of initial page route should be completed.
-      expect(initialPageless1Completed, true);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      await tester.pumpAndSettle();
-      expect(secondPageless1Completed, true);
-      expect(secondPageless2Completed, true);
-      expect(thirdPageless1Completed, false);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('4'), name: 'forth'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator));
-      expect(thirdPageless1Completed, true);
-      await tester.pumpAndSettle();
-      expect(find.text('forth'), findsOneWidget);
-    });
-
-    testWidgets('complex case 1 - with always remove transition delegate', (WidgetTester tester) async {
-      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
-      final AlwaysRemoveTransitionDelegate transitionDelegate = AlwaysRemoveTransitionDelegate();
-      List<TestPage> myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-      ];
-      bool onPopPage(Route<dynamic> route, dynamic result) {
-        myPages.removeWhere((Page<dynamic> page) => route.settings == page);
-        return route.didPop(result);
-      }
-
-      // Add initial page route with one pageless route.
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      bool initialPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('initial-pageless1'),
-          settings: null,
-        )
-      ).then((_) => initialPageless1Completed = true);
-      await tester.pumpAndSettle();
-
-      // Pushes second page route with two pageless routes.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      bool secondPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless1'),
-          settings: null,
-        )
-      ).then((_) => secondPageless1Completed = true);
-      await tester.pumpAndSettle();
-      bool secondPageless2Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('second-pageless2'),
-          settings: null,
-        )
-      ).then((_) => secondPageless2Completed = true);
-      await tester.pumpAndSettle();
-
-      // Pushes third page route with one pageless route.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('1'), name: 'initial'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      bool thirdPageless1Completed = false;
-      navigator.currentState.push(
-        MaterialPageRoute<void>(
-          builder: (BuildContext context) => const Text('third-pageless1'),
-          settings: null,
-        )
-      ).then((_) => thirdPageless1Completed = true);
-      await tester.pumpAndSettle();
-
-      // Nothing has been popped.
-      expect(initialPageless1Completed, false);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-
-      // Switches order and removes the initial page route.
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-        const TestPage(key: ValueKey<String>('2'), name: 'second'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      // The pageless route of initial page route should be removed without complete.
-      expect(initialPageless1Completed, false);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('3'), name: 'third'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      await tester.pumpAndSettle();
-      expect(initialPageless1Completed, false);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-
-      myPages = <TestPage>[
-        const TestPage(key: ValueKey<String>('4'), name: 'forth'),
-      ];
-      await tester.pumpWidget(buildNavigator(myPages, onPopPage, navigator, transitionDelegate));
-      await tester.pump();
-      expect(initialPageless1Completed, false);
-      expect(secondPageless1Completed, false);
-      expect(secondPageless2Completed, false);
-      expect(thirdPageless1Completed, false);
-      expect(find.text('forth'), findsOneWidget);
-    });
-
-  });
 }
 
 class _TickingWidget extends StatefulWidget {
@@ -2402,62 +1742,6 @@
   }
 }
 
-class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> {
-  @override
-  Iterable<RouteTransitionRecord> resolve({
-    List<RouteTransitionRecord> newPageRouteHistory,
-    Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
-    Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
-  }) {
-    final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
-    void handleExitingRoute(RouteTransitionRecord location) {
-      if (!locationToExitingPageRoute.containsKey(location))
-        return;
-
-      final RouteTransitionRecord exitingPageRoute = locationToExitingPageRoute[location];
-      final bool hasPagelessRoute = pageRouteToPagelessRoutes.containsKey(exitingPageRoute);
-
-      exitingPageRoute.markForRemove();
-      results.add(exitingPageRoute);
-
-      if (hasPagelessRoute) {
-        final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
-        for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
-          pagelessRoute.markForRemove();
-        }
-      }
-      handleExitingRoute(exitingPageRoute);
-    }
-    handleExitingRoute(null);
-
-    for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
-      if (pageRoute.isEntering) {
-        pageRoute.markForAdd();
-      }
-      results.add(pageRoute);
-      handleExitingRoute(pageRoute);
-
-    }
-    return results;
-  }
-}
-
-class TestPage extends Page<void> {
-  const TestPage({
-    LocalKey key,
-    String name,
-    Object arguments,
-  }) : super(key: key, name: name, arguments: arguments);
-
-  @override
-  Route<void> createRoute(BuildContext context) {
-    return MaterialPageRoute<void>(
-      builder: (BuildContext context) => Text(name),
-      settings: this,
-    );
-  }
-}
-
 class NoAnimationPageRoute extends PageRouteBuilder<void> {
   NoAnimationPageRoute({WidgetBuilder pageBuilder})
       : super(pageBuilder: (BuildContext context, __, ___) {
