     @grammarUpdated(grammar.scopeName)
     @emit 'grammar-added', grammar
 
-  removeGrammar: (grammar) ->
-    _.remove(@grammars, grammar)
-    delete @grammarsByScopeName[grammar.scopeName]
-    _.remove(@injectionGrammars, grammar)
-    @grammarUpdated(grammar.scopeName)
-
-  removeGrammarForScopeName: (scopeName) ->
-    grammar = @grammarForScopeName(scopeName)
-    @removeGrammar(grammar) if grammar?
-
-  grammarUpdated: (scopeName) ->
-    for grammar in @grammars when grammar.scopeName isnt scopeName
-      @emit 'grammar-updated', grammar if grammar.grammarUpdated(scopeName)
-
-  grammarForScopeName: (scopeName) ->
-    @grammarsByScopeName[scopeName]
-
-  createGrammar: (grammarPath, object) ->
-    grammar = new Grammar(this, object)
-    grammar.path = grammarPath
-    grammar
-
+  # Public: Read a grammar synchronously but don't add it to the registry.
+  #
+  # * grammarPath: A {String} absolute file path to a grammar file.
+  #
+  # Returns a {Grammar}.
   readGrammarSync: (grammarPath) ->
     @createGrammar(grammarPath, fs.readObjectSync(grammarPath))
 
+  # Public: Read a grammar asynchronously but don't 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.
   readGrammar: (grammarPath, callback) ->
     fs.readObject grammarPath, (error, object) =>
       if error?

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

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

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

        @addGrammar(grammar)
        callback?(null, grammar)

  # Public: Get the grammar override for the given file path.
  #
  # * filePath: A {String} file path.
  #
  # Returns a {Grammar} or undefined.
  grammarOverrideForPath: (filePath) ->
    @grammarOverridesByPath[filePath]

  # 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

  # 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
