     fs.close fd, _
 
     @_page.positions.splice index, 0, position
+
+  unlock: (_) ->
+    super()
 
 class Cassette
   constructor: (@record, @key) ->

# ### Iterator
#
# The application developer uses an iterator to move across the leaf pages of
# the b-tree in ascending collation order. The cursor is always visiting a
# single leaf page. 

#
class Iterator
  constructor: (@_io, @_page, @_index, @_key, @_found, @_exclusive) ->
    @_exclusive or= false
    @_offset = 0

  found: (_) -> @_found

  unlock: -> @_io.unlock @_page

  end: -> @_index + @_offset is @_page.count

  get: (_) ->
    if @_index + @_offset < @_page.count
      @_io.stash(@_page, @_index + @_offset++, _).record

  next: (_) ->
    if @_page.right is -1
      false

      @_page = next
      true

  # Unlock all leaf pages held by the iterator.
  unlock: -> @_io.unlock @_page

# ### Mutator

# A mutator is an iterator that can also edit leaf pages. It can delete records
# from the currently visit leaf page. It can insert records into the current
# leaf page, if the record belongs in the current leaf page. Like an `Iterator`
# it  moves bacross the leaf pages of an the b-tree in ascending collation
# order. It has random access to the records in the page using an index into the
# array of records.
#
# #### Ambiguous Insert Locations
# 
# Like the ambiguous range starts above, insert locations for new records can be
# ambiguous if the binary search indicates that a record should be inserted at
# the end of the leaf page, after the current last record in the leaf page. If
# the insert location is after the last record, it could be the case that the
# record really belongs to a right sibling leaf page page.
#
# As in the case of ambiguous range starts, an insert location is unambiguous if
# the key is the search key used to locate the first page of the mutator. The
# key is determined to belong inside the leaf page by virtue of a desent of the
# b-tree. That is unambiguous.
#
# Using the example of time series data again, the application developer may
# have an hour of events she wishes to insert into a day of events, within a
# b-tree of years of events. Because the events took place within an hour, they
# would all be inserted into leaf pages that are close to each other, perhaps
# right next to each other, or maybe they all fall within a single leaf page.
# 
# Rather than inserting an event at a time, desecnding the tree for each event,
# the application developer can create a mutator uses the earliest event as a
# key. This will give her the correct page for that first event. She can then
# insert the remainder of the events in their ascending order, while moving
# forward with the mutator in ascending order. If an event does not belong in
# the current leaf page, she can move the mutator forward to the next leaf page
# and see if it belongs there.
#
# The problem is that, after inserting that first record, if we determine that
# the  insert location for a subsequent record is after the last record on the
# current page, then it could be the case that it really belongs in in some
# right sibling page. If the first key of the next sibling page is less than or
# equal to the insert key, then we are on the wrong page. Unless we inspect the
# next page, the insert location is ambiguous.
#
# To obtain an unambiguous insert location without descending the b-tree to
# create a new mutator, we add a `Mutator.peek` method.
#
# This gives the mutator permission to peek at the right sibling leaf page of
# the current leaf page, to determine if a record whose insert location is after
# the last record of the current page.
#
# If you do not grant the mutator permission to peek, then you cannot use the
# mutator to insert records into subsequent pages. You have to grant permission
# to peek for each page.
# 
# Why would you want to deny permission to peek when you're inserting a set of
# records? Maybe you're not certain that the records are close togther.
#
# Let's say our application developer wants to insert a set of events, but only
# a few of those events occured at or about the same time. They are for the most
# part in completely different months of the year.
#
# She might take the opportunity to see if the next event belongs on the current
# leaf page, but if it is actually a month away, the insert location will
# definately be after the last record in the page. She might not want to load
# the next page to resolve the ambiguity, when it is not likely to be resovled
# that the currnet leaf page is the correct leaf page.  Instead, she creates a
# new mutator to resolve the ambiguity, even though there is a slight chance
# she'll come back to the same page.
#
# If she is only inserting a single record, there's no ambiguity, because she'll
# use the key of the record to create the mutator. There is no need to enable
# peek for a single insert, but there is no real cost either.
#
# TODO The lock must held because deleting the record definately can change
# during editing. The balancer can swoop in and prune the dead first records and
# thereby change the key. It could not delete the page nor merge the page, but
# it can prune dead first records.
#
# The lock is held becase the first record of the next sibling might otherwise
# change, it might be deleted. When the first key is deleted, the range of the
# the keys that valid for the current page increases. We have a race condition
# where we might reject an insertion into the current record because it is
# less than the first key of the next, but the first key of the next page has
# been deleted, and the current record is less than the range of the new first
# key, it is within the extended range.

#
class Mutator extends Iterator
  peek: ->
    @_peek = @_count
  insert: (cassette, _) ->
    # If we are at the first page and the key is equal to the key that created
    # the mutator, than this is the correct leaf page for the record.
    unambiguous = @count is 1 and @key and @_io.comparator(@key, key) is 0

    if unambiguous
      index = @index
    else
      index = @_io.find page, key, page.deleted, _
      die { ambiguous, cassette }

    # duplicate keys: Duplicate keys again. Now it occurs to me that duplicates
    # are actually not difficult for the application developer to implement
    # given a mutator. The application developer can move forward through a
    # series and append a record that has one greater than the maximum record.
    # Not a problem to worry about ambiguity in this case. Ah, we need to peek
    # though, because we need to get that number.
    #
    # In fact, given a key plus a maximum series value, you will always land
    # after the last one the series, or else a record that is less than the key,
    # which means that the series is zero. Deleted keys present a problem, so we
    # need to expose a leaf page key to the user, which, in case of a delete, is
    # definately the greatest in the series.

    # Since we need to fsync anyway, we open the file and and close the file
    # when we append a JSON object to it.  Because no file handles are kept
