anchor.diff:  
   class RouteEvent {
     final String path;
  -  Function _responseCall;
  -
  -  RouteEvent(this.path, Function this._responseCall);
  -
  -  void allowLeave(Future<bool> veto) {
  -    _responseCall(veto);
  -  }
  -
  -  RouteEvent _clone(Function newRespCall) => new RouteEvent(path, newRespCall);
  +  Future<bool> _allowLeaveFuture;
  +
  +  RouteEvent(this.path);
  +
  +  void allowLeave(Future<bool> allow) {
  +    _allowLeaveFuture = allow;
  +  }
  +
  +  RouteEvent _clone() => new RouteEvent(path);
   }
   
   abstract class Routable {
  
positive.code:       var match = prefixMatch(route.path, path);
        var tailPath = path.substring(match.end);
        if (!identical(route, _currentRoute)) {
          _processNewRoute(path, tailPath, match, route, completer);
        } else {
          if (route.child != null) {
            route.child.handle(tailPath).then((_) {
              completer.complete();
            });
          } else {
            completer.complete();
          }
        }
      } else {
        var url = _getUrl(path);
        if (url != null) {
          // always give handlers a non-fragment path
  
negative.code:    * with the path version of the URL by converting the # to a /.
     */
    Future handle(String path) {
      List matchingRoutes = _routes.where(
          (r) => matchesPrefix(r.path, path)).toList();
      if (!matchingRoutes.isEmpty) {
        if (matchingRoutes.length > 1) {
          _logger.warning("More than one route matches $path");
  