anchor.diff:        } else {
           _logger.info("Unhandled path: $path");
         }
  -      completer.complete();
  -    }
  -    return completer.future;
  -  }
  -
  -  _processNewRoute(String path, String tailPath, Match match, _Route route,
  -                   Completer completer) {
  +    }
  +    return new Future.value();
  +  }
  +
  +  Future _processNewRoute(String path, String tailPath, Match match,
  +                          _Route route) {
       var headPath = path.substring(0, match.end);
  -    var event = new RouteEvent(headPath,
  -        (_) => throw new StateError('Cannot veto on enter!'));
  +    var event = new RouteEvent(headPath);
       // before we make this a new current route, leave the old
  -    _leaveCurrentRoute(event).then((bool allowNavigation) {
  +    return _leaveCurrentRoute(event).then((bool allowNavigation) {
         if (allowNavigation) {
           _currentRoute = route;
           if (route.enter != null) {
             route.enter(event);
           }
           if (route.child != null) {
  -          route.child.handle(tailPath).then((_) {
  -            completer.complete();
  -          });
  -        } else {
  -          completer.complete();
  +          return route.child.handle(tailPath);
           }
  -      } else {
  -        completer.complete();
         }
       });
     }
   
  -  bool reduceBools(bool a, bool b) => a && b;
  -
  -  Future<bool> _leaveCurrentRoute(RouteEvent e) {
  -    Completer<bool> completer = new Completer<bool>();
  +  Future<bool> _leaveCurrentRoute(RouteEvent e) =>
  +      Future.wait(_leaveCurrentRouteHelper(e))
  +          .then((values) => values.fold(true, (c, v) => c && v));
  +
  +  List<Future<bool>> _leaveCurrentRouteHelper(RouteEvent e) {
  +    var futures = [];
       if (_currentRoute != null) {
         List<Future<bool>> pendingResponses = <Future<bool>>[];
  -      // We create a copy of the route event with a new veto callback
  -      var event = e._clone((Future<bool> r) => pendingResponses.add(r));
  -
  +      // We create a copy of the route event
  +      var event = e._clone();
         if (_currentRoute.leave != null) {
           _currentRoute.leave(event);
         }
  +      if (event._allowLeaveFuture != null) {
  +        futures.add(event._allowLeaveFuture);
  +      }
         if (_currentRoute.child != null) {
  -        _currentRoute.child._leaveCurrentRoute(event).then((allowNavigation) {
  -          if (!allowNavigation) {
  -            completer.complete(false);
  -          } else {
  -            _completePendingResponses(pendingResponses, completer);
  -          }
  -        });
  -      } else {
  -        _completePendingResponses(pendingResponses, completer);
  -      }
  -    } else {
  -      completer.complete(true);
  -    }
  -    return completer.future;
  -  }
  -
  -  _completePendingResponses(List<Future<bool>> pendingResponses,
  -                            Completer<bool> completer) {
  -    if (pendingResponses.length == 0) {
  -      completer.complete(true);
  -    } else {
  -      Future.wait(pendingResponses).then((List<bool> responses) {
  -        completer.complete(responses.reduce(reduceBools));
  -      });
  -    }
  -    return true;
  +        futures.addAll(_currentRoute.child._leaveCurrentRoute(event));
  +      }
  +    }
  +    return futures;
     }
   
     /**
  
positive.code: 
  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);
  }
  
  abstract class Routable {
  
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");
  