         else
           currentMapping[key] = extend {}, registryEntry
           # We don't need these properties in the content scripts.
-          delete registryEntry[prop] for prop in ["keySequence", "description"]
+          delete currentMapping[key][prop] for prop in ["keySequence", "description"]
     chrome.storage.local.set normalModeKeyStateMapping: keyStateMapping
 
   # An ordered listing of all available commands, grouped by type. This is the order they will

Commands =
  init: ->
    for own command, descriptor of commandDescriptions
      @addCommand(command, descriptor[0], descriptor[1])
    @loadKeyMappings Settings.get "keyMappings"
    Settings.postUpdateHooks["keyMappings"] = @loadKeyMappings.bind this

  loadKeyMappings: (customKeyMappings) ->
    @clearKeyMappingsAndSetDefaults()
    @parseCustomKeyMappings customKeyMappings
    @generateKeyStateMapping()
    chrome.storage.local.set mapKeyRegistry: @mapKeyRegistry

  availableCommands: {}
  keyToCommandRegistry: {}

  # Registers a command, making it available to be optionally bound to a key.
  # options:
  #  - background: whether this command needs to be run against the background page.
  addCommand: (command, description, options = {}) ->
    if command of @availableCommands
      BgUtils.log "#{command} is already defined! Check commands.coffee for duplicates."
      return

    @availableCommands[command] = extend options, description: description

  mapKeyToCommand: ({ key, keySequence, command, options }) ->
    unless @availableCommands[command]
      BgUtils.log "#{command} doesn't exist!"
      return

    options ?= {}
    @keyToCommandRegistry[key] = extend { keySequence, command, options }, @availableCommands[command]

  # Lower-case the appropriate portions of named keys.
  #

      else
        [key[0], @parseKeySequence(key[1..])...]

  # Command options follow command mappings, and are of one of two forms:
  #   key=value     - a value
  #   key           - a flag
