diff --git a/bin/merb b/bin/merb
old mode 100644
new mode 100755
diff --git a/lib/merb.rb b/lib/merb.rb
index 76cb3e269e46fdf9b63cda7cb563c6cf40fdcb15..a2ab4ed47f9cb2ab942da5c46a2b561758a0d704 100644
--- a/lib/merb.rb
+++ b/lib/merb.rb
@@ -15,7 +15,7 @@ require 'merb_core/core_ext'
 require 'merb_core/gem_ext/erubis'
 require 'merb_core/logger'
 require 'merb_core/version'
-
+require 'merb_core/controller/mime'
 
 module Merb
   class << self
@@ -23,6 +23,7 @@ module Merb
     def start(argv=ARGV)
       Merb::Config.parse_args(argv)
       BootLoader.run
+      
       case Merb::Config[:adapter]
       when "mongrel"
         adapter = Merb::Rack::Mongrel
diff --git a/lib/merb_core/boot/bootloader.rb b/lib/merb_core/boot/bootloader.rb
index d873924860bf4da06ac93db5c6a188f63dd1c3cc..57da75f05e28e8a256922bf345ccd3902e0a0b02 100644
--- a/lib/merb_core/boot/bootloader.rb
+++ b/lib/merb_core/boot/bootloader.rb
@@ -20,7 +20,7 @@ module Merb
       end
       
       def run
-        subclasses.each {|klass| Object.full_const_get(klass).new.run }
+        subclasses.each {|klass| Object.full_const_get(klass).run }
       end
       
       def after(klass)
@@ -37,95 +37,128 @@ module Merb
   
 end
 
-class Merb::BootLoader::BuildFramework < Merb::BootLoader
-  def run
-    build_framework
+class Merb::BootLoader::LoadInit < Merb::BootLoader
+  def self.run
+    if Merb::Config[:init_file]
+      require Merb.root / Merb::Config[:init_file]
+    elsif File.exists?(Merb.root / "config" / "merb_init.rb")
+      require Merb.root / "config" / "merb_init"
+    elsif File.exists?(Merb.root / "merb_init.rb")
+      require Merb.root / "merb_init"
+    elsif File.exists?(Merb.root / "application.rb")
+      require Merb.root / "application"
+    end
+  end
+end
+
+class Merb::BootLoader::Environment < Merb::BootLoader
+  def self.run
+    Merb.environment = Merb::Config[:environment]
+  end
+end
+
+class Merb::BootLoader::Logger < Merb::BootLoader
+  def self.run
+    Merb.logger = Merb::Logger.new(Merb.dir_for(:log) / "test_log")
+    Merb.logger.level = Merb::Logger.const_get(Merb::Config[:log_level].upcase) rescue Merb::Logger::INFO    
   end
+end
+
+class Merb::BootLoader::BuildFramework < Merb::BootLoader
+  class << self
+    def run
+      build_framework
+    end
   
-  # This method should be overridden in merb_init.rb before Merb.start to set up a different
-  # framework structure
-  def build_framework
-    %[view model controller helper mailer part].each do |component|
-      Merb.push_path(component.to_sym, Merb.root_path("app/#{component}s"))
+    # This method should be overridden in merb_init.rb before Merb.start to set up a different
+    # framework structure
+    def build_framework
+      %w[view model controller helper mailer part].each do |component|
+        Merb.push_path(component.to_sym, Merb.root_path("app/#{component}s"))
+      end
+      Merb.push_path(:application,    Merb.root_path("app/controllers/application.rb"))
+      Merb.push_path(:config,         Merb.root_path("config/router.rb"))
+      Merb.push_path(:lib,            Merb.root_path("lib"))    
     end
-    Merb.push_path(:application,    Merb.root_path("app/controllers/application.rb"))
-    Merb.push_path(:config,         Merb.root_path("config/router.rb"))
-    Merb.push_path(:lib,            Merb.root_path("lib"))    
   end
 end
 
 class Merb::BootLoader::LoadPaths < Merb::BootLoader
   LOADED_CLASSES = {}
   
-  def run
-    # Add models, controllers, and lib to the load path
-    $LOAD_PATH.unshift Merb.load_paths[:model].first      if Merb.load_paths[:model]
-    $LOAD_PATH.unshift Merb.load_paths[:controller].first if Merb.load_paths[:controller]
-    $LOAD_PATH.unshift Merb.load_paths[:lib].first        if Merb.load_paths[:lib]
+  class << self
+    def run
+      # Add models, controllers, and lib to the load path
+      $LOAD_PATH.unshift Merb.load_paths[:model].first      if Merb.load_paths[:model]
+      $LOAD_PATH.unshift Merb.load_paths[:controller].first if Merb.load_paths[:controller]
+      $LOAD_PATH.unshift Merb.load_paths[:lib].first        if Merb.load_paths[:lib]
     
-    # Require all the files in the registered load paths
-    puts Merb.load_paths.inspect
-    Merb.load_paths.each do |name, path|
-      Dir[path.first / path.last].each do |file| 
-        klasses = ObjectSpace.classes.dup
-        require f
-        LOADED_CLASSES[file] = ObjectSpace.classes - klasses
+      # Require all the files in the registered load paths
+      puts Merb.load_paths.inspect
+      Merb.load_paths.each do |name, path|
+        Dir[path.first / path.last].each do |file| 
+          klasses = ObjectSpace.classes.dup
+          require file
+          LOADED_CLASSES[file] = ObjectSpace.classes - klasses
+        end
       end
     end
-  end
 
-  def reload(file)
-    if klasses = LOADED_CLASSES[file]
-      klasses.each do |klass|
-        remove_constant(klass)
+    def reload(file)
+      if klasses = LOADED_CLASSES[file]
+        klasses.each do |klass|
+          remove_constant(klass)
+        end
       end
+      load file
     end
-    load file
-  end
   
-  def remove_constant(const)
-    # This is to support superclasses (like AbstractController) that track
-    # their subclasses in a class variable. Classes that wish to use this
-    # functionality are required to alias it to _subclasses_list. Plugins
-    # for ORMs and other libraries should keep this in mind.
-    if klass.superclass.respond_to?(:_subclasses_list)
-      klass.superclass.send(:_subclasses_list).delete(klass)
-      klass.superclass.send(:_subclasses_list).delete(klass.to_s)          
-    end
+    def remove_constant(const)
+      # This is to support superclasses (like AbstractController) that track
+      # their subclasses in a class variable. Classes that wish to use this
+      # functionality are required to alias it to _subclasses_list. Plugins
+      # for ORMs and other libraries should keep this in mind.
+      if klass.superclass.respond_to?(:_subclasses_list)
+        klass.superclass.send(:_subclasses_list).delete(klass)
+        klass.superclass.send(:_subclasses_list).delete(klass.to_s)          
+      end
   
-    parts = const.to_s.split("::")
-    base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::"))
-    object = parts[-1].intern
-    Merb.logger.debugger("Removing constant #{object} from #{base}")
-    base.send(:remove_const, object) if object
+      parts = const.to_s.split("::")
+      base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::"))
+      object = parts[-1].intern
+      Merb.logger.debugger("Removing constant #{object} from #{base}")
+      base.send(:remove_const, object) if object
+    end
   end
   
 end
 
 class Merb::BootLoader::Templates < Merb::BootLoader
-  def run
-    template_paths.each do |path|
-      Merb::Template.inline_template(path)
+  class << self
+    def run
+      template_paths.each do |path|
+        Merb::Template.inline_template(path)
+      end
     end
-  end
   
-  def template_paths
-    extension_glob = "{#{Merb::Template::EXTENSIONS.keys.join(',')}}"
+    def template_paths
+      extension_glob = "{#{Merb::Template::EXTENSIONS.keys.join(',')}}"
 
-    # This gets all templates set in the controllers template roots        
-    # We separate the two maps because most of controllers will have
-    # the same _template_root, so it's silly to be globbing the same
-    # path over and over.
-    template_paths = Merb::AbstractController._abstract_subclasses.map do |klass| 
-      Object.full_const_get(klass)._template_root
-    end.uniq.map {|path| Dir["#{path}/**/*.#{extension_glob}"] }
+      # This gets all templates set in the controllers template roots        
+      # We separate the two maps because most of controllers will have
+      # the same _template_root, so it's silly to be globbing the same
+      # path over and over.
+      template_paths = Merb::AbstractController._abstract_subclasses.map do |klass| 
+        Object.full_const_get(klass)._template_root
+      end.uniq.compact.map {|path| Dir["#{path}/**/*.#{extension_glob}"] }
     
-    # This gets the templates that might be created outside controllers
-    # template roots.  eg app/views/shared/*
-    template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view)
+      # This gets the templates that might be created outside controllers
+      # template roots.  eg app/views/shared/*
+      template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view)
     
-    template_paths.flatten.compact.uniq
-  end  
+      template_paths.flatten.compact.uniq
+    end
+  end
 end
 
 class Merb::BootLoader::Libraries < Merb::BootLoader
@@ -145,18 +178,41 @@ class Merb::BootLoader::Libraries < Merb::BootLoader
   def self.add_libraries(hsh)
     @@libraries.merge!(hsh)
   end
-  
-  def run
+
+  def self.run
     @@libraries.each do |exclude, choices|
       require_first_working(*choices) unless Merb::Config[exclude]
     end
   end
-  
-  def require_first_working(first, *rest)
+
+  def self.require_first_working(first, *rest)
     p first, rest
     require first
   rescue LoadError
     raise LoadError if rest.empty?
     require_first_working rest.unshift, *rest
   end
+end
+
+class Merb::BootLoader::MimeTypes < Merb::BootLoader
+  def self.run
+    # Sets the default mime-types
+    # 
+    # By default, the mime-types include:
+    # :all:: no transform, */*
+    # :yaml:: to_yaml, application/x-yaml or text/yaml
+    # :text:: to_text, text/plain
+    # :html:: to_html, text/html or application/xhtml+xml or application/html
+    # :xml:: to_xml, application/xml or text/xml or application/x-xml, adds "Encoding: UTF-8" response header
+    # :js:: to_json, text/javascript ot application/javascript or application/x-javascript
+    # :json:: to_json, application/json or text/x-json
+    Merb.available_mime_types.clear
+    Merb.add_mime_type(:all,  nil,      %w[*/*])
+    Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml])
+    Merb.add_mime_type(:text, :to_text, %w[text/plain])
+    Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html])
+    Merb.add_mime_type(:xml,  :to_xml,  %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8")
+    Merb.add_mime_type(:js,   :to_json, %w[text/javascript application/javascript application/x-javascript])
+    Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json])      
+  end
 end
\ No newline at end of file
diff --git a/lib/merb_core/config.rb b/lib/merb_core/config.rb
index c92f2e6f071c234551ecb16a4716d47fa92f6c7b..ab0864e0174b54833c758f9f22a840d3b53c7653 100644
--- a/lib/merb_core/config.rb
+++ b/lib/merb_core/config.rb
@@ -92,6 +92,10 @@ module Merb
              options[:cluster] = nodes
            end
 
+           opts.on("-I", "--init-file FILE", "Name of the file to load first") do |init_file|
+             options[:init_file] = init_file
+           end
+
            opts.on("-p", "--port PORTNUM", "Port to run merb on, defaults to 4000.") do |port|
              options[:port] = port
            end
@@ -261,29 +265,29 @@ module Merb
 
          @configuration = Merb::Config.apply_configuration_from_file options, environment_merb_yml
          
-         case Merb::Config[:environment].to_s
-         when 'production'
-           Merb::Config[:reloader] = Merb::Config.fetch(:reloader, false)
-           Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, false)
-           Merb::Config[:cache_templates] = true
-         else
-           Merb::Config[:reloader] = Merb::Config.fetch(:reloader, true)
-           Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, true)
-         end
-
-         Merb::Config[:reloader_time] ||= 0.5 if Merb::Config[:reloader] == true
-
-
-         if Merb::Config[:reloader]
-           Thread.abort_on_exception = true
-           Thread.new do
-             loop do
-               sleep( Merb::Config[:reloader_time] )
-               ::Merb::BootLoader.reload if ::Merb::BootLoader.app_loaded?
-             end
-             Thread.exit
-           end
-         end
+         # case Merb::Config[:environment].to_s
+         # when 'production'
+         #   Merb::Config[:reloader] = Merb::Config.fetch(:reloader, false)
+         #   Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, false)
+         #   Merb::Config[:cache_templates] = true
+         # else
+         #   Merb::Config[:reloader] = Merb::Config.fetch(:reloader, true)
+         #   Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, true)
+         # end
+         # 
+         # Merb::Config[:reloader_time] ||= 0.5 if Merb::Config[:reloader] == true
+         # 
+         # 
+         # if Merb::Config[:reloader]
+         #   Thread.abort_on_exception = true
+         #   Thread.new do
+         #     loop do
+         #       sleep( Merb::Config[:reloader_time] )
+         #       ::Merb::BootLoader.reload if ::Merb::BootLoader.app_loaded?
+         #     end
+         #     Thread.exit
+         #   end
+         # end
          @configuration
        end
        
diff --git a/lib/merb_core/controller/abstract_controller.rb b/lib/merb_core/controller/abstract_controller.rb
index fbf83372793da6da4b803b799994f0e341fddf88..f5e9a59057d67a6d56377a516a726cf51aa03d6f 100644
--- a/lib/merb_core/controller/abstract_controller.rb
+++ b/lib/merb_core/controller/abstract_controller.rb
@@ -96,7 +96,7 @@ class Merb::AbstractController
   # the superclass.
   #---
   # @public
-  def _template_location(action, controller = controller_name, type = nil)
+  def _template_location(action, type = nil, controller = controller_name)
     "#{controller}/#{action}"
   end
   
@@ -106,6 +106,8 @@ class Merb::AbstractController
   # own subclasses. We're using a Set so we don't have to worry about
   # uniqueness.
   self._abstract_subclasses = Set.new
+  self._template_root = Merb.dir_for(:view)
+  
   def self.subclasses_list() _abstract_subclasses end
   
   class << self
@@ -114,7 +116,6 @@ class Merb::AbstractController
     #   The controller that is being inherited from Merb::AbstractController
     def inherited(klass)
       _abstract_subclasses << klass.to_s
-      klass._template_root ||= Merb.dir_for(:view)
       super
     end
     
diff --git a/lib/merb_core/controller/merb_controller.rb b/lib/merb_core/controller/merb_controller.rb
index 7283f006bb0501b29f825da129600cf045264b62..98af6ef3330a6b3f46d7bb1f8643261e28155ae5 100644
--- a/lib/merb_core/controller/merb_controller.rb
+++ b/lib/merb_core/controller/merb_controller.rb
@@ -71,6 +71,10 @@ class Merb::Controller < Merb::AbstractController
     end
   end
   
+  def _template_location(action, type = nil, controller = controller_name)
+    "#{controller}/#{action}.#{type}"
+  end  
+  
   # Sets the variables that came in through the dispatch as available to
   # the controller. This is called by .build, so see it for more
   # information.
@@ -107,9 +111,7 @@ class Merb::Controller < Merb::AbstractController
         request.cookies[_session_id_key] = request.params[_session_id_key]
       end
     end
-    @_request, @_response, @_status, @_headers = 
-      request, response, status, headers
-
+    @request, @response, @status, @headers = request, response, status, headers
     nil
   end
   
@@ -135,7 +137,8 @@ class Merb::Controller < Merb::AbstractController
     @_benchmarks[:action_time] = Time.now - start
   end
   
-  _attr_reader :request, :response, :status, :headers
+  attr_reader :request, :response, :headers
+  attr_accessor :status
   def params()  request.params  end
   def cookies() request.cookies end
   def session() request.session end
diff --git a/lib/merb_core/controller/mime.rb b/lib/merb_core/controller/mime.rb
index d17570786ca318cff7201c4b1e947ae229b01de8..ff9abe4d1c452aeabfcf5f7dc7a2c7cdd3f67035 100644
--- a/lib/merb_core/controller/mime.rb
+++ b/lib/merb_core/controller/mime.rb
@@ -8,7 +8,7 @@ module Merb
 
     # Any specific outgoing headers should be included here.  These are not
     # the content-type header but anything in addition to it.
-    # +tranform_method+ should be set to a symbol of the method used to
+    # +transform_method+ should be set to a symbol of the method used to
     # transform a resource into this mime type.
     # For example for the :xml mime type an object might be transformed by
     # calling :to_xml, or for the :js mime type, :to_json.
@@ -71,27 +71,6 @@ module Merb
     def mime_by_request_header(header)
       available_mime_types.find {|key,info| info[request_headers].include?(header)}.first
     end
-
-    # Resets the default mime-types
-    # 
-    # By default, the mime-types include:
-    # :all:: no transform, */*
-    # :yaml:: to_yaml, application/x-yaml or text/yaml
-    # :text:: to_text, text/plain
-    # :html:: to_html, text/html or application/xhtml+xml or application/html
-    # :xml:: to_xml, application/xml or text/xml or application/x-xml, adds "Encoding: UTF-8" response header
-    # :js:: to_json, text/javascript ot application/javascript or application/x-javascript
-    # :json:: to_json, application/json or text/x-json
-    def reset_default_mime_types!
-      available_mime_types.clear
-      Merb.add_mime_type(:all,  nil,      %w[*/*])
-      Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml])
-      Merb.add_mime_type(:text, :to_text, %w[text/plain])
-      Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html])
-      Merb.add_mime_type(:xml,  :to_xml,  %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8")
-      Merb.add_mime_type(:js,   :to_json, %w[text/javascript application/javascript application/x-javascript])
-      Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json])      
-    end
     
   end
 end
\ No newline at end of file
diff --git a/lib/merb_core/controller/mixins/render.rb b/lib/merb_core/controller/mixins/render.rb
index 8e096546d4647bb597ab2e00a4b15d09db35e9c9..a298263af7d655d9ce43007554f3827046831287 100644
--- a/lib/merb_core/controller/mixins/render.rb
+++ b/lib/merb_core/controller/mixins/render.rb
@@ -51,21 +51,22 @@ module Merb::RenderMixin
     
     # If you don't specify a thing to render, assume they want to render the current action
     thing ||= action_name.to_sym
-    
+
     # Content negotiation
     opts[:format] ? (self.content_type = opts[:format]) : content_type 
     
     # Do we have a template to try to render?
     if thing.is_a?(Symbol) || opts[:template]
-      
+
       # Find a template path to look up (_template_location adds flexibility here)
-      template_location = _template_root / (opts[:template] || _template_location(thing))
+      template_location = _template_root / (opts[:template] || _template_location(thing, content_type))
+      
       # Get the method name from the previously inlined list
       template_method = Merb::Template.template_for(template_location)
 
       # Raise an error if there's no template
       raise TemplateNotFound, "No template found at #{template_location}" unless 
-        self.respond_to?(template_method)
+        template_method && self.respond_to?(template_method)
 
       # Call the method in question and throw the content for later consumption by the layout
       throw_content(:for_layout, self.send(template_method))
diff --git a/lib/merb_core/controller/mixins/responder.rb b/lib/merb_core/controller/mixins/responder.rb
index e910b2b32c844ab51cf2a10d0ad26c314dbb3631..5ac67fb907aaf9f95effc7eb3cbb07b8963ce022 100644
--- a/lib/merb_core/controller/mixins/responder.rb
+++ b/lib/merb_core/controller/mixins/responder.rb
@@ -97,6 +97,8 @@ module Merb
   # and none of the provides methods can be used.
   module ResponderMixin
     
+    TYPES = {}
+    
     class ContentTypeAlreadySet < StandardError; end
     
     # ==== Parameters
@@ -105,6 +107,7 @@ module Merb
       base.extend(ClassMethods)
       base.class_eval do
         class_inheritable_accessor :class_provided_formats
+        self.class_provided_formats = []
       end
       base.reset_provides
     end
@@ -178,171 +181,253 @@ module Merb
       def reset_provides
         only_provides(:html)
       end
-      
-      # ==== Returns
-      # The current list of formats provided for this instance of the controller. 
-      # It starts with what has been set in the controller (or :html by default) 
-      # but can be modifed on a per-action basis.      
-      def _provided_formats
-        @_provided_formats ||= class_provided_formats.dup
+    end
+
+    # ==== Returns
+    # The current list of formats provided for this instance of the controller. 
+    # It starts with what has been set in the controller (or :html by default) 
+    # but can be modifed on a per-action basis.      
+    def _provided_formats
+      @_provided_formats ||= class_provided_formats.dup
+    end
+    
+    # Sets the provided formats for this action.  Usually, you would
+    # use a combination of +provides+, +only_provides+ and +does_not_provide+
+    # to manage this, but you can set it directly.
+    # 
+    # ==== Parameters
+    # *formats<Symbol>:: A list of formats to be passed to provides
+    #
+    # ==== Raises
+    # Merb::ResponderMixin::ContentTypeAlreadySet::
+    #   Content negotiation already occured, and the content_type is set.
+    #
+    # ==== Returns
+    # Array:: List of formats passed in
+    def _set_provided_formats(*formats)
+      if @_content_type
+        raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
       end
-      
-      # Sets the provided formats for this action.  Usually, you would
-      # use a combination of +provides+, +only_provides+ and +does_not_provide+
-      # to manage this, but you can set it directly.
-      # 
-      # ==== Parameters
-      # *formats<Symbol>:: A list of formats to be passed to provides
-      #
-      # ==== Raises
-      # Merb::ResponderMixin::ContentTypeAlreadySet::
-      #   Content negotiation already occured, and the content_type is set.
-      #
-      # ==== Returns
-      # Array:: List of formats passed in
-      def _set_provided_formats(*formats)
-        if @_content_type
-          raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
-        end
-        @_provided_formats = []
-        provides(*formats)
+      @_provided_formats = []
+      provides(*formats)
+    end
+    alias :_provided_formats= :_set_provided_formats   
+    
+    # Adds formats to the list of provided formats for this particular 
+    # request. Usually used to add formats to a single action. See also
+    # the controller-level provides that affects all actions in a controller.
+    #
+    # ==== Parameters
+    # *formats<Symbol>:: A list of formats to add to the per-action list
+    #                    of provided formats
+    #
+    # ==== Raises
+    # Merb::ResponderMixin::ContentTypeAlreadySet::
+    #   Content negotiation already occured, and the content_type is set.
+    #
+    # ==== Returns
+    # Array:: List of formats passed in
+    #
+    #---
+    # @public
+    def provides(*formats)
+      if @_content_type
+        raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
       end
-      alias :_provided_formats= :_set_provided_formats   
-      
-      # Adds formats to the list of provided formats for this particular 
-      # request. Usually used to add formats to a single action. See also
-      # the controller-level provides that affects all actions in a controller.
-      #
-      # ==== Parameters
-      # *formats<Symbol>:: A list of formats to add to the per-action list
-      #                    of provided formats
-      #
-      # ==== Raises
-      # Merb::ResponderMixin::ContentTypeAlreadySet::
-      #   Content negotiation already occured, and the content_type is set.
-      #
-      # ==== Returns
-      # Array:: List of formats passed in
-      #
-      #---
-      # @public
-      def provides(*formats)
-        if @_content_type
-          raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
-        end
-        formats.each do |fmt|
-          _provided_formats << fmt unless _provided_formats.include?(fmt)
-        end
+      formats.each do |fmt|
+        _provided_formats << fmt unless _provided_formats.include?(fmt)
       end
+    end
 
-      # Sets list of provided formats for this particular 
-      # request. Usually used to limit formats to a single action. See also
-      # the controller-level only_provides that affects all actions
-      # in a controller.      
-      # 
-      # ==== Parameters
-      # *formats<Symbol>:: A list of formats to use as the per-action list
-      #                    of provided formats
-      #
-      # ==== Returns
-      # Array:: List of formats passed in
-      #
-      #---
-      # @public
-      def only_provides(*formats)
-        self._provided_formats = *formats
-      end
-      
-      # Removes formats from the list of provided formats for this particular 
-      # request. Usually used to remove formats from a single action.  See
-      # also the controller-level does_not_provide that affects all actions in a
-      # controller.
-      #
-      # ==== Parameters
-      # *formats<Symbol>:: Registered mime-type
-      # 
-      # ==== Returns
-      # Array:: List of formats that remain after removing the ones not to provide
-      #
-      #---
-      # @public      
-      def does_not_provide(*formats)
-        formats.flatten!
-        self._provided_formats -= formats
-      end
-      
-      # Do the content negotiation:
-      # 1. if params[:format] is there, and provided, use it
-      # 2. Parse the Accept header
-      # 3. If it's */*, use the first provided format
-      # 4. Look for one that is provided, in order of request
-      # 5. Raise 406 if none found
-      def _perform_content_negotiation # :nodoc:
-        raise Merb::ControllerExceptions::NotAcceptable if provided_formats.empty?
-        if fmt = params[:format]
-          return fmt.to_sym if provided_formats.include?(fmt.to_sym)
-        else
-          accepts = Responder.parse(request.accept).map {|t| t.to_sym}
-          return provided_formats.first if accepts.include?(:all)
-          return accepts.each { |type| break type if provided_formats.include?(type) }
-        end
-        raise Merb::ControllerExceptions::NotAcceptable          
+    # Sets list of provided formats for this particular 
+    # request. Usually used to limit formats to a single action. See also
+    # the controller-level only_provides that affects all actions
+    # in a controller.      
+    # 
+    # ==== Parameters
+    # *formats<Symbol>:: A list of formats to use as the per-action list
+    #                    of provided formats
+    #
+    # ==== Returns
+    # Array:: List of formats passed in
+    #
+    #---
+    # @public
+    def only_provides(*formats)
+      self._provided_formats = *formats
+    end
+    
+    # Removes formats from the list of provided formats for this particular 
+    # request. Usually used to remove formats from a single action.  See
+    # also the controller-level does_not_provide that affects all actions in a
+    # controller.
+    #
+    # ==== Parameters
+    # *formats<Symbol>:: Registered mime-type
+    # 
+    # ==== Returns
+    # Array:: List of formats that remain after removing the ones not to provide
+    #
+    #---
+    # @public      
+    def does_not_provide(*formats)
+      formats.flatten!
+      self._provided_formats -= formats
+    end
+    
+    # Do the content negotiation:
+    # 1. if params[:format] is there, and provided, use it
+    # 2. Parse the Accept header
+    # 3. If it's */*, use the first provided format
+    # 4. Look for one that is provided, in order of request
+    # 5. Raise 406 if none found
+    def _perform_content_negotiation # :nodoc:
+      raise Merb::ControllerExceptions::NotAcceptable if _provided_formats.empty?
+      if fmt = params[:format] && _provided_formats.include?(fmt.to_sym)
+        return fmt.to_sym
       end
+      accepts = Responder.parse(request.accept).map {|t| t.to_sym}
+      return _provided_formats.first if accepts.include?(:all)
+      (accepts & _provided_formats).first || (raise Merb::ControllerExceptions::NotAcceptable)
+    end
 
-      # Returns the output format for this request, based on the 
-      # provided formats, <tt>params[:format]</tt> and the client's HTTP
-      # Accept header.
-      #
-      # The first time this is called, it triggers content negotiation
-      # and caches the value.  Once you call +content_type+ you can
-      # not set or change the list of provided formats.
-      #
-      # Called automatically by +render+, so you should only call it if
-      # you need the value, not to trigger content negotiation. 
-      # 
-      # ==== Parameters
-      # fmt<String?>:: 
-      #   An optional format to use instead of performing content negotiation.
-      #   This can be used to pass in the values of opts[:format] from the 
-      #   render function to short-circuit content-negotiation when it's not
-      #   necessary. This optional parameter should not be considered part
-      #   of the public API.
-      #
-      # ==== Returns
-      # Symbol:: The content-type that will be used for this controller.
-      #
-      #---
-      # @public
-      def content_type(fmt = nil)
-        self.content_type = (fmt || _perform_content_negotiation) unless @_content_type
-        @_content_type
+    # Returns the output format for this request, based on the 
+    # provided formats, <tt>params[:format]</tt> and the client's HTTP
+    # Accept header.
+    #
+    # The first time this is called, it triggers content negotiation
+    # and caches the value.  Once you call +content_type+ you can
+    # not set or change the list of provided formats.
+    #
+    # Called automatically by +render+, so you should only call it if
+    # you need the value, not to trigger content negotiation. 
+    # 
+    # ==== Parameters
+    # fmt<String?>:: 
+    #   An optional format to use instead of performing content negotiation.
+    #   This can be used to pass in the values of opts[:format] from the 
+    #   render function to short-circuit content-negotiation when it's not
+    #   necessary. This optional parameter should not be considered part
+    #   of the public API.
+    #
+    # ==== Returns
+    # Symbol:: The content-type that will be used for this controller.
+    #
+    #---
+    # @public
+    def content_type(fmt = nil)
+      @_content_type = (fmt || _perform_content_negotiation) unless @_content_type
+      @_content_type
+    end
+    
+    # Sets the content type of the current response to a value based on 
+    # a passed in key. The Content-Type header will be set to the first
+    # registered header for the mime-type.
+    #
+    # ==== Parameters
+    # type<Symbol>:: A type that is in the list of registered mime-types.
+    #
+    # ==== Raises
+    # ArgumentError:: "type" is not in the list of registered mime-types.
+    #
+    # ==== Returns
+    # Symbol:: The content-type that was passed in.
+    #
+    #---
+    # @semipublic
+    def content_type=(type)
+      unless Merb.available_mime_types.has_key?(type)
+        raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{type}") 
+      end        
+      headers['Content-Type'] = Merb.available_mime_types[type].first        
+      @_content_type = type
+    end
+    
+  end
+
+  class Responder
+  
+    protected
+    def self.parse(accept_header)
+      # parse the raw accept header into a unique, sorted array of AcceptType objects
+      list = accept_header.to_s.split(/,/).enum_for(:each_with_index).map do |entry,index|
+        AcceptType.new(entry,index += 1)
+      end.sort.uniq
+      # firefox (and possibly other browsers) send broken default accept headers.
+      # fix them up by sorting alternate xml forms (namely application/xhtml+xml)
+      # ahead of pure xml types (application/xml,text/xml).
+      if app_xml = list.detect{|e| e.super_range == 'application/xml'}
+        list.select{|e| e.to_s =~ /\+xml/}.each { |acc_type|
+          list[list.index(acc_type)],list[list.index(app_xml)] = 
+            list[list.index(app_xml)],list[list.index(acc_type)] }
       end
-      
-      # Sets the content type of the current response to a value based on 
-      # a passed in key. The Content-Type header will be set to the first
-      # registered header for the mime-type.
-      #
-      # ==== Parameters
-      # type<Symbol>:: A type that is in the list of registered mime-types.
-      #
-      # ==== Raises
-      # ArgumentError:: "type" is not in the list of registered mime-types.
-      #
-      # ==== Returns
-      # Symbol:: The content-type that was passed in.
-      #
-      #---
-      # @semipublic
-      def content_type=(type)
-        unless Merb.available_mime_types.has_key?(type)
-          raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{type}") 
-        end        
-        headers['Content-Type'] = Merb.available_mime_types[type].first        
-        @_content_type = type
+      list
+    end
+    
+    public
+    def self.params_to_query_string(value, prefix = nil)
+      case value
+      when Array
+        value.map { |v|
+          params_to_query_string(v, "#{prefix}[]")
+        } * "&"
+      when Hash
+        value.map { |k, v|
+          params_to_query_string(v, prefix ? "#{prefix}[#{Merb::Request.escape(k)}]" : Merb::Request.escape(k))
+        } * "&"
+      else
+        "#{prefix}=#{Merb::Request.escape(value)}"
       end
+    end      
       
-    end
+  end
+
+  class AcceptType
+
+    attr_reader :media_range, :quality, :index, :type, :sub_type
     
+    def initialize(entry,index)
+      @index = index
+      @media_range, quality = entry.split(/;\s*q=/).map{|a| a.strip }
+      @type, @sub_type = @media_range.split(/\//)
+      quality ||= 0.0 if @media_range == '*/*'
+      @quality = ((quality || 1.0).to_f * 100).to_i
+    end
+  
+    def <=>(entry)
+      c = entry.quality <=> quality
+      c = index <=> entry.index if c == 0
+      c
+    end
+  
+    def eql?(entry)
+      synonyms.include?(entry.media_range)
+    end
+  
+    def ==(entry); eql?(entry); end
+  
+    def hash; super_range.hash; end
+  
+    def synonyms
+      @syns ||= Merb.available_mime_types.values.map do |e| 
+        e[:request_headers] if e[:request_headers].include?(@media_range)
+      end.compact.flatten
+    end
+  
+    def super_range
+      synonyms.first || @media_range
+    end
+  
+    def to_sym
+      Merb.available_mime_types.select{|k,v| 
+        v[:request_headers] == synonyms || v[:request_headers][0] == synonyms[0]}.flatten.first
+    end
+  
+    def to_s
+      @media_range
+    end
+  
   end
+
     
 end
\ No newline at end of file
diff --git a/lib/merb_core/dispatch/dispatcher.rb b/lib/merb_core/dispatch/dispatcher.rb
index c458c9f9ad454d3b0c3055d6b2a8e88b17712b44..f7fed0f539a20f9cce08b72c551725ad0563bf37 100644
--- a/lib/merb_core/dispatch/dispatcher.rb
+++ b/lib/merb_core/dispatch/dispatcher.rb
@@ -33,10 +33,10 @@ class Merb::Dispatcher
 
     # 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))
-      exception = controller_exception(exception)
-      dispatch_exception(request, response, exception)
+    # rescue => exception
+    #   Merb.logger.error(Merb.exception(exception))
+    #   exception = controller_exception(exception)
+    #   dispatch_exception(request, response, exception)
     end
     
     private
@@ -49,10 +49,10 @@ class Merb::Dispatcher
     def dispatch_action(klass, action, request, response, status=200)
       # build controller
       controller = klass.build(request, response, status)
-      if @@use_mutex
-        @@mutex.synchronize { controller.dispatch(action) }
+      if use_mutex
+        @@mutex.synchronize { controller._dispatch(action) }
       else
-        controller.dispatch(action)
+        controller._dispatch(action)
       end
       [controller, action]
     end
diff --git a/lib/merb_core/rack/adapter.rb b/lib/merb_core/rack/adapter.rb
index ffc7117e9733e83b0567bbe4a43fac7663800b7d..217399a5382d0b3878aaea3d3e302173c5b5f119 100644
--- a/lib/merb_core/rack/adapter.rb
+++ b/lib/merb_core/rack/adapter.rb
@@ -40,7 +40,7 @@ module Merb
         begin
           controller, action = ::Merb::Dispatcher.handle(request, response)
         rescue Object => e
-          return [500, {"Content-Type"=>"text/html"}, "Internal Server Error"]
+          return [500, {"Content-Type"=>"text/html"}, e.message + "<br/>" + e.backtrace.join("<br/>")]
         end
         [controller.status, controller.headers, controller.body]
       end
diff --git a/lib/merb_core/test/request_helper.rb b/lib/merb_core/test/request_helper.rb
index 10a9fb3ace56eaf1db0fa300df3fb2ab88a7118a..f302a3b71539182ba142cd208fe6d6aae171b1a1 100644
--- a/lib/merb_core/test/request_helper.rb
+++ b/lib/merb_core/test/request_helper.rb
@@ -26,8 +26,10 @@ module Merb::Test::RequestHelper
     Merb::Test::FakeRequest.new(env, StringIO.new(req))
   end
   
-  def dispatch_to(controller_klass, action, env = {}, opt = {}, &blk)
-    request = fake_request(env, opt)
+  def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
+    request = fake_request(env, 
+      :query_string => Merb::Responder.params_to_query_string(params))
+
     controller = controller_klass.build(request)
     controller.instance_eval(&blk) if block_given?
     controller._dispatch(action)
diff --git a/spec/public/abstract_controller/spec_helper.rb b/spec/public/abstract_controller/spec_helper.rb
index df759008d14e7572b5c44de24f77f828f83f1682..694cee2592a210a5c1fa40ca7846beeaa09725fe 100644
--- a/spec/public/abstract_controller/spec_helper.rb
+++ b/spec/public/abstract_controller/spec_helper.rb
@@ -1,12 +1,10 @@
 __DIR__ = File.dirname(__FILE__)
 require File.join(__DIR__, "..", "..", "spec_helper")
 
-# The framework structure *must* be set up before loading in framework
-# files.
 require File.join(__DIR__, "controllers", "filters")
 require File.join(__DIR__, "controllers", "render")
 
-Merb::BootLoader::Templates.new.run
+Merb::BootLoader::Templates.run
 
 module Merb::Test::Behaviors
   def dispatch_should_make_body(klass, body, action = :index)
diff --git a/spec/public/controller/base_spec.rb b/spec/public/controller/base_spec.rb
index 1709e612629ed2c2b6af4579a8b89684aca9aa3c..5bcdb59948cc22592639b1aee9bd233ff2c306fa 100644
--- a/spec/public/controller/base_spec.rb
+++ b/spec/public/controller/base_spec.rb
@@ -10,11 +10,11 @@ describe Merb::Controller, " callable actions" do
   end
   
   it "should dispatch to callable actions" do
-    dispatch_to(Merb::Test::Fixtures::TestFoo, :index).body.should == "index"
+    dispatch_to(Merb::Test::Fixtures::TestBase, :index).body.should == "index"
   end
 
   it "should not dispatch to hidden actions" do
-    calling { dispatch_to(Merb::Test::Fixtures::TestFoo, :hidden) }.
+    calling { dispatch_to(Merb::Test::Fixtures::TestBase, :hidden) }.
       should raise_error(Merb::ControllerExceptions::ActionNotFound)
   end
     
diff --git a/spec/public/controller/controllers/base.rb b/spec/public/controller/controllers/base.rb
index a1b3beb27899df781d943427d9b23945f02e14de..c4b69a440a9da3c3486208d2cb95ccb8bdb974b9 100644
--- a/spec/public/controller/controllers/base.rb
+++ b/spec/public/controller/controllers/base.rb
@@ -3,7 +3,7 @@ module Merb::Test::Fixtures
     self._template_root = File.dirname(__FILE__) / "views"
   end
   
-  class TestFoo < ControllerTesting
+  class TestBase < ControllerTesting
     def index
       "index"
     end
diff --git a/spec/public/controller/controllers/responder.rb b/spec/public/controller/controllers/responder.rb
new file mode 100644
index 0000000000000000000000000000000000000000..867192e8f6e995a43fd5cd3daffa0ec11b3d31e5
--- /dev/null
+++ b/spec/public/controller/controllers/responder.rb
@@ -0,0 +1,25 @@
+module Merb::Test::Fixtures
+  class ControllerTesting < Merb::Controller
+    self._template_root = File.dirname(__FILE__) / "views"
+  end
+  
+  class TestResponder < ControllerTesting
+    def index
+      render
+    end
+  end
+  
+  class TestHtmlDefault < TestResponder; end
+  
+  class TestClassProvides < TestResponder; 
+    provides :xml
+  end
+  
+  class TestLocalProvides < TestResponder; 
+    def index
+      provides :xml
+      render
+    end
+  end
+  
+end
\ No newline at end of file
diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..1bfb77d4a44c444bba6888ae7740f7df4b074c58
--- /dev/null
+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb
@@ -0,0 +1 @@
+This should not be rendered
\ No newline at end of file
diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb
new file mode 100644
index 0000000000000000000000000000000000000000..7c91f633987348e87e5e34e1d9e87d9dd0e5100c
--- /dev/null
+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb
@@ -0,0 +1 @@
+<XML:Class provides='true' />
\ No newline at end of file
diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..eb4b52bf5a7aaba8f1706de419f42789c05684a2
--- /dev/null
+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb
@@ -0,0 +1 @@
+HTML: Default
\ No newline at end of file
diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..a3a841a89c62e6174038935a42da9cd24ff54413
--- /dev/null
+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb
@@ -0,0 +1 @@
+This should not render
\ No newline at end of file
diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb
new file mode 100644
index 0000000000000000000000000000000000000000..c1384ec6af0357b585cc367035d1bc3a30347ade
--- /dev/null
+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb
@@ -0,0 +1 @@
+<XML:Local provides='true' />
\ No newline at end of file
diff --git a/spec/public/controller/responder_spec.rb b/spec/public/controller/responder_spec.rb
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bcf18532442e5965cf6ca8501770d7b7a1eb2429 100644
--- a/spec/public/controller/responder_spec.rb
+++ b/spec/public/controller/responder_spec.rb
@@ -0,0 +1,31 @@
+require File.join(File.dirname(__FILE__), "spec_helper")
+
+describe Merb::Controller, " responds" do
+  
+  before do
+    Merb.push_path(:layout, File.dirname(__FILE__) / "controllers" / "views" / "layouts")    
+    Merb::Router.prepare do |r|
+      r.default_routes
+    end
+  end
+  
+  it "should default the mime-type to HTML" do
+    dispatch_to(Merb::Test::Fixtures::TestHtmlDefault, :index).body.should == "HTML: Default"
+  end
+
+  it "should use other mime-types if they are provided on the class level" do
+    controller = dispatch_to(Merb::Test::Fixtures::TestClassProvides, :index, {}, :http_accept => "application/xml")
+    controller.body.should == "<XML:Class provides='true' />"
+  end
+
+  it "should fail if none of the acceptable mime-types are available" do
+    calling { dispatch_to(Merb::Test::Fixtures::TestClassProvides, :index, {}, :http_accept => "application/json") }.
+      should raise_error(Merb::ControllerExceptions::NotAcceptable)
+  end
+  
+  it "should use mime-types that are provided at the local level" do
+    controller = dispatch_to(Merb::Test::Fixtures::TestLocalProvides, :index, {}, :http_accept => "application/xml")
+    controller.body.should == "<XML:Local provides='true' />"    
+  end
+    
+end
\ No newline at end of file
diff --git a/spec/public/controller/spec_helper.rb b/spec/public/controller/spec_helper.rb
index f68628a63740f4ce0235a15d71c5889e55ecaf78..e360194c1fbaf72c3298c61543c2d3a19b512b41 100644
--- a/spec/public/controller/spec_helper.rb
+++ b/spec/public/controller/spec_helper.rb
@@ -1,4 +1,10 @@
 __DIR__ = File.dirname(__FILE__)
+require 'ruby-debug'
+
 require File.join(__DIR__, "..", "..", "spec_helper")
 
-require File.join(__DIR__, "controllers", "base")
\ No newline at end of file
+require File.join(__DIR__, "controllers", "base")
+require File.join(__DIR__, "controllers", "responder")
+
+Merb::BootLoader::Templates.run
+Merb::BootLoader::MimeTypes.run
\ No newline at end of file
