       hide: -> $el.hide()
       is_clean: -> editor.getValue() is '' and not @.used
       run: ->
-        context.used = true
-        context.output_cell?.$el.remove()
-        context.output_cell = run context, editor.getValue()
-        context.input_number = notebook.input_number++
-        context.$el.attr 'data-cell-number', context.input_number
-
-    editor.lead_cell = context
+        cell.used = true
+        cell.output_cell?.$el.remove()
+        cell.output_cell = run cell, editor.getValue()
+        cell.input_number = notebook.input_number++
+        cell.$el.attr 'data-cell-number', cell.input_number
+
+    editor.lead_cell = cell
 
     error_marks = []
 

      fragment = uri.fragment()
      if fragment.length > 0 and fragment[0] == '/'
        id = fragment[1..]
        run_in_available_context notebook, "gist #{JSON.stringify id}, run: true; quiet"
      else
        program = if location.search isnt ''
          atob decodeURIComponent location.search[1..]
        else
          'intro'

        run_in_available_context notebook, program

    run: (cell) ->
      cell.run()

    notebook.$document.empty()
    notebook.cells.length = 0

  cell_index = (cell) ->
    cell.notebook.cells.indexOf cell

  seek = (start_cell, direction, predicate) ->
    notebook = start_cell.notebook
    index = cell_index(start_cell) + direction
    loop
      cell = notebook.cells[index]
      return unless cell?
      return cell if predicate cell
      index += direction

  input_cell_at_offset = (cell, offset) ->
    seek cell, offset, is_input

  get_input_cell_by_number = (notebook, number) ->
    for cell in notebook
      return cell if cell.input_number == number

  remove_cell = (cell) ->
    index = cell_index cell
    cell.$el.remove()
    cell.notebook.cells.splice index, 1

  hide_cell = (cell) ->
    cell.visible = false
    cell.$el.hide()

  insert_cell = (cell, position={}) ->
    if position.before?
      offset = 0
      current_cell = position.before
      current_cell.$el.before cell.$el
    else if position.after?
      offset = 1
      current_cell = position.after
      current_cell.$el.after cell.$el
    else
      cell.notebook.$document.append cell.$el
      cell.notebook.cells.push cell
      cell.rendered()
      return

    index = cell_index current_cell
    current_cell.notebook.cells.splice index + offset, 0, cell

    cell.rendered()

  add_context = (notebook, code='') ->
    cell = create_input_cell notebook
    set_cell_value cell, code
    insert_cell cell

    {editor} = cell
    editor.focus()
    cell

  add_input_cell = (notebook, opts={}) ->
    cell = create_input_cell notebook
    set_cell_value cell, opts.code if opts.code?
    insert_cell cell, opts
    cell

  run_in_available_context = (notebook, code) ->
    add_context(notebook, code).run()

  # Add an input cell above the last input cell
  run_in_info_context = (current_cell, code) ->
    cell = add_input_cell current_cell.notebook, code: code, before: current_cell
    cell.run()

  run_after = (current_cell, code) ->
    cell = add_input_cell current_cell.notebook, code: code, after: current_cell
    cell.run()

  create_input_cell = (notebook) ->
    $el = $ '<div class="cell input"/>'
    $code = $ '<div class="code"/>'
    $el.append $code

    editor = CodeMirror $code.get(0),
      value: ''
      mode: 'coffeescript'
      keyMap: 'lead'
      tabSize: 2
      viewportMargin: Infinity
      gutters: ['error']

    editor.setCursor(line: editor.lineCount() - 1)

    cell =
      type: 'input'
      notebook: notebook
      used: false
      editor: editor
