# File lib/parslet/atoms/base.rb, line 23
  def parse(io, options={})
    source = io.respond_to?(:line_and_column) ? 
      io : 
      Parslet::Source.new(io)

    # Try to cheat. Assuming that we'll be able to parse the input, don't 
    # run error reporting code. 
    success, value = setup_and_apply(source, nil, !options[:prefix])
    
    # If we didn't succeed the parse, raise an exception for the user. 
    # Stack trace will be off, but the error tree should explain the reason
    # it failed.
    unless success
      # Cheating has not paid off. Now pay the cost: Rerun the parse,
      # gathering error information in the process.
      reporter = options[:reporter] || Parslet::ErrorReporter::Tree.new
      source.pos = 0
      success, value = setup_and_apply(source, reporter, !options[:prefix])
      
      fail "Assertion failed: success was true when parsing with reporter" \
        if success
      
      # Value is a Parslet::Cause, which can be turned into an exception:
      value.raise
      
      fail "NEVER REACHED"
    end
    
    # assert: success is true

    # Extra input is now handled inline with the rest of the parsing. If 
    # really we have success == true, prefix: false and still some input 
    # is left dangling, that is a BUG.
    if !options[:prefix] && source.chars_left > 0
      fail "BUG: New error strategy should not reach this point."
    end
    
    return flatten(value)
  end