       @redoStack.push(inverse)
       inverse.applyTo(@buffer)
 
+  # Public: Redoes the last operation.
   redo: ->
     if patch = @redoStack.pop()
       inverse = patch.invert(@buffer)
       @undoStack.push(inverse)
       inverse.applyTo(@buffer)
 
+  # Public: Wraps the given function in a transaction, meaning all changes will
+  # be undone/redone at the same time. The transaction will be aborted if the
+  # function throws an exception. The function's execution will be halted if
+  # ::abortTransaction is called.
   transact: (fn) ->
     @beginTransaction()
     try

      else
        throw error

  beginTransaction: ->
    if ++@transactionDepth is 1
      @currentTransaction = new Transaction()

  commitTransaction: ->
    if --@transactionDepth is 0
      @undoStack.push(@currentTransaction) if @currentTransaction.hasBufferPatches()
      @currentTransaction = null

  abortTransaction: ->
    if @transactCallDepth is 0
      inverse = @currentTransaction.invert(@buffer)


  constructor: (@buffer, @undoStack=[], @redoStack=[]) ->

  # Private: Used by {Serializable} during serialization
  serializeParams: ->
    undoStack: @undoStack.map (patch) -> patch.serialize()
    redoStack: @redoStack.map (patch) -> patch.serialize()

  # Private: Used by {Serializable} during deserialization
  deserializeParams: (params) ->
    params.undoStack = params.undoStack.map (patchState) => @constructor.deserialize(patchState)
    params.redoStack = params.redoStack.map (patchState) => @constructor.deserialize(patchState)
    params

  # Private: Called by {TextBuffer} to store a patch in the undo stack. Clears
  # the redo stack
  recordNewPatch: (patch) ->
    if @currentTransaction?
      @currentTransaction.push(patch)
