anchor.diff:      scrollToHash(url.hash);
     }
   
  -  router.fireEvent('activate-route-end', eventDetail, router);
  -  router.fireEvent('activate-route-end', eventDetail, eventDetail['route']);
  +  _fireEvent('activate-route-end', eventDetail, router);
  +  _fireEvent('activate-route-end', eventDetail, eventDetail['route']);
   }
   
   /// Call when the previousRoute has finished the transition animation out.
  
positive.code:     'route': route,
      'oldRoute': router._activeRoute
    };
    if (!router.fireEvent('activate-route-start', eventDetail, router)) {
      //TODO: are dashes allowed in Polymer event names?
      return;
    }
    if (!router.fireEvent('activate-route-start', eventDetail, route)) {
      return;
    }
  
  
negative.code:       }
      }
  
      _fireEvent('route-not-found', eventDetail, this);
    }
  }
  
  /*---------------------------------------------------------------------------*/
  
  /// fireEvent(type, detail, node) - Fire a new CustomEvent(type, detail) on the node
  ///
  /// listen with document.querySelector('app-router').addEventListener(type, function(event) {
  ///   event.detail, event.preventDefault()
  /// })
  bool _fireEvent(String type, Object detail, Node node) {
    CustomEvent event =
        new CustomEvent(type, detail: detail, canBubble: false, cancelable: true);
    return node.dispatchEvent(event);
  }
  
  /// Activate the route
  void activateRoute(WebRouter router, WebRoute route, RouteUri url) {
  