class Sinatra::Base

def accept_mime_types(types)

def accept_mime_types(types)
  types = [types] unless types.kind_of? Array
  types.map!{|t| media_type(t)}
  condition {
    matching_types = (request.accept & types)
    unless matching_types.empty?
      response.headers['Content-Type'] = matching_types.first
      true
    else
      false
    end
  }
end

def before(&block)

def before(&block)
  @filters << block
end

def call(env)

def call(env)
  dup.call!(env)
end

def call(env)

def call(env)
  construct_middleware if @callsite.nil?
  @callsite.call(env)
end

def call!(env)

def call!(env)
  @env      = env
  @request  = Request.new(env)
  @response = Response.new
  @params   = nil
  error_detection { dispatch! }
  @response.finish
end

def compile(path)

def compile(path)
  keys = []
  if path.respond_to? :to_str
    pattern =
      URI.encode(path).gsub(/((:\w+)|\*)/) do |match|
        if match == "*"
          keys << 'splat'
          "(.*?)"
        else
          keys << $2[1..-1]
          "([^/?&#\.]+)"
        end
      end
    [/^#{pattern}$/, keys]
  elsif path.respond_to? :=~
    [path, keys]
  else
    raise TypeError, path
  end
end

def condition(&block)

def condition(&block)
  @conditions << block
end

def configure(*envs, &block)

def configure(*envs, &block)
  yield if envs.empty? || envs.include?(environment.to_sym)
end

def construct_middleware(builder=Rack::Builder.new)

def construct_middleware(builder=Rack::Builder.new)
  builder.use Rack::Session::Cookie if sessions?
  builder.use Rack::CommonLogger if logging?
  builder.use Rack::MethodOverride if methodoverride?
  @middleware.each { |c, args, bk| builder.use(c, *args, &bk) }
  builder.run new
  @callsite = builder.to_app
end

def delete(path, opts={}, &bk); route 'DELETE', path, opts, &bk; end

def delete(path, opts={}, &bk); route 'DELETE', path, opts, &bk; end

def development? ; environment == :development ; end

def development? ; environment == :development ; end

def disable(*opts)

def disable(*opts)
  opts.each { |key| set(key, false) }
end

def dispatch!

def dispatch!
  self.class.filters.each do |block|
    res = catch(:halt) { instance_eval(&block) ; :continue }
    return unless res == :continue
  end
  if routes = self.class.routes[@request.request_method]
    path = @request.path_info
    original_params = nested_params(@request.params)
    routes.each do |pattern, keys, conditions, method_name|
      if pattern =~ path
        values = $~.captures.map{|val| val && unescape(val) }
        params =
          if keys.any?
            keys.zip(values).inject({}) do |hash,(k,v)|
              if k == 'splat'
                (hash[k] ||= []) << v
              else
                hash[k] = v
              end
              hash
            end
          elsif values.any?
            {'captures' => values}
          else
            {}
          end
        @params = original_params.merge(params)
        catch(:pass) {
          conditions.each { |cond|
            throw :pass if instance_eval(&cond) == false }
          return invoke(method_name)
        }
      end
    end
  end
  raise NotFound
end

def dupe_routes

def dupe_routes
  routes.inject({}) do |hash,(request_method,routes)|
    hash[request_method] = routes.dup
    hash
  end
end

def enable(*opts)

def enable(*opts)
  opts.each { |key| set(key, true) }
end

def error(codes=Exception, &block)

def error(codes=Exception, &block)
  if codes.respond_to? :each
    codes.each { |err| error(err, &block) }
  else
    @errors[codes] = block
  end
end

def error_detection

def error_detection
  errmap = self.class.errors
  yield
rescue NotFound => boom
  @env['sinatra.error'] = boom
  @response.status = 404
  @response.body = ['<h1>Not Found</h1>']
  handler = errmap[boom.class] || errmap[NotFound]
  invoke handler unless handler.nil?
rescue ::Exception => boom
  @env['sinatra.error'] = boom
  if options.dump_errors?
    msg = ["#{boom.class} - #{boom.message}:", *boom.backtrace].join("\n ")
    @env['rack.errors'] << msg
  end
  raise boom if options.raise_errors?
  @response.status = 500
  invoke errmap[boom.class] || errmap[Exception]
ensure
  if @response.status >= 400 && errmap.key?(response.status)
    invoke errmap[response.status]
  end
end

def get(path, opts={}, &block)

def get(path, opts={}, &block)
  conditions = @conditions.dup
  route('GET', path, opts, &block)
  @conditions = conditions
  head(path, opts) { invoke(block) ; [] }
end

def halt(*response)

def halt(*response)
  throw :halt, *response
end

def head(path, opts={}, &bk); route 'HEAD', path, opts, &bk; end

def head(path, opts={}, &bk); route 'HEAD', path, opts, &bk; end

def host_name(pattern)

def host_name(pattern)
  condition { pattern === request.host }
end

def indifferent_hash

def indifferent_hash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end

def inherited(subclass)

def inherited(subclass)
  subclass.routes = dupe_routes
  subclass.templates = templates.dup
  subclass.conditions = []
  subclass.filters = filters.dup
  subclass.errors = errors.dup
  subclass.middleware = middleware.dup
  subclass.send :reset_middleware
  super
end

def initialize(app=nil)

def initialize(app=nil)
  @app = app
  yield self if block_given?
end

def invoke(block)

def invoke(block)
  res = catch(:halt) { instance_eval(&block) }
  return if res.nil?
  case
  when res.respond_to?(:to_str)
    @response.body = [res]
  when res.respond_to?(:to_ary)
    res = res.to_ary
    if Fixnum === res.first
      if res.length == 3
        @response.status, headers, body = res
        @response.body = body if body
        headers.each { |k, v| @response.headers[k] = v } if headers
      elsif res.length == 2
        @response.status = res.first
        @response.body = res.last
      else
        raise TypeError, "#{res.inspect} not supported"
      end
    else
      @response.body = res
    end
  when res.respond_to?(:each)
    @response.body = res
  when (100...599) === res
    @response.status = res
  end
  res
end

def layout(name=:layout, &block)

def layout(name=:layout, &block)
  template name, &block
end

def media_type(type)

Look up a media type by file extension in Rack's mime registry.
def media_type(type)
  return type if type.nil? || type.to_s.include?('/')
  type = ".#{type}" unless type.to_s[0] == ?.
  Rack::Mime.mime_type(type, nil)
end

def metadef(message, &block)

def metadef(message, &block)
  (class << self; self; end).
    send :define_method, message, &block
end

def nested_params(params)

def nested_params(params)
  return indifferent_hash.merge(params) if !params.keys.join.include?('[')
  params.inject indifferent_hash do |res, (key,val)|
    if key =~ /\[.*\]/
      splat = key.scan(/(^[^\[]+)|\[([^\]]+)\]/).flatten.compact
      head, last = splat[0..-2], splat[-1]
      head.inject(res){ |s,v| s[v] ||= indifferent_hash }[last] = val
    end
    res
  end
end

def not_found(&block)

def not_found(&block)
  error 404, &block
end

def options

def options
  self.class
end

def pass

def pass
  throw :pass
end

def post(path, opts={}, &bk); route 'POST', path, opts, &bk; end

def post(path, opts={}, &bk); route 'POST', path, opts, &bk; end

def production? ; environment == :production ; end

def production? ; environment == :production ; end

def put(path, opts={}, &bk); route 'PUT', path, opts, &bk; end

def put(path, opts={}, &bk); route 'PUT', path, opts, &bk; end

def reset_middleware

def reset_middleware
  @callsite = nil
end

def route(verb, path, opts={}, &block)

def route(verb, path, opts={}, &block)
  host_name  opts[:host]  if opts.key?(:host)
  user_agent opts[:agent] if opts.key?(:agent)
  accept_mime_types opts[:provides] if opts.key?(:provides)
  pattern, keys = compile(path)
  conditions, @conditions = @conditions, []
  define_method "#{verb} #{path}", &block
  unbound_method = instance_method("#{verb} #{path}")
  block = lambda { unbound_method.bind(self).call }
  (routes[verb] ||= []).
    push([pattern, keys, conditions, block]).last
end

def run!(options={})

def run!(options={})
  set(options)
  handler = Rack::Handler.get(server)
  handler_name = handler.name.gsub(/.*::/, '')
  puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
    "on #{port} for #{environment} with backup from #{handler_name}"
  handler.run self, :Host => host, :Port => port do |server|
    trap(:INT) do
      ## Use thins' hard #stop! if available, otherwise just #stop
      server.respond_to?(:stop!) ? server.stop! : server.stop
      puts "\n== Sinatra has ended his set (crowd applauds)"
    end
  end
rescue Errno::EADDRINUSE => e
  puts "== Someone is already performing on port #{port}!"
end

def set(option, value=self)

def set(option, value=self)
  if value.kind_of?(Proc)
    metadef(option, &value)
    metadef("#{option}?") { !!__send__(option) }
    metadef("#{option}=") { |val| set(option, Proc.new{val}) }
  elsif value == self && option.respond_to?(:to_hash)
    option.to_hash.each(&method(:set))
  elsif respond_to?("#{option}=")
    __send__ "#{option}=", value
  else
    set option, Proc.new{value}
  end
  self
end

def template(name, &block)

def template(name, &block)
  templates[name] = block
end

def test? ; environment == :test ; end

def test? ; environment == :test ; end

def use(middleware, *args, &block)

def use(middleware, *args, &block)
  reset_middleware
  @middleware << [middleware, args, block]
end

def use_in_file_templates!

def use_in_file_templates!
  line = caller.detect do |s|
    [
     /lib\/sinatra.*\.rb/,
     /\(.*\)/,
     /rubygems\/custom_require\.rb/
    ].all? { |x| s !~ x }
  end
  file = line.sub(/:\d+.*$/, '')
  if data = ::IO.read(file).split('__END__')[1]
    data.gsub!(/\r\n/, "\n")
    template = nil
    data.each_line do |line|
      if line =~ /^@@\s*(.*)/
        template = templates[$1.to_sym] = ''
      elsif template
        template << line
      end
    end
  end
end

def user_agent(pattern)

def user_agent(pattern)
  condition {
    if request.user_agent =~ pattern
      @params[:agent] = $~[1..-1]
      true
    else
      false
    end
  }
end