     '[': 219
     ']': 221
     '\\': 220
+
+  shiftedKeys:
+    48: ')', 49: '!', 50: '@', 51: '#', 52: '$', 53: '%', 54: '^'
+    55: '&', 56: '*', 57: '(', 65: 'A', 66: 'B', 67: 'C', 68: 'D'
+    69: 'E', 70: 'F', 71: 'G', 72: 'H', 73: 'I', 74: 'J', 75: 'K'
+    76: 'L', 77: 'M', 78: 'N', 79: 'O', 80: 'P', 81: 'Q', 82: 'R'
+    83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', 89: 'Y'
+    90: 'Z', 186: ':', 187: '+', 188: '<', 189: '_', 190: '>'
+    191: '?', 192: '~', 219: '{', 220: '|', 221: '}', 222: '"'


    modifiers = []
    key = null

    for k in keys
      if modifier = @modifierKeys[k.toLowerCase()]
        modifiers.push modifier unless modifier == @modifierKeys['shift'] # Shift is implied? YES
      else if key
        throw "#{@name}: #{binding} specifies TWO keys, we don't handle that yet."
      else if namedKey = @namedKeys[k.toLowerCase()]
        key = namedKey
      else if k.length > 1
        throw "#{@name}: #{binding} uses an unknown key #{k}."
      else


  load: (path) ->
    try
#       Watcher.watch path, =>
#         # Should we keep track of which file bindings are associated with?
#         # That way we could clear bindings when the file is changed
#         # or deleted. I think the answer is yes, but I don't want to
#         # do this right now.
#         console.log "#{@name}: Reloading #{path}"
#         @load path

      json = CoffeeScript.eval "return " + (fs.read path)
      # Iterate in reverse order scopes are declared.
