         @addGrammar(grammar)
         callback?(null, grammar)
 
-  grammarOverrideForPath: (path) ->
-    @grammarOverridesByPath[path]
+  # Public: Get the grammar override for the given file path.
+  #
+  # * filePath: A {String} file path.
+  #
+  # Returns a {Grammar} or undefined.
+  grammarOverrideForPath: (filePath) ->
+    @grammarOverridesByPath[filePath]
 
-  setGrammarOverrideForPath: (path, scopeName) ->
-    @grammarOverridesByPath[path] = scopeName
+  # Public: Set the grammar override for the given file path.
+  #
+  # * filePath: A {String} file path.
+  #
+  # * scopeName: A {String} such as `"source.js"`.
+  #
+  # Returns a {Grammar} or undefined.
+  setGrammarOverrideForPath: (filePath, scopeName) ->
+    @grammarOverridesByPath[filePath] = scopeName
 
-  clearGrammarOverrideForPath: (path) ->
-    delete @grammarOverridesByPath[path]
+  # Public: Remove the grammar override for the given file path.
+  #
+  # * filePath: A {String} file path.
+  clearGrammarOverrideForPath: (filePath) ->
+    delete @grammarOverridesByPath[filePath]
 
+  # Public: Remove all grammar overrides.
   clearGrammarOverrides: ->
     @grammarOverridesByPath = {}
 
+  # Public: Select a grammar for the given file path and file contents.
+  #
+  # This picks the best match by checking the file path and contents against
+  # each grammar.
+  #
+  # * filePath: A {String} file path.
+  #
+  # * fileContents: A {String} of text for the file path.
+  #
+  # Return a {Grammar}, never null.
   selectGrammar: (filePath, fileContents) ->
     _.max @grammars, (grammar) -> grammar.getScore(filePath, fileContents)
+
+  createToken: (value, scopes) -> {value, scopes}
+
+  grammarUpdated: (scopeName) ->
+    for grammar in @grammars when grammar.scopeName isnt scopeName
+      @emit 'grammar-updated', grammar if grammar.grammarUpdated(scopeName)
+
+  createGrammar: (grammarPath, object) ->
+    grammar = new Grammar(this, object)
+    grammar.path = grammarPath
+    grammar

    @nullGrammar = new NullGrammar(this)
    @addGrammar(@nullGrammar)

  createToken: (value, scopes) -> {value, scopes}

  addGrammar: (grammar) ->
    @grammars.push(grammar)
    @grammarsByScopeName[grammar.scopeName] = grammar

      else
        callback?(null, @createGrammar(grammarPath, object))

  # Public: Read a grammar synchronously and add it to this registry.
  #
  # * grammarPath: A {String} absolute file path to a grammar file.
  #
  # Returns a {Grammar}.
  loadGrammarSync: (grammarPath) ->
    grammar = @readGrammarSync(grammarPath)
    @addGrammar(grammar)
    grammar

  # Public: Read a grammar asynchronously and add it to the registry.
  #
  # * grammarPath: A {String} absolute file path to a grammar file.
  #
  # * callback: A {Function} to call when loaded with `(error, grammar)`
  #             arguments.
  loadGrammar: (grammarPath, callback) ->
    fs.readObject grammarPath, (error, object) =>
      if error?
