       @previousLocation = Turbolinks.Location.box(previousLocation)
       @location = Turbolinks.Location.box(location)
       @adapter = @controller.adapter
+      @state = "initialized"
   
   start: ->
-    unless @started
-      @started = true
+    if @state is "initialized"
+      @state = "started"
       @adapter.visitStarted(this)
 
   cancel: ->
-    if @started and not @canceled
+    if @state is "started"
       @request?.cancel()
-      @canceled = true
+      @state = "canceled"
+
+  complete: ->
+    if @state is "started"
+      @state = "completed"
+      @adapter.visitCompleted?(this)
+      @resolve()
+
+  fail: ->
+    if @state is "started"
+      @state = "failed"
+      @adapter.visitFailed?(this)
+      @reject()
 
   then: ->
     @promise.then(arguments...)

      if @snapshotRestored = @controller.restoreSnapshotForLocationWithAction(@location, @action)
        @adapter.visitSnapshotRestored?(this)
      unless @shouldIssueRequest()
        @resolve()

  loadResponse: ->
    if @response?
      @saveSnapshot()
      if @request.failed
        @controller.loadErrorResponse(@response)
        @reject()
      else
        @controller.loadResponse(@response)
        @resolve()
      @adapter.visitResponseLoaded?(this)

  # HTTP Request delegate
  

  saveSnapshot: ->
    unless @snapshotSaved
      @controller.saveSnapshotForLocation(@previousLocation)
      @snapshotSaved = true
