# File lib/merb-core/dispatch/dispatcher.rb, line 27
    def handle(rack_env)
      start   = Time.now
      request = Merb::Request.new(rack_env)
      
      route_index, route_params = Merb::Router.match(request)
      
      if route_params.empty?
        raise ::Merb::ControllerExceptions::NotFound, "No routes match the request, #{request.uri}"
      end
      request.route_params = route_params
      request.params.merge! route_params
            
      controller_name = (route_params[:namespace] ? route_params[:namespace] + '/' : '') + route_params[:controller]
      
      unless controller_name
        raise Merb::ControllerExceptions::NotFound, "Route matched, but route did not specify a controller" 
      end
      
      Merb.logger.debug("Routed to: #{request.route_params.inspect}")

      cnt = controller_name.snake_case.to_const_string
      
      if !Merb::Controller._subclasses.include?(cnt)
        raise Merb::ControllerExceptions::NotFound, "Controller '#{cnt}' not found"
      end
      if cnt == "Application"
        raise Merb::ControllerExceptions::NotFound, "The 'Application' controller has no public actions"
      end

      begin
        klass = Object.full_const_get(cnt)
      rescue NameError
        raise Merb::ControllerExceptions::NotFound
      end

      Merb.logger.info("Params: #{klass._filter_params(request.params).inspect}")

      action = route_params[:action]

      if route_index && route = Merb::Router.routes[route_index]
        #Fixate the session ID if it is enabled on the route
        if route.allow_fixation? && request.params.key?(Merb::Controller._session_id_key)
          request.cookies[Merb::Controller._session_id_key] = request.params[Merb::Controller._session_id_key]
        end
      end      

      controller = dispatch_action(klass, action, request)
      controller._benchmarks[:dispatch_time] = Time.now - start  
      Merb.logger.info controller._benchmarks.inspect
      Merb.logger.flush

      controller
    # this is the custom dispatch_exception; it allows failures to still be dispatched
    # to the error controller
    rescue => exception
      Merb.logger.error(Merb.exception(exception))
      unless request.xhr?
        exception = controller_exception(exception)
        dispatch_exception(request, exception)
      else
        Struct.new(:headers, :status, :body).new({}, 500,
          "\#{exception.message}\n\nParams:\n\#{(request.params || {}).map { |p,v| \"  \#{p}: \#{v}\\n\"}.join(\"\\n\")}\n\nSession:\n\#{(request.session || {}).map { |p,v| \"  \#{p}: \#{v}\\n\"}.join(\"\\n\")}\n\nCookies:\n\#{(request.cookies || {}).map { |p,v| \"  \#{p}: \#{v}\\n\"}.join(\"\\n\")}\n\nStacktrace:\n\#{exception.backtrace.join(\"\\n\")}\n"
        )
      end
    end