<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>CONFIG</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,6 +1,6 @@
 class Merb::Controller &lt; AbstractController
   
-  class_inheritable_accessor :_session_id_key, :_session_expiry
+  class_inheritable_accessor :_session_id_key, :_session_expiry, :_hidden_actions
   cattr_accessor :_subclasses, :_session_secret_key
   self._subclasses = Set.new
   self.session_secret_key = nil
@@ -10,5 +10,110 @@ class Merb::Controller &lt; AbstractController
   include Merb::ResponderMixin
   include Merb::ControllerExceptions
   
-  
+  class &lt;&lt; self
+    
+    # ==== Parameters
+    # klass&lt;Merb::Controller&gt;:: The Merb::Controller inheriting from the
+    #                           base class
+    def inherited(klass)
+      _subclasses &lt;&lt; klass.to_s
+      klass._hidden_actions = Merb::Controller.public_instance_methods
+      super
+    end
+
+    # A list of actions that should not be available as callable actions
+    def hidden_actions
+      _hidden_actions
+    end
+    
+    # Hide each of the given methods from being callable as actions.
+    #
+    # ==== Parameters
+    # *names&lt;~to-s&gt;:: Actions that should be added to the list 
+    def hide_action(*names)
+      _hidden_actions = _hidden_actions | names.collect { |n| n.to_s })
+    end
+    
+    # Build a new controller.
+    #
+    # ==== Parameters
+    # request&lt;Merb::Request&gt;:: The Merb::Request that came in from Mongrel
+    # response&lt;IO&gt;:: 
+    #   The response IO object to write the response to. This could be any
+    #   IO object, but is probably an HTTPResponse
+    # status&lt;Integer&gt;:: An integer code for the status
+    # headers&lt;Hash{header =&gt; value}&gt;:: 
+    #   A hash of headers to start the controller with. These headers
+    #   can be overridden later by the #headers method
+    def build(request, response = StringIO.new, status=200, headers={'Content-Type' =&gt; 'text/html; charset=utf-8'})
+      cont = new
+      cont.set_dispatch_variables(request, response, status, headers)
+      cont
+    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.
+    #
+    # This method uses the :session_id_cookie_only and :query_string_whitelist
+    # configuration options. See CONFIG for more details.
+    #
+    # ==== Parameters
+    # request&lt;Merb::Request&gt;:: The Merb::Request that came in from Mongrel
+    # response&lt;IO&gt;:: 
+    #   The response IO object to write the response to. This could be any
+    #   IO object, but is probably an HTTPResponse
+    # status&lt;Integer&gt;:: An integer code for the status
+    # headers&lt;Hash{header =&gt; value}&gt;:: 
+    #   A hash of headers to start the controller with. These headers
+    #   can be overridden later by the #headers method
+    def set_dispatch_variables(request, response, status, headers)
+      if request.params.key?(_session_id_key)
+        if Merb::Config[:session_id_cookie_only]
+          # This condition allows for certain controller/action paths to allow
+          # a session ID to be passed in a query string. This is needed for
+          # Flash Uploads to work since flash will not pass a Session Cookie
+          # Recommend running session.regenerate after any controller taking
+          # advantage of this in case someone is attempting a session fixation
+          # attack
+          if Merb::Config[:query_string_whitelist].include?(&quot;#{request.controller_name}/#{request.action}&quot;)
+          # FIXME to use routes not controller and action names -----^
+            request.cookies[_session_id_key] = request.params[_session_id_key]
+          end
+        else
+          request.cookies[_session_id_key] = request.params[_session_id_key]
+        end
+      end
+      @_request  = request
+      @_response = response
+      @_status   = status
+      @_headers  = headers
+    end
+    
+    # Dispatch the action
+    #
+    # ==== Parameters
+    def dispatch(action=:index)
+      start = Time.now    
+      if self.class.callable_actions[action.to_s]
+        params[:action] ||= action
+        setup_session
+        super(action)
+        finalize_session
+      else
+        raise ActionNotFound, &quot;Action '#{action}' was not found in #{self.class}&quot;
+      end
+      @_benchmarks[:action_time] = Time.now - start
+      Merb.logger.info(&quot;Time spent in #{self.class}##{action} action: #{@_benchmarks[:action_time]} seconds&quot;)
+    end
+    
+    _attr_reader :body, :status, :request, :params, :headers, :response
+    def params()  request.params  end
+    def cookies() request.cookies end
+    def session() request.session end
+    def route()   request.route   end
+    
+    
+    
+  end
 end
\ No newline at end of file</diff>
      <filename>lib/merb_core/controller/controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,34 @@
 # to, for example, an array without those additions being shared with either their parent, siblings, or
 # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
 class Class # :nodoc:
+  
+  def _attr_reader(*syms)
+    syms.flatten.each do |sym|
+      class_eval &lt;&lt;-EOS
+        def #{sym}
+          @_sym
+        end
+      EOS
+    end
+  end
+
+  def _attr_writer(*syms)
+    syms.flatten.each do |sym|
+      class_eval &lt;&lt;-EOS
+        def #{sym}=(val)
+          @_sym = val
+        end
+      EOS
+    end
+  end
+  
+  def _attr_accessor(*syms)
+    syms.flatten.each do |sym|
+      _attr_reader sym
+      _attr_writer sym
+    end
+  end
+  
   def cattr_reader(*syms)
     syms.flatten.each do |sym|
       next if sym.is_a?(Hash)</diff>
      <filename>lib/merb_core/core_ext/class.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e11196de18e713d643f28995688562a646168775</id>
    </parent>
  </parents>
  <author>
    <name>Yehuda Katz</name>
    <email>wycats@gmail.com</email>
  </author>
  <url>http://github.com/wycats/merb-core/commit/248c2837aa42dc12b323dc6da15445ae3a774b6e</url>
  <id>248c2837aa42dc12b323dc6da15445ae3a774b6e</id>
  <committed-date>2008-01-12T13:30:36-08:00</committed-date>
  <authored-date>2008-01-12T13:30:36-08:00</authored-date>
  <message>Parts of Merb::Controller ported over
_attr_accessor added for def foo; @_foo; end
added CONFIG to track Merb::Config</message>
  <tree>ceb6ba85efdbaefc9d9864f692e215c979b27e4f</tree>
  <committer>
    <name>Yehuda Katz</name>
    <email>wycats@gmail.com</email>
  </committer>
</commit>
