     prefixPattern = new RegExp("^#{@joinPath('/', Batman.pathPrefix)}")
     result = fullPath.replace(prefixPattern, '')
     result
-  handleCurrentURL: =>
-    url = @getCurrentURL()
-    return if url is @cachedURL
-    @dispatch(@cachedURL = url)
-  
   redirect: (params) ->
     url = super
-    @cachedURL = url
     window.history.pushState(null,'',@urlFor(url))
 
 class Batman.HashHistory extends Batman.HistoryManager
   HASH_PREFIX: '#!'
-  start: =>
-    return if typeof window is 'undefined'
-    return if @started
-    @started = yes
-    if 'onhashchange' of window
+  if 'onhashchange' of window
+    @::startWatching = ->
       $addEventListener window, 'hashchange', @handleCurrentURL
-    else
+    @::stopWatching = ->
+      $removeEventListener window, 'hashchange', @handleCurrentURL
+  else
+    @::startWatching = ->
       @interval = setInterval @handleCurrentURL, 100
-    Batman.currentApp.prevent 'ready'
-    $setImmediate =>
-      @handleCurrentURL()
-      Batman.currentApp.allow 'ready'
-      Batman.currentApp.fire 'ready'
-
-  stop: =>
-    if @interval
+    @::stopWatching = ->
       @interval = clearInterval @interval
-    else
-      $removeEventListener window, 'hashchange', @handleCurrentURL
-    @started = no
 
   urlFor: (url) -> @HASH_PREFIX + url
-  
   getCurrentURL: -> window.location.hash.replace(@HASH_PREFIX, '')
-  
-  handleCurrentURL: =>
-    hash = @getCurrentURL()
-    return if hash is @cachedHash
-    @dispatch(@cachedHash = hash)
-
   redirect: (params) ->
     url = super
-    @cachedHash = url
     window.location.hash = @urlFor(url)
 
 Batman.HistoryManager.defaultClass = if Batman.StateHistory.isSupported()

  redirect: (url) ->
    if $typeOf(url) isnt 'String'
      url = @app.dispatcher.findUrl(url)
    @dispatch url
  joinPath: (segments...) ->
    segments = for seg, i in segments
      seg = "/#{seg}" unless i is 0 or seg.charAt(0) is '/'

class Batman.HistoryManager
  @forApp: (app) -> app.historyManager or new @defaultClass(app)
  constructor: (@app) ->
  start: ->
    return if typeof window is 'undefined'
    return if @started
    @started = yes
    @startWatching()
    Batman.currentApp.prevent 'ready'
    $setImmediate =>
      @handleCurrentURL()
      Batman.currentApp.allow 'ready'
      Batman.currentApp.fire 'ready'
  stop: ->
    @stopWatching()
    @started = no
  handleCurrentURL: =>
    url = @getCurrentURL()
    return if url is @cachedURL
    @dispatch(@cachedURL = url)
  dispatch: (url) ->
    url = @joinPath('/', url)
    @app.dispatcher.dispatch url
