 
     @terminal.sessionEndedCallback = (sessions) =>
       @emit "WebTerm.terminated"
+      @clearConnectionAttempts()
 
     @terminal.setTitleCallback = (title) =>
       #@tabPane.setTitle title

      @terminal.setFocused false
      KD.getSingleton('windowController').removeLayer @

    $(window).on "blur", =>
      @terminal.setFocused false



    @appStorage = new AppStorage 'WebTerm', '1.0'
    @appStorage.fetchStorage =>
      @appStorage.setValue 'font'      , 'ubuntu-mono' if not @appStorage.getValue('font')?
      @appStorage.setValue 'fontSize'  , 14 if not @appStorage.getValue('fontSize')?
      @appStorage.setValue 'theme'     , 'green-on-black' if not @appStorage.getValue('theme')?
      @appStorage.setValue 'visualBell', false if not @appStorage.getValue('visualBell')?
      @appStorage.setValue 'scrollback', 1000 if not @appStorage.getValue('scrollback')?
      @updateSettings()

      delegateOptions = @getDelegate().getOptions()
      myOptions       = @getOptions()

      KD.getSingleton("vmController").run
        method        : "webterm.connect",
        vmName        : delegateOptions.vmName
        withArgs      :
          remote      : @terminal.clientInterface
          sizeX       : @terminal.sizeX
          sizeY       : @terminal.sizeY
          joinUser    : myOptions.joinUser or delegateOptions.joinUser
          session     : myOptions.session  or delegateOptions.session
          noScreen    : delegateOptions.noScreen
      , (err, remote) =>
        if err
          warn err
          if err.message is "Invalid session identifier."
            return @reinitializeWebTerm()

        @terminal.eventHandler = (data)=> @emit "WebTermEvent", data
        @terminal.server       = remote
        @setKeyView()
        @emit "WebTermConnected", remote
        @sessionId = remote.session

    KD.getSingleton("status").once "reconnected", => @handleReconnect()

    kiteErrorCallback = (err) =>
      @reconnected               = no
      {code, serviceGenericName} = err

      if code is 503 and serviceGenericName.indexOf("kite-os") is 0
        @reconnectAttemptFailed serviceGenericName, @getDelegate().getOption "vmName"

    kiteController = KD.getSingleton "kiteController"
    kiteController.on "KiteError", kiteErrorCallback

    @on "KiteErrorBindingNeedsToBeRemoved", =>
      kiteController.off "KiteError", kiteErrorCallback

  reconnectAttemptFailed: (serviceGenericName, vmName) ->
    return  if @reconnected or not serviceGenericName

    kiteController = KD.getSingleton "kiteController"
    [prefix, kiteType, kiteRegion] = serviceGenericName.split "-"
    serviceName = "~#{kiteType}-#{kiteRegion}~#{vmName}"

    @setBackoffTimeout(
      @bound "atttemptToReconnect"
      @bound "handleConnectionFailure"
    )

    kiteController.kiteInstances[serviceName]?.cycleChannel()

  atttemptToReconnect: ->
    return  if @reconnected
    @reconnectingNotification ?= new KDNotificationView
      type      : "mini"
      title     : "Trying to reconnect your Terminal"
      duration  : 2 * 60 * 1000 # 2 mins
      container : @container

    vmController = KD.getSingleton "vmController"
    hasResponse  = no

    vmController.info @getDelegate().getOption("vmName"), (err, res) =>
      hasResponse = yes
      @handleReconnect()
      @clearConnectionAttempts()

    @utils.wait 500, => @reconnectAttemptFailed() unless hasResponse

  clearConnectionAttempts: ->
    @emit "KiteErrorBindingNeedsToBeRemoved"
    @clearBackoffTimeout()

  handleReconnect: ->
    return  if @reconnected
    @clearConnectionAttempts()
    options =
      session  : @sessionId
      joinUser : KD.nick()

    @reinitializeWebTerm options
    @reconnectingNotification?.destroy()
    @reconnected = yes

  reinitializeWebTerm: (options = {}) ->
    options.delegate = @getDelegate()
    @addSubView webterm = new WebTermView options

    webterm.on "WebTermConnected", =>
      @getSubViews().first.destroy() # TODO: refactor this, don't use subviews

  handleConnectionFailure: ->
    return if @failedToReconnect
    @reconnectingNotification?.destroy()
    @reconnected       = no
    @failedToReconnect = yes
    @clearConnectionAttempts()
    new KDNotificationView
      type      : "mini"
      title     : "Sorry, something is wrong with our backend."
      container : @container
      cssClass  : "error"
      duration  : 15 * 1000 # 15 secs

  destroy: ->
    super
