           func tab.id, { file: file, allFrames: contentScripts.all_frames }, checkLastRuntimeError
 
 currentVersion = Utils.getCurrentVersion()
-tabQueue = {} # windowId -> Array
 tabInfoMap = {} # tabId -> object with various tab properties
 keyQueue = "" # Queue of keys typed
 validFirstKeys = {}

  openTabInfo = tabInfoMap[tabId]
  updatePositionsAndWindowsForAllTabsInWindow(openTabInfo.windowId)

  # If we restore pages that content scripts can't run on, they'll ignore Vimium keystrokes when they
  # reappear. Pretend they never existed and adjust tab indices accordingly. Could possibly expand this into
  # a blacklist in the future.
  unless chrome.sessions
    if (/^(chrome|view-source:)[^:]*:\/\/.*/.test(openTabInfo.url))
      for own i of tabQueue[openTabInfo.windowId]
        if (tabQueue[openTabInfo.windowId][i].positionIndex > openTabInfo.positionIndex)
          tabQueue[openTabInfo.windowId][i].positionIndex--
      return

    if (tabQueue[openTabInfo.windowId])
      tabQueue[openTabInfo.windowId].push(openTabInfo)
    else
      tabQueue[openTabInfo.windowId] = [openTabInfo]

  # keep the reference around for a while to wait for the last messages from the closed tab (e.g. for updating
  # scroll position)
  tabInfoMap.deletor = -> delete tabInfoMap[tabId]
  setTimeout tabInfoMap.deletor, 1000
  delete frameIdsForTab[tabId]
  delete urlForTab[tabId]

unless chrome.sessions
  chrome.windows.onRemoved.addListener (windowId) -> delete tabQueue[windowId]

# End action functions



# Event handlers
selectionChangedHandlers = []
# This is exported for use by "marks.coffee".
root.tabLoadedHandlers = {} # tabId -> function()

# A secret, available only within the current instantiation of Vimium.  The secret is big, likely unguessable
