<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>actionmailer/test/fixtures/auto_layout_mailer/hello.html.erb</filename>
    </added>
    <added>
      <filename>actionmailer/test/fixtures/explicit_layout_mailer/logout.html.erb</filename>
    </added>
    <added>
      <filename>actionmailer/test/fixtures/explicit_layout_mailer/signup.html.erb</filename>
    </added>
    <added>
      <filename>actionmailer/test/fixtures/layouts/auto_layout_mailer.html.erb</filename>
    </added>
    <added>
      <filename>actionmailer/test/fixtures/layouts/spam.html.erb</filename>
    </added>
    <added>
      <filename>actionmailer/test/mail_layout_test.rb</filename>
    </added>
    <added>
      <filename>actionpack/lib/action_view/helpers.rb</filename>
    </added>
    <added>
      <filename>actionpack/lib/action_view/locale/en-US.yml</filename>
    </added>
    <added>
      <filename>activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb</filename>
    </added>
    <added>
      <filename>activerecord/lib/active_record/dynamic_finder_match.rb</filename>
    </added>
    <added>
      <filename>activerecord/lib/active_record/locale/en-US.yml</filename>
    </added>
    <added>
      <filename>activerecord/test/cases/i18n_test.rb</filename>
    </added>
    <added>
      <filename>activerecord/test/cases/pooled_connections_test.rb</filename>
    </added>
    <added>
      <filename>activerecord/test/migrations/broken/100_migration_that_raises_exception.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/core_ext/module/synchronization.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/core_ext/rexml.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/locale/en-US.yml</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/secure_random.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/i18n.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/i18n/backend/simple.rb</filename>
    </added>
    <added>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/i18n/exceptions.rb</filename>
    </added>
    <added>
      <filename>activesupport/test/core_ext/module/synchronization_test.rb</filename>
    </added>
    <added>
      <filename>activesupport/test/secure_random_test.rb</filename>
    </added>
    <added>
      <filename>ci/ci_build.rb</filename>
    </added>
    <added>
      <filename>ci/ci_setup_notes.txt</filename>
    </added>
    <added>
      <filename>ci/cruise_config.rb</filename>
    </added>
    <added>
      <filename>ci/geminstaller.yml</filename>
    </added>
    <added>
      <filename>ci/site.css</filename>
    </added>
    <added>
      <filename>ci/site_config.rb</filename>
    </added>
    <added>
      <filename>railties/test/error_page_test.rb</filename>
    </added>
    <added>
      <filename>railties/test/fixtures/eager/zoo.rb</filename>
    </added>
    <added>
      <filename>railties/test/fixtures/eager/zoo/reptile_house.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,8 @@
+* Add layout functionality to mailers [Pratik]
+
+  Mailer layouts behaves just like controller layouts, except layout names need to
+  have '_mailer' postfix for them to be automatically picked up.
+
 *2.1.0 (May 31st, 2008)*
 
 * Fixed that a return-path header would be ignored #7572 [joost]</diff>
      <filename>actionmailer/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -21,13 +21,13 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
-unless defined?(ActionController)
-  begin
-    $:.unshift &quot;#{File.dirname(__FILE__)}/../../actionpack/lib&quot;
+begin
+  require 'action_controller'
+rescue LoadError
+  actionpack_path = &quot;#{File.dirname(__FILE__)}/../../actionpack/lib&quot;
+  if File.directory?(actionpack_path)
+    $:.unshift actionpack_path
     require 'action_controller'
-  rescue LoadError
-    require 'rubygems'
-    gem 'actionpack', '&gt;= 1.12.5'
   end
 end
 </diff>
      <filename>actionmailer/lib/action_mailer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -246,7 +246,10 @@ module ActionMailer #:nodoc:
   #   +implicit_parts_order+.
   class Base
     include AdvAttrAccessor, PartContainer
-    include ActionController::UrlWriter if Object.const_defined?(:ActionController)
+    if Object.const_defined?(:ActionController)
+      include ActionController::UrlWriter
+      include ActionController::Layout
+    end
 
     private_class_method :new #:nodoc:
 
@@ -362,6 +365,7 @@ module ActionMailer #:nodoc:
 
     # The mail object instance referenced by this mailer.
     attr_reader :mail
+    attr_reader :template_name, :default_template_name, :action_name
 
     class &lt;&lt; self
       attr_writer :mailer_name
@@ -374,11 +378,16 @@ module ActionMailer #:nodoc:
       alias_method :controller_name, :mailer_name
       alias_method :controller_path, :mailer_name
 
-      def method_missing(method_symbol, *parameters)#:nodoc:
-        case method_symbol.id2name
-          when /^create_([_a-z]\w*)/  then new($1, *parameters).mail
-          when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver!
-          when &quot;new&quot; then nil
+      def respond_to?(method_symbol, include_private = false) #:nodoc:
+        matches_dynamic_method?(method_symbol) || super
+      end
+
+      def method_missing(method_symbol, *parameters) #:nodoc:
+        match = matches_dynamic_method?(method_symbol)
+        case match[1]
+          when 'create'  then new(match[2], *parameters).mail
+          when 'deliver' then new(match[2], *parameters).deliver!
+          when 'new'     then nil
           else super
         end
       end
@@ -424,6 +433,12 @@ module ActionMailer #:nodoc:
       def template_root=(root)
         self.view_paths = ActionView::Base.process_view_paths(root)
       end
+
+      private
+        def matches_dynamic_method?(method_name) #:nodoc:
+          method_name = method_name.to_s
+          /(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name)
+        end
     end
 
     # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
@@ -519,6 +534,7 @@ module ActionMailer #:nodoc:
         @content_type ||= @@default_content_type.dup
         @implicit_parts_order ||= @@default_implicit_parts_order.dup
         @template ||= method_name
+        @default_template_name = @action_name = @template
         @mailer_name ||= self.class.name.underscore
         @parts ||= []
         @headers ||= {}
@@ -535,7 +551,22 @@ module ActionMailer #:nodoc:
         if opts[:file] &amp;&amp; (opts[:file] !~ /\// &amp;&amp; !opts[:file].respond_to?(:render))
           opts[:file] = &quot;#{mailer_name}/#{opts[:file]}&quot;
         end
-        initialize_template_class(body).render(opts)
+
+        begin
+          old_template, @template = @template, initialize_template_class(body)
+          layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
+          @template.render(opts.merge(:layout =&gt; layout))
+        ensure
+          @template = old_template
+        end
+      end
+
+      def default_template_format
+        :html
+      end
+
+      def candidate_for_layout?(options)
+        !@template.send(:_exempt_from_layout?, default_template_name)
       end
 
       def template_root</diff>
      <filename>actionmailer/lib/action_mailer/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -72,7 +72,7 @@ module ActionMailer
         methods.flatten.each do |method|
           master_helper_module.module_eval &lt;&lt;-end_eval
             def #{method}(*args, &amp;block)
-              controller.send!(%(#{method}), *args, &amp;block)
+              controller.__send__(%(#{method}), *args, &amp;block)
             end
           end_eval
         end
@@ -92,7 +92,7 @@ module ActionMailer
           inherited_without_helper(child)
           begin
             child.master_helper_module = Module.new
-            child.master_helper_module.send! :include, master_helper_module
+            child.master_helper_module.__send__(:include, master_helper_module)
             child.helper child.name.to_s.underscore
           rescue MissingSourceFile =&gt; e
             raise unless e.is_missing?(&quot;helpers/#{child.name.to_s.underscore}_helper&quot;)</diff>
      <filename>actionmailer/lib/action_mailer/helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,13 +20,13 @@ class RenderMailer &lt; ActionMailer::Base
     subject    &quot;rendering rxml template&quot;
     from       &quot;tester@example.com&quot;
   end
-  
+
   def included_subtemplate(recipient)
     recipients recipient
     subject    &quot;Including another template in the one being rendered&quot;
     from       &quot;tester@example.com&quot;
   end
-  
+
   def included_old_subtemplate(recipient)
     recipients recipient
     subject    &quot;Including another template in the one being rendered&quot;
@@ -83,17 +83,11 @@ class RenderHelperTest &lt; Test::Unit::TestCase
     mail = RenderMailer.deliver_rxml_template(@recipient)
     assert_equal &quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;\n&lt;test/&gt;&quot;, mail.body.strip
   end
-  
+
   def test_included_subtemplate
     mail = RenderMailer.deliver_included_subtemplate(@recipient)
     assert_equal &quot;Hey Ho, let's go!&quot;, mail.body.strip
   end
-  
-  def test_deprecated_old_subtemplate
-    assert_raises ActionView::ActionViewError do
-      RenderMailer.deliver_included_old_subtemplate(@recipient)
-    end
-  end
 end
 
 class FirstSecondHelperTest &lt; Test::Unit::TestCase</diff>
      <filename>actionmailer/test/mail_render_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -968,3 +968,55 @@ class MethodNamingTest &lt; Test::Unit::TestCase
     end
   end
 end
+
+class RespondToTest &lt; Test::Unit::TestCase
+  class RespondToMailer &lt; ActionMailer::Base; end
+
+  def setup
+    set_delivery_method :test
+  end
+
+  def teardown
+    restore_delivery_method
+  end
+
+  def test_should_respond_to_new
+    assert RespondToMailer.respond_to?(:new)
+  end
+
+  def test_should_respond_to_create_with_template_suffix
+    assert RespondToMailer.respond_to?(:create_any_old_template)
+  end
+
+  def test_should_respond_to_deliver_with_template_suffix
+    assert RespondToMailer.respond_to?(:deliver_any_old_template)
+  end
+
+  def test_should_not_respond_to_new_with_template_suffix
+    assert !RespondToMailer.respond_to?(:new_any_old_template)
+  end
+
+  def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore
+    assert !RespondToMailer.respond_to?(:createany_old_template)
+  end
+
+  def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore
+    assert !RespondToMailer.respond_to?(:deliverany_old_template)
+  end
+
+  def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter
+    assert !RespondToMailer.respond_to?(:create_Any_old_template)
+  end
+
+  def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter
+    assert !RespondToMailer.respond_to?(:deliver_Any_old_template)
+  end
+
+  def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit
+    assert !RespondToMailer.respond_to?(:create_1_template)
+  end
+
+  def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit
+    assert !RespondToMailer.respond_to?(:deliver_1_template)
+  end
+end</diff>
      <filename>actionmailer/test/mail_service_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,49 @@
 *Edge*
 
+* Changed the X-Runtime header to report in milliseconds [DHH]
+
+* Changed BenchmarkHelper#benchmark to report in milliseconds [DHH]
+
+* Changed logging format to be millisecond based and skip misleading stats [DHH]. Went from:
+
+    Completed in 0.10000 (4 reqs/sec) | Rendering: 0.04000 (40%) | DB: 0.00400 (4%) | 200 OK [http://example.com]
+
+  ...to:
+  
+    Completed in 100ms (View: 40, DB: 4) | 200 OK [http://example.com]
+
+* Add support for shallow nesting of routes. #838 [S. Brent Faulkner]
+
+  Example :
+
+  map.resources :users, :shallow =&gt; true do |user|
+    user.resources :posts
+  end
+
+  - GET /users/1/posts (maps to PostsController#index action as usual)
+    named route &quot;user_posts&quot; is added as usual.
+
+  - GET /posts/2 (maps to PostsController#show action as if it were not nested)
+    Additionally, named route &quot;post&quot; is added too.
+
+* Added button_to_remote helper.  #3641 [Donald Piret, Tarmo T&#228;nav]
+
+* Deprecate render_component. Please use render_component plugin from http://github.com/rails/render_component/tree/master [Pratik]
+
+* Routes may be restricted to lists of HTTP methods instead of a single method or :any.  #407 [Brennan Dunn, Gaius Centus Novus]
+    map.resource :posts, :collection =&gt; { :search =&gt; [:get, :post] }
+    map.session 'session', :requirements =&gt; { :method =&gt; [:get, :post, :delete] }
+
+* Deprecated implicit local assignments when rendering partials [Josh Peek]
+
+* Introduce current_cycle helper method to return the current value without bumping the cycle.  #417 [Ken Collins]
+
+* Allow polymorphic_url helper to take url options. #880 [Tarmo T&#228;nav]
+
+* Switched integration test runner to use Rack processor instead of CGI [Josh Peek]
+
+* Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck]
+
 * Added back ActionController::Base.allow_concurrency flag [Josh Peek]
 
 * AbstractRequest.relative_url_root is no longer automatically configured by a HTTP header. It can now be set in your configuration environment with config.action_controller.relative_url_root [Josh Peek]</diff>
      <filename>actionpack/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -21,16 +21,13 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
-$:.unshift(File.dirname(__FILE__)) unless
-  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-
-unless defined?(ActiveSupport)
-  begin
-    $:.unshift &quot;#{File.dirname(__FILE__)}/../../activesupport/lib&quot;
+begin
+  require 'active_support'
+rescue LoadError
+  activesupport_path = &quot;#{File.dirname(__FILE__)}/../../activesupport/lib&quot;
+  if File.directory?(activesupport_path)
+    $:.unshift activesupport_path
     require 'active_support'
-  rescue LoadError
-    require 'rubygems'
-    gem 'activesupport'
   end
 end
 </diff>
      <filename>actionpack/lib/action_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -396,54 +396,31 @@ module ActionController
       #   # The same, but shorter.
       #   assert_select &quot;ol&gt;li&quot;, 4
       def assert_select_rjs(*args, &amp;block)
-        rjs_type = nil
-        arg      = args.shift
+        rjs_type = args.first.is_a?(Symbol) ? args.shift : nil
+        id       = args.first.is_a?(String) ? args.shift : nil
 
         # If the first argument is a symbol, it's the type of RJS statement we're looking
         # for (update, replace, insertion, etc). Otherwise, we're looking for just about
         # any RJS statement.
-        if arg.is_a?(Symbol)
-          rjs_type = arg
-
+        if rjs_type
           if rjs_type == :insert
-            arg = args.shift
-            position  = arg
-            insertion = &quot;insert_#{arg}&quot;.to_sym
-            raise ArgumentError, &quot;Unknown RJS insertion type #{arg}&quot; unless RJS_STATEMENTS[insertion]
+            position  = args.shift
+            insertion = &quot;insert_#{position}&quot;.to_sym
+            raise ArgumentError, &quot;Unknown RJS insertion type #{position}&quot; unless RJS_STATEMENTS[insertion]
             statement = &quot;(#{RJS_STATEMENTS[insertion]})&quot;
           else
             raise ArgumentError, &quot;Unknown RJS statement type #{rjs_type}&quot; unless RJS_STATEMENTS[rjs_type]
             statement = &quot;(#{RJS_STATEMENTS[rjs_type]})&quot;
           end
-          arg = args.shift
         else
           statement = &quot;#{RJS_STATEMENTS[:any]}&quot;
         end
-        position ||= Regexp.new(RJS_INSERTIONS.join('|'))
 
         # Next argument we're looking for is the element identifier. If missing, we pick
-        # any element.
-        if arg.is_a?(String)
-          id = Regexp.quote(arg)
-          arg = args.shift
-        else
-          id = &quot;[^\&quot;]*&quot;
-        end
-
-        pattern =
-          case rjs_type
-            when :chained_replace, :chained_replace_html
-              Regexp.new(&quot;\\$\\(\&quot;#{id}\&quot;\\)#{statement}\\(#{RJS_PATTERN_HTML}\\)&quot;, Regexp::MULTILINE)
-            when :remove, :show, :hide, :toggle
-              Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;\\)&quot;)
-            when :replace, :replace_html
-              Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;, #{RJS_PATTERN_HTML}\\)&quot;)
-            when :insert, :insert_html
-              Regexp.new(&quot;Element.insert\\(\\\&quot;#{id}\\\&quot;, \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);&quot;)
-             else
-              Regexp.union(Regexp.new(&quot;#{statement}\\(\&quot;#{id}\&quot;, #{RJS_PATTERN_HTML}\\)&quot;),
-                Regexp.new(&quot;Element.insert\\(\\\&quot;#{id}\\\&quot;, \\{ #{position}: #{RJS_PATTERN_HTML} \\}\\);&quot;))
-           end
+        # any element, otherwise we replace it in the statement.
+        pattern = Regexp.new(
+          id ? statement.gsub(RJS_ANY_ID, &quot;\&quot;#{id}\&quot;&quot;) : statement
+        )
 
         # Duplicate the body since the next step involves destroying it.
         matches = nil
@@ -472,7 +449,13 @@ module ActionController
           matches
         else
           # RJS statement not found.
-          flunk args.shift || &quot;No RJS statement that replaces or inserts HTML content.&quot;
+          case rjs_type
+            when :remove, :show, :hide, :toggle
+              flunk_message = &quot;No RJS statement that #{rjs_type.to_s}s '#{id}' was rendered.&quot;
+            else
+              flunk_message = &quot;No RJS statement that replaces or inserts HTML content.&quot;
+          end
+          flunk args.shift || flunk_message
         end
       end
 
@@ -582,26 +565,23 @@ module ActionController
 
       protected
         unless const_defined?(:RJS_STATEMENTS)
-          RJS_STATEMENTS = {
-            :replace              =&gt; /Element\.replace/,
-            :replace_html         =&gt; /Element\.update/,
-            :chained_replace      =&gt; /\.replace/,
-            :chained_replace_html =&gt; /\.update/,
-            :remove               =&gt; /Element\.remove/,
-            :show                 =&gt; /Element\.show/,
-            :hide                 =&gt; /Element\.hide/,
-            :toggle                 =&gt; /Element\.toggle/
+          RJS_PATTERN_HTML  = &quot;\&quot;((\\\\\&quot;|[^\&quot;])*)\&quot;&quot;
+          RJS_ANY_ID        = &quot;\&quot;([^\&quot;])*\&quot;&quot;
+          RJS_STATEMENTS    = {
+            :chained_replace      =&gt; &quot;\\$\\(#{RJS_ANY_ID}\\)\\.replace\\(#{RJS_PATTERN_HTML}\\)&quot;,
+            :chained_replace_html =&gt; &quot;\\$\\(#{RJS_ANY_ID}\\)\\.update\\(#{RJS_PATTERN_HTML}\\)&quot;,
+            :replace_html         =&gt; &quot;Element\\.update\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)&quot;,
+            :replace              =&gt; &quot;Element\\.replace\\(#{RJS_ANY_ID}, #{RJS_PATTERN_HTML}\\)&quot;
           }
-          RJS_STATEMENTS[:any] = Regexp.new(&quot;(#{RJS_STATEMENTS.values.join('|')})&quot;)
-          RJS_PATTERN_HTML = /&quot;((\\&quot;|[^&quot;])*)&quot;/
-          RJS_INSERTIONS = [:top, :bottom, :before, :after]
+          [:remove, :show, :hide, :toggle].each do |action|
+            RJS_STATEMENTS[action] = &quot;Element\\.#{action}\\(#{RJS_ANY_ID}\\)&quot;
+          end
+          RJS_INSERTIONS = [&quot;top&quot;, &quot;bottom&quot;, &quot;before&quot;, &quot;after&quot;]
           RJS_INSERTIONS.each do |insertion|
-            RJS_STATEMENTS[&quot;insert_#{insertion}&quot;.to_sym] = /Element.insert\(\&quot;([^\&quot;]*)\&quot;, \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
+            RJS_STATEMENTS[&quot;insert_#{insertion}&quot;.to_sym] = &quot;Element.insert\\(#{RJS_ANY_ID}, \\{ #{insertion}: #{RJS_PATTERN_HTML} \\}\\)&quot;
           end
-          RJS_STATEMENTS[:insert_html] = Regexp.new(RJS_INSERTIONS.collect do |insertion|
-            /Element.insert\(\&quot;([^\&quot;]*)\&quot;, \{ #{insertion.to_s.downcase}: #{RJS_PATTERN_HTML} \}\);/
-          end.join('|'))
-          RJS_PATTERN_EVERYTHING = Regexp.new(&quot;#{RJS_STATEMENTS[:any]}\\(\&quot;([^\&quot;]*)\&quot;, #{RJS_PATTERN_HTML}\\)&quot;, Regexp::MULTILINE)
+          RJS_STATEMENTS[:insert_html] = &quot;Element.insert\\(#{RJS_ANY_ID}, \\{ (#{RJS_INSERTIONS.join('|')}): #{RJS_PATTERN_HTML} \\}\\)&quot;
+          RJS_STATEMENTS[:any] = Regexp.new(&quot;(#{RJS_STATEMENTS.values.join('|')})&quot;)
           RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
         end
 
@@ -615,8 +595,8 @@ module ActionController
             root = HTML::Node.new(nil)
 
             while true
-              next if body.sub!(RJS_PATTERN_EVERYTHING) do |match|
-                html = unescape_rjs($3)
+              next if body.sub!(RJS_STATEMENTS[:any]) do |match|
+                html = unescape_rjs(match)
                 matches = HTML::Document.new(html).root.children.select { |n| n.tag? }
                 root.children.concat matches
                 &quot;&quot;</diff>
      <filename>actionpack/lib/action_controller/assertions/selector_assertions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -260,10 +260,11 @@ module ActionController #:nodoc:
 
     include StatusCodes
 
+    cattr_reader :protected_instance_variables
     # Controller specific instance variables which will not be accessible inside views.
-    @@protected_view_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
-                                    @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
-                                    @_flash @_response)
+    @@protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
+                                        @action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
+                                        @_flash @_response)
 
     # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
     # and images to a dedicated asset server away from the main web server. Example:
@@ -393,16 +394,9 @@ module ActionController #:nodoc:
     # directive. Values should always be specified as strings.
     attr_internal :headers
 
-    # Holds the hash of variables that are passed on to the template class to be made available to the view. This hash
-    # is generated by taking a snapshot of all the instance variables in the current scope just before a template is rendered.
-    attr_accessor :assigns
-
     # Returns the name of the action this controller is processing.
     attr_accessor :action_name
 
-    # Templates that are exempt from layouts
-    @@exempt_from_layout = Set.new([/\.rjs$/])
-
     class &lt;&lt; self
       # Factory for the standard create, process loop where the controller is discarded after processing.
       def process(request, response) #:nodoc:
@@ -520,13 +514,7 @@ module ActionController #:nodoc:
         protected :filter_parameters
       end
 
-      # Don't render layouts for templates with the given extensions.
-      def exempt_from_layout(*extensions)
-        regexps = extensions.collect do |extension|
-          extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
-        end
-        @@exempt_from_layout.merge regexps
-      end
+      delegate :exempt_from_layout, :to =&gt; 'ActionView::Base'
     end
 
     public
@@ -538,7 +526,6 @@ module ActionController #:nodoc:
         assign_shortcuts(request, response)
         initialize_current_url
         assign_names
-        forget_variables_added_to_assigns
 
         log_processing
 
@@ -548,13 +535,16 @@ module ActionController #:nodoc:
           @@guard.synchronize { send(method, *arguments) }
         end
 
-        assign_default_content_type_and_charset
-        response.prepare! unless component_request?
-        response
+        send_response
       ensure
         process_cleanup
       end
 
+      def send_response
+        response.prepare! unless component_request?
+        response
+      end
+
       # Returns a URL that has been rewritten according to the options hash and the defined Routes.
       # (For doing a complete redirect, use redirect_to).
       #
@@ -781,9 +771,6 @@ module ActionController #:nodoc:
       #   render :file =&gt; &quot;/path/to/some/template.erb&quot;, :layout =&gt; true, :status =&gt; 404
       #   render :file =&gt; &quot;c:/path/to/some/template.erb&quot;, :layout =&gt; true, :status =&gt; 404
       #
-      #   # Renders a template relative to the template root and chooses the proper file extension
-      #   render :file =&gt; &quot;some/template&quot;, :use_full_path =&gt; true
-      #
       # === Rendering text
       #
       # Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text
@@ -863,7 +850,7 @@ module ActionController #:nodoc:
         raise DoubleRenderError, &quot;Can only render or redirect once per action&quot; if performed?
 
         if options.nil?
-          return render_for_file(default_template_name, nil, true)
+          return render(:file =&gt; default_template_name, :layout =&gt; true)
         elsif !extra_options.is_a?(Hash)
           raise RenderError, &quot;You called render with invalid options : #{options.inspect}, #{extra_options.inspect}&quot;
         else
@@ -874,6 +861,9 @@ module ActionController #:nodoc:
           end
         end
 
+        response.layout = layout = pick_layout(options)
+        logger.info(&quot;Rendering template within #{layout}&quot;) if logger &amp;&amp; layout
+
         if content_type = options[:content_type]
           response.content_type = content_type.to_s
         end
@@ -883,26 +873,21 @@ module ActionController #:nodoc:
         end
 
         if options.has_key?(:text)
-          render_for_text(options[:text], options[:status])
+          text = layout ? @template.render(options.merge(:text =&gt; options[:text], :layout =&gt; layout)) : options[:text]
+          render_for_text(text, options[:status])
 
         else
           if file = options[:file]
-            render_for_file(file, options[:status], nil, options[:locals] || {})
+            render_for_file(file, options[:status], layout, options[:locals] || {})
 
           elsif template = options[:template]
-            render_for_file(template, options[:status], true, options[:locals] || {})
+            render_for_file(template, options[:status], layout, options[:locals] || {})
 
           elsif inline = options[:inline]
-            add_variables_to_assigns
-            render_for_text(@template.render(options), options[:status])
+            render_for_text(@template.render(options.merge(:layout =&gt; layout)), options[:status])
 
           elsif action_name = options[:action]
-            template = default_template_name(action_name.to_s)
-            if options[:layout] &amp;&amp; !template_exempt_from_layout?(template)
-              render_with_a_layout(:file =&gt; template, :status =&gt; options[:status], :layout =&gt; true)
-            else
-              render_with_no_layout(:file =&gt; template, :status =&gt; options[:status])
-            end
+            render_for_file(default_template_name(action_name.to_s), options[:status], layout)
 
           elsif xml = options[:xml]
             response.content_type ||= Mime::XML
@@ -914,36 +899,26 @@ module ActionController #:nodoc:
             response.content_type ||= Mime::JSON
             render_for_text(json, options[:status])
 
-          elsif partial = options[:partial]
-            partial = default_template_name if partial == true
-            add_variables_to_assigns
-
-            if collection = options[:collection]
-              render_for_text(
-                @template.send!(:render_partial_collection, partial, collection,
-                options[:spacer_template], options[:locals], options[:as]), options[:status]
-              )
+          elsif options[:partial]
+            options[:partial] = default_template_name if options[:partial] == true
+            if layout
+              render_for_text(@template.render(:text =&gt; @template.render(options), :layout =&gt; layout), options[:status])
             else
-              render_for_text(
-                @template.send!(:render_partial, partial,
-                options[:object], options[:locals]), options[:status]
-              )
+              render_for_text(@template.render(options), options[:status])
             end
 
           elsif options[:update]
-            add_variables_to_assigns
-            @template.send! :evaluate_assigns
+            @template.send(:_evaluate_assigns_and_ivars)
 
             generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &amp;block)
             response.content_type = Mime::JS
             render_for_text(generator.to_s, options[:status])
 
           elsif options[:nothing]
-            # Safari doesn't pass the headers of the return if the response is zero length
-            render_for_text(&quot; &quot;, options[:status])
+            render_for_text(nil, options[:status])
 
           else
-            render_for_file(default_template_name, options[:status], true)
+            render_for_file(default_template_name, options[:status], layout)
           end
         end
       end
@@ -954,7 +929,6 @@ module ActionController #:nodoc:
         render(options, &amp;block)
       ensure
         erase_render_results
-        forget_variables_added_to_assigns
         reset_variables_added_to_assigns
       end
 
@@ -1139,10 +1113,9 @@ module ActionController #:nodoc:
 
 
     private
-      def render_for_file(template_path, status = nil, use_full_path = nil, locals = {}) #:nodoc:
-        add_variables_to_assigns
+      def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
         logger.info(&quot;Rendering #{template_path}&quot; + (status ? &quot; (#{status})&quot; : '')) if logger
-        render_for_text(@template.render(:file =&gt; template_path, :locals =&gt; locals), status)
+        render_for_text @template.render(:file =&gt; template_path, :locals =&gt; locals, :layout =&gt; layout), status
       end
 
       def render_for_text(text = nil, status = nil, append_response = false) #:nodoc:
@@ -1154,13 +1127,17 @@ module ActionController #:nodoc:
           response.body ||= ''
           response.body &lt;&lt; text.to_s
         else
-          response.body = text.is_a?(Proc) ? text : text.to_s
+          response.body = case text
+            when Proc then text
+            when nil  then &quot; &quot; # Safari doesn't pass the headers of the return if the response is zero length
+            else           text.to_s
+          end
         end
       end
 
       def initialize_template_class(response)
         response.template = ActionView::Base.new(self.class.view_paths, {}, self)
-        response.template.extend self.class.master_helper_module
+        response.template.helpers.send :include, self.class.master_helper_module
         response.redirected_to = nil
         @performed_render = @performed_redirect = false
       end
@@ -1173,7 +1150,6 @@ module ActionController #:nodoc:
 
         @_session = @_response.session
         @template = @_response.template
-        @assigns  = @_response.template.assigns
 
         @_headers = @_response.headers
       end
@@ -1201,7 +1177,7 @@ module ActionController #:nodoc:
         elsif respond_to? :method_missing
           method_missing action_name
           default_render unless performed?
-        elsif template_exists? &amp;&amp; template_public?
+        elsif template_exists?
           default_render
         else
           raise UnknownAction, &quot;No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}&quot;, caller
@@ -1217,13 +1193,9 @@ module ActionController #:nodoc:
       end
 
       def assign_default_content_type_and_charset
-        response.content_type ||= Mime::HTML
-        response.charset      ||= self.class.default_charset unless sending_file?
-      end
-
-      def sending_file?
-        response.headers[&quot;Content-Transfer-Encoding&quot;] == &quot;binary&quot;
+        response.assign_default_content_type_and_charset!
       end
+      deprecate :assign_default_content_type_and_charset =&gt; :'response.assign_default_content_type_and_charset!'
 
       def action_methods
         self.class.action_methods
@@ -1241,27 +1213,10 @@ module ActionController #:nodoc:
           hidden_actions
       end
 
-      def add_variables_to_assigns
-        unless @variables_added
-          add_instance_variables_to_assigns
-          @variables_added = true
-        end
-      end
-
-      def forget_variables_added_to_assigns
-        @variables_added = nil
-      end
-
       def reset_variables_added_to_assigns
         @template.instance_variable_set(&quot;@assigns_added&quot;, nil)
       end
 
-      def add_instance_variables_to_assigns
-        (instance_variable_names - @@protected_view_variables).each do |var|
-          @assigns[var[1..-1]] = instance_variable_get(var)
-        end
-      end
-
       def request_origin
         # this *needs* to be cached!
         # otherwise you'd get different results if calling it more than once
@@ -1277,16 +1232,7 @@ module ActionController #:nodoc:
       end
 
       def template_exists?(template_name = default_template_name)
-        @template.file_exists?(template_name)
-      end
-
-      def template_public?(template_name = default_template_name)
-        @template.file_public?(template_name)
-      end
-
-      def template_exempt_from_layout?(template_name = default_template_name)
-        template_name = @template.pick_template(template_name).to_s if @template
-        @@exempt_from_layout.any? { |ext| template_name =~ ext }
+        @template.send(:_pick_template, template_name) ? true : false
       rescue ActionView::MissingTemplate
         false
       end</diff>
      <filename>actionpack/lib/action_controller/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,7 +24,7 @@ module ActionController #:nodoc:
         if logger &amp;&amp; logger.level == log_level
           result = nil
           seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
-          logger.add(log_level, &quot;#{title} (#{'%.5f' % seconds})&quot;)
+          logger.add(log_level, &quot;#{title} (#{('%.1f' % (seconds * 1000))}ms)&quot;)
           result
         else
           yield
@@ -42,53 +42,65 @@ module ActionController #:nodoc:
 
     protected
       def render_with_benchmark(options = nil, extra_options = {}, &amp;block)
-        unless logger
-          render_without_benchmark(options, extra_options, &amp;block)
-        else
-          db_runtime = ActiveRecord::Base.connection.reset_runtime if Object.const_defined?(&quot;ActiveRecord&quot;) &amp;&amp; ActiveRecord::Base.connected?
+        if logger
+          if Object.const_defined?(&quot;ActiveRecord&quot;) &amp;&amp; ActiveRecord::Base.connected?
+            db_runtime = ActiveRecord::Base.connection.reset_runtime
+          end
 
           render_output = nil
-          @rendering_runtime = Benchmark::realtime{ render_output = render_without_benchmark(options, extra_options, &amp;block) }
+          @view_runtime = Benchmark::realtime { render_output = render_without_benchmark(options, extra_options, &amp;block) }
 
           if Object.const_defined?(&quot;ActiveRecord&quot;) &amp;&amp; ActiveRecord::Base.connected?
             @db_rt_before_render = db_runtime
             @db_rt_after_render = ActiveRecord::Base.connection.reset_runtime
-            @rendering_runtime -= @db_rt_after_render
+            @view_runtime -= @db_rt_after_render
           end
 
           render_output
+        else
+          render_without_benchmark(options, extra_options, &amp;block)
         end
       end    
 
     private
       def perform_action_with_benchmark
-        unless logger
-          perform_action_without_benchmark
-        else
-          runtime = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
+        if logger
+          seconds = [ Benchmark::measure{ perform_action_without_benchmark }.real, 0.0001 ].max
+          logging_view          = defined?(@view_runtime)
+          logging_active_record = Object.const_defined?(&quot;ActiveRecord&quot;) &amp;&amp; ActiveRecord::Base.connected?
+
+          log_message  = &quot;Completed in #{sprintf(&quot;%.0f&quot;, seconds * 1000)}ms&quot;
+
+          if logging_view || logging_active_record
+            log_message &lt;&lt; &quot; (&quot;
+            log_message &lt;&lt; view_runtime if logging_view
+
+            if logging_active_record
+              log_message &lt;&lt; &quot;, &quot; + active_record_runtime + &quot;)&quot;
+            else
+              &quot;)&quot;
+            end
+          end
 
-          log_message  = &quot;Completed in #{sprintf(&quot;%.5f&quot;, runtime)} (#{(1 / runtime).floor} reqs/sec)&quot;
-          log_message &lt;&lt; rendering_runtime(runtime) if defined?(@rendering_runtime)
-          log_message &lt;&lt; active_record_runtime(runtime) if Object.const_defined?(&quot;ActiveRecord&quot;) &amp;&amp; ActiveRecord::Base.connected?
           log_message &lt;&lt; &quot; | #{headers[&quot;Status&quot;]}&quot;
           log_message &lt;&lt; &quot; [#{complete_request_uri rescue &quot;unknown&quot;}]&quot;
 
           logger.info(log_message)
-          response.headers[&quot;X-Runtime&quot;] = sprintf(&quot;%.5f&quot;, runtime)
+          response.headers[&quot;X-Runtime&quot;] = &quot;#{sprintf(&quot;%.0f&quot;, seconds * 1000)}ms&quot;
+        else
+          perform_action_without_benchmark
         end
       end
 
-      def rendering_runtime(runtime)
-        percentage = @rendering_runtime * 100 / runtime
-        &quot; | Rendering: %.5f (%d%%)&quot; % [@rendering_runtime, percentage.to_i]
+      def view_runtime
+        &quot;View: %.0f&quot; % (@view_runtime * 1000)
       end
 
-      def active_record_runtime(runtime)
-        db_runtime    = ActiveRecord::Base.connection.reset_runtime
-        db_runtime    += @db_rt_before_render if @db_rt_before_render
-        db_runtime    += @db_rt_after_render if @db_rt_after_render
-        db_percentage = db_runtime * 100 / runtime
-        &quot; | DB: %.5f (%d%%)&quot; % [db_runtime, db_percentage.to_i]
+      def active_record_runtime
+        db_runtime = ActiveRecord::Base.connection.reset_runtime
+        db_runtime += @db_rt_before_render if @db_rt_before_render
+        db_runtime += @db_rt_after_render if @db_rt_after_render
+        &quot;DB: %.0f&quot; % (db_runtime * 1000)
       end
   end
 end</diff>
      <filename>actionpack/lib/action_controller/benchmarking.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,8 +38,8 @@ module ActionController #:nodoc:
     #     caches_action :show, :cache_path =&gt; { :project =&gt; 1 }, :expires_in =&gt; 1.hour
     #     caches_action :feed, :cache_path =&gt; Proc.new { |controller|
     #       controller.params[:user_id] ?
-    #         controller.send(:user_list_url, c.params[:user_id], c.params[:id]) :
-    #         controller.send(:list_url, c.params[:id]) }
+    #         controller.send(:user_list_url, controller.params[:user_id], controller.params[:id]) :
+    #         controller.send(:list_url, controller.params[:id]) }
     #   end
     #
     # If you pass :layout =&gt; false, it will only cache your action content. It is useful when your layout has dynamic information.
@@ -90,7 +90,7 @@ module ActionController #:nodoc:
             set_content_type!(controller, cache_path.extension)
             options = { :text =&gt; cache }
             options.merge!(:layout =&gt; true) if cache_layout?
-            controller.send!(:render, options)
+            controller.__send__(:render, options)
             false
           else
             controller.action_cache_path = cache_path
@@ -121,7 +121,7 @@ module ActionController #:nodoc:
           end
 
           def content_for_layout(controller)
-            controller.response.layout &amp;&amp; controller.response.template.instance_variable_get('@content_for_layout')
+            controller.response.layout &amp;&amp; controller.response.template.instance_variable_get('@cached_content_for_layout')
           end
       end
 </diff>
      <filename>actionpack/lib/action_controller/caching/actions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -83,13 +83,13 @@ module ActionController #:nodoc:
             controller_callback_method_name = &quot;#{timing}_#{controller.controller_name.underscore}&quot;
             action_callback_method_name     = &quot;#{controller_callback_method_name}_#{controller.action_name}&quot;
 
-            send!(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
-            send!(action_callback_method_name)     if respond_to?(action_callback_method_name, true)
+            __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
+            __send__(action_callback_method_name)     if respond_to?(action_callback_method_name, true)
           end
 
           def method_missing(method, *arguments)
             return if @controller.nil?
-            @controller.send!(method, *arguments)
+            @controller.__send__(method, *arguments)
           end
       end
     end</diff>
      <filename>actionpack/lib/action_controller/caching/sweeping.rb</filename>
    </modified>
    <modified>
      <diff>@@ -48,7 +48,7 @@ module ActionController #:nodoc:
     def initialize(cgi, session_options = {})
       @cgi = cgi
       @session_options = session_options
-      @env = @cgi.send!(:env_table)
+      @env = @cgi.__send__(:env_table)
       super()
     end
 
@@ -107,7 +107,7 @@ module ActionController #:nodoc:
     end
 
     def method_missing(method_id, *arguments)
-      @cgi.send!(method_id, *arguments) rescue super
+      @cgi.__send__(method_id, *arguments) rescue super
     end
 
     private
@@ -164,7 +164,7 @@ end_msg
       begin
         output.write(@cgi.header(@headers))
 
-        if @cgi.send!(:env_table)['REQUEST_METHOD'] == 'HEAD'
+        if @cgi.__send__(:env_table)['REQUEST_METHOD'] == 'HEAD'
           return
         elsif @body.respond_to?(:call)
           # Flush the output now in case the @body Proc uses</diff>
      <filename>actionpack/lib/action_controller/cgi_process.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,7 @@ module ActionController #:nodoc:
     def self.included(base) #:nodoc:
       base.class_eval do
         include InstanceMethods
+        include ActiveSupport::Deprecation
         extend ClassMethods
         helper HelperMethods
 
@@ -64,7 +65,7 @@ module ActionController #:nodoc:
 
     module HelperMethods
       def render_component(options)
-        @controller.send!(:render_component_as_string, options)
+        @controller.__send__(:render_component_as_string, options)
       end
     end
 
@@ -82,6 +83,7 @@ module ActionController #:nodoc:
             render_for_text(component_response(options, true).body, response.headers[&quot;Status&quot;])
           end
         end
+        deprecate :render_component =&gt; &quot;Please install render_component plugin from http://github.com/rails/render_component/tree/master&quot;
 
         # Returns the component response as a string
         def render_component_as_string(options) #:doc:
@@ -95,6 +97,7 @@ module ActionController #:nodoc:
             end
           end
         end
+        deprecate :render_component_as_string =&gt; &quot;Please install render_component plugin from http://github.com/rails/render_component/tree/master&quot;
 
         def flash_with_components(refresh = false) #:nodoc:
           if !defined?(@_flash) || refresh</diff>
      <filename>actionpack/lib/action_controller/components.rb</filename>
    </modified>
    <modified>
      <diff>@@ -44,7 +44,7 @@ module ActionController
       def to_prepare(identifier = nil, &amp;block)
         @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
         callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier =&gt; identifier)
-        @prepare_dispatch_callbacks | callback
+        @prepare_dispatch_callbacks.replace_or_append!(callback)
       end
 
       # If the block raises, send status code as a last-ditch response.</diff>
      <filename>actionpack/lib/action_controller/dispatcher.rb</filename>
    </modified>
    <modified>
      <diff>@@ -199,8 +199,8 @@ module ActionController #:nodoc:
           Proc.new do |controller, action|
             method.before(controller)
 
-            if controller.send!(:performed?)
-              controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+            if controller.__send__(:performed?)
+              controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
             else
               begin
                 action.call
@@ -223,8 +223,8 @@ module ActionController #:nodoc:
 
       def call(controller, &amp;block)
         super
-        if controller.send!(:performed?)
-          controller.send!(:halt_filter_chain, method, :rendered_or_redirected)
+        if controller.__send__(:performed?)
+          controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
         end
       end
     end</diff>
      <filename>actionpack/lib/action_controller/filters.rb</filename>
    </modified>
    <modified>
      <diff>@@ -204,8 +204,8 @@ module ActionController #:nodoc:
 
           begin
             child.master_helper_module = Module.new
-            child.master_helper_module.send! :include, master_helper_module
-            child.send! :default_helper_module!
+            child.master_helper_module.__send__ :include, master_helper_module
+            child.__send__ :default_helper_module!
           rescue MissingSourceFile =&gt; e
             raise unless e.is_missing?(&quot;helpers/#{child.controller_path}_helper&quot;)
           end</diff>
      <filename>actionpack/lib/action_controller/helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -117,7 +117,7 @@ module ActionController
 
       def authentication_request(controller, realm)
         controller.headers[&quot;WWW-Authenticate&quot;] = %(Basic realm=&quot;#{realm.gsub(/&quot;/, &quot;&quot;)}&quot;)
-        controller.send! :render, :text =&gt; &quot;HTTP Basic: Access denied.\n&quot;, :status =&gt; :unauthorized
+        controller.__send__ :render, :text =&gt; &quot;HTTP Basic: Access denied.\n&quot;, :status =&gt; :unauthorized
       end
     end
   end</diff>
      <filename>actionpack/lib/action_controller/http_authentication.rb</filename>
    </modified>
    <modified>
      <diff>@@ -228,21 +228,6 @@ module ActionController
       end
 
       private
-        class StubCGI &lt; CGI #:nodoc:
-          attr_accessor :stdinput, :stdoutput, :env_table
-
-          def initialize(env, stdinput = nil)
-            self.env_table = env
-            self.stdoutput = StringIO.new
-
-            super
-
-            stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding)
-            stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding)
-            @stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
-          end
-        end
-
         # Tailors the session based on the given URI, setting the HTTPS value
         # and the hostname.
         def interpret_uri(path)
@@ -290,9 +275,8 @@ module ActionController
 
           ActionController::Base.clear_last_instantiation!
 
-          cgi = StubCGI.new(env, data)
-          ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput)
-          @result = cgi.stdoutput.string
+          env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '')
+          @status, @headers, result_body = ActionController::Dispatcher.new.call(env)
           @request_count += 1
 
           @controller = ActionController::Base.last_instantiation
@@ -306,32 +290,34 @@ module ActionController
 
           @html_document = nil
 
-          parse_result
-          return status
-        rescue MultiPartNeededException
-          boundary = &quot;----------XnJLe9ZIbbGUYtzPQJ16u1&quot;
-          status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({&quot;CONTENT_TYPE&quot; =&gt; &quot;multipart/form-data; boundary=#{boundary}&quot;}))
-          return status
-        end
+          # Inject status back in for backwords compatibility with CGI
+          @headers['Status'] = @status
 
-        # Parses the result of the response and extracts the various values,
-        # like cookies, status, headers, etc.
-        def parse_result
-          response_headers, result_body = @result.split(/\r\n\r\n/, 2)
+          @status, @status_message = @status.split(/ /)
+          @status = @status.to_i
 
-          @headers = Hash.new { |h,k| h[k] = [] }
-          response_headers.to_s.each_line do |line|
-            key, value = line.strip.split(/:\s*/, 2)
-            @headers[key.downcase] &lt;&lt; value
+          cgi_headers = Hash.new { |h,k| h[k] = [] }
+          @headers.each do |key, value|
+            cgi_headers[key.downcase] &lt;&lt; value
           end
+          cgi_headers['set-cookie'] = cgi_headers['set-cookie'].first
+          @headers = cgi_headers
 
-          (@headers['set-cookie'] || [] ).each do |string|
-            name, value = string.match(/^([^=]*)=([^;]*);/)[1,2]
+          @response.headers['cookie'] ||= []
+          (@headers['set-cookie'] || []).each do |cookie|
+            name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
             @cookies[name] = value
+
+            # Fake CGI cookie header
+            # DEPRECATE: Use response.headers[&quot;Set-Cookie&quot;] instead
+            @response.headers['cookie'] &lt;&lt; CGI::Cookie::new(&quot;name&quot; =&gt; name, &quot;value&quot; =&gt; value)
           end
 
-          @status, @status_message = @headers[&quot;status&quot;].first.to_s.split(/ /)
-          @status = @status.to_i
+          return status
+        rescue MultiPartNeededException
+          boundary = &quot;----------XnJLe9ZIbbGUYtzPQJ16u1&quot;
+          status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({&quot;CONTENT_TYPE&quot; =&gt; &quot;multipart/form-data; boundary=#{boundary}&quot;}))
+          return status
         end
 
         # Encode the cookies hash in a format suitable for passing to a
@@ -344,13 +330,15 @@ module ActionController
 
         # Get a temporary URL writer object
         def generic_url_rewriter
-          cgi = StubCGI.new('REQUEST_METHOD' =&gt; &quot;GET&quot;,
-                            'QUERY_STRING'   =&gt; &quot;&quot;,
-                            &quot;REQUEST_URI&quot;    =&gt; &quot;/&quot;,
-                            &quot;HTTP_HOST&quot;      =&gt; host,
-                            &quot;SERVER_PORT&quot;    =&gt; https? ? &quot;443&quot; : &quot;80&quot;,
-                            &quot;HTTPS&quot;          =&gt; https? ? &quot;on&quot; : &quot;off&quot;)
-          ActionController::UrlRewriter.new(ActionController::CgiRequest.new(cgi), {})
+          env = {
+            'REQUEST_METHOD' =&gt; &quot;GET&quot;,
+            'QUERY_STRING'   =&gt; &quot;&quot;,
+            &quot;REQUEST_URI&quot;    =&gt; &quot;/&quot;,
+            &quot;HTTP_HOST&quot;      =&gt; host,
+            &quot;SERVER_PORT&quot;    =&gt; https? ? &quot;443&quot; : &quot;80&quot;,
+            &quot;HTTPS&quot;          =&gt; https? ? &quot;on&quot; : &quot;off&quot;
+          }
+          ActionController::UrlRewriter.new(ActionController::RackRequest.new(env), {})
         end
 
         def name_with_prefix(prefix, name)
@@ -451,12 +439,12 @@ EOF
       end
 
       %w(get post put head delete cookies assigns
-         xml_http_request get_via_redirect post_via_redirect).each do |method|
+         xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
         define_method(method) do |*args|
           reset! unless @integration_session
           # reset the html_document variable, but only for new get/post calls
           @html_document = nil unless %w(cookies assigns).include?(method)
-          returning @integration_session.send!(method, *args) do
+          returning @integration_session.__send__(method, *args) do
             copy_session_variables!
           end
         end
@@ -481,12 +469,12 @@ EOF
           self.class.fixture_table_names.each do |table_name|
             name = table_name.tr(&quot;.&quot;, &quot;_&quot;)
             next unless respond_to?(name)
-            extras.send!(:define_method, name) { |*args| delegate.send(name, *args) }
+            extras.__send__(:define_method, name) { |*args| delegate.send(name, *args) }
           end
         end
 
         # delegate add_assertion to the test case
-        extras.send!(:define_method, :add_assertion) { test_result.add_assertion }
+        extras.__send__(:define_method, :add_assertion) { test_result.add_assertion }
         session.extend(extras)
         session.delegate = self
         session.test_result = @_result
@@ -500,7 +488,7 @@ EOF
       def copy_session_variables! #:nodoc:
         return unless @integration_session
         %w(controller response request).each do |var|
-          instance_variable_set(&quot;@#{var}&quot;, @integration_session.send!(var))
+          instance_variable_set(&quot;@#{var}&quot;, @integration_session.__send__(var))
         end
       end
 </diff>
      <filename>actionpack/lib/action_controller/integration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,11 +3,6 @@ module ActionController #:nodoc:
     def self.included(base)
       base.extend(ClassMethods)
       base.class_eval do
-        # NOTE: Can't use alias_method_chain here because +render_without_layout+ is already
-        # defined as a publicly exposed method
-        alias_method :render_with_no_layout, :render
-        alias_method :render, :render_with_a_layout
-
         class &lt;&lt; self
           alias_method_chain :inherited, :layout
         end
@@ -169,17 +164,17 @@ module ActionController #:nodoc:
       # performance and have access to them as any normal template would.
       def layout(template_name, conditions = {}, auto = false)
         add_layout_conditions(conditions)
-        write_inheritable_attribute &quot;layout&quot;, template_name
-        write_inheritable_attribute &quot;auto_layout&quot;, auto
+        write_inheritable_attribute(:layout, template_name)
+        write_inheritable_attribute(:auto_layout, auto)
       end
 
       def layout_conditions #:nodoc:
-        @layout_conditions ||= read_inheritable_attribute(&quot;layout_conditions&quot;)
+        @layout_conditions ||= read_inheritable_attribute(:layout_conditions)
       end
 
       def default_layout(format) #:nodoc:
-        layout = read_inheritable_attribute(&quot;layout&quot;)
-        return layout unless read_inheritable_attribute(&quot;auto_layout&quot;)
+        layout = read_inheritable_attribute(:layout)
+        return layout unless read_inheritable_attribute(:auto_layout)
         @default_layout ||= {}
         @default_layout[format] ||= default_layout_with_format(format, layout)
         @default_layout[format]
@@ -199,7 +194,7 @@ module ActionController #:nodoc:
         end
 
         def add_layout_conditions(conditions)
-          write_inheritable_hash &quot;layout_conditions&quot;, normalize_conditions(conditions)
+          write_inheritable_hash(:layout_conditions, normalize_conditions(conditions))
         end
 
         def normalize_conditions(conditions)
@@ -221,10 +216,10 @@ module ActionController #:nodoc:
     # object). If the layout was defined without a directory, layouts is assumed. So &lt;tt&gt;layout &quot;weblog/standard&quot;&lt;/tt&gt; will return
     # weblog/standard, but &lt;tt&gt;layout &quot;standard&quot;&lt;/tt&gt; will return layouts/standard.
     def active_layout(passed_layout = nil)
-      layout = passed_layout || self.class.default_layout(response.template.template_format)
+      layout = passed_layout || self.class.default_layout(default_template_format)
       active_layout = case layout
         when String then layout
-        when Symbol then send!(layout)
+        when Symbol then __send__(layout)
         when Proc   then layout.call(self)
       end
 
@@ -240,51 +235,24 @@ module ActionController #:nodoc:
       end
     end
 
-    protected
-      def render_with_a_layout(options = nil, extra_options = {}, &amp;block) #:nodoc:
-        template_with_options = options.is_a?(Hash)
-
-        if (layout = pick_layout(template_with_options, options)) &amp;&amp; apply_layout?(template_with_options, options)
-          options = options.merge :layout =&gt; false if template_with_options
-          logger.info(&quot;Rendering template within #{layout}&quot;) if logger
-
-          content_for_layout = render_with_no_layout(options, extra_options, &amp;block)
-          erase_render_results
-          add_variables_to_assigns
-          @template.instance_variable_set(&quot;@content_for_layout&quot;, content_for_layout)
-          response.layout = layout
-          status = template_with_options ? options[:status] : nil
-          render_for_text(@template.render(layout), status)
-        else
-          render_with_no_layout(options, extra_options, &amp;block)
-        end
-      end
-
-
     private
-      def apply_layout?(template_with_options, options)
-        return false if options == :update
-        template_with_options ?  candidate_for_layout?(options) : !template_exempt_from_layout?
-      end
-
       def candidate_for_layout?(options)
-        (options.has_key?(:layout) &amp;&amp; options[:layout] != false) ||
-          options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing).compact.empty? &amp;&amp;
-          !template_exempt_from_layout?(options[:template] || default_template_name(options[:action]))
+        options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty? &amp;&amp;
+          !@template.__send__(:_exempt_from_layout?, options[:template] || default_template_name(options[:action]))
       end
 
-      def pick_layout(template_with_options, options)
-        if template_with_options
-          case layout = options[:layout]
-            when FalseClass
-              nil
-            when NilClass, TrueClass
-              active_layout if action_has_layout?
-            else
-              active_layout(layout)
+      def pick_layout(options)
+        if options.has_key?(:layout)
+          case layout = options.delete(:layout)
+          when FalseClass
+            nil
+          when NilClass, TrueClass
+            active_layout if action_has_layout? &amp;&amp; !@template.__send__(:_exempt_from_layout?, default_template_name)
+          else
+            active_layout(layout)
           end
         else
-          active_layout if action_has_layout?
+          active_layout if action_has_layout? &amp;&amp; candidate_for_layout?(options)
         end
       end
 
@@ -304,7 +272,13 @@ module ActionController #:nodoc:
       end
 
       def layout_directory?(layout_name)
-        @template.file_exists?(&quot;#{File.join('layouts', layout_name)}.#{@template.template_format}&quot;)
+        @template.__send__(:_pick_template, &quot;#{File.join('layouts', layout_name)}.#{@template.template_format}&quot;) ? true : false
+      rescue ActionView::MissingTemplate
+        false
+      end
+
+      def default_template_format
+        response.template.template_format
       end
   end
 end</diff>
      <filename>actionpack/lib/action_controller/layout.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+require 'set'
+
 module Mime
   SET              = []
   EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }</diff>
      <filename>actionpack/lib/action_controller/mime_type.rb</filename>
    </modified>
    <modified>
      <diff>@@ -102,7 +102,13 @@ module ActionController
       args &lt;&lt; format if format
       
       named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options)
-      send!(named_route, *args)
+
+      url_options = options.except(:action, :routing_type, :format)
+      unless url_options.empty?
+        args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args &lt;&lt; url_options
+      end
+
+      __send__(named_route, *args)
     end
 
     # Returns the path component of a URL for the given record. It uses
@@ -114,19 +120,19 @@ module ActionController
 
     %w(edit new formatted).each do |action|
       module_eval &lt;&lt;-EOT, __FILE__, __LINE__
-        def #{action}_polymorphic_url(record_or_hash)
-          polymorphic_url(record_or_hash, :action =&gt; &quot;#{action}&quot;)
+        def #{action}_polymorphic_url(record_or_hash, options = {})
+          polymorphic_url(record_or_hash, options.merge(:action =&gt; &quot;#{action}&quot;))
         end
 
-        def #{action}_polymorphic_path(record_or_hash)
-          polymorphic_url(record_or_hash, :action =&gt; &quot;#{action}&quot;, :routing_type =&gt; :path)
+        def #{action}_polymorphic_path(record_or_hash, options = {})
+          polymorphic_url(record_or_hash, options.merge(:action =&gt; &quot;#{action}&quot;, :routing_type =&gt; :path))
         end
       EOT
     end
 
     private
       def action_prefix(options)
-        options[:action] ? &quot;#{options[:action]}_&quot; : &quot;&quot;
+        options[:action] ? &quot;#{options[:action]}_&quot; : options[:format] ? &quot;formatted_&quot; : &quot;&quot;
       end
 
       def routing_type(options)
@@ -143,7 +149,7 @@ module ActionController
             if parent.is_a?(Symbol) || parent.is_a?(String)
               string &lt;&lt; &quot;#{parent}_&quot;
             else
-              string &lt;&lt; &quot;#{RecordIdentifier.send!(&quot;singular_class_name&quot;, parent)}_&quot;
+              string &lt;&lt; &quot;#{RecordIdentifier.__send__(&quot;singular_class_name&quot;, parent)}_&quot;
             end
           end
         end
@@ -151,7 +157,7 @@ module ActionController
         if record.is_a?(Symbol) || record.is_a?(String)
           route &lt;&lt; &quot;#{record}_&quot;
         else
-          route &lt;&lt; &quot;#{RecordIdentifier.send!(&quot;#{inflection}_class_name&quot;, record)}_&quot;
+          route &lt;&lt; &quot;#{RecordIdentifier.__send__(&quot;#{inflection}_class_name&quot;, record)}_&quot;
         end
 
         action_prefix(options) + namespace + route + routing_type(options).to_s</diff>
      <filename>actionpack/lib/action_controller/polymorphic_routes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,7 +25,7 @@ module ActionController #:nodoc:
     end
 
     %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO
-        PATH_TRANSLATED QUERY_STRING REMOTE_HOST
+        PATH_TRANSLATED REMOTE_HOST
         REMOTE_IDENT REMOTE_USER SCRIPT_NAME
         SERVER_NAME SERVER_PROTOCOL
 
@@ -37,6 +37,15 @@ module ActionController #:nodoc:
       end
     end
 
+    def query_string
+      qs = super
+      if !qs.blank?
+        qs
+      else
+        @env['QUERY_STRING']
+      end
+    end
+
     def body_stream #:nodoc:
       @env['rack.input']
     end
@@ -156,6 +165,10 @@ end_msg
     end
 
     def out(output = $stdout, &amp;block)
+      # Nasty hack because CGI sessions are closed after the normal
+      # prepare! statement
+      set_cookies!
+
       @block = block
       @status = headers.delete(&quot;Status&quot;)
       if [204, 304].include?(status.to_i)
@@ -200,7 +213,7 @@ end_msg
       convert_language!
       convert_expires!
       set_status!
-      set_cookies!
+      # set_cookies!
     end
 
     private</diff>
      <filename>actionpack/lib/action_controller/rack_process.rb</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,7 @@ module ActionController
     # such as { 'RAILS_ENV' =&gt; 'production' }.
     attr_reader :env
 
-    # The true HTTP request method as a lowercase symbol, such as &lt;tt&gt;:get&lt;/tt&gt;.
+    # The true HTTP request \method as a lowercase symbol, such as &lt;tt&gt;:get&lt;/tt&gt;.
     # UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS.
     def request_method
       method = @env['REQUEST_METHOD']
@@ -32,7 +32,7 @@ module ActionController
     end
     memoize :request_method
 
-    # The HTTP request method as a lowercase symbol, such as &lt;tt&gt;:get&lt;/tt&gt;.
+    # The HTTP request \method as a lowercase symbol, such as &lt;tt&gt;:get&lt;/tt&gt;.
     # Note, HEAD is returned as &lt;tt&gt;:get&lt;/tt&gt; since the two are functionally
     # equivalent from the application's perspective.
     def method
@@ -59,19 +59,21 @@ module ActionController
       request_method == :delete
     end
 
-    # Is this a HEAD request? &lt;tt&gt;request.method&lt;/tt&gt; sees HEAD as &lt;tt&gt;:get&lt;/tt&gt;,
-    # so check the HTTP method directly.
+    # Is this a HEAD request? Since &lt;tt&gt;request.method&lt;/tt&gt; sees HEAD as &lt;tt&gt;:get&lt;/tt&gt;,
+    # this \method checks the actual HTTP \method directly.
     def head?
       request_method == :head
     end
 
     # Provides access to the request's HTTP headers, for example:
-    #  request.headers[&quot;Content-Type&quot;] # =&gt; &quot;text/plain&quot;
+    #
+    #   request.headers[&quot;Content-Type&quot;] # =&gt; &quot;text/plain&quot;
     def headers
       ActionController::Http::Headers.new(@env)
     end
     memoize :headers
 
+    # Returns the content length of the request as an integer.
     def content_length
       @env['CONTENT_LENGTH'].to_i
     end
@@ -79,14 +81,14 @@ module ActionController
 
     # The MIME type of the HTTP request, such as Mime::XML.
     #
-    # For backward compatibility, the post format is extracted from the
+    # For backward compatibility, the post \format is extracted from the
     # X-Post-Data-Format HTTP header if present.
     def content_type
       Mime::Type.lookup(content_type_without_parameters)
     end
     memoize :content_type
 
-    # Returns the accepted MIME type for the request
+    # Returns the accepted MIME type for the request.
     def accepts
       header = @env['HTTP_ACCEPT'].to_s.strip
 
@@ -100,7 +102,7 @@ module ActionController
 
     def if_modified_since
       if since = env['HTTP_IF_MODIFIED_SINCE']
-        Time.rfc2822(since)
+        Time.rfc2822(since) rescue nil
       end
     end
     memoize :if_modified_since
@@ -123,7 +125,7 @@ module ActionController
       not_modified?(response.last_modified) || etag_matches?(response.etag)
     end
 
-    # Returns the Mime type for the format used in the request.
+    # Returns the Mime type for the \format used in the request.
     #
     #   GET /posts/5.xml   | request.format =&gt; Mime::XML
     #   GET /posts/5.xhtml | request.format =&gt; Mime::HTML
@@ -142,8 +144,8 @@ module ActionController
     end
 
 
-    # Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.
-    # Example:
+    # Sets the \format by string extension, which can be used to force custom formats
+    # that are not controlled by the extension.
     #
     #   class ApplicationController &lt; ActionController::Base
     #     before_filter :adjust_format_for_iphone
@@ -159,7 +161,7 @@ module ActionController
     end
 
     # Returns a symbolized version of the &lt;tt&gt;:format&lt;/tt&gt; parameter of the request.
-    # If no format is given it returns &lt;tt&gt;:js&lt;/tt&gt;for AJAX requests and &lt;tt&gt;:html&lt;/tt&gt;
+    # If no \format is given it returns &lt;tt&gt;:js&lt;/tt&gt;for Ajax requests and &lt;tt&gt;:html&lt;/tt&gt;
     # otherwise.
     def template_format
       parameter_format = parameters[:format]
@@ -190,17 +192,19 @@ module ActionController
     # the right-hand-side of X-Forwarded-For
     TRUSTED_PROXIES = /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
 
-    # Determine originating IP address.  REMOTE_ADDR is the standard
+    # Determines originating IP address.  REMOTE_ADDR is the standard
     # but will fail if the user is behind a proxy.  HTTP_CLIENT_IP and/or
     # HTTP_X_FORWARDED_FOR are set by proxies so check for these if
     # REMOTE_ADDR is a proxy.  HTTP_X_FORWARDED_FOR may be a comma-
     # delimited list in the case of multiple chained proxies; the last
     # address which is not trusted is the originating IP.
     def remote_ip
-      if TRUSTED_PROXIES !~ @env['REMOTE_ADDR']
-        return @env['REMOTE_ADDR']
-      end
+      remote_addr_list = @env['REMOTE_ADDR'] &amp;&amp; @env['REMOTE_ADDR'].split(',').collect(&amp;:strip)
 
+      unless remote_addr_list.blank?
+        not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES}
+        return not_trusted_addrs.first unless not_trusted_addrs.empty?
+      end
       remote_ips = @env['HTTP_X_FORWARDED_FOR'] &amp;&amp; @env['HTTP_X_FORWARDED_FOR'].split(',')
 
       if @env.include? 'HTTP_CLIENT_IP'
@@ -235,13 +239,13 @@ EOM
     memoize :server_software
 
 
-    # Returns the complete URL used for this request
+    # Returns the complete URL used for this request.
     def url
       protocol + host_with_port + request_uri
     end
     memoize :url
 
-    # Return 'https://' if this is an SSL request and 'http://' otherwise.
+    # Returns 'https://' if this is an SSL request and 'http://' otherwise.
     def protocol
       ssl? ? 'https://' : 'http://'
     end
@@ -252,6 +256,7 @@ EOM
       @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
     end
 
+    # Returns the \host for this request, such as &quot;example.com&quot;.
     def raw_host_with_port
       if forwarded = env[&quot;HTTP_X_FORWARDED_HOST&quot;]
         forwarded.split(/,\s?/).last
@@ -266,8 +271,8 @@ EOM
     end
     memoize :host
 
-    # Returns a host:port string for this request, such as example.com or
-    # example.com:8080.
+    # Returns a \host:\port string for this request, such as &quot;example.com&quot; or
+    # &quot;example.com:8080&quot;.
     def host_with_port
       &quot;#{host}#{port_string}&quot;
     end
@@ -283,7 +288,7 @@ EOM
     end
     memoize :port
 
-    # Returns the standard port number for this request's protocol
+    # Returns the standard \port number for this request's protocol.
     def standard_port
       case protocol
         when 'https://' then 443
@@ -291,13 +296,13 @@ EOM
       end
     end
 
-    # Returns a port suffix like &quot;:8080&quot; if the port number of this request
-    # is not the default HTTP port 80 or HTTPS port 443.
+    # Returns a \port suffix like &quot;:8080&quot; if the \port number of this request
+    # is not the default HTTP \port 80 or HTTPS \port 443.
     def port_string
       port == standard_port ? '' : &quot;:#{port}&quot;
     end
 
-    # Returns the domain part of a host, such as rubyonrails.org in &quot;www.rubyonrails.org&quot;. You can specify
+    # Returns the \domain part of a \host, such as &quot;rubyonrails.org&quot; in &quot;www.rubyonrails.org&quot;. You can specify
     # a different &lt;tt&gt;tld_length&lt;/tt&gt;, such as 2 to catch rubyonrails.co.uk in &quot;www.rubyonrails.co.uk&quot;.
     def domain(tld_length = 1)
       return nil unless named_host?(host)
@@ -305,8 +310,9 @@ EOM
       host.split('.').last(1 + tld_length).join('.')
     end
 
-    # Returns all the subdomains as an array, so [&quot;dev&quot;, &quot;www&quot;] would be returned for &quot;dev.www.rubyonrails.org&quot;.
-    # You can specify a different &lt;tt&gt;tld_length&lt;/tt&gt;, such as 2 to catch [&quot;www&quot;] instead of [&quot;www&quot;, &quot;rubyonrails&quot;]
+    # Returns all the \subdomains as an array, so &lt;tt&gt;[&quot;dev&quot;, &quot;www&quot;]&lt;/tt&gt; would be
+    # returned for &quot;dev.www.rubyonrails.org&quot;. You can specify a different &lt;tt&gt;tld_length&lt;/tt&gt;,
+    # such as 2 to catch &lt;tt&gt;[&quot;www&quot;]&lt;/tt&gt; instead of &lt;tt&gt;[&quot;www&quot;, &quot;rubyonrails&quot;]&lt;/tt&gt;
     # in &quot;www.rubyonrails.co.uk&quot;.
     def subdomains(tld_length = 1)
       return [] unless named_host?(host)
@@ -314,7 +320,7 @@ EOM
       parts[0..-(tld_length+2)]
     end
 
-    # Return the query string, accounting for server idiosyncrasies.
+    # Returns the query string, accounting for server idiosyncrasies.
     def query_string
       if uri = @env['REQUEST_URI']
         uri.split('?', 2)[1] || ''
@@ -324,7 +330,7 @@ EOM
     end
     memoize :query_string
 
-    # Return the request URI, accounting for server idiosyncrasies.
+    # Returns the request URI, accounting for server idiosyncrasies.
     # WEBrick includes the full URL. IIS leaves REQUEST_URI blank.
     def request_uri
       if uri = @env['REQUEST_URI']
@@ -350,7 +356,8 @@ EOM
     end
     memoize :request_uri
 
-    # Returns the interpreted path to requested resource after all the installation directory of this application was taken into account
+    # Returns the interpreted \path to requested resource after all the installation
+    # directory of this application was taken into account.
     def path
       path = (uri = request_uri) ? uri.split('?').first.to_s : ''
 
@@ -360,7 +367,7 @@ EOM
     end
     memoize :path
 
-    # Read the request body. This is useful for web services that need to
+    # Read the request \body. This is useful for web services that need to
     # work with raw requests directly.
     def raw_post
       unless env.include? 'RAW_POST_DATA'
@@ -370,7 +377,7 @@ EOM
       env['RAW_POST_DATA']
     end
 
-    # Returns both GET and POST parameters in a single hash.
+    # Returns both GET and POST \parameters in a single hash.
     def parameters
       @parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
     end
@@ -380,17 +387,17 @@ EOM
       @symbolized_path_parameters = @parameters = nil
     end
 
-    # The same as &lt;tt&gt;path_parameters&lt;/tt&gt; with explicitly symbolized keys
+    # The same as &lt;tt&gt;path_parameters&lt;/tt&gt; with explicitly symbolized keys.
     def symbolized_path_parameters
       @symbolized_path_parameters ||= path_parameters.symbolize_keys
     end
 
-    # Returns a hash with the parameters used to form the path of the request.
-    # Returned hash keys are strings.  See &lt;tt&gt;symbolized_path_parameters&lt;/tt&gt; for symbolized keys.
-    #
-    # Example:
+    # Returns a hash with the \parameters used to form the \path of the request.
+    # Returned hash keys are strings:
     #
     #   {'action' =&gt; 'my_action', 'controller' =&gt; 'my_controller'}
+    #
+    # See &lt;tt&gt;symbolized_path_parameters&lt;/tt&gt; for symbolized keys.
     def path_parameters
       @path_parameters ||= {}
     end</diff>
      <filename>actionpack/lib/action_controller/request.rb</filename>
    </modified>
    <modified>
      <diff>@@ -148,7 +148,7 @@ module ActionController #:nodoc:
       end
 
       # Overwrite to implement public exception handling (for requests answering false to &lt;tt&gt;local_request?&lt;/tt&gt;).  By
-      # default will call render_optional_error_file.  Override this method to provide more user friendly error messages.s
+      # default will call render_optional_error_file.  Override this method to provide more user friendly error messages.
       def rescue_action_in_public(exception) #:doc:
         render_optional_error_file response_code_for_rescue(exception)
       end
@@ -177,12 +177,9 @@ module ActionController #:nodoc:
       # Render detailed diagnostics for unhandled exceptions rescued from
       # a controller action.
       def rescue_action_locally(exception)
-        add_variables_to_assigns
         @template.instance_variable_set(&quot;@exception&quot;, exception)
         @template.instance_variable_set(&quot;@rescues_path&quot;, File.dirname(rescues_path(&quot;stub&quot;)))
-        @template.send!(:assign_variables_from_controller)
-
-        @template.instance_variable_set(&quot;@contents&quot;, @template.render(:file =&gt; template_path_for_local_rescue(exception), :use_full_path =&gt; false))
+        @template.instance_variable_set(&quot;@contents&quot;, @template.render(:file =&gt; template_path_for_local_rescue(exception)))
 
         response.content_type = Mime::HTML
         render_for_file(rescues_path(&quot;layout&quot;), response_code_for_rescue(exception))</diff>
      <filename>actionpack/lib/action_controller/rescue.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,23 +1,23 @@
 module ActionController
   # == Overview
   #
-  # ActionController::Resources are a way of defining RESTful resources.  A RESTful resource, in basic terms,
+  # ActionController::Resources are a way of defining RESTful \resources.  A RESTful \resource, in basic terms,
   # is something that can be pointed at and it will respond with a representation of the data requested.
   # In real terms this could mean a user with a browser requests an HTML page, or that a desktop application
   # requests XML data.
   #
   # RESTful design is based on the assumption that there are four generic verbs that a user of an
-  # application can request from a resource (the noun).
+  # application can request from a \resource (the noun).
   #
-  # Resources can be requested using four basic HTTP verbs (GET, POST, PUT, DELETE), the method used
+  # \Resources can be requested using four basic HTTP verbs (GET, POST, PUT, DELETE), the method used
   # denotes the type of action that should take place.
   #
   # === The Different Methods and their Usage
   #
-  # [+GET+]     Requests for a resource, no saving or editing of a resource should occur in a GET request
-  # [+POST+]    Creation of resources
-  # [+PUT+]     Editing of attributes on a resource
-  # [+DELETE+]  Deletion of a resource
+  # * GET    - Requests for a \resource, no saving or editing of a \resource should occur in a GET request.
+  # * POST   - Creation of \resources.
+  # * PUT    - Editing of attributes on a \resource.
+  # * DELETE - Deletion of a \resource.
   #
   # === Examples
   #
@@ -85,16 +85,24 @@ module ActionController
         @new_path  ||= &quot;#{path}/#{new_action}&quot;
       end
 
+      def shallow_path_prefix
+        @shallow_path_prefix ||= &quot;#{path_prefix unless @options[:shallow]}&quot;
+      end
+
       def member_path
-        @member_path ||= &quot;#{path}/:id&quot;
+        @member_path ||= &quot;#{shallow_path_prefix}/#{path_segment}/:id&quot;
       end
 
       def nesting_path_prefix
-        @nesting_path_prefix ||= &quot;#{path}/:#{singular}_id&quot;
+        @nesting_path_prefix ||= &quot;#{shallow_path_prefix}/#{path_segment}/:#{singular}_id&quot;
+      end
+
+      def shallow_name_prefix
+        @shallow_name_prefix ||= &quot;#{name_prefix unless @options[:shallow]}&quot;
       end
 
       def nesting_name_prefix
-        &quot;#{name_prefix}#{singular}_&quot;
+        &quot;#{shallow_name_prefix}#{singular}_&quot;
       end
 
       def action_separator
@@ -141,12 +149,14 @@ module ActionController
         super
       end
 
+      alias_method :shallow_path_prefix, :path_prefix
+      alias_method :shallow_name_prefix, :name_prefix
       alias_method :member_path,         :path
       alias_method :nesting_path_prefix, :path
     end
 
     # Creates named routes for implementing verb-oriented controllers
-    # for a collection resource.
+    # for a collection \resource.
     #
     # For example:
     #
@@ -238,23 +248,24 @@ module ActionController
     #
     # The +resources+ method accepts the following options to customize the resulting routes:
     # * &lt;tt&gt;:collection&lt;/tt&gt; - Add named routes for other actions that operate on the collection.
-    #   Takes a hash of &lt;tt&gt;#{action} =&gt; #{method}&lt;/tt&gt;, where method is &lt;tt&gt;:get&lt;/tt&gt;/&lt;tt&gt;:post&lt;/tt&gt;/&lt;tt&gt;:put&lt;/tt&gt;/&lt;tt&gt;:delete&lt;/tt&gt;
-    #   or &lt;tt&gt;:any&lt;/tt&gt; if the method does not matter.  These routes map to a URL like /messages/rss, with a route of +rss_messages_url+.
+    #   Takes a hash of &lt;tt&gt;#{action} =&gt; #{method}&lt;/tt&gt;, where method is &lt;tt&gt;:get&lt;/tt&gt;/&lt;tt&gt;:post&lt;/tt&gt;/&lt;tt&gt;:put&lt;/tt&gt;/&lt;tt&gt;:delete&lt;/tt&gt;,
+    #   an array of any of the previous, or &lt;tt&gt;:any&lt;/tt&gt; if the method does not matter.
+    #   These routes map to a URL like /messages/rss, with a route of +rss_messages_url+.
     # * &lt;tt&gt;:member&lt;/tt&gt; - Same as &lt;tt&gt;:collection&lt;/tt&gt;, but for actions that operate on a specific member.
-    # * &lt;tt&gt;:new&lt;/tt&gt; - Same as &lt;tt&gt;:collection&lt;/tt&gt;, but for actions that operate on the new resource action.
+    # * &lt;tt&gt;:new&lt;/tt&gt; - Same as &lt;tt&gt;:collection&lt;/tt&gt;, but for actions that operate on the new \resource action.
     # * &lt;tt&gt;:controller&lt;/tt&gt; - Specify the controller name for the routes.
     # * &lt;tt&gt;:singular&lt;/tt&gt; - Specify the singular name used in the member routes.
     # * &lt;tt&gt;:requirements&lt;/tt&gt; - Set custom routing parameter requirements.
-    # * &lt;tt&gt;:conditions&lt;/tt&gt; - Specify custom routing recognition conditions.  Resources sets the &lt;tt&gt;:method&lt;/tt&gt; value for the method-specific routes.
-    # * &lt;tt&gt;:as&lt;/tt&gt; - Specify a different resource name to use in the URL path. For example:
+    # * &lt;tt&gt;:conditions&lt;/tt&gt; - Specify custom routing recognition conditions.  \Resources sets the &lt;tt&gt;:method&lt;/tt&gt; value for the method-specific routes.
+    # * &lt;tt&gt;:as&lt;/tt&gt; - Specify a different \resource name to use in the URL path. For example:
     #     # products_path == '/productos'
     #     map.resources :products, :as =&gt; 'productos' do |product|
     #       # product_reviews_path(product) == '/productos/1234/comentarios'
     #       product.resources :product_reviews, :as =&gt; 'comentarios'
     #     end
     #
-    # * &lt;tt&gt;:has_one&lt;/tt&gt; - Specify nested resources, this is a shorthand for mapping singleton resources beneath the current.
-    # * &lt;tt&gt;:has_many&lt;/tt&gt; - Same has &lt;tt&gt;:has_one&lt;/tt&gt;, but for plural resources.
+    # * &lt;tt&gt;:has_one&lt;/tt&gt; - Specify nested \resources, this is a shorthand for mapping singleton \resources beneath the current.
+    # * &lt;tt&gt;:has_many&lt;/tt&gt; - Same has &lt;tt&gt;:has_one&lt;/tt&gt;, but for plural \resources.
     #
     #   You may directly specify the routing association with +has_one+ and +has_many+ like:
     #
@@ -277,18 +288,18 @@ module ActionController
     #
     # * &lt;tt&gt;:path_prefix&lt;/tt&gt; - Set a prefix to the routes with required route variables.
     #
-    #   Weblog comments usually belong to a post, so you might use resources like:
+    #   Weblog comments usually belong to a post, so you might use +resources+ like:
     #
     #     map.resources :articles
     #     map.resources :comments, :path_prefix =&gt; '/articles/:article_id'
     #
-    #   You can nest resources calls to set this automatically:
+    #   You can nest +resources+ calls to set this automatically:
     #
     #     map.resources :articles do |article|
     #       article.resources :comments
     #     end
     #
-    #   The comment resources work the same, but must now include a value for &lt;tt&gt;:article_id&lt;/tt&gt;.
+    #   The comment \resources work the same, but must now include a value for &lt;tt&gt;:article_id&lt;/tt&gt;.
     #
     #     article_comments_url(@article)
     #     article_comment_url(@article, @comment)
@@ -306,17 +317,42 @@ module ActionController
     #     map.resources :tags, :path_prefix =&gt; '/books/:book_id', :name_prefix =&gt; 'book_'
     #     map.resources :tags, :path_prefix =&gt; '/toys/:toy_id',   :name_prefix =&gt; 'toy_'
     #
-    # You may also use &lt;tt&gt;:name_prefix&lt;/tt&gt; to override the generic named routes in a nested resource:
+    # You may also use &lt;tt&gt;:name_prefix&lt;/tt&gt; to override the generic named routes in a nested \resource:
     #
     #   map.resources :articles do |article|
     #     article.resources :comments, :name_prefix =&gt; nil
     #   end
     #
-    # This will yield named resources like so:
+    # This will yield named \resources like so:
     #
     #   comments_url(@article)
     #   comment_url(@article, @comment)
     #
+    # * &lt;tt&gt;:shallow&lt;/tt&gt; - If true, paths for nested resources which reference a specific member
+    #   (ie. those with an :id parameter) will not use the parent path prefix or name prefix.
+    #
+    # The &lt;tt&gt;:shallow&lt;/tt&gt; option is inherited by any nested resource(s).
+    #
+    # For example, 'users', 'posts' and 'comments' all use shallow paths with the following nested resources:
+    #
+    #   map.resources :users, :shallow =&gt; true do |user|
+    #     user.resources :posts do |post|
+    #       post.resources :comments
+    #     end
+    #   end
+    #   # --&gt; GET /users/1/posts (maps to the PostsController#index action as usual)
+    #   #     also adds the usual named route called &quot;user_posts&quot;
+    #   # --&gt; GET /posts/2 (maps to the PostsController#show action as if it were not nested)
+    #   #     also adds the named route called &quot;post&quot;
+    #   # --&gt; GET /posts/2/comments (maps to the CommentsController#index action)
+    #   #     also adds the named route called &quot;post_comments&quot;
+    #   # --&gt; GET /comments/2 (maps to the CommentsController#show action as if it were not nested)
+    #   #     also adds the named route called &quot;comment&quot;
+    #
+    # You may also use &lt;tt&gt;:shallow&lt;/tt&gt; in combination with the +has_one+ and +has_many+ shorthand notations like:
+    #
+    #   map.resources :users, :has_many =&gt; { :posts =&gt; :comments }, :shallow =&gt; true
+    #
     # If &lt;tt&gt;map.resources&lt;/tt&gt; is called with multiple resources, they all get the same options applied.
     #
     # Examples:
@@ -349,28 +385,28 @@ module ActionController
     #
     # The +resources+ method sets HTTP method restrictions on the routes it generates. For example, making an
     # HTTP POST on &lt;tt&gt;new_message_url&lt;/tt&gt; will raise a RoutingError exception. The default route in
-    # &lt;tt&gt;config/routes.rb&lt;/tt&gt; overrides this and allows invalid HTTP methods for resource routes.
+    # &lt;tt&gt;config/routes.rb&lt;/tt&gt; overrides this and allows invalid HTTP methods for \resource routes.
     def resources(*entities, &amp;block)
       options = entities.extract_options!
       entities.each { |entity| map_resource(entity, options.dup, &amp;block) }
     end
 
-    # Creates named routes for implementing verb-oriented controllers for a singleton resource.
-    # A singleton resource is global to its current context.  For unnested singleton resources,
-    # the resource is global to the current user visiting the application, such as a user's
-    # /account profile.  For nested singleton resources, the resource is global to its parent
-    # resource, such as a &lt;tt&gt;projects&lt;/tt&gt; resource that &lt;tt&gt;has_one :project_manager&lt;/tt&gt;.
-    # The &lt;tt&gt;project_manager&lt;/tt&gt; should be mapped as a singleton resource under &lt;tt&gt;projects&lt;/tt&gt;:
+    # Creates named routes for implementing verb-oriented controllers for a singleton \resource.
+    # A singleton \resource is global to its current context.  For unnested singleton \resources,
+    # the \resource is global to the current user visiting the application, such as a user's
+    # &lt;tt&gt;/account&lt;/tt&gt; profile.  For nested singleton \resources, the \resource is global to its parent
+    # \resource, such as a &lt;tt&gt;projects&lt;/tt&gt; \resource that &lt;tt&gt;has_one :project_manager&lt;/tt&gt;.
+    # The &lt;tt&gt;project_manager&lt;/tt&gt; should be mapped as a singleton \resource under &lt;tt&gt;projects&lt;/tt&gt;:
     #
     #   map.resources :projects do |project|
     #     project.resource :project_manager
     #   end
     #
-    # See map.resources for general conventions.  These are the main differences:
-    # * A singular name is given to map.resource.  The default controller name is still taken from the plural name.
+    # See +resources+ for general conventions.  These are the main differences:
+    # * A singular name is given to &lt;tt&gt;map.resource&lt;/tt&gt;.  The default controller name is still taken from the plural name.
     # * To specify a custom plural name, use the &lt;tt&gt;:plural&lt;/tt&gt; option.  There is no &lt;tt&gt;:singular&lt;/tt&gt; option.
-    # * No default index route is created for the singleton resource controller.
-    # * When nesting singleton resources, only the singular name is used as the path prefix (example: 'account/messages/1')
+    # * No default index route is created for the singleton \resource controller.
+    # * When nesting singleton \resources, only the singular name is used as the path prefix (example: 'account/messages/1')
     #
     # For example:
     #
@@ -442,7 +478,7 @@ module ActionController
           map_associations(resource, options)
 
           if block_given?
-            with_options(:path_prefix =&gt; resource.nesting_path_prefix, :name_prefix =&gt; resource.nesting_name_prefix, :namespace =&gt; options[:namespace], &amp;block)
+            with_options(:path_prefix =&gt; resource.nesting_path_prefix, :name_prefix =&gt; resource.nesting_name_prefix, :namespace =&gt; options[:namespace], :shallow =&gt; options[:shallow], &amp;block)
           end
         end
       end
@@ -459,29 +495,45 @@ module ActionController
           map_associations(resource, options)
 
           if block_given?
-            with_options(:path_prefix =&gt; resource.nesting_path_prefix, :name_prefix =&gt; resource.nesting_name_prefix, :namespace =&gt; options[:namespace], &amp;block)
+            with_options(:path_prefix =&gt; resource.nesting_path_prefix, :name_prefix =&gt; resource.nesting_name_prefix, :namespace =&gt; options[:namespace], :shallow =&gt; options[:shallow], &amp;block)
           end
         end
       end
 
       def map_associations(resource, options)
+        map_has_many_associations(resource, options.delete(:has_many), options) if options[:has_many]
+
         path_prefix = &quot;#{options.delete(:path_prefix)}#{resource.nesting_path_prefix}&quot;
         name_prefix = &quot;#{options.delete(:name_prefix)}#{resource.nesting_name_prefix}&quot;
 
-        Array(options[:has_many]).each do |association|
-          resources(association, :path_prefix =&gt; path_prefix, :name_prefix =&gt; name_prefix, :namespace =&gt; options[:namespace])
+        Array(options[:has_one]).each do |association|
+          resource(association, :path_prefix =&gt; path_prefix, :name_prefix =&gt; name_prefix, :namespace =&gt; options[:namespace], :shallow =&gt; options[:shallow])
         end
+      end
 
-        Array(options[:has_one]).each do |association|
-          resource(association, :path_prefix =&gt; path_prefix, :name_prefix =&gt; name_prefix, :namespace =&gt; options[:namespace])
+      def map_has_many_associations(resource, associations, options)
+        case associations
+        when Hash
+          associations.each do |association,has_many|
+            map_has_many_associations(resource, association, options.merge(:has_many =&gt; has_many))
+          end
+        when Array
+          associations.each do |association|
+            map_has_many_associations(resource, association, options)
+          end
+        when Symbol, String
+          resources(associations, :path_prefix =&gt; resource.nesting_path_prefix, :name_prefix =&gt; resource.nesting_name_prefix, :namespace =&gt; options[:namespace], :shallow =&gt; options[:shallow], :has_many =&gt; options[:has_many])
+        else
         end
       end
 
       def map_collection_actions(map, resource)
         resource.collection_methods.each do |method, actions|
           actions.each do |action|
-            action_options = action_options_for(action, resource, method)
-            map_named_routes(map, &quot;#{action}_#{resource.name_prefix}#{resource.plural}&quot;, &quot;#{resource.path}#{resource.action_separator}#{action}&quot;, action_options)
+            [method].flatten.each do |m|
+              action_options = action_options_for(action, resource, m)
+              map_named_routes(map, &quot;#{action}_#{resource.name_prefix}#{resource.plural}&quot;, &quot;#{resource.path}#{resource.action_separator}#{action}&quot;, action_options)
+            end
           end
         end
       end
@@ -521,17 +573,19 @@ module ActionController
       def map_member_actions(map, resource)
         resource.member_methods.each do |method, actions|
           actions.each do |action|
-            action_options = action_options_for(action, resource, method)
+            [method].flatten.each do |m|
+              action_options = action_options_for(action, resource, m)
 
-            action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
-            action_path ||= Base.resources_path_names[action] || action
+              action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
+              action_path ||= Base.resources_path_names[action] || action
 
-            map_named_routes(map, &quot;#{action}_#{resource.name_prefix}#{resource.singular}&quot;, &quot;#{resource.member_path}#{resource.action_separator}#{action_path}&quot;, action_options)
+              map_named_routes(map, &quot;#{action}_#{resource.shallow_name_prefix}#{resource.singular}&quot;, &quot;#{resource.member_path}#{resource.action_separator}#{action_path}&quot;, action_options)
+            end
           end
         end
 
         show_action_options = action_options_for(&quot;show&quot;, resource)
-        map_named_routes(map, &quot;#{resource.name_prefix}#{resource.singular}&quot;, resource.member_path, show_action_options)
+        map_named_routes(map, &quot;#{resource.shallow_name_prefix}#{resource.singular}&quot;, resource.member_path, show_action_options)
 
         update_action_options = action_options_for(&quot;update&quot;, resource)
         map_unnamed_routes(map, resource.member_path, update_action_options)
@@ -574,4 +628,4 @@ end
 
 class ActionController::Routing::RouteSet::Mapper
   include ActionController::Resources
-end
\ No newline at end of file
+end</diff>
      <filename>actionpack/lib/action_controller/resources.rb</filename>
    </modified>
    <modified>
      <diff>@@ -40,6 +40,8 @@ module ActionController # :nodoc:
     attr_accessor :session, :cookies, :assigns, :template, :layout
     attr_accessor :redirected_to, :redirected_to_method_params
 
+    delegate :default_charset, :to =&gt; 'ActionController::Base'
+
     def initialize
       @body, @headers, @session, @assigns = &quot;&quot;, DEFAULT_HEADERS.merge(&quot;cookie&quot; =&gt; []), [], []
     end
@@ -60,19 +62,31 @@ module ActionController # :nodoc:
     # the character set information will also be included in the content type
     # information.
     def content_type=(mime_type)
-      self.headers[&quot;Content-Type&quot;] = charset ? &quot;#{mime_type}; charset=#{charset}&quot; : mime_type
+      self.headers[&quot;Content-Type&quot;] =
+        if mime_type =~ /charset/ || (c = charset).nil?
+          mime_type.to_s
+        else
+          &quot;#{mime_type}; charset=#{c}&quot;
+        end
     end
-    
+
     # Returns the response's content MIME type, or nil if content type has been set.
     def content_type
       content_type = String(headers[&quot;Content-Type&quot;] || headers[&quot;type&quot;]).split(&quot;;&quot;)[0]
       content_type.blank? ? nil : content_type
     end
-    
-    def charset=(encoding)
-      self.headers[&quot;Content-Type&quot;] = &quot;#{content_type || Mime::HTML}; charset=#{encoding}&quot;
+
+    # Set the charset of the Content-Type header. Set to nil to remove it.
+    # If no content type is set, it defaults to HTML.
+    def charset=(charset)
+      headers[&quot;Content-Type&quot;] =
+        if charset
+          &quot;#{content_type || Mime::HTML}; charset=#{charset}&quot;
+        else
+          content_type || Mime::HTML.to_s
+        end
     end
-    
+
     def charset
       charset = String(headers[&quot;Content-Type&quot;] || headers[&quot;type&quot;]).split(&quot;;&quot;)[1]
       charset.blank? ? nil : charset.strip.split(&quot;=&quot;)[1]
@@ -104,9 +118,19 @@ module ActionController # :nodoc:
       self.body = &quot;&lt;html&gt;&lt;body&gt;You are being &lt;a href=\&quot;#{url}\&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;&quot;
     end
 
+    def sending_file?
+      headers[&quot;Content-Transfer-Encoding&quot;] == &quot;binary&quot;
+    end
+
+    def assign_default_content_type_and_charset!
+      self.content_type ||= Mime::HTML
+      self.charset ||= default_charset unless sending_file?
+    end
+
     def prepare!
-      set_content_length!
+      assign_default_content_type_and_charset!
       handle_conditional_get!
+      set_content_length!
       convert_content_type!
     end
 </diff>
      <filename>actionpack/lib/action_controller/response.rb</filename>
    </modified>
    <modified>
      <diff>@@ -187,12 +187,14 @@ module ActionController
       private
         def validate_route_conditions(conditions)
           if method = conditions[:method]
-            if method == :head
-              raise ArgumentError, &quot;HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers&quot;
-            end
+            [method].flatten.each do |m|
+              if m == :head
+                raise ArgumentError, &quot;HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers&quot;
+              end
 
-            unless HTTP_METHODS.include?(method.to_sym)
-              raise ArgumentError, &quot;Invalid HTTP method specified in route conditions: #{conditions.inspect}&quot;
+              unless HTTP_METHODS.include?(m.to_sym)
+                raise ArgumentError, &quot;Invalid HTTP method specified in route conditions: #{conditions.inspect}&quot;
+              end
             end
           end
         end</diff>
      <filename>actionpack/lib/action_controller/routing/builder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -103,9 +103,10 @@ module ActionController
         end
 
         # This case uses almost the same code as positional arguments,
-        # but add an args.last.to_query on the end
+        # but add a question mark and args.last.to_query on the end,
+        # unless the last arg is empty
         def generation_code
-          super.insert(-2, '?#{args.last.to_query}')
+          super.insert(-2, '#{\'?\' + args.last.to_query unless args.last.empty?}')
         end
 
         # To avoid generating &quot;http://localhost/?host=foo.example.com&quot; we</diff>
      <filename>actionpack/lib/action_controller/routing/optimisations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -201,7 +201,7 @@ module ActionController
         # recognition, not generation.
         def recognition_conditions
           result = [&quot;(match = #{Regexp.new(recognition_pattern).inspect}.match(path))&quot;]
-          result &lt;&lt; &quot;conditions[:method] === env[:method]&quot; if conditions[:method]
+          result &lt;&lt; &quot;[conditions[:method]].flatten.include?(env[:method])&quot; if conditions[:method]
           result
         end
 </diff>
      <filename>actionpack/lib/action_controller/routing/route.rb</filename>
    </modified>
    <modified>
      <diff>@@ -115,7 +115,7 @@ module ActionController
         def install(destinations = [ActionController::Base, ActionView::Base], regenerate = false)
           reset! if regenerate
           Array(destinations).each do |dest|
-            dest.send! :include, @module
+            dest.__send__(:include, @module)
           end
         end
 
@@ -353,7 +353,7 @@ module ActionController
           if generate_all
             # Used by caching to expire all paths for a resource
             return routes.collect do |route|
-              route.send!(method, options, merged, expire_on)
+              route.__send__(method, options, merged, expire_on)
             end.compact
           end
 
@@ -361,7 +361,7 @@ module ActionController
           routes = routes_by_controller[controller][action][options.keys.sort_by { |x| x.object_id }]
 
           routes.each do |route|
-            results = route.send!(method, options, merged, expire_on)
+            results = route.__send__(method, options, merged, expire_on)
             return results if results &amp;&amp; (!results.is_a?(Array) || results.first)
           end
         end</diff>
      <filename>actionpack/lib/action_controller/routing/route_set.rb</filename>
    </modified>
    <modified>
      <diff>@@ -160,7 +160,7 @@ module ActionController
         s &lt;&lt; &quot;\n#{expiry_statement}&quot;
       end
 
-      def interpolation_chunk(value_code = &quot;#{local_name}&quot;)
+      def interpolation_chunk(value_code = local_name)
         &quot;\#{URI.escape(#{value_code}.to_s, ActionController::Routing::Segment::UNSAFE_PCHAR)}&quot;
       end
 
@@ -231,7 +231,7 @@ module ActionController
       end
 
       # Don't URI.escape the controller name since it may contain slashes.
-      def interpolation_chunk(value_code = &quot;#{local_name}&quot;)
+      def interpolation_chunk(value_code = local_name)
         &quot;\#{#{value_code}.to_s}&quot;
       end
 
@@ -251,7 +251,7 @@ module ActionController
     end
 
     class PathSegment &lt; DynamicSegment #:nodoc:
-      def interpolation_chunk(value_code = &quot;#{local_name}&quot;)
+      def interpolation_chunk(value_code = local_name)
         &quot;\#{#{value_code}}&quot;
       end
 </diff>
      <filename>actionpack/lib/action_controller/routing/segments.rb</filename>
    </modified>
    <modified>
      <diff>@@ -86,14 +86,14 @@ module ActionController #:nodoc:
           raise ArgumentError, &quot;only one of either :only or :except are allowed&quot;
         end
 
-        write_inheritable_array(&quot;session_options&quot;, [options])
+        write_inheritable_array(:session_options, [options])
       end
 
       # So we can declare session options in the Rails initializer.
       alias_method :session=, :session
 
       def cached_session_options #:nodoc:
-        @session_options ||= read_inheritable_attribute(&quot;session_options&quot;) || []
+        @session_options ||= read_inheritable_attribute(:session_options) || []
       end
 
       def session_options_for(request, action) #:nodoc:</diff>
      <filename>actionpack/lib/action_controller/session_management.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,6 +6,6 @@
 &lt;/h1&gt;
 &lt;pre&gt;&lt;%=h @exception.clean_message %&gt;&lt;/pre&gt;
 
-&lt;%= render(:file =&gt; @rescues_path + &quot;/_trace.erb&quot;, :use_full_path =&gt; false) %&gt;
+&lt;%= render(:file =&gt; @rescues_path + &quot;/_trace.erb&quot;) %&gt;
 
-&lt;%= render(:file =&gt; @rescues_path + &quot;/_request_and_response.erb&quot;, :use_full_path =&gt; false) %&gt;
+&lt;%= render(:file =&gt; @rescues_path + &quot;/_request_and_response.erb&quot;) %&gt;</diff>
      <filename>actionpack/lib/action_controller/templates/rescues/diagnostics.erb</filename>
    </modified>
    <modified>
      <diff>@@ -15,7 +15,7 @@
 
 &lt;% @real_exception = @exception
    @exception = @exception.original_exception || @exception %&gt;
-&lt;%= render(:file =&gt; @rescues_path + &quot;/_trace.erb&quot;, :use_full_path =&gt; false) %&gt;
+&lt;%= render(:file =&gt; @rescues_path + &quot;/_trace.erb&quot;) %&gt;
 &lt;% @exception = @real_exception %&gt;
 
-&lt;%= render(:file =&gt; @rescues_path + &quot;/_request_and_response.erb&quot;, :use_full_path =&gt; false) %&gt;
+&lt;%= render(:file =&gt; @rescues_path + &quot;/_request_and_response.erb&quot;) %&gt;</diff>
      <filename>actionpack/lib/action_controller/templates/rescues/template_error.erb</filename>
    </modified>
    <modified>
      <diff>@@ -3,6 +3,8 @@ require 'action_controller/test_case'
 
 module ActionController #:nodoc:
   class Base
+    attr_reader :assigns
+
     # Process a test request called with a TestRequest object.
     def self.process_test(request)
       new.process_test(request)
@@ -14,7 +16,12 @@ module ActionController #:nodoc:
 
     def process_with_test(*args)
       returning process_without_test(*args) do
-        add_variables_to_assigns
+        @assigns = {}
+        (instance_variable_names - @@protected_instance_variables).each do |var|
+          value = instance_variable_get(var)
+          @assigns[var[1..-1]] = value
+          response.template.assigns[var[1..-1]] = value if response
+        end
       end
     end
 
@@ -211,7 +218,7 @@ module ActionController #:nodoc:
     # Returns the template of the file which was used to
     # render this response (or nil)
     def rendered_template
-      template._first_render
+      template.send(:_first_render)
     end
 
     # A shortcut to the flash. Returns an empty hash if no session flash exists.
@@ -331,7 +338,7 @@ module ActionController #:nodoc:
     attr_reader :original_filename
 
     # The content type of the &quot;uploaded&quot; file
-    attr_reader :content_type
+    attr_accessor :content_type
 
     def initialize(path, content_type = Mime::TEXT, binary = false)
       raise &quot;#{path} file does not exist&quot; unless File.exist?(path)
@@ -350,7 +357,7 @@ module ActionController #:nodoc:
     alias local_path path
 
     def method_missing(method_name, *args, &amp;block) #:nodoc:
-      @tempfile.send!(method_name, *args, &amp;block)
+      @tempfile.__send__(method_name, *args, &amp;block)
     end
   end
 
@@ -396,7 +403,7 @@ module ActionController #:nodoc:
     def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
       @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
       @request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
-      returning send!(request_method, action, parameters, session, flash) do
+      returning __send__(request_method, action, parameters, session, flash) do
         @request.env.delete 'HTTP_X_REQUESTED_WITH'
         @request.env.delete 'HTTP_ACCEPT'
       end
@@ -429,7 +436,7 @@ module ActionController #:nodoc:
 
     def build_request_uri(action, parameters)
       unless @request.env['REQUEST_URI']
-        options = @controller.send!(:rewrite_options, parameters)
+        options = @controller.__send__(:rewrite_options, parameters)
         options.update(:only_path =&gt; true, :action =&gt; action)
 
         url = ActionController::UrlRewriter.new(@request, parameters)</diff>
      <filename>actionpack/lib/action_controller/test_process.rb</filename>
    </modified>
    <modified>
      <diff>@@ -80,7 +80,7 @@ module ActionController #:nodoc:
       #   array (may also be a single value).
       def verify(options={})
         before_filter :only =&gt; options[:only], :except =&gt; options[:except] do |c|
-          c.send! :verify_action, options
+          c.__send__ :verify_action, options
         end
       end
     end
@@ -116,7 +116,7 @@ module ActionController #:nodoc:
     end
     
     def apply_redirect_to(redirect_to_option) # :nodoc:
-      (redirect_to_option.is_a?(Symbol) &amp;&amp; redirect_to_option != :back) ? self.send!(redirect_to_option) : redirect_to_option
+      (redirect_to_option.is_a?(Symbol) &amp;&amp; redirect_to_option != :back) ? self.__send__(redirect_to_option) : redirect_to_option
     end
     
     def apply_remaining_actions(options) # :nodoc:</diff>
      <filename>actionpack/lib/action_controller/verification.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,6 +21,15 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
+begin
+  require 'active_support'
+rescue LoadError
+  activesupport_path = &quot;#{File.dirname(__FILE__)}/../../activesupport/lib&quot;
+  if File.directory?(activesupport_path)
+    $:.unshift activesupport_path
+    require 'active_support'
+  end
+end
 
 require 'action_view/template_handlers'
 require 'action_view/renderable'
@@ -34,14 +43,11 @@ require 'action_view/base'
 require 'action_view/partials'
 require 'action_view/template_error'
 
-I18n.backend.populate do
-  require 'action_view/locale/en-US.rb'
-end
+I18n.load_translations &quot;#{File.dirname(__FILE__)}/action_view/locale/en-US.yml&quot;
+
+require 'action_view/helpers'
 
 ActionView::Base.class_eval do
   include ActionView::Partials
-
-  ActionView::Base.helper_modules.each do |helper_module|
-    include helper_module
-  end
+  include ActionView::Helpers
 end</diff>
      <filename>actionpack/lib/action_view.rb</filename>
    </modified>
    <modified>
      <diff>@@ -158,10 +158,10 @@ module ActionView #:nodoc:
   # See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
   class Base
     include ERB::Util
+    extend ActiveSupport::Memoizable
 
     attr_accessor :base_path, :assigns, :template_extension
     attr_accessor :controller
-    attr_accessor :_first_render, :_last_render
 
     attr_writer :template_format
 
@@ -184,6 +184,17 @@ module ActionView #:nodoc:
         &quot;deprecated and has no effect. Please remove it from your config files.&quot;, caller)
     end
 
+    # Templates that are exempt from layouts
+    @@exempt_from_layout = Set.new([/\.rjs$/])
+
+    # Don't render layouts for templates with the given extensions.
+    def self.exempt_from_layout(*extensions)
+      regexps = extensions.collect do |extension|
+        extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
+      end
+      @@exempt_from_layout.merge(regexps)
+    end
+
     # Specify whether RJS responses should be wrapped in a try/catch block
     # that alert()s the caught exception (and then re-raises it).
     @@debug_rjs = false
@@ -203,27 +214,28 @@ module ActionView #:nodoc:
     end
     include CompiledTemplates
 
-    def self.helper_modules #:nodoc:
-      helpers = []
-      Dir.entries(File.expand_path(&quot;#{File.dirname(__FILE__)}/helpers&quot;)).sort.each do |file|
-        next unless file =~ /^([a-z][a-z_]*_helper).rb$/
-        require &quot;action_view/helpers/#{$1}&quot;
-        helper_module_name = $1.camelize
-        if Helpers.const_defined?(helper_module_name)
-          helpers &lt;&lt; Helpers.const_get(helper_module_name)
-        end
-      end
-      return helpers
-    end
-
     def self.process_view_paths(value)
       ActionView::PathSet.new(Array(value))
     end
 
+    attr_reader :helpers
+
+    class ProxyModule &lt; Module
+      def initialize(receiver)
+        @receiver = receiver
+      end
+
+      def include(*args)
+        super(*args)
+        @receiver.extend(*args)
+      end
+    end
+
     def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
       @assigns = assigns_for_first_render
       @assigns_added = nil
       @controller = controller
+      @helpers = ProxyModule.new(self)
       self.view_paths = view_paths
     end
 
@@ -239,45 +251,29 @@ module ActionView #:nodoc:
       local_assigns ||= {}
 
       if options.is_a?(String)
-        render_file(options, nil, local_assigns)
+        render(:file =&gt; options, :locals =&gt; local_assigns)
       elsif options == :update
         update_page(&amp;block)
       elsif options.is_a?(Hash)
         options = options.reverse_merge(:locals =&gt; {})
-
-        if partial_layout = options.delete(:layout)
-          if block_given?
-            begin
-              @_proc_for_layout = block
-              concat(render(options.merge(:partial =&gt; partial_layout)))
-            ensure
-              @_proc_for_layout = nil
-            end
-          else
-            begin
-              original_content_for_layout, @content_for_layout = @content_for_layout, render(options)
-              render(options.merge(:partial =&gt; partial_layout))
-            ensure
-              @content_for_layout = original_content_for_layout
-            end
-          end
+        if options[:layout]
+          _render_with_layout(options, local_assigns, &amp;block)
         elsif options[:file]
-          render_file(options[:file], nil, options[:locals])
-        elsif options[:partial] &amp;&amp; options[:collection]
-          render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as])
+          if options[:use_full_path]
+            ActiveSupport::Deprecation.warn(&quot;use_full_path option has been deprecated and has no affect.&quot;, caller)
+          end
+
+          _pick_template(options[:file]).render_template(self, options[:locals])
         elsif options[:partial]
-          render_partial(options[:partial], options[:object], options[:locals])
+          render_partial(options)
         elsif options[:inline]
-          render_inline(options[:inline], options[:locals], options[:type])
+          InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
+        elsif options[:text]
+          options[:text]
         end
       end
     end
 
-    # Returns true is the file may be rendered implicitly.
-    def file_public?(template_path)#:nodoc:
-      template_path.split('/').last[0,1] != '_'
-    end
-
     # The format to be used when choosing between multiple templates with
     # the same name but differing formats.  See +Request#template_format+
     # for more details.
@@ -291,105 +287,95 @@ module ActionView #:nodoc:
       end
     end
 
-    def file_exists?(template_path)
-      pick_template(template_path) ? true : false
-    rescue MissingTemplate
-      false
-    end
+    private
+      attr_accessor :_first_render, :_last_render
 
-    # Gets the extension for an existing template with the given template_path.
-    # Returns the format with the extension if that template exists.
-    #
-    #   pick_template('users/show')
-    #   # =&gt; 'users/show.html.erb'
-    #
-    #   pick_template('users/legacy')
-    #   # =&gt; 'users/legacy.rhtml'
-    #
-    def pick_template(template_path)
-      return template_path if template_path.respond_to?(:render)
-
-      path = template_path.sub(/^\//, '')
-      if m = path.match(/(.*)\.(\w+)$/)
-        template_file_name, template_file_extension = m[1], m[2]
-      else
-        template_file_name = path
-      end
+      # Evaluate the local assigns and pushes them to the view.
+      def _evaluate_assigns_and_ivars #:nodoc:
+        unless @assigns_added
+          @assigns.each { |key, value| instance_variable_set(&quot;@#{key}&quot;, value) }
 
-      # OPTIMIZE: Checks to lookup template in view path
-      if template = self.view_paths[&quot;#{template_file_name}.#{template_format}&quot;]
-        template
-      elsif template = self.view_paths[template_file_name]
-        template
-      elsif _first_render &amp;&amp; template = self.view_paths[&quot;#{template_file_name}.#{_first_render.format_and_extension}&quot;]
-        template
-      elsif template_format == :js &amp;&amp; template = self.view_paths[&quot;#{template_file_name}.html&quot;]
-        @template_format = :html
-        template
-      else
-        template = Template.new(template_path, view_paths)
-
-        if self.class.warn_cache_misses &amp;&amp; logger
-          logger.debug &quot;[PERFORMANCE] Rendering a template that was &quot; +
-            &quot;not found in view path. Templates outside the view path are &quot; +
-            &quot;not cached and result in expensive disk operations. Move this &quot; +
-            &quot;file into #{view_paths.join(':')} or add the folder to your &quot; +
-            &quot;view path list&quot;
-        end
+          if @controller
+            variables = @controller.instance_variables
+            variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
+            variables.each {|name| instance_variable_set(name, @controller.instance_variable_get(name)) }
+          end
 
-        template
+          @assigns_added = true
+        end
       end
-    end
 
-    extend ActiveSupport::Memoizable
-    memoize :pick_template
-
-    private
-      # Renders the template present at &lt;tt&gt;template_path&lt;/tt&gt;. The hash in &lt;tt&gt;local_assigns&lt;/tt&gt;
-      # is made available as local variables.
-      def render_file(template_path, use_full_path = nil, local_assigns = {}) #:nodoc:
-        unless use_full_path == nil
-          ActiveSupport::Deprecation.warn(&quot;use_full_path option has been deprecated and has no affect.&quot;, caller)
+      def _set_controller_content_type(content_type) #:nodoc:
+        if controller.respond_to?(:response)
+          controller.response.content_type ||= content_type
         end
+      end
 
-        if defined?(ActionMailer) &amp;&amp; defined?(ActionMailer::Base) &amp;&amp; controller.is_a?(ActionMailer::Base) &amp;&amp;
-            template_path.is_a?(String) &amp;&amp; !template_path.include?(&quot;/&quot;)
-          raise ActionViewError, &lt;&lt;-END_ERROR
-  Due to changes in ActionMailer, you need to provide the mailer_name along with the template name.
-
-    render &quot;user_mailer/signup&quot;
-    render :file =&gt; &quot;user_mailer/signup&quot;
-
-  If you are rendering a subtemplate, you must now use controller-like partial syntax:
+      def _pick_template(template_path)
+        return template_path if template_path.respond_to?(:render)
 
-    render :partial =&gt; 'signup' # no mailer_name necessary
-          END_ERROR
+        path = template_path.sub(/^\//, '')
+        if m = path.match(/(.*)\.(\w+)$/)
+          template_file_name, template_file_extension = m[1], m[2]
+        else
+          template_file_name = path
         end
 
-        template = pick_template(template_path)
-        template.render_template(self, local_assigns)
-      end
-
-      def render_inline(text, local_assigns = {}, type = nil)
-        InlineTemplate.new(text, type).render(self, local_assigns)
-      end
+        # OPTIMIZE: Checks to lookup template in view path
+        if template = self.view_paths[&quot;#{template_file_name}.#{template_format}&quot;]
+          template
+        elsif template = self.view_paths[template_file_name]
+          template
+        elsif _first_render &amp;&amp; template = self.view_paths[&quot;#{template_file_name}.#{_first_render.format_and_extension}&quot;]
+          template
+        elsif template_format == :js &amp;&amp; template = self.view_paths[&quot;#{template_file_name}.html&quot;]
+          @template_format = :html
+          template
+        else
+          template = Template.new(template_path, view_paths)
+
+          if self.class.warn_cache_misses &amp;&amp; logger
+            logger.debug &quot;[PERFORMANCE] Rendering a template that was &quot; +
+              &quot;not found in view path. Templates outside the view path are &quot; +
+              &quot;not cached and result in expensive disk operations. Move this &quot; +
+              &quot;file into #{view_paths.join(':')} or add the folder to your &quot; +
+              &quot;view path list&quot;
+          end
 
-      # Evaluate the local assigns and pushes them to the view.
-      def evaluate_assigns
-        unless @assigns_added
-          assign_variables_from_controller
-          @assigns_added = true
+          template
         end
       end
+      memoize :_pick_template
 
-      # Assigns instance variables from the controller to the view.
-      def assign_variables_from_controller
-        @assigns.each { |key, value| instance_variable_set(&quot;@#{key}&quot;, value) }
+      def _exempt_from_layout?(template_path) #:nodoc:
+        template = _pick_template(template_path).to_s
+        @@exempt_from_layout.any? { |ext| template =~ ext }
+      rescue ActionView::MissingTemplate
+        return false
       end
 
-      def set_controller_content_type(content_type)
-        if controller.respond_to?(:response)
-          controller.response.content_type ||= content_type
+      def _render_with_layout(options, local_assigns, &amp;block) #:nodoc:
+        partial_layout = options.delete(:layout)
+
+        if block_given?
+          begin
+            @_proc_for_layout = block
+            concat(render(options.merge(:partial =&gt; partial_layout)))
+          ensure
+            @_proc_for_layout = nil
+          end
+        else
+          begin
+            original_content_for_layout, @content_for_layout = @content_for_layout, render(options)
+            if (options[:inline] || options[:file] || options[:text])
+              @cached_content_for_layout = @content_for_layout
+              render(:file =&gt; partial_layout, :locals =&gt; local_assigns)
+            else
+              render(options.merge(:partial =&gt; partial_layout))
+            end
+          ensure
+            @content_for_layout = original_content_for_layout
+          end
         end
       end
   end</diff>
      <filename>actionpack/lib/action_view/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -189,15 +189,15 @@ module ActionView
           end
           options[:object_name] ||= params.first
 
-          I18n.with_options :locale =&gt; options[:locale], :scope =&gt; [:active_record, :error] do |locale|
+          I18n.with_options :locale =&gt; options[:locale], :scope =&gt; [:activerecord, :errors, :template] do |locale|
             header_message = if options.include?(:header_message)
               options[:header_message]
             else
               object_name = options[:object_name].to_s.gsub('_', ' ')
-              object_name = I18n.t(object_name, :default =&gt; object_name)
-              locale.t :header_message, :count =&gt; count, :object_name =&gt; object_name
+              object_name = I18n.t(object_name, :default =&gt; object_name, :scope =&gt; [:activerecord, :models], :count =&gt; 1)
+              locale.t :header, :count =&gt; count, :model =&gt; object_name
             end
-            message = options.include?(:message) ? options[:message] : locale.t(:message)
+            message = options.include?(:message) ? options[:message] : locale.t(:body)
             error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join
 
             contents = ''
@@ -246,7 +246,7 @@ module ActionView
 
       alias_method :tag_without_error_wrapping, :tag
       def tag(name, options)
-        if object.respond_to?(&quot;errors&quot;) &amp;&amp; object.errors.respond_to?(&quot;on&quot;)
+        if object.respond_to?(:errors) &amp;&amp; object.errors.respond_to?(:on)
           error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
         else
           tag_without_error_wrapping(name, options)
@@ -255,7 +255,7 @@ module ActionView
 
       alias_method :content_tag_without_error_wrapping, :content_tag
       def content_tag(name, value, options)
-        if object.respond_to?(&quot;errors&quot;) &amp;&amp; object.errors.respond_to?(&quot;on&quot;)
+        if object.respond_to?(:errors) &amp;&amp; object.errors.respond_to?(:on)
           error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
         else
           content_tag_without_error_wrapping(name, value, options)
@@ -264,7 +264,7 @@ module ActionView
 
       alias_method :to_date_select_tag_without_error_wrapping, :to_date_select_tag
       def to_date_select_tag(options = {}, html_options = {})
-        if object.respond_to?(&quot;errors&quot;) &amp;&amp; object.errors.respond_to?(&quot;on&quot;)
+        if object.respond_to?(:errors) &amp;&amp; object.errors.respond_to?(:on)
           error_wrapping(to_date_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
         else
           to_date_select_tag_without_error_wrapping(options, html_options)
@@ -273,7 +273,7 @@ module ActionView
 
       alias_method :to_datetime_select_tag_without_error_wrapping, :to_datetime_select_tag
       def to_datetime_select_tag(options = {}, html_options = {})
-        if object.respond_to?(&quot;errors&quot;) &amp;&amp; object.errors.respond_to?(&quot;on&quot;)
+        if object.respond_to?(:errors) &amp;&amp; object.errors.respond_to?(:on)
             error_wrapping(to_datetime_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
           else
             to_datetime_select_tag_without_error_wrapping(options, html_options)
@@ -282,7 +282,7 @@ module ActionView
 
       alias_method :to_time_select_tag_without_error_wrapping, :to_time_select_tag
       def to_time_select_tag(options = {}, html_options = {})
-        if object.respond_to?(&quot;errors&quot;) &amp;&amp; object.errors.respond_to?(&quot;on&quot;)
+        if object.respond_to?(:errors) &amp;&amp; object.errors.respond_to?(:on)
           error_wrapping(to_time_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
         else
           to_time_select_tag_without_error_wrapping(options, html_options)
@@ -298,7 +298,7 @@ module ActionView
       end
 
       def column_type
-        object.send(&quot;column_for_attribute&quot;, @method_name).type
+        object.send(:column_for_attribute, @method_name).type
       end
     end
   end</diff>
      <filename>actionpack/lib/action_view/helpers/active_record_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -104,7 +104,7 @@ module ActionView
       ASSETS_DIR      = defined?(Rails.public_path) ? Rails.public_path : &quot;public&quot;
       JAVASCRIPTS_DIR = &quot;#{ASSETS_DIR}/javascripts&quot;
       STYLESHEETS_DIR = &quot;#{ASSETS_DIR}/stylesheets&quot;
-      JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].map(&amp;:to_s).freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
+      JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
 
       # Returns a link tag that browsers and news readers can use to auto-detect
       # an RSS or ATOM feed. The +type+ can either be &lt;tt&gt;:rss&lt;/tt&gt; (default) or</diff>
      <filename>actionpack/lib/action_view/helpers/asset_tag_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,7 +17,7 @@ module ActionView
       #       # GET /posts.atom
       #       def index
       #         @posts = Post.find(:all)
-      #         
+      #
       #         respond_to do |format|
       #           format.html
       #           format.atom
@@ -29,12 +29,12 @@ module ActionView
       #     atom_feed do |feed|
       #       feed.title(&quot;My great blog!&quot;)
       #       feed.updated((@posts.first.created_at))
-      #     
+      #
       #       for post in @posts
       #         feed.entry(post) do |entry|
       #           entry.title(post.title)
       #           entry.content(post.body, :type =&gt; 'html')
-      #     
+      #
       #           entry.author do |author|
       #             author.name(&quot;DHH&quot;)
       #           end
@@ -47,8 +47,9 @@ module ActionView
       # * &lt;tt&gt;:language&lt;/tt&gt;: Defaults to &quot;en-US&quot;.
       # * &lt;tt&gt;:root_url&lt;/tt&gt;: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
       # * &lt;tt&gt;:url&lt;/tt&gt;: The URL for this feed. Defaults to the current URL.
-      # * &lt;tt&gt;:schema_date&lt;/tt&gt;: The date at which the tag scheme for the feed was first used. A good default is the year you 
-      #   created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, 
+      # * &lt;tt&gt;:id&lt;/tt&gt;: The id for this feed. Defaults to &quot;tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(&quot;.&quot;)[0]}&quot;
+      # * &lt;tt&gt;:schema_date&lt;/tt&gt;: The date at which the tag scheme for the feed was first used. A good default is the year you
+      #   created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
       #   2005 is used (as an &quot;I don't care&quot; value).
       #
       # Other namespaces can be added to the root element:
@@ -81,7 +82,7 @@ module ActionView
         else
           options[:schema_date] = &quot;2005&quot; # The Atom spec copyright date
         end
-        
+
         xml = options[:xml] || eval(&quot;xml&quot;, block.binding)
         xml.instruct!
 
@@ -89,10 +90,10 @@ module ActionView
         feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}
 
         xml.feed(feed_opts) do
-          xml.id(&quot;tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(&quot;.&quot;)[0]}&quot;)      
+          xml.id(options[:id] || &quot;tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(&quot;.&quot;)[0]}&quot;)
           xml.link(:rel =&gt; 'alternate', :type =&gt; 'text/html', :href =&gt; options[:root_url] || (request.protocol + request.host_with_port))
           xml.link(:rel =&gt; 'self', :type =&gt; 'application/atom+xml', :href =&gt; options[:url] || request.url)
-          
+
           yield AtomFeedBuilder.new(xml, self, options)
         end
       end
@@ -102,7 +103,7 @@ module ActionView
         def initialize(xml, view, feed_options = {})
           @xml, @view, @feed_options = xml, view, feed_options
         end
-        
+
         # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used.
         def updated(date_or_time = nil)
           @xml.updated((date_or_time || Time.now.utc).xmlschema)
@@ -115,9 +116,10 @@ module ActionView
         # * &lt;tt&gt;:published&lt;/tt&gt;: Time first published. Defaults to the created_at attribute on the record if one such exists.
         # * &lt;tt&gt;:updated&lt;/tt&gt;: Time of update. Defaults to the updated_at attribute on the record if one such exists.
         # * &lt;tt&gt;:url&lt;/tt&gt;: The URL for this entry. Defaults to the polymorphic_url for the record.
+        # * &lt;tt&gt;:id&lt;/tt&gt;: The ID for this entry. Defaults to &quot;tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}&quot;
         def entry(record, options = {})
-          @xml.entry do 
-            @xml.id(&quot;tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}&quot;)
+          @xml.entry do
+            @xml.id(options[:id] || &quot;tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}&quot;)
 
             if options[:published] || (record.respond_to?(:created_at) &amp;&amp; record.created_at)
               @xml.published((options[:published] || record.created_at).xmlschema)</diff>
      <filename>actionpack/lib/action_view/helpers/atom_feed_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -15,15 +15,15 @@ module ActionView
       #    &lt;%= expensive_files_operation %&gt;
       #  &lt;% end %&gt;
       #
-      # That would add something like &quot;Process data files (0.34523)&quot; to the log,
+      # That would add something like &quot;Process data files (345.2ms)&quot; to the log,
       # which you can then use to compare timings when optimizing your code.
       #
       # You may give an optional logger level as the second argument
       # (:debug, :info, :warn, :error); the default value is :info.
       def benchmark(message = &quot;Benchmarking&quot;, level = :info)
         if controller.logger
-          real = Benchmark.realtime { yield }
-          controller.logger.send(level, &quot;#{message} (#{'%.5f' % real})&quot;)
+          seconds = Benchmark.realtime { yield }
+          controller.logger.send(level, &quot;#{message} (#{'%.1f' % (seconds * 1000)}ms)&quot;)
         else
           yield
         end</diff>
      <filename>actionpack/lib/action_view/helpers/benchmark_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -155,10 +155,10 @@ module ActionView
       # Creates a file upload field.  If you are using file uploads then you will also need
       # to set the multipart option for the form tag:
       #
-      #   &lt;%= form_tag { :action =&gt; &quot;post&quot; }, { :multipart =&gt; true } %&gt;
+      #   &lt;% form_tag '/upload', :multipart =&gt; true do %&gt;
       #     &lt;label for=&quot;file&quot;&gt;File to Upload&lt;/label&gt; &lt;%= file_field_tag &quot;file&quot; %&gt;
       #     &lt;%= submit_tag %&gt;
-      #   &lt;%= end_form_tag %&gt;
+      #   &lt;% end %&gt;
       #
       # The specified URL will then be passed a File object containing the selected file, or if the field
       # was left blank, a StringIO object.</diff>
      <filename>actionpack/lib/action_view/helpers/form_tag_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -255,6 +255,14 @@ module ActionView
         link_to_function(name, remote_function(options), html_options || options.delete(:html))
       end
 
+      # Creates a button with an onclick event which calls a remote action
+      # via XMLHttpRequest
+      # The options for specifying the target with :url
+      # and defining callbacks is the same as link_to_remote.
+      def button_to_remote(name, options = {}, html_options = {})
+        button_to_function(name, remote_function(options), html_options)
+      end
+
       # Periodically calls the specified url (&lt;tt&gt;options[:url]&lt;/tt&gt;) every
       # &lt;tt&gt;options[:frequency]&lt;/tt&gt; seconds (default is 10). Usually used to
       # update a specified div (&lt;tt&gt;options[:update]&lt;/tt&gt;) with the results
@@ -588,9 +596,7 @@ module ActionView
 
         private
           def include_helpers_from_context
-            @context.extended_by.each do |mod|
-              extend mod unless mod.name =~ /^ActionView::Helpers/
-            end
+            extend @context.helpers if @context.respond_to?(:helpers)
             extend GeneratorMethods
           end
 
@@ -608,7 +614,7 @@ module ActionView
         # Example:
         #
         #   # Generates:
-        #   #     new Element.insert(&quot;list&quot;, { bottom: &lt;li&gt;Some item&lt;/li&gt;&quot; });
+        #   #     new Element.insert(&quot;list&quot;, { bottom: &quot;&lt;li&gt;Some item&lt;/li&gt;&quot; });
         #   #     new Effect.Highlight(&quot;list&quot;);
         #   #     [&quot;status-indicator&quot;, &quot;cancel-link&quot;].each(Element.hide);
         #   update_page do |page|
@@ -1054,7 +1060,7 @@ module ActionView
 
         js_options['asynchronous'] = options[:type] != :synchronous
         js_options['method']       = method_option_to_s(options[:method]) if options[:method]
-        js_options['insertion']    = options[:position].to_s.downcase if options[:position]
+        js_options['insertion']    = &quot;'#{options[:position].to_s.downcase}'&quot; if options[:position]
         js_options['evalScripts']  = options[:script].nil? || options[:script]
 
         if options[:form]</diff>
      <filename>actionpack/lib/action_view/helpers/prototype_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -49,9 +49,9 @@ module ActionView
       #
       def content_tag_for(tag_name, record, *args, &amp;block)
         prefix  = args.first.is_a?(Hash) ? nil : args.shift
-        options = args.first.is_a?(Hash) ? args.shift : {}
-        concat content_tag(tag_name, capture(&amp;block), 
-          options.merge({ :class =&gt; &quot;#{dom_class(record)} #{options[:class]}&quot;.strip, :id =&gt; dom_id(record, prefix) }))
+        options = args.extract_options!
+        options.merge!({ :class =&gt; &quot;#{dom_class(record)} #{options[:class]}&quot;.strip, :id =&gt; dom_id(record, prefix) })
+        content_tag(tag_name, options, &amp;block)
       end
     end
   end</diff>
      <filename>actionpack/lib/action_view/helpers/record_tag_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,22 +1,27 @@
 require 'action_view/helpers/tag_helper'
-require 'html/document'
+
+begin
+  require 'html/document'
+rescue LoadError
+  html_scanner_path = &quot;#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner&quot;
+  if File.directory?(html_scanner_path)
+    $:.unshift html_scanner_path
+    require 'html/document'
+  end
+end
 
 module ActionView
   module Helpers #:nodoc:
     # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
     # These helper methods extend ActionView making them callable within your template files.
     module SanitizeHelper
-      def self.included(base)
-        base.extend(ClassMethods)
-      end
-      
       # This +sanitize+ helper will html encode all tags and strip all attributes that aren't specifically allowed.
       # It also strips href/src tags with invalid protocols, like javascript: especially.  It does its best to counter any
       # tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters.  Check out
       # the extensive test suite.
       #
       #   &lt;%= sanitize @article.body %&gt;
-      # 
+      #
       # You can add or remove tags/attributes if you want to customize it a bit.  See ActionView::Base for full docs on the
       # available options.  You can add tags/attributes for single uses of +sanitize+ by passing either the &lt;tt&gt;:attributes&lt;/tt&gt; or &lt;tt&gt;:tags&lt;/tt&gt; options:
       #
@@ -27,27 +32,27 @@ module ActionView
       # Custom Use (only the mentioned tags and attributes are allowed, nothing else)
       #
       #   &lt;%= sanitize @article.body, :tags =&gt; %w(table tr td), :attributes =&gt; %w(id class style)
-      # 
+      #
       # Add table tags to the default allowed tags
-      #   
+      #
       #   Rails::Initializer.run do |config|
       #     config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
       #   end
-      # 
+      #
       # Remove tags to the default allowed tags
-      #   
+      #
       #   Rails::Initializer.run do |config|
       #     config.after_initialize do
       #       ActionView::Base.sanitized_allowed_tags.delete 'div'
       #     end
       #   end
-      # 
+      #
       # Change allowed default attributes
-      # 
+      #
       #   Rails::Initializer.run do |config|
       #     config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
       #   end
-      # 
+      #
       # Please note that sanitizing user-provided text does not guarantee that the
       # resulting markup is valid (conforming to a document type) or even well-formed.
       # The output may still contain e.g. unescaped '&lt;', '&gt;', '&amp;' characters and
@@ -62,8 +67,8 @@ module ActionView
         self.class.white_list_sanitizer.sanitize_css(style)
       end
 
-      # Strips all HTML tags from the +html+, including comments.  This uses the 
-      # html-scanner tokenizer and so its HTML parsing ability is limited by 
+      # Strips all HTML tags from the +html+, including comments.  This uses the
+      # html-scanner tokenizer and so its HTML parsing ability is limited by
       # that of html-scanner.
       #
       # ==== Examples
@@ -73,10 +78,10 @@ module ActionView
       #
       #   strip_tags(&quot;&lt;b&gt;Bold&lt;/b&gt; no more!  &lt;a href='more.html'&gt;See more here&lt;/a&gt;...&quot;)
       #   # =&gt; Bold no more!  See more here...
-      # 
+      #
       #   strip_tags(&quot;&lt;div id='top-bar'&gt;Welcome to my website!&lt;/div&gt;&quot;)
       #   # =&gt; Welcome to my website!
-      def strip_tags(html)     
+      def strip_tags(html)
         self.class.full_sanitizer.sanitize(html)
       end
 
@@ -96,21 +101,48 @@ module ActionView
       end
 
       module ClassMethods #:nodoc:
-        def self.extended(base)
-          class &lt;&lt; base
-            attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer
-
-            # we want these to be class methods on ActionView::Base, they'll get mattr_readers for these below.
-            helper_def = [:sanitized_protocol_separator, :sanitized_uri_attributes, :sanitized_bad_tags, :sanitized_allowed_tags,
-                :sanitized_allowed_attributes, :sanitized_allowed_css_properties, :sanitized_allowed_css_keywords,
-                :sanitized_shorthand_css_properties, :sanitized_allowed_protocols, :sanitized_protocol_separator=].collect! do |prop|
-              prop = prop.to_s
-              &quot;def #{prop}(#{:value if prop =~ /=$/}) white_list_sanitizer.#{prop.sub /sanitized_/, ''} #{:value if prop =~ /=$/} end&quot;
-            end.join(&quot;\n&quot;)
-            eval helper_def
-          end
-        end
-        
+        attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer
+
+        def sanitized_protocol_separator
+          white_list_sanitizer.protocol_separator
+        end
+
+        def sanitized_uri_attributes
+          white_list_sanitizer.uri_attributes
+        end
+
+        def sanitized_bad_tags
+          white_list_sanitizer.bad_tags
+        end
+
+        def sanitized_allowed_tags
+          white_list_sanitizer.allowed_tags
+        end
+
+        def sanitized_allowed_attributes
+          white_list_sanitizer.allowed_attributes
+        end
+
+        def sanitized_allowed_css_properties
+          white_list_sanitizer.allowed_css_properties
+        end
+
+        def sanitized_allowed_css_keywords
+          white_list_sanitizer.allowed_css_keywords
+        end
+
+        def sanitized_shorthand_css_properties
+          white_list_sanitizer.shorthand_css_properties
+        end
+
+        def sanitized_allowed_protocols
+          white_list_sanitizer.allowed_protocols
+        end
+
+        def sanitized_protocol_separator=(value)
+          white_list_sanitizer.protocol_separator = value
+        end
+
         # Gets the HTML::FullSanitizer instance used by +strip_tags+.  Replace with
         # any object that responds to +sanitize+.
         #</diff>
      <filename>actionpack/lib/action_view/helpers/sanitize_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,14 @@
 require 'action_view/helpers/tag_helper'
-require 'html/document'
+
+begin
+  require 'html/document'
+rescue LoadError
+  html_scanner_path = &quot;#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner&quot;
+  if File.directory?(html_scanner_path)
+    $:.unshift html_scanner_path
+    require 'html/document'
+  end
+end
 
 module ActionView
   module Helpers #:nodoc:
@@ -289,7 +298,7 @@ module ActionView
             &quot;&quot;
           else
             textilized = RedCloth.new(text, [ :hard_breaks ])
-            textilized.hard_breaks = true if textilized.respond_to?(&quot;hard_breaks=&quot;)
+            textilized.hard_breaks = true if textilized.respond_to?(:hard_breaks=)
             textilized.to_html
           end
         end
@@ -439,8 +448,10 @@ module ActionView
       # array every time it is called. This can be used for example, to alternate
       # classes for table rows.  You can use named cycles to allow nesting in loops.
       # Passing a Hash as the last parameter with a &lt;tt&gt;:name&lt;/tt&gt; key will create a
-      # named cycle.  You can manually reset a cycle by calling reset_cycle and passing the
-      # name of the cycle.
+      # named cycle. The default name for a cycle without a +:name+ key is
+      # &lt;tt&gt;&quot;default&quot;&lt;/tt&gt;. You can manually reset a cycle by calling reset_cycle
+      # and passing the name of the cycle. The current cycle string can be obtained
+      # anytime using the current_cycle method.
       #
       # ==== Examples
       #   # Alternate CSS classes for even and odd numbers...
@@ -487,6 +498,23 @@ module ActionView
         return cycle.to_s
       end
 
+      # Returns the current cycle string after a cycle has been started. Useful
+      # for complex table highlighing or any other design need which requires
+      # the current cycle string in more than one place.
+      #
+      # ==== Example
+      #   # Alternate background colors
+      #   @items = [1,2,3,4]
+      #   &lt;% @items.each do |item| %&gt;
+      #     &lt;div style=&quot;background-color:&lt;%= cycle(&quot;red&quot;,&quot;white&quot;,&quot;blue&quot;) %&gt;&quot;&gt;
+      #       &lt;span style=&quot;background-color:&lt;%= current_cycle %&gt;&quot;&gt;&lt;%= item %&gt;&lt;/span&gt;
+      #     &lt;/div&gt;
+      #   &lt;% end %&gt;
+      def current_cycle(name = &quot;default&quot;)
+        cycle = get_cycle(name)
+        cycle.current_value unless cycle.nil?
+      end
+
       # Resets a cycle so that it starts from the first element the next time
       # it is called. Pass in +name+ to reset a named cycle.
       #
@@ -523,11 +551,29 @@ module ActionView
           @index = 0
         end
 
+        def current_value
+          @values[previous_index].to_s
+        end
+
         def to_s
           value = @values[@index].to_s
-          @index = (@index + 1) % @values.size
+          @index = next_index
           return value
         end
+
+        private
+
+        def next_index
+          step_index(1)
+        end
+
+        def previous_index
+          step_index(-1)
+        end
+
+        def step_index(n)
+          (@index + n) % @values.size
+        end
       end
 
       private</diff>
      <filename>actionpack/lib/action_view/helpers/text_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,10 +11,12 @@ module ActionView
         keys = I18n.send :normalize_translation_keys, e.locale, e.key, e.options[:scope]
         content_tag('span', keys.join(', '), :class =&gt; 'translation_missing')
       end
+      alias :t :translate
 
       def localize(*args)
         I18n.localize *args
       end
+      alias :l :localize
     end
   end
 end
\ No newline at end of file</diff>
      <filename>actionpack/lib/action_view/helpers/translation_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,14 +1,15 @@
 module ActionView
-  # There's also a convenience method for rendering sub templates within the current controller that depends on a single object
-  # (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
-  # prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
+  # There's also a convenience method for rendering sub templates within the current controller that depends on a
+  # single object (we call this kind of sub templates for partials). It relies on the fact that partials should
+  # follow the naming convention of being prefixed with an underscore -- as to separate them from regular
+  # templates that could be rendered on their own.
   #
   # In a template for Advertiser#account:
   #
   #  &lt;%= render :partial =&gt; &quot;account&quot; %&gt;
   #
-  # This would render &quot;advertiser/_account.erb&quot; and pass the instance variable @account in as a local variable +account+ to
-  # the template for display.
+  # This would render &quot;advertiser/_account.erb&quot; and pass the instance variable @account in as a local variable
+  # +account+ to the template for display.
   #
   # In another template for Advertiser#buy, we could have:
   #
@@ -18,24 +19,24 @@ module ActionView
   #     &lt;%= render :partial =&gt; &quot;ad&quot;, :locals =&gt; { :ad =&gt; ad } %&gt;
   #   &lt;% end %&gt;
   #
-  # This would first render &quot;advertiser/_account.erb&quot; with @buyer passed in as the local variable +account+, then render
-  # &quot;advertiser/_ad.erb&quot; and pass the local variable +ad+ to the template for display.
+  # This would first render &quot;advertiser/_account.erb&quot; with @buyer passed in as the local variable +account+, then
+  # render &quot;advertiser/_ad.erb&quot; and pass the local variable +ad+ to the template for display.
   #
   # == Rendering a collection of partials
   #
-  # The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub
-  # template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders
-  # a partial by the same name as the elements contained within. So the three-lined example in &quot;Using partials&quot; can be rewritten
-  # with a single line:
+  # The example of partial use describes a familiar pattern where a template needs to iterate over an array and
+  # render a sub template for each of the elements. This pattern has been implemented as a single method that
+  # accepts an array and renders a partial by the same name as the elements contained within. So the three-lined
+  # example in &quot;Using partials&quot; can be rewritten with a single line:
   #
   #   &lt;%= render :partial =&gt; &quot;ad&quot;, :collection =&gt; @advertisements %&gt;
   #
-  # This will render &quot;advertiser/_ad.erb&quot; and pass the local variable +ad+ to the template for display. An iteration counter
-  # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
-  # example above, the template would be fed +ad_counter+.
+  # This will render &quot;advertiser/_ad.erb&quot; and pass the local variable +ad+ to the template for display. An
+  # iteration counter will automatically be made available to the template with a name of the form
+  # +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+.
   #
-  # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects,
-  # like Active Records, in there.
+  # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also
+  # just keep domain objects, like Active Records, in there.
   #
   # == Rendering shared partials
   #
@@ -47,8 +48,9 @@ module ActionView
   #
   # == Rendering partials with layouts
   #
-  # Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally
-  # for the entire action, but they work in a similar fashion. Imagine a list with two types of users:
+  # Partials can have their own layouts applied to them. These layouts are different than the ones that are
+  # specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types
+  # of users:
   #
   #   &lt;%# app/views/users/index.html.erb &amp;&gt;
   #   Here's the administrator:
@@ -139,38 +141,45 @@ module ActionView
     extend ActiveSupport::Memoizable
 
     private
-      def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nodoc:
-        local_assigns ||= {}
+      def render_partial(options = {}) #:nodoc:
+        local_assigns = options[:locals] || {}
 
-        case partial_path
+        case partial_path = options[:partial]
         when String, Symbol, NilClass
-          pick_template(find_partial_path(partial_path)).render_partial(self, object_assigns, local_assigns)
+          if options.has_key?(:collection)
+            render_partial_collection(options)
+          else
+            _pick_partial_template(partial_path).render_partial(self, options[:object], local_assigns)
+          end
         when ActionView::Helpers::FormBuilder
           builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
-          render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym =&gt; partial_path))
+          local_assigns.merge!(builder_partial_path.to_sym =&gt; partial_path)
+          render_partial(:partial =&gt; builder_partial_path, :object =&gt; options[:object], :locals =&gt; local_assigns)
         when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
-          if partial_path.any?
-            collection = partial_path
-            render_partial_collection(nil, collection, nil, local_assigns)
-          else
-            &quot;&quot;
-          end
+          render_partial_collection(options.except(:partial).merge(:collection =&gt; partial_path))
         else
-          render_partial(ActionController::RecordIdentifier.partial_path(partial_path, controller.class.controller_path), partial_path, local_assigns)
+          object = partial_path
+          render_partial(
+            :partial =&gt; ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
+            :object =&gt; object,
+            :locals =&gt; local_assigns
+          )
         end
       end
 
-      def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc:
-        return &quot; &quot; if collection.empty?
+      def render_partial_collection(options = {}) #:nodoc:
+        return nil if options[:collection].blank?
 
-        local_assigns = local_assigns ? local_assigns.clone : {}
-        spacer = partial_spacer_template ? render(:partial =&gt; partial_spacer_template) : ''
+        partial = options[:partial]
+        spacer = options[:spacer_template] ? render(:partial =&gt; options[:spacer_template]) : ''
+        local_assigns = options[:locals] ? options[:locals].clone : {}
+        as = options[:as]
 
         index = 0
-        collection.map do |object|
-          _partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
-          path = find_partial_path(_partial_path)
-          template = pick_template(path)
+        options[:collection].map do |object|
+          _partial_path ||= partial ||
+            ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
+          template = _pick_partial_template(_partial_path)
           local_assigns[template.counter_name] = index
           result = template.render_partial(self, object, local_assigns, as)
           index += 1
@@ -178,15 +187,17 @@ module ActionView
         end.join(spacer)
       end
 
-      def find_partial_path(partial_path)
+      def _pick_partial_template(partial_path) #:nodoc:
         if partial_path.include?('/')
-          File.join(File.dirname(partial_path), &quot;_#{File.basename(partial_path)}&quot;)
-        elsif respond_to?(:controller)
-          &quot;#{controller.class.controller_path}/_#{partial_path}&quot;
+          path = File.join(File.dirname(partial_path), &quot;_#{File.basename(partial_path)}&quot;)
+        elsif controller
+          path = &quot;#{controller.class.controller_path}/_#{partial_path}&quot;
         else
-          &quot;_#{partial_path}&quot;
+          path = &quot;_#{partial_path}&quot;
         end
+
+        _pick_template(path)
       end
-      memoize :find_partial_path
+      memoize :_pick_partial_template
   end
 end</diff>
      <filename>actionpack/lib/action_view/partials.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 module ActionView #:nodoc:
-  class PathSet &lt; ActiveSupport::TypedArray #:nodoc:
+  class PathSet &lt; Array #:nodoc:
     def self.type_cast(obj)
       if obj.is_a?(String)
         if Base.warn_cache_misses &amp;&amp; defined?(Rails) &amp;&amp; Rails.initialized?
@@ -15,6 +15,30 @@ module ActionView #:nodoc:
       end
     end
 
+    def initialize(*args)
+      super(*args).map! { |obj| self.class.type_cast(obj) }
+    end
+
+    def &lt;&lt;(obj)
+      super(self.class.type_cast(obj))
+    end
+
+    def concat(array)
+      super(array.map! { |obj| self.class.type_cast(obj) })
+    end
+
+    def insert(index, obj)
+      super(index, self.class.type_cast(obj))
+    end
+
+    def push(*objs)
+      super(*objs.map { |obj| self.class.type_cast(obj) })
+    end
+
+    def unshift(*objs)
+      super(*objs.map { |obj| self.class.type_cast(obj) })
+    end
+
     class Path #:nodoc:
       def self.eager_load_templates!
         @eager_load_templates = true</diff>
      <filename>actionpack/lib/action_view/paths.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,11 +26,11 @@ module ActionView
     def render(view, local_assigns = {})
       compile(local_assigns)
 
-      view._first_render ||= self
-      view._last_render = self
+      view.send(:_first_render=, self) unless view.send(:_first_render)
+      view.send(:_last_render=, self)
 
-      view.send(:evaluate_assigns)
-      view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type)
+      view.send(:_evaluate_assigns_and_ivars)
+      view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
 
       view.send(method_name(local_assigns), local_assigns) do |*names|
         if proc = view.instance_variable_get(&quot;@_proc_for_layout&quot;)
@@ -72,7 +72,7 @@ module ActionView
         end_src
 
         begin
-          logger = Base.logger
+          logger = defined?(ActionController) &amp;&amp; Base.logger
           logger.debug &quot;Compiling template #{render_symbol}&quot; if logger
 
           ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)</diff>
      <filename>actionpack/lib/action_view/renderable.rb</filename>
    </modified>
    <modified>
      <diff>@@ -16,15 +16,25 @@ module ActionView
     memoize :counter_name
 
     def render(view, local_assigns = {})
-      ActionController::Base.benchmark(&quot;Rendered #{path_without_format_and_extension}&quot;, Logger::DEBUG, false) do
+      if defined? ActionController
+        ActionController::Base.benchmark(&quot;Rendered #{path_without_format_and_extension}&quot;, Logger::DEBUG, false) do
+          super
+        end
+      else
         super
       end
     end
 
     def render_partial(view, object = nil, local_assigns = {}, as = nil)
       object ||= local_assigns[:object] ||
-        local_assigns[variable_name] ||
-        view.controller.instance_variable_get(&quot;@#{variable_name}&quot;) if view.respond_to?(:controller)
+        local_assigns[variable_name]
+
+      if view.respond_to?(:controller)
+        object ||= ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+          view.controller.instance_variable_get(&quot;@#{variable_name}&quot;),
+          &quot;@#{variable_name} will no longer be implicitly assigned to #{variable_name}&quot;
+        )
+      end
 
       # Ensure correct object is reassigned to other accessors
       local_assigns[:object] = local_assigns[variable_name] = object</diff>
      <filename>actionpack/lib/action_view/renderable_partial.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+require 'action_controller/mime_type'
+
 module ActionView #:nodoc:
   class Template
     extend TemplateHandlers</diff>
      <filename>actionpack/lib/action_view/template.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ module ActionView
     attr_reader :original_exception
 
     def initialize(template, assigns, original_exception)
-      @base_path = template.base_path
+      @base_path = template.base_path.to_s
       @assigns, @source, @original_exception = assigns.dup, template.source, original_exception
       @file_path = template.filename
       @backtrace = compute_backtrace</diff>
      <filename>actionpack/lib/action_view/template_error.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ module ActionView
       include Compilable
 
       def compile(template)
-        &quot;set_controller_content_type(Mime::XML);&quot; +
+        &quot;_set_controller_content_type(Mime::XML);&quot; +
           &quot;xml = ::Builder::XmlMarkup.new(:indent =&gt; 2);&quot; +
           &quot;self.output_buffer = xml.target!;&quot; +
           template.source +</diff>
      <filename>actionpack/lib/action_view/template_handlers/builder.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,9 +25,7 @@ module ActionView
       end
     end
 
-    ActionView::Base.helper_modules.each do |helper_module|
-      include helper_module
-    end
+    include ActionView::Helpers
     include ActionController::PolymorphicRoutes
     include ActionController::RecordIdentifier
 
@@ -56,7 +54,7 @@ module ActionView
     private
       def method_missing(selector, *args)
         controller = TestController.new
-        return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
+        return controller.__send__(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
         super
       end
   end</diff>
      <filename>actionpack/lib/action_view/test_case.rb</filename>
    </modified>
    <modified>
      <diff>@@ -39,6 +39,11 @@ class RenderPartialWithRecordIdentificationController &lt; ActionController::Base
     @developers = Developer.find(:all)
     render :partial =&gt; @developers
   end
+
+  def render_with_record_collection_and_spacer_template
+    @developer = Developer.find(1)
+    render :partial =&gt; @developer.projects, :spacer_template =&gt; 'test/partial_only'
+  end
 end
 
 class RenderPartialWithRecordIdentificationTest &lt; ActiveRecordTestCase
@@ -81,6 +86,11 @@ class RenderPartialWithRecordIdentificationTest &lt; ActiveRecordTestCase
     assert_equal 'DavidJamisfixture_3fixture_4fixture_5fixture_6fixture_7fixture_8fixture_9fixture_10Jamis', @response.body
   end
 
+  def test_render_with_record_collection_and_spacer_template
+    get :render_with_record_collection_and_spacer_template
+    assert_equal 'Active Recordonly partialActive Controller', @response.body
+  end
+
   def test_rendering_partial_with_has_one_association
     mascot = Company.find(1).mascot
     get :render_with_has_one_association</diff>
      <filename>actionpack/test/activerecord/render_partial_with_record_identification_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -433,6 +433,17 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     assert_select_rjs :remove, &quot;test1&quot;
   end
 
+  def test_assert_select_rjs_for_remove_offers_useful_error_when_assertion_fails
+    render_rjs do |page|
+      page.remove &quot;test_with_typo&quot;
+    end
+
+    assert_select_rjs :remove, &quot;test1&quot;
+
+    rescue Test::Unit::AssertionFailedError
+      assert_equal &quot;No RJS statement that removes 'test1' was rendered.&quot;, $!.message
+  end
+
   def test_assert_select_rjs_for_remove_ignores_block
     render_rjs do |page|
       page.remove &quot;test1&quot;
@@ -454,6 +465,17 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     assert_select_rjs :show, &quot;test1&quot;
   end
 
+  def test_assert_select_rjs_for_show_offers_useful_error_when_assertion_fails
+    render_rjs do |page|
+      page.show &quot;test_with_typo&quot;
+    end
+
+    assert_select_rjs :show, &quot;test1&quot;
+
+    rescue Test::Unit::AssertionFailedError
+      assert_equal &quot;No RJS statement that shows 'test1' was rendered.&quot;, $!.message
+  end
+
   def test_assert_select_rjs_for_show_ignores_block
     render_rjs do |page|
       page.show &quot;test1&quot;
@@ -475,6 +497,17 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     assert_select_rjs :hide, &quot;test1&quot;
   end
 
+  def test_assert_select_rjs_for_hide_offers_useful_error_when_assertion_fails
+    render_rjs do |page|
+      page.hide &quot;test_with_typo&quot;
+    end
+
+    assert_select_rjs :hide, &quot;test1&quot;
+
+    rescue Test::Unit::AssertionFailedError
+      assert_equal &quot;No RJS statement that hides 'test1' was rendered.&quot;, $!.message
+  end
+
   def test_assert_select_rjs_for_hide_ignores_block
     render_rjs do |page|
       page.hide &quot;test1&quot;
@@ -496,6 +529,17 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     assert_select_rjs :toggle, &quot;test1&quot;
   end
 
+  def test_assert_select_rjs_for_toggle_offers_useful_error_when_assertion_fails
+    render_rjs do |page|
+      page.toggle &quot;test_with_typo&quot;
+    end
+
+    assert_select_rjs :toggle, &quot;test1&quot;
+
+    rescue Test::Unit::AssertionFailedError
+      assert_equal &quot;No RJS statement that toggles 'test1' was rendered.&quot;, $!.message
+  end
+
   def test_assert_select_rjs_for_toggle_ignores_block
     render_rjs do |page|
       page.toggle &quot;test1&quot;
@@ -555,6 +599,11 @@ class AssertSelectTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_assert_select_rjs_raise_errors
+    assert_raises(ArgumentError) { assert_select_rjs(:destroy) }
+    assert_raises(ArgumentError) { assert_select_rjs(:insert, :left) }
+  end
+
   # Simple selection from a single result.
   def test_nested_assert_select_rjs_with_single_result
     render_rjs do |page|</diff>
      <filename>actionpack/test/controller/assert_select_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -84,11 +84,11 @@ class ControllerInstanceTests &lt; Test::Unit::TestCase
   def test_action_methods
     @empty_controllers.each do |c|
       hide_mocha_methods_from_controller(c)
-      assert_equal Set.new, c.send!(:action_methods), &quot;#{c.controller_path} should be empty!&quot;
+      assert_equal Set.new, c.__send__(:action_methods), &quot;#{c.controller_path} should be empty!&quot;
     end
     @non_empty_controllers.each do |c|
       hide_mocha_methods_from_controller(c)
-      assert_equal Set.new(%w(public_action)), c.send!(:action_methods), &quot;#{c.controller_path} should not be empty!&quot;
+      assert_equal Set.new(%w(public_action)), c.__send__(:action_methods), &quot;#{c.controller_path} should not be empty!&quot;
     end
   end
 
@@ -100,7 +100,7 @@ class ControllerInstanceTests &lt; Test::Unit::TestCase
         :expects, :mocha, :mocha_inspect, :reset_mocha, :stubba_object,
         :stubba_method, :stubs, :verify, :__metaclass__, :__is_a__, :to_matcher,
       ]
-      controller.class.send!(:hide_action, *mocha_methods)
+      controller.class.__send__(:hide_action, *mocha_methods)
     end
 end
 
@@ -140,7 +140,7 @@ class PerformActionTest &lt; Test::Unit::TestCase
   
   def test_method_missing_is_not_an_action_name
     use_controller MethodMissingController
-    assert ! @controller.send!(:action_methods).include?('method_missing')
+    assert ! @controller.__send__(:action_methods).include?('method_missing')
     
     get :method_missing
     assert_response :success</diff>
      <filename>actionpack/test/controller/base_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -77,49 +77,64 @@ class ComponentsTest &lt; Test::Unit::TestCase
   end
 
   def test_calling_from_controller
-    get :calling_from_controller
-    assert_equal &quot;Lady of the House, speaking&quot;, @response.body
+    assert_deprecated do
+      get :calling_from_controller
+      assert_equal &quot;Lady of the House, speaking&quot;, @response.body
+    end
   end
 
   def test_calling_from_controller_with_params
-    get :calling_from_controller_with_params
-    assert_equal &quot;David of the House, speaking&quot;, @response.body
+    assert_deprecated do
+      get :calling_from_controller_with_params
+      assert_equal &quot;David of the House, speaking&quot;, @response.body
+    end
   end
 
   def test_calling_from_controller_with_different_status_code
-    get :calling_from_controller_with_different_status_code
-    assert_equal 500, @response.response_code
+    assert_deprecated do
+      get :calling_from_controller_with_different_status_code
+      assert_equal 500, @response.response_code
+    end
   end
 
   def test_calling_from_template
-    get :calling_from_template
-    assert_equal &quot;Ring, ring: Lady of the House, speaking&quot;, @response.body
+    assert_deprecated do
+      get :calling_from_template
+      assert_equal &quot;Ring, ring: Lady of the House, speaking&quot;, @response.body
+    end
   end
 
   def test_etag_is_set_for_parent_template_when_calling_from_template
-    get :calling_from_template
-    expected_etag = etag_for(&quot;Ring, ring: Lady of the House, speaking&quot;)
-    assert_equal expected_etag, @response.headers['ETag']
+    assert_deprecated do
+      get :calling_from_template
+      expected_etag = etag_for(&quot;Ring, ring: Lady of the House, speaking&quot;)
+      assert_equal expected_etag, @response.headers['ETag']
+    end
   end
 
   def test_internal_calling
-    get :internal_caller
-    assert_equal &quot;Are you there? Yes, ma'am&quot;, @response.body
+    assert_deprecated do
+      get :internal_caller
+      assert_equal &quot;Are you there? Yes, ma'am&quot;, @response.body
+    end
   end
 
   def test_flash
-    get :set_flash
-    assert_equal 'My stoney baby', flash[:notice]
-    get :use_flash
-    assert_equal 'My stoney baby', @response.body
-    get :use_flash
-    assert_equal 'no flash', @response.body
+    assert_deprecated do
+      get :set_flash
+      assert_equal 'My stoney baby', flash[:notice]
+      get :use_flash
+      assert_equal 'My stoney baby', @response.body
+      get :use_flash
+      assert_equal 'no flash', @response.body
+    end
   end
 
   def test_component_redirect_redirects
-    get :calling_redirected
-
-    assert_redirected_to :controller=&gt;&quot;callee&quot;, :action =&gt; &quot;being_called&quot;
+    assert_deprecated do
+      get :calling_redirected
+      assert_redirected_to :controller=&gt;&quot;callee&quot;, :action =&gt; &quot;being_called&quot;
+    end
   end
 
   def test_component_multiple_redirect_redirects
@@ -128,9 +143,10 @@ class ComponentsTest &lt; Test::Unit::TestCase
   end
 
   def test_component_as_string_redirect_renders_redirected_action
-    get :calling_redirected_as_string
-
-    assert_equal &quot;Lady of the House, speaking&quot;, @response.body
+    assert_deprecated do
+      get :calling_redirected_as_string
+      assert_equal &quot;Lady of the House, speaking&quot;, @response.body
+    end
   end
 
   protected</diff>
      <filename>actionpack/test/controller/components_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,6 +19,11 @@ class ContentTypeController &lt; ActionController::Base
     render :text =&gt; &quot;hello world!&quot;
   end
 
+  def render_nil_charset_from_body
+    response.charset = nil
+    render :text =&gt; &quot;hello world!&quot;
+  end
+
   def render_default_for_rhtml
   end
 
@@ -85,8 +90,23 @@ class ContentTypeTest &lt; Test::Unit::TestCase
 
   def test_charset_from_body
     get :render_charset_from_body
+    assert_equal Mime::HTML, @response.content_type
     assert_equal &quot;utf-16&quot;, @response.charset
+  end
+
+  def test_nil_charset_from_body
+    get :render_nil_charset_from_body
     assert_equal Mime::HTML, @response.content_type
+    assert_equal &quot;utf-8&quot;, @response.charset, @response.headers.inspect
+  end
+
+  def test_nil_default_for_rhtml
+    ContentTypeController.default_charset = nil
+    get :render_default_for_rhtml
+    assert_equal Mime::HTML, @response.content_type
+    assert_nil @response.charset, @response.headers.inspect
+  ensure
+    ContentTypeController.default_charset = &quot;utf-8&quot;
   end
 
   def test_default_for_rhtml</diff>
      <filename>actionpack/test/controller/content_type_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ class FilterParamTest &lt; Test::Unit::TestCase
 
     test_hashes.each do |before_filter, after_filter, filter_words|
       FilterParamController.filter_parameter_logging(*filter_words)
-      assert_equal after_filter, @controller.send!(:filter_parameters, before_filter)
+      assert_equal after_filter, @controller.__send__(:filter_parameters, before_filter)
 
       filter_words.push('blah')
       FilterParamController.filter_parameter_logging(*filter_words) do |key, value|
@@ -37,7 +37,7 @@ class FilterParamTest &lt; Test::Unit::TestCase
       before_filter['barg'] = {'bargain'=&gt;'gain', 'blah'=&gt;'bar', 'bar'=&gt;{'bargain'=&gt;{'blah'=&gt;'foo'}}}
       after_filter['barg'] = {'bargain'=&gt;'niag', 'blah'=&gt;'[FILTERED]', 'bar'=&gt;{'bargain'=&gt;{'blah'=&gt;'[FILTERED]'}}}
 
-      assert_equal after_filter, @controller.send!(:filter_parameters, before_filter)
+      assert_equal after_filter, @controller.__send__(:filter_parameters, before_filter)
     end
   end
 </diff>
      <filename>actionpack/test/controller/filter_params_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -111,15 +111,15 @@ class FilterTest &lt; Test::Unit::TestCase
   end
 
   class OnlyConditionProcController &lt; ConditionalFilterController
-    before_filter(:only =&gt; :show) {|c| c.assigns[&quot;ran_proc_filter&quot;] = true }
+    before_filter(:only =&gt; :show) {|c| c.instance_variable_set(:&quot;@ran_proc_filter&quot;, true) }
   end
 
   class ExceptConditionProcController &lt; ConditionalFilterController
-    before_filter(:except =&gt; :show_without_filter) {|c| c.assigns[&quot;ran_proc_filter&quot;] = true }
+    before_filter(:except =&gt; :show_without_filter) {|c| c.instance_variable_set(:&quot;@ran_proc_filter&quot;, true) }
   end
 
   class ConditionalClassFilter
-    def self.filter(controller) controller.assigns[&quot;ran_class_filter&quot;] = true end
+    def self.filter(controller) controller.instance_variable_set(:&quot;@ran_class_filter&quot;, true) end
   end
 
   class OnlyConditionClassController &lt; ConditionalFilterController
@@ -131,7 +131,7 @@ class FilterTest &lt; Test::Unit::TestCase
   end
 
   class AnomolousYetValidConditionController &lt; ConditionalFilterController
-    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.assigns[&quot;ran_proc_filter1&quot;] = true }, :except =&gt; :show_without_filter) { |c| c.assigns[&quot;ran_proc_filter2&quot;] = true}
+    before_filter(ConditionalClassFilter, :ensure_login, Proc.new {|c| c.instance_variable_set(:&quot;@ran_proc_filter1&quot;, true)}, :except =&gt; :show_without_filter) { |c| c.instance_variable_set(:&quot;@ran_proc_filter2&quot;, true)}
   end
 
   class ConditionalOptionsFilter &lt; ConditionalFilterController
@@ -225,16 +225,16 @@ class FilterTest &lt; Test::Unit::TestCase
   end
 
   class ProcController &lt; PrependingController
-    before_filter(proc { |c| c.assigns[&quot;ran_proc_filter&quot;] = true })
+    before_filter(proc { |c| c.instance_variable_set(:&quot;@ran_proc_filter&quot;, true) })
   end
 
   class ImplicitProcController &lt; PrependingController
-    before_filter { |c| c.assigns[&quot;ran_proc_filter&quot;] = true }
+    before_filter { |c| c.instance_variable_set(:&quot;@ran_proc_filter&quot;, true) }
   end
 
   class AuditFilter
     def self.filter(controller)
-      controller.assigns[&quot;was_audited&quot;] = true
+      controller.instance_variable_set(:&quot;@was_audited&quot;, true)
     end
   end
 
@@ -242,12 +242,12 @@ class FilterTest &lt; Test::Unit::TestCase
     def before(controller)
       @execution_log = &quot;before&quot;
       controller.class.execution_log &lt;&lt; &quot; before aroundfilter &quot; if controller.respond_to? :execution_log
-      controller.assigns[&quot;before_ran&quot;] = true
+      controller.instance_variable_set(:&quot;@before_ran&quot;, true)
     end
 
     def after(controller)
-      controller.assigns[&quot;execution_log&quot;] = @execution_log + &quot; and after&quot;
-      controller.assigns[&quot;after_ran&quot;] = true
+      controller.instance_variable_set(:&quot;@execution_log&quot;, @execution_log + &quot; and after&quot;)
+      controller.instance_variable_set(:&quot;@after_ran&quot;, true)
       controller.class.execution_log &lt;&lt; &quot; after aroundfilter &quot; if controller.respond_to? :execution_log
     end
   end
@@ -364,7 +364,7 @@ class FilterTest &lt; Test::Unit::TestCase
       begin
         yield
       rescue ErrorToRescue =&gt; ex
-        controller.send! :render, :text =&gt; &quot;I rescued this: #{ex.inspect}&quot;
+        controller.__send__ :render, :text =&gt; &quot;I rescued this: #{ex.inspect}&quot;
       end
     end
   end
@@ -726,9 +726,9 @@ end
 
 class ControllerWithProcFilter &lt; PostsController
   around_filter(:only =&gt; :no_raise) do |c,b|
-    c.assigns['before'] = true
+    c.instance_variable_set(:&quot;@before&quot;, true)
     b.call
-    c.assigns['after'] = true
+    c.instance_variable_set(:&quot;@after&quot;, true)
   end
 end
 </diff>
      <filename>actionpack/test/controller/filters_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -243,7 +243,7 @@ class IntegrationTestUsesCorrectClass &lt; ActionController::IntegrationTest
     reset!
     stub_integration_session(@integration_session)
     %w( get post head put delete ).each do |verb|
-      assert_nothing_raised(&quot;'#{verb}' should use integration test methods&quot;) { send!(verb, '/') }
+      assert_nothing_raised(&quot;'#{verb}' should use integration test methods&quot;) { __send__(verb, '/') }
     end
   end
 end
@@ -253,7 +253,14 @@ class IntegrationProcessTest &lt; ActionController::IntegrationTest
     session :off
 
     def get
-      render :text =&gt; &quot;OK&quot;, :status =&gt; 200
+      respond_to do |format|
+        format.html { render :text =&gt; &quot;OK&quot;, :status =&gt; 200 }
+        format.js { render :text =&gt; &quot;JS OK&quot;, :status =&gt; 200 }
+      end
+    end
+
+    def get_with_params
+      render :text =&gt; &quot;foo: #{params[:foo]}&quot;, :status =&gt; 200
     end
 
     def post
@@ -320,9 +327,12 @@ class IntegrationProcessTest &lt; ActionController::IntegrationTest
       assert_equal [&quot;410 Gone&quot;], headers[&quot;status&quot;]
       assert_response 410
       assert_response :gone
-      assert_equal nil, response.headers[&quot;Set-Cookie&quot;]
+      assert_equal [&quot;cookie_1=; path=/&quot;, &quot;cookie_3=chocolate; path=/&quot;], response.headers[&quot;Set-Cookie&quot;]
       assert_equal [&quot;cookie_1=; path=/&quot;, &quot;cookie_3=chocolate; path=/&quot;], headers['set-cookie']
-      assert_equal [[], [&quot;chocolate&quot;]], response.headers[&quot;cookie&quot;]
+      assert_equal [
+        CGI::Cookie::new(&quot;name&quot; =&gt; &quot;cookie_1&quot;, &quot;value&quot; =&gt; &quot;&quot;),
+        CGI::Cookie::new(&quot;name&quot; =&gt; &quot;cookie_3&quot;, &quot;value&quot; =&gt; &quot;chocolate&quot;)
+      ], response.headers[&quot;cookie&quot;]
       assert_equal [], headers[&quot;cookie&quot;]
       assert_equal({&quot;cookie_1&quot;=&gt;&quot;&quot;, &quot;cookie_2&quot;=&gt;&quot;oatmeal&quot;, &quot;cookie_3&quot;=&gt;&quot;chocolate&quot;}, cookies)
       assert_equal &quot;Gone&quot;, response.body
@@ -345,6 +355,48 @@ class IntegrationProcessTest &lt; ActionController::IntegrationTest
     end
   end
 
+  def test_xml_http_request_get
+    with_test_route_set do
+      xhr :get, '/get'
+      assert_equal 200, status
+      assert_equal &quot;OK&quot;, status_message
+      assert_equal &quot;200 OK&quot;, response.headers[&quot;Status&quot;]
+      assert_equal [&quot;200 OK&quot;], headers[&quot;status&quot;]
+      assert_response 200
+      assert_response :success
+      assert_response :ok
+      assert_equal &quot;JS OK&quot;, response.body
+    end
+  end
+
+  def test_get_with_query_string
+    with_test_route_set do
+      get '/get_with_params?foo=bar'
+      assert_equal '/get_with_params?foo=bar', request.env[&quot;REQUEST_URI&quot;]
+      assert_equal '/get_with_params?foo=bar', request.request_uri
+      assert_equal nil, request.env[&quot;QUERY_STRING&quot;]
+      assert_equal 'foo=bar', request.query_string
+      assert_equal 'bar', request.parameters['foo']
+
+      assert_equal 200, status
+      assert_equal &quot;foo: bar&quot;, response.body
+    end
+  end
+
+  def test_get_with_parameters
+    with_test_route_set do
+      get '/get_with_params', :foo =&gt; &quot;bar&quot;
+      assert_equal '/get_with_params', request.env[&quot;REQUEST_URI&quot;]
+      assert_equal '/get_with_params', request.request_uri
+      assert_equal 'foo=bar', request.env[&quot;QUERY_STRING&quot;]
+      assert_equal 'foo=bar', request.query_string
+      assert_equal 'bar', request.parameters['foo']
+
+      assert_equal 200, status
+      assert_equal &quot;foo: bar&quot;, response.body
+    end
+  end
+
   private
     def with_test_route_set
       with_routing do |set|</diff>
      <filename>actionpack/test/controller/integration_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -79,53 +79,6 @@ class LayoutAutoDiscoveryTest &lt; Test::Unit::TestCase
   end
 end
 
-class ExemptFromLayoutTest &lt; Test::Unit::TestCase
-  def setup
-    @controller = LayoutTest.new
-    @request    = ActionController::TestRequest.new
-    @response   = ActionController::TestResponse.new
-  end
-
-  def test_rjs_exempt_from_layout
-    assert @controller.send!(:template_exempt_from_layout?, 'test.rjs')
-  end
-
-  def test_rhtml_and_rxml_not_exempt_from_layout
-    assert !@controller.send!(:template_exempt_from_layout?, 'test.rhtml')
-    assert !@controller.send!(:template_exempt_from_layout?, 'test.rxml')
-  end
-
-  def test_other_extension_not_exempt_from_layout
-    assert !@controller.send!(:template_exempt_from_layout?, 'test.random')
-  end
-
-  def test_add_extension_to_exempt_from_layout
-    ['rpdf', :rpdf].each do |ext|
-      assert_nothing_raised do
-        ActionController::Base.exempt_from_layout ext
-      end
-      assert @controller.send!(:template_exempt_from_layout?, &quot;test.#{ext}&quot;)
-    end
-  end
-
-  def test_add_regexp_to_exempt_from_layout
-    ActionController::Base.exempt_from_layout /\.rdoc/
-    assert @controller.send!(:template_exempt_from_layout?, 'test.rdoc')
-  end
-
-  def test_rhtml_exempt_from_layout_status_should_prevent_layout_render
-    ActionController::Base.exempt_from_layout :rhtml
-
-    assert @controller.send!(:template_exempt_from_layout?, 'test.rhtml')
-    assert @controller.send!(:template_exempt_from_layout?, 'hello.rhtml')
-
-    get :hello
-    assert_equal 'hello.rhtml', @response.body
-    ActionController::Base.exempt_from_layout.delete(/\.rhtml$/)
-  end
-end
-
-
 class DefaultLayoutController &lt; LayoutTest
 end
 
@@ -179,8 +132,6 @@ class LayoutSetInResponseTest &lt; Test::Unit::TestCase
     ActionController::Base.exempt_from_layout :rhtml
     @controller = RenderWithTemplateOptionController.new
 
-    assert @controller.send(:template_exempt_from_layout?, 'alt/hello.rhtml')
-
     get :hello
     assert_equal &quot;alt/hello.rhtml&quot;, @response.body.strip
 </diff>
      <filename>actionpack/test/controller/layout_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -60,6 +60,18 @@ uses_mocha 'polymorphic URL helpers' do
       edit_polymorphic_url(@article)
     end
 
+    def test_url_helper_prefixed_with_edit_with_url_options
+      @article.save
+      expects(:edit_article_url).with(@article, :param1 =&gt; '10')
+      edit_polymorphic_url(@article, :param1 =&gt; '10')
+    end
+
+    def test_url_helper_with_url_options
+      @article.save
+      expects(:article_url).with(@article, :param1 =&gt; '10')
+      polymorphic_url(@article, :param1 =&gt; '10')
+    end
+
     def test_formatted_url_helper
       expects(:formatted_article_url).with(@article, :pdf)
       formatted_polymorphic_url([@article, :pdf])
@@ -67,10 +79,16 @@ uses_mocha 'polymorphic URL helpers' do
 
     def test_format_option
       @article.save
-      expects(:article_url).with(@article, :pdf)
+      expects(:formatted_article_url).with(@article, :pdf)
       polymorphic_url(@article, :format =&gt; :pdf)
     end
 
+    def test_format_option_with_url_options
+      @article.save
+      expects(:formatted_article_url).with(@article, :pdf, :param1 =&gt; '10')
+      polymorphic_url(@article, :format =&gt; :pdf, :param1 =&gt; '10')
+    end
+
     def test_id_and_format_option
       @article.save
       expects(:article_url).with(:id =&gt; @article, :format =&gt; :pdf)
@@ -147,7 +165,7 @@ uses_mocha 'polymorphic URL helpers' do
     def test_nesting_with_array_containing_singleton_resource_and_format_option
       @tag = Tag.new
       @tag.save
-      expects(:article_response_tag_url).with(@article, @tag, :pdf)
+      expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf)
       polymorphic_url([@article, :response, @tag], :format =&gt; :pdf)
     end
 </diff>
      <filename>actionpack/test/controller/polymorphic_routes_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -241,7 +241,7 @@ class RackResponseTest &lt; BaseRackTest
     status, headers, body = @response.out(@output)
     assert_equal &quot;200 OK&quot;, status
     assert_equal({
-      &quot;Content-Type&quot; =&gt; &quot;text/html&quot;,
+      &quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;,
       &quot;Cache-Control&quot; =&gt; &quot;private, max-age=0, must-revalidate&quot;,
       &quot;ETag&quot; =&gt; '&quot;65a8e27d8879283831b664bd8b7f0ad4&quot;',
       &quot;Set-Cookie&quot; =&gt; [],
@@ -261,7 +261,7 @@ class RackResponseTest &lt; BaseRackTest
 
     status, headers, body = @response.out(@output)
     assert_equal &quot;200 OK&quot;, status
-    assert_equal({&quot;Content-Type&quot; =&gt; &quot;text/html&quot;, &quot;Cache-Control&quot; =&gt; &quot;no-cache&quot;, &quot;Set-Cookie&quot; =&gt; []}, headers)
+    assert_equal({&quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;, &quot;Cache-Control&quot; =&gt; &quot;no-cache&quot;, &quot;Set-Cookie&quot; =&gt; []}, headers)
 
     parts = []
     body.each { |part| parts &lt;&lt; part }
@@ -278,7 +278,7 @@ class RackResponseTest &lt; BaseRackTest
     status, headers, body = @response.out(@output)
     assert_equal &quot;200 OK&quot;, status
     assert_equal({
-      &quot;Content-Type&quot; =&gt; &quot;text/html&quot;,
+      &quot;Content-Type&quot; =&gt; &quot;text/html; charset=utf-8&quot;,
       &quot;Cache-Control&quot; =&gt; &quot;private, max-age=0, must-revalidate&quot;,
       &quot;ETag&quot; =&gt; '&quot;65a8e27d8879283831b664bd8b7f0ad4&quot;',
       &quot;Set-Cookie&quot; =&gt; [&quot;name=Josh; path=&quot;],</diff>
      <filename>actionpack/test/controller/rack_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,22 @@ module Fun
   end
 end
 
+class MockLogger
+  attr_reader :logged
+
+  def initialize
+    @logged = []
+  end
+
+  def method_missing(method, *args)
+    @logged &lt;&lt; args.first
+  end
+end
+
 class TestController &lt; ActionController::Base
+  class LabellingFormBuilder &lt; ActionView::Helpers::FormBuilder
+  end
+
   layout :determine_layout
 
   def hello_world
@@ -58,6 +73,57 @@ class TestController &lt; ActionController::Base
     render :text =&gt; &quot;hello world&quot;
   end
 
+  def render_text_hello_world_with_layout
+    @variable_for_layout = &quot;, I'm here!&quot;
+    render :text =&gt; &quot;hello world&quot;, :layout =&gt; true
+  end
+
+  def hello_world_with_layout_false
+    render :layout =&gt; false
+  end
+
+  def render_file_with_instance_variables
+    @secret = 'in the sauce'
+    path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
+    render :file =&gt; path
+  end
+
+  def render_file_not_using_full_path
+    @secret = 'in the sauce'
+    render :file =&gt; 'test/render_file_with_ivar'
+  end
+
+  def render_file_not_using_full_path_with_dot_in_path
+    @secret = 'in the sauce'
+    render :file =&gt; 'test/dot.directory/render_file_with_ivar'
+  end
+
+  def render_file_from_template
+    @secret = 'in the sauce'
+    @path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
+  end
+
+  def render_file_with_locals
+    path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
+    render :file =&gt; path, :locals =&gt; {:secret =&gt; 'in the sauce'}
+  end
+
+  def accessing_request_in_template
+    render :inline =&gt;  &quot;Hello: &lt;%= request.host %&gt;&quot;
+  end
+
+  def accessing_logger_in_template
+    render :inline =&gt;  &quot;&lt;%= logger.class %&gt;&quot;
+  end
+
+  def accessing_action_name_in_template
+    render :inline =&gt;  &quot;&lt;%= action_name %&gt;&quot;
+  end
+
+  def accessing_controller_name_in_template
+    render :inline =&gt;  &quot;&lt;%= controller_name %&gt;&quot;
+  end
+
   def render_json_hello_world
     render :json =&gt; {:hello =&gt; 'world'}.to_json
   end
@@ -126,7 +192,7 @@ class TestController &lt; ActionController::Base
   end
 
   def builder_layout_test
-    render :action =&gt; &quot;hello&quot;
+    render :action =&gt; &quot;hello&quot;, :layout =&gt; &quot;layouts/builder&quot;
   end
 
   def builder_partial_test
@@ -168,8 +234,232 @@ class TestController &lt; ActionController::Base
     @foo = render_to_string :inline =&gt; &quot;this is a test&quot;
   end
 
-  def partial
-    render :partial =&gt; 'partial'
+  def default_render
+    if @alternate_default_render
+      @alternate_default_render.call
+    else
+      render
+    end
+  end
+
+  def render_action_hello_world_as_symbol
+    render :action =&gt; :hello_world
+  end
+
+  def layout_test_with_different_layout
+    render :action =&gt; &quot;hello_world&quot;, :layout =&gt; &quot;standard&quot;
+  end
+
+  def rendering_without_layout
+    render :action =&gt; &quot;hello_world&quot;, :layout =&gt; false
+  end
+
+  def layout_overriding_layout
+    render :action =&gt; &quot;hello_world&quot;, :layout =&gt; &quot;standard&quot;
+  end
+
+  def rendering_nothing_on_layout
+    render :nothing =&gt; true
+  end
+
+  def render_to_string_with_assigns
+    @before = &quot;i'm before the render&quot;
+    render_to_string :text =&gt; &quot;foo&quot;
+    @after = &quot;i'm after the render&quot;
+    render :action =&gt; &quot;test/hello_world&quot;
+  end
+
+  def render_to_string_with_exception
+    render_to_string :file =&gt; &quot;exception that will not be caught - this will certainly not work&quot;
+  end
+
+  def render_to_string_with_caught_exception
+    @before = &quot;i'm before the render&quot;
+    begin
+      render_to_string :file =&gt; &quot;exception that will be caught- hope my future instance vars still work!&quot;
+    rescue
+    end
+    @after = &quot;i'm after the render&quot;
+    render :action =&gt; &quot;test/hello_world&quot;
+  end
+
+  def accessing_params_in_template_with_layout
+    render :layout =&gt; nil, :inline =&gt;  &quot;Hello: &lt;%= params[:name] %&gt;&quot;
+  end
+
+  def render_with_explicit_template
+    render :template =&gt; &quot;test/hello_world&quot;
+  end
+
+  def render_with_explicit_template_with_locals
+    render :template =&gt; &quot;test/render_file_with_locals&quot;, :locals =&gt; { :secret =&gt; 'area51' }
+  end
+
+  def double_render
+    render :text =&gt; &quot;hello&quot;
+    render :text =&gt; &quot;world&quot;
+  end
+
+  def double_redirect
+    redirect_to :action =&gt; &quot;double_render&quot;
+    redirect_to :action =&gt; &quot;double_render&quot;
+  end
+
+  def render_and_redirect
+    render :text =&gt; &quot;hello&quot;
+    redirect_to :action =&gt; &quot;double_render&quot;
+  end
+
+  def render_to_string_and_render
+    @stuff = render_to_string :text =&gt; &quot;here is some cached stuff&quot;
+    render :text =&gt; &quot;Hi web users! #{@stuff}&quot;
+  end
+
+  def rendering_with_conflicting_local_vars
+    @name = &quot;David&quot;
+    def @template.name() nil end
+    render :action =&gt; &quot;potential_conflicts&quot;
+  end
+
+  def hello_world_from_rxml_using_action
+    render :action =&gt; &quot;hello_world_from_rxml.builder&quot;
+  end
+
+  def hello_world_from_rxml_using_template
+    render :template =&gt; &quot;test/hello_world_from_rxml.builder&quot;
+  end
+
+  module RenderTestHelper
+    def rjs_helper_method_from_module
+      page.visual_effect :highlight
+    end
+  end
+
+  helper RenderTestHelper
+  helper do
+    def rjs_helper_method(value)
+      page.visual_effect :highlight, value
+    end
+  end
+
+  def enum_rjs_test
+    render :update do |page|
+      page.select('.product').each do |value|
+        page.rjs_helper_method_from_module
+        page.rjs_helper_method(value)
+        page.sortable(value, :url =&gt; { :action =&gt; &quot;order&quot; })
+        page.draggable(value)
+      end
+    end
+  end
+
+  def delete_with_js
+    @project_id = 4
+  end
+
+  def render_js_with_explicit_template
+    @project_id = 4
+    render :template =&gt; 'test/delete_with_js'
+  end
+
+  def render_js_with_explicit_action_template
+    @project_id = 4
+    render :action =&gt; 'delete_with_js'
+  end
+
+  def update_page
+    render :update do |page|
+      page.replace_html 'balance', '$37,000,000.00'
+      page.visual_effect :highlight, 'balance'
+    end
+  end
+
+  def update_page_with_instance_variables
+    @money = '$37,000,000.00'
+    @div_id = 'balance'
+    render :update do |page|
+      page.replace_html @div_id, @money
+      page.visual_effect :highlight, @div_id
+    end
+  end
+
+  def update_page_with_view_method
+    render :update do |page|
+      page.replace_html 'person', pluralize(2, 'person')
+    end
+  end
+
+  def action_talk_to_layout
+    # Action template sets variable that's picked up by layout
+  end
+
+  def render_text_with_assigns
+    @hello = &quot;world&quot;
+    render :text =&gt; &quot;foo&quot;
+  end
+
+  def yield_content_for
+    render :action =&gt; &quot;content_for&quot;, :layout =&gt; &quot;yield&quot;
+  end
+
+  def render_content_type_from_body
+    response.content_type = Mime::RSS
+    render :text =&gt; &quot;hello world!&quot;
+  end
+
+  def head_with_location_header
+    head :location =&gt; &quot;/foo&quot;
+  end
+
+  def head_with_symbolic_status
+    head :status =&gt; params[:status].intern
+  end
+
+  def head_with_integer_status
+    head :status =&gt; params[:status].to_i
+  end
+
+  def head_with_string_status
+    head :status =&gt; params[:status]
+  end
+
+  def head_with_custom_header
+    head :x_custom_header =&gt; &quot;something&quot;
+  end
+
+  def head_with_status_code_first
+    head :forbidden, :x_custom_header =&gt; &quot;something&quot;
+  end
+
+  def render_with_location
+    render :xml =&gt; &quot;&lt;hello/&gt;&quot;, :location =&gt; &quot;http://example.com&quot;, :status =&gt; 201
+  end
+
+  def render_with_object_location
+    customer = Customer.new(&quot;Some guy&quot;, 1)
+    render :xml =&gt; &quot;&lt;customer/&gt;&quot;, :location =&gt; customer_url(customer), :status =&gt; :created
+  end
+
+  def render_with_to_xml
+    to_xmlable = Class.new do
+      def to_xml
+        &quot;&lt;i-am-xml/&gt;&quot;
+      end
+    end.new
+
+    render :xml =&gt; to_xmlable
+  end
+
+  def render_using_layout_around_block
+    render :action =&gt; &quot;using_layout_around_block&quot;
+  end
+
+  def render_using_layout_around_block_with_args
+    render :action =&gt; &quot;using_layout_around_block_with_args&quot;
+  end
+
+  def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
+    render :action =&gt; &quot;using_layout_around_block&quot;, :layout =&gt; &quot;layouts/block_with_layout&quot;
   end
 
   def partial_dot_html
@@ -192,12 +482,8 @@ class TestController &lt; ActionController::Base
     end
   end
 
-  def default_render
-    if @alternate_default_render
-      @alternate_default_render.call
-    else
-      render
-    end
+  def partial
+    render :partial =&gt; 'partial'
   end
 
   def render_alternate_default
@@ -209,14 +495,126 @@ class TestController &lt; ActionController::Base
     end
   end
 
-  def rescue_action(e) raise end
+  def partial_only_with_layout
+    render :partial =&gt; &quot;partial_only&quot;, :layout =&gt; true
+  end
+
+  def render_to_string_with_partial
+    @partial_only = render_to_string :partial =&gt; &quot;partial_only&quot;
+    @partial_with_locals = render_to_string :partial =&gt; &quot;customer&quot;, :locals =&gt; { :customer =&gt; Customer.new(&quot;david&quot;) }
+    render :action =&gt; &quot;test/hello_world&quot;
+  end
+
+  def partial_with_counter
+    render :partial =&gt; &quot;counter&quot;, :locals =&gt; { :counter_counter =&gt; 5 }
+  end
+
+  def partial_with_locals
+    render :partial =&gt; &quot;customer&quot;, :locals =&gt; { :customer =&gt; Customer.new(&quot;david&quot;) }
+  end
+
+  def partial_with_form_builder
+    render :partial =&gt; ActionView::Helpers::FormBuilder.new(:post, nil, @template, {}, Proc.new {})
+  end
+
+  def partial_with_form_builder_subclass
+    render :partial =&gt; LabellingFormBuilder.new(:post, nil, @template, {}, Proc.new {})
+  end
+
+  def partial_collection
+    render :partial =&gt; &quot;customer&quot;, :collection =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ]
+  end
+
+  def partial_collection_with_as
+    render :partial =&gt; &quot;customer_with_var&quot;, :collection =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ], :as =&gt; :customer
+  end
+
+  def partial_collection_with_counter
+    render :partial =&gt; &quot;customer_counter&quot;, :collection =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ]
+  end
+
+  def partial_collection_with_locals
+    render :partial =&gt; &quot;customer_greeting&quot;, :collection =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ], :locals =&gt; { :greeting =&gt; &quot;Bonjour&quot; }
+  end
+
+  def partial_collection_with_spacer
+    render :partial =&gt; &quot;customer&quot;, :spacer_template =&gt; &quot;partial_only&quot;, :collection =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ]
+  end
+
+  def partial_collection_shorthand_with_locals
+    render :partial =&gt; [ Customer.new(&quot;david&quot;), Customer.new(&quot;mary&quot;) ], :locals =&gt; { :greeting =&gt; &quot;Bonjour&quot; }
+  end
+
+  def partial_collection_shorthand_with_different_types_of_records
+    render :partial =&gt; [
+        BadCustomer.new(&quot;mark&quot;),
+        GoodCustomer.new(&quot;craig&quot;),
+        BadCustomer.new(&quot;john&quot;),
+        GoodCustomer.new(&quot;zach&quot;),
+        GoodCustomer.new(&quot;brandon&quot;),
+        BadCustomer.new(&quot;dan&quot;) ],
+      :locals =&gt; { :greeting =&gt; &quot;Bonjour&quot; }
+  end
+
+  def empty_partial_collection
+    render :partial =&gt; &quot;customer&quot;, :collection =&gt; []
+  end
+
+  def partial_collection_shorthand_with_different_types_of_records_with_counter
+    partial_collection_shorthand_with_different_types_of_records
+  end
+
+  def missing_partial
+    render :partial =&gt; 'thisFileIsntHere'
+  end
+
+  def partial_with_hash_object
+    render :partial =&gt; &quot;hash_object&quot;, :object =&gt; {:first_name =&gt; &quot;Sam&quot;}
+  end
+
+  def partial_hash_collection
+    render :partial =&gt; &quot;hash_object&quot;, :collection =&gt; [ {:first_name =&gt; &quot;Pratik&quot;}, {:first_name =&gt; &quot;Amy&quot;} ]
+  end
+
+  def partial_hash_collection_with_locals
+    render :partial =&gt; &quot;hash_greeting&quot;, :collection =&gt; [ {:first_name =&gt; &quot;Pratik&quot;}, {:first_name =&gt; &quot;Amy&quot;} ], :locals =&gt; { :greeting =&gt; &quot;Hola&quot; }
+  end
+
+  def partial_with_implicit_local_assignment
+    @customer = Customer.new(&quot;Marcel&quot;)
+    render :partial =&gt; &quot;customer&quot;
+  end
+
+  def render_call_to_partial_with_layout
+    render :action =&gt; &quot;calling_partial_with_layout&quot;
+  end
+
+  def render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+    render :action =&gt; &quot;calling_partial_with_layout&quot;, :layout =&gt; &quot;layouts/partial_with_layout&quot;
+  end
+
+  def rescue_action(e)
+    raise
+  end
 
   private
     def determine_layout
       case action_name
-        when &quot;layout_test&quot;;         &quot;layouts/standard&quot;
-        when &quot;builder_layout_test&quot;; &quot;layouts/builder&quot;
-        when &quot;render_symbol_json&quot;;  &quot;layouts/standard&quot;  # to make sure layouts don't interfere
+        when &quot;hello_world&quot;, &quot;layout_test&quot;, &quot;rendering_without_layout&quot;,
+             &quot;rendering_nothing_on_layout&quot;, &quot;render_text_hello_world&quot;,
+             &quot;render_text_hello_world_with_layout&quot;,
+             &quot;hello_world_with_layout_false&quot;,
+             &quot;partial_only&quot;, &quot;partial_only_with_layout&quot;,
+             &quot;accessing_params_in_template&quot;,
+             &quot;accessing_params_in_template_with_layout&quot;,
+             &quot;render_with_explicit_template&quot;,
+             &quot;render_js_with_explicit_template&quot;,
+             &quot;render_js_with_explicit_action_template&quot;,
+             &quot;delete_with_js&quot;, &quot;update_page&quot;, &quot;update_page_with_instance_variables&quot;
+
+          &quot;layouts/standard&quot;
+        when &quot;action_talk_to_layout&quot;, &quot;layout_overriding_layout&quot;
+          &quot;layouts/talk_from_action&quot;
       end
     end
 end
@@ -227,13 +625,24 @@ class RenderTest &lt; Test::Unit::TestCase
     @response   = ActionController::TestResponse.new
     @controller = TestController.new
 
+    # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+    # a more accurate simulation of what happens in &quot;real life&quot;.
+    @controller.logger = Logger.new(nil)
+
     @request.host = &quot;www.nextangle.com&quot;
   end
 
   def test_simple_show
     get :hello_world
     assert_response 200
+    assert_response :success
     assert_template &quot;test/hello_world&quot;
+    assert_equal &quot;&lt;html&gt;Hello world!&lt;/html&gt;&quot;, @response.body
+  end
+
+  def test_renders_default_template_for_missing_action
+    get :'hyphen-ated'
+    assert_template 'test/hyphen-ated'
   end
 
   def test_render
@@ -290,6 +699,41 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_equal &quot;hello world&quot;, @response.body
   end
 
+  def test_do_with_render_text_and_layout
+    get :render_text_hello_world_with_layout
+    assert_equal &quot;&lt;html&gt;hello world, I'm here!&lt;/html&gt;&quot;, @response.body
+  end
+
+  def test_do_with_render_action_and_layout_false
+    get :hello_world_with_layout_false
+    assert_equal 'Hello world!', @response.body
+  end
+
+  def test_render_file_with_instance_variables
+    get :render_file_with_instance_variables
+    assert_equal &quot;The secret is in the sauce\n&quot;, @response.body
+  end
+
+  def test_render_file_not_using_full_path
+    get :render_file_not_using_full_path
+    assert_equal &quot;The secret is in the sauce\n&quot;, @response.body
+  end
+
+  def test_render_file_not_using_full_path_with_dot_in_path
+    get :render_file_not_using_full_path_with_dot_in_path
+    assert_equal &quot;The secret is in the sauce\n&quot;, @response.body
+  end
+
+  def test_render_file_with_locals
+    get :render_file_with_locals
+    assert_equal &quot;The secret is in the sauce\n&quot;, @response.body
+  end
+
+  def test_render_file_from_template
+    get :render_file_from_template
+    assert_equal &quot;The secret is in the sauce\n&quot;, @response.body
+  end
+
   def test_render_json
     get :render_json_hello_world
     assert_equal '{&quot;hello&quot;: &quot;world&quot;}', @response.body
@@ -317,6 +761,7 @@ class RenderTest &lt; Test::Unit::TestCase
   def test_render_custom_code
     get :render_custom_code
     assert_response 404
+    assert_response :missing
     assert_equal 'hello world', @response.body
   end
 
@@ -329,7 +774,7 @@ class RenderTest &lt; Test::Unit::TestCase
   def test_render_text_with_nil
     get :render_text_with_nil
     assert_response 200
-    assert_equal '', @response.body
+    assert_equal ' ', @response.body
   end
 
   def test_render_text_with_false
@@ -355,6 +800,26 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_raises(ActionController::UnknownAction, &quot;No action responded to [determine_layout]&quot;) { get :determine_layout }
   end
 
+  def test_access_to_request_in_view
+    get :accessing_request_in_template
+    assert_equal &quot;Hello: www.nextangle.com&quot;, @response.body
+  end
+
+  def test_access_to_logger_in_view
+    get :accessing_logger_in_template
+    assert_equal &quot;Logger&quot;, @response.body
+  end
+
+  def test_access_to_action_name_in_view
+    get :accessing_action_name_in_template
+    assert_equal &quot;accessing_action_name_in_template&quot;, @response.body
+  end
+
+  def test_access_to_controller_name_in_view
+    get :accessing_controller_name_in_template
+    assert_equal &quot;test&quot;, @response.body # name is explicitly set to 'test' inside the controller.
+  end
+
   def test_render_xml
     get :render_xml_hello
     assert_equal &quot;&lt;html&gt;\n  &lt;p&gt;Hello David&lt;/p&gt;\n&lt;p&gt;This is grand!&lt;/p&gt;\n&lt;/html&gt;\n&quot;, @response.body
@@ -371,6 +836,19 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_equal &quot;&lt;test&gt;\n  &lt;hello/&gt;\n&lt;/test&gt;\n&quot;, @response.body
   end
 
+  def test_enum_rjs_test
+    get :enum_rjs_test
+    body = %{
+      $$(&quot;.product&quot;).each(function(value, index) {
+      new Effect.Highlight(element,{});
+      new Effect.Highlight(value,{});
+      Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value)})}});
+      new Draggable(value, {});
+      });
+    }.gsub(/^      /, '').strip
+    assert_equal body, @response.body
+  end
+
   def test_layout_rendering
     get :layout_test
     assert_equal &quot;&lt;html&gt;Hello world!&lt;/html&gt;&quot;, @response.body
@@ -381,14 +859,9 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_equal &quot;&lt;wrapper&gt;\n&lt;html&gt;\n  &lt;p&gt;Hello &lt;/p&gt;\n&lt;p&gt;This is grand!&lt;/p&gt;\n&lt;/html&gt;\n&lt;/wrapper&gt;\n&quot;, @response.body
   end
 
-  # def test_partials_list
-  #   get :partials_list
-  #   assert_equal &quot;goodbyeHello: davidHello: marygoodbye\n&quot;, process_request.body
-  # end
-
-  def test_partial_only
-    get :partial_only
-    assert_equal &quot;only partial&quot;, @response.body
+  def test_partials_list
+    get :partials_list
+    assert_equal &quot;goodbyeHello: davidHello: marygoodbye\n&quot;, @response.body
   end
 
   def test_render_to_string
@@ -438,6 +911,252 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_equal '&lt;test&gt;passed formatted html erb&lt;/test&gt;', @response.body
   end
 
+  def test_should_render_xml_but_keep_custom_content_type
+    get :render_xml_with_custom_content_type
+    assert_equal &quot;application/atomsvc+xml&quot;, @response.content_type
+  end
+
+  def test_render_with_default_from_accept_header
+    xhr :get, :greeting
+    assert_equal &quot;$(\&quot;body\&quot;).visualEffect(\&quot;highlight\&quot;);&quot;, @response.body
+  end
+
+  def test_render_rjs_with_default
+    get :delete_with_js
+    assert_equal %!Element.remove(&quot;person&quot;);\nnew Effect.Highlight(\&quot;project-4\&quot;,{});!, @response.body
+  end
+
+  def test_render_rjs_template_explicitly
+    get :render_js_with_explicit_template
+    assert_equal %!Element.remove(&quot;person&quot;);\nnew Effect.Highlight(\&quot;project-4\&quot;,{});!, @response.body
+  end
+
+  def test_rendering_rjs_action_explicitly
+    get :render_js_with_explicit_action_template
+    assert_equal %!Element.remove(&quot;person&quot;);\nnew Effect.Highlight(\&quot;project-4\&quot;,{});!, @response.body
+  end
+
+  def test_layout_test_with_different_layout
+    get :layout_test_with_different_layout
+    assert_equal &quot;&lt;html&gt;Hello world!&lt;/html&gt;&quot;, @response.body
+  end
+
+  def test_rendering_without_layout
+    get :rendering_without_layout
+    assert_equal &quot;Hello world!&quot;, @response.body
+  end
+
+  def test_layout_overriding_layout
+    get :layout_overriding_layout
+    assert_no_match %r{&lt;title&gt;}, @response.body
+  end
+
+  def test_rendering_nothing_on_layout
+    get :rendering_nothing_on_layout
+    assert_equal &quot; &quot;, @response.body
+  end
+
+  def test_render_to_string
+    assert_not_deprecated { get :hello_in_a_string }
+    assert_equal &quot;How's there? goodbyeHello: davidHello: marygoodbye\n&quot;, @response.body
+  end
+
+  def test_render_to_string_doesnt_break_assigns
+    get :render_to_string_with_assigns
+    assert_equal &quot;i'm before the render&quot;, assigns(:before)
+    assert_equal &quot;i'm after the render&quot;, assigns(:after)
+  end
+
+  def test_bad_render_to_string_still_throws_exception
+    assert_raises(ActionView::MissingTemplate) { get :render_to_string_with_exception }
+  end
+
+  def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
+    assert_nothing_raised { get :render_to_string_with_caught_exception }
+    assert_equal &quot;i'm before the render&quot;, assigns(:before)
+    assert_equal &quot;i'm after the render&quot;, assigns(:after)
+  end
+
+  def test_accessing_params_in_template_with_layout
+    get :accessing_params_in_template_with_layout, :name =&gt; &quot;David&quot;
+    assert_equal &quot;&lt;html&gt;Hello: David&lt;/html&gt;&quot;, @response.body
+  end
+
+  def test_render_with_explicit_template
+    get :render_with_explicit_template
+    assert_response :success
+  end
+
+  def test_double_render
+    assert_raises(ActionController::DoubleRenderError) { get :double_render }
+  end
+
+  def test_double_redirect
+    assert_raises(ActionController::DoubleRenderError) { get :double_redirect }
+  end
+
+  def test_render_and_redirect
+    assert_raises(ActionController::DoubleRenderError) { get :render_and_redirect }
+  end
+
+  # specify the one exception to double render rule - render_to_string followed by render
+  def test_render_to_string_and_render
+    get :render_to_string_and_render
+    assert_equal(&quot;Hi web users! here is some cached stuff&quot;, @response.body)
+  end
+
+  def test_rendering_with_conflicting_local_vars
+    get :rendering_with_conflicting_local_vars
+    assert_equal(&quot;First: David\nSecond: Stephan\nThird: David\nFourth: David\nFifth: &quot;, @response.body)
+  end
+
+  def test_action_talk_to_layout
+    get :action_talk_to_layout
+    assert_equal &quot;&lt;title&gt;Talking to the layout&lt;/title&gt;\nAction was here!&quot;, @response.body
+  end
+
+  def test_render_text_with_assigns
+    get :render_text_with_assigns
+    assert_equal &quot;world&quot;, assigns[&quot;hello&quot;]
+  end
+
+  def test_template_with_locals
+    get :render_with_explicit_template_with_locals
+    assert_equal &quot;The secret is area51\n&quot;, @response.body
+  end
+
+  def test_update_page
+    get :update_page
+    assert_template nil
+    assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
+    assert_equal 2, @response.body.split($/).length
+  end
+
+  def test_update_page_with_instance_variables
+    get :update_page_with_instance_variables
+    assert_template nil
+    assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
+    assert_match /balance/, @response.body
+    assert_match /\$37/, @response.body
+  end
+
+  def test_update_page_with_view_method
+    get :update_page_with_view_method
+    assert_template nil
+    assert_equal 'text/javascript; charset=utf-8', @response.headers['type']
+    assert_match /2 people/, @response.body
+  end
+
+  def test_yield_content_for
+    assert_not_deprecated { get :yield_content_for }
+    assert_equal &quot;&lt;title&gt;Putting stuff in the title!&lt;/title&gt;\n\nGreat stuff!\n&quot;, @response.body
+  end
+
+  def test_overwritting_rendering_relative_file_with_extension
+    get :hello_world_from_rxml_using_template
+    assert_equal &quot;&lt;html&gt;\n  &lt;p&gt;Hello&lt;/p&gt;\n&lt;/html&gt;\n&quot;, @response.body
+
+    get :hello_world_from_rxml_using_action
+    assert_equal &quot;&lt;html&gt;\n  &lt;p&gt;Hello&lt;/p&gt;\n&lt;/html&gt;\n&quot;, @response.body
+  end
+
+  def test_head_with_location_header
+    get :head_with_location_header
+    assert @response.body.blank?
+    assert_equal &quot;/foo&quot;, @response.headers[&quot;Location&quot;]
+    assert_response :ok
+  end
+
+  def test_head_with_custom_header
+    get :head_with_custom_header
+    assert @response.body.blank?
+    assert_equal &quot;something&quot;, @response.headers[&quot;X-Custom-Header&quot;]
+    assert_response :ok
+  end
+
+  def test_head_with_symbolic_status
+    get :head_with_symbolic_status, :status =&gt; &quot;ok&quot;
+    assert_equal &quot;200 OK&quot;, @response.headers[&quot;Status&quot;]
+    assert_response :ok
+
+    get :head_with_symbolic_status, :status =&gt; &quot;not_found&quot;
+    assert_equal &quot;404 Not Found&quot;, @response.headers[&quot;Status&quot;]
+    assert_response :not_found
+
+    ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code|
+      get :head_with_symbolic_status, :status =&gt; status.to_s
+      assert_equal code, @response.response_code
+      assert_response status
+    end
+  end
+
+  def test_head_with_integer_status
+    ActionController::StatusCodes::STATUS_CODES.each do |code, message|
+      get :head_with_integer_status, :status =&gt; code.to_s
+      assert_equal message, @response.message
+    end
+  end
+
+  def test_head_with_string_status
+    get :head_with_string_status, :status =&gt; &quot;404 Eat Dirt&quot;
+    assert_equal 404, @response.response_code
+    assert_equal &quot;Eat Dirt&quot;, @response.message
+    assert_response :not_found
+  end
+
+  def test_head_with_status_code_first
+    get :head_with_status_code_first
+    assert_equal 403, @response.response_code
+    assert_equal &quot;Forbidden&quot;, @response.message
+    assert_equal &quot;something&quot;, @response.headers[&quot;X-Custom-Header&quot;]
+    assert_response :forbidden
+  end
+
+  def test_rendering_with_location_should_set_header
+    get :render_with_location
+    assert_equal &quot;http://example.com&quot;, @response.headers[&quot;Location&quot;]
+  end
+
+  def test_rendering_xml_should_call_to_xml_if_possible
+    get :render_with_to_xml
+    assert_equal &quot;&lt;i-am-xml/&gt;&quot;, @response.body
+  end
+
+  def test_rendering_with_object_location_should_set_header_with_url_for
+    ActionController::Routing::Routes.draw do |map|
+      map.resources :customers
+      map.connect ':controller/:action/:id'
+    end
+
+    get :render_with_object_location
+    assert_equal &quot;http://www.nextangle.com/customers/1&quot;, @response.headers[&quot;Location&quot;]
+  end
+
+  def test_should_use_implicit_content_type
+    get :implicit_content_type, :format =&gt; 'atom'
+    assert_equal Mime::ATOM, @response.content_type
+  end
+
+  def test_using_layout_around_block
+    get :render_using_layout_around_block
+    assert_equal &quot;Before (David)\nInside from block\nAfter&quot;, @response.body
+  end
+
+  def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
+    get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout
+    assert_equal &quot;Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n&quot;, @response.body
+  end
+
+  def test_using_layout_around_block_with_args
+    get :render_using_layout_around_block_with_args
+    assert_equal &quot;Before\narg1arg2\nAfter&quot;, @response.body
+  end
+
+  def test_partial_only
+    get :partial_only
+    assert_equal &quot;only partial&quot;, @response.body
+  end
+
   def test_should_render_html_formatted_partial
     get :partial
     assert_equal 'partial html', @response.body
@@ -468,14 +1187,115 @@ class RenderTest &lt; Test::Unit::TestCase
     assert_equal %(Element.replace(&quot;foo&quot;, &quot;partial html&quot;);), @response.body
   end
 
-  def test_should_render_xml_but_keep_custom_content_type
-    get :render_xml_with_custom_content_type
-    assert_equal &quot;application/atomsvc+xml&quot;, @response.content_type
+  def test_partial_only_with_layout
+    get :partial_only_with_layout
+    assert_equal &quot;&lt;html&gt;only partial&lt;/html&gt;&quot;, @response.body
   end
 
-  def test_should_use_implicit_content_type
-    get :implicit_content_type, :format =&gt; 'atom'
-    assert_equal Mime::ATOM, @response.content_type
+  def test_render_to_string_partial
+    get :render_to_string_with_partial
+    assert_equal &quot;only partial&quot;, assigns(:partial_only)
+    assert_equal &quot;Hello: david&quot;, assigns(:partial_with_locals)
+  end
+
+  def test_partial_with_counter
+    get :partial_with_counter
+    assert_equal &quot;5&quot;, @response.body
+  end
+
+  def test_partial_with_locals
+    get :partial_with_locals
+    assert_equal &quot;Hello: david&quot;, @response.body
+  end
+
+  def test_partial_with_form_builder
+    get :partial_with_form_builder
+    assert_match(/&lt;label/, @response.body)
+    assert_template('test/_form')
+  end
+
+  def test_partial_with_form_builder_subclass
+    get :partial_with_form_builder_subclass
+    assert_match(/&lt;label/, @response.body)
+    assert_template('test/_labelling_form')
+  end
+
+  def test_partial_collection
+    get :partial_collection
+    assert_equal &quot;Hello: davidHello: mary&quot;, @response.body
+  end
+
+  def test_partial_collection_with_as
+    get :partial_collection_with_as
+    assert_equal &quot;david david davidmary mary mary&quot;, @response.body
+  end
+
+  def test_partial_collection_with_counter
+    get :partial_collection_with_counter
+    assert_equal &quot;david0mary1&quot;, @response.body
+  end
+
+  def test_partial_collection_with_locals
+    get :partial_collection_with_locals
+    assert_equal &quot;Bonjour: davidBonjour: mary&quot;, @response.body
+  end
+
+  def test_partial_collection_with_spacer
+    get :partial_collection_with_spacer
+    assert_equal &quot;Hello: davidonly partialHello: mary&quot;, @response.body
+  end
+
+  def test_partial_collection_shorthand_with_locals
+    get :partial_collection_shorthand_with_locals
+    assert_equal &quot;Bonjour: davidBonjour: mary&quot;, @response.body
+  end
+
+  def test_partial_collection_shorthand_with_different_types_of_records
+    get :partial_collection_shorthand_with_different_types_of_records
+    assert_equal &quot;Bonjour bad customer: mark0Bonjour good customer: craig1Bonjour bad customer: john2Bonjour good customer: zach3Bonjour good customer: brandon4Bonjour bad customer: dan5&quot;, @response.body
+  end
+
+  def test_empty_partial_collection
+    get :empty_partial_collection
+    assert_equal &quot; &quot;, @response.body
+  end
+
+  def test_partial_with_hash_object
+    get :partial_with_hash_object
+    assert_equal &quot;Sam\nmaS\n&quot;, @response.body
+  end
+
+  def test_hash_partial_collection
+    get :partial_hash_collection
+    assert_equal &quot;Pratik\nkitarP\nAmy\nymA\n&quot;, @response.body
+  end
+
+  def test_partial_hash_collection_with_locals
+    get :partial_hash_collection_with_locals
+    assert_equal &quot;Hola: PratikHola: Amy&quot;, @response.body
+  end
+
+  def test_partial_with_implicit_local_assignment
+    assert_deprecated do
+      get :partial_with_implicit_local_assignment
+      assert_equal &quot;Hello: Marcel&quot;, @response.body
+    end
+  end
+
+  def test_render_missing_partial_template
+    assert_raises(ActionView::MissingTemplate) do
+      get :missing_partial
+    end
+  end
+
+  def test_render_call_to_partial_with_layout
+    get :render_call_to_partial_with_layout
+    assert_equal &quot;Before (David)\nInside from partial (David)\nAfter&quot;, @response.body
+  end
+
+  def test_render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+    get :render_call_to_partial_with_layout_in_main_layout_and_within_content_for_layout
+    assert_equal &quot;Before (Anthony)\nInside from partial (Anthony)\nAfter\nBefore (David)\nInside from partial (David)\nAfter\nBefore (Ramm)\nInside from partial (Ramm)\nAfter&quot;, @response.body
   end
 end
 
@@ -501,6 +1321,12 @@ class EtagRenderTest &lt; Test::Unit::TestCase
     assert @response.body.empty?
   end
 
+  def test_render_against_etag_request_should_have_no_content_length_when_match
+    @request.if_none_match = etag_for(&quot;hello david&quot;)
+    get :render_hello_world_from_variable
+    assert !@response.headers.has_key?(&quot;Content-Length&quot;)
+  end
+
   def test_render_against_etag_request_should_200_when_no_match
     @request.if_none_match = etag_for(&quot;hello somewhere else&quot;)
     get :render_hello_world_from_variable
@@ -577,3 +1403,21 @@ class LastModifiedRenderTest &lt; Test::Unit::TestCase
     assert_equal @last_modified, @response.headers['Last-Modified']
   end
 end
+
+class RenderingLoggingTest &lt; Test::Unit::TestCase
+  def setup
+    @request    = ActionController::TestRequest.new
+    @response   = ActionController::TestResponse.new
+    @controller = TestController.new
+
+    @request.host = &quot;www.nextangle.com&quot;
+  end
+
+  def test_logger_prints_layout_and_template_rendering_info
+    @controller.logger = MockLogger.new
+    get :layout_test
+    logged = @controller.logger.logged.find_all {|l| l =~ /render/i }
+    assert_equal &quot;Rendering template within layouts/standard&quot;, logged[0]
+    assert_equal &quot;Rendering test/hello_world&quot;, logged[1]
+  end
+end</diff>
      <filename>actionpack/test/controller/render_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,6 +17,9 @@ class RequestTest &lt; Test::Unit::TestCase
     @request.remote_addr = '1.2.3.4'
     assert_equal '1.2.3.4', @request.remote_ip(true)
 
+    @request.remote_addr = '1.2.3.4,3.4.5.6'
+    assert_equal '1.2.3.4', @request.remote_ip(true)
+
     @request.env['HTTP_CLIENT_IP'] = '2.3.4.5'
     assert_equal '1.2.3.4', @request.remote_ip(true)
 </diff>
      <filename>actionpack/test/controller/request_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -264,6 +264,19 @@ class ResourcesTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_array_as_collection_or_member_method_value
+    with_restful_routing :messages, :collection =&gt; { :search =&gt; [:get, :post] }, :member =&gt; { :toggle =&gt; [:get, :post] } do
+      assert_restful_routes_for :messages do |options|
+        [:get, :post].each do |method|
+          assert_recognizes(options.merge(:action =&gt; 'search'), :path =&gt; &quot;/messages/search&quot;, :method =&gt; method)
+        end
+        [:get, :post].each do |method|
+          assert_recognizes(options.merge(:action =&gt; 'toggle', :id =&gt; '1'), :path =&gt; '/messages/1/toggle', :method =&gt; method)
+        end
+      end
+    end
+  end
+
   def test_with_new_action
     with_restful_routing :messages, :new =&gt; { :preview =&gt; :post } do
       preview_options = {:action =&gt; 'preview'}
@@ -366,6 +379,31 @@ class ResourcesTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_shallow_nested_restful_routes
+    with_routing do |set|
+      set.draw do |map|
+        map.resources :threads, :shallow =&gt; true do |map|
+          map.resources :messages do |map|
+            map.resources :comments
+          end
+        end
+      end
+
+      assert_simply_restful_for :threads,
+        :shallow =&gt; true
+      assert_simply_restful_for :messages,
+        :name_prefix =&gt; 'thread_',
+        :path_prefix =&gt; 'threads/1/',
+        :shallow =&gt; true,
+        :options =&gt; { :thread_id =&gt; '1' }
+      assert_simply_restful_for :comments,
+        :name_prefix =&gt; 'message_',
+        :path_prefix =&gt; 'messages/2/',
+        :shallow =&gt; true,
+        :options =&gt; { :message_id =&gt; '2' }
+    end
+  end
+
   def test_restful_routes_dont_generate_duplicates
     with_restful_routing :messages do
       routes = ActionController::Routing::Routes.routes
@@ -416,6 +454,32 @@ class ResourcesTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_resources_has_many_hash_should_become_nested_resources
+    with_routing do |set|
+      set.draw do |map|
+        map.resources :threads, :has_many =&gt; { :messages =&gt; [ :comments, { :authors =&gt; :threads } ] }
+      end
+
+      assert_simply_restful_for :threads
+      assert_simply_restful_for :messages, :name_prefix =&gt; &quot;thread_&quot;, :path_prefix =&gt; 'threads/1/', :options =&gt; { :thread_id =&gt; '1' }
+      assert_simply_restful_for :comments, :name_prefix =&gt; &quot;thread_message_&quot;, :path_prefix =&gt; 'threads/1/messages/1/', :options =&gt; { :thread_id =&gt; '1', :message_id =&gt; '1' }
+      assert_simply_restful_for :authors,  :name_prefix =&gt; &quot;thread_message_&quot;, :path_prefix =&gt; 'threads/1/messages/1/', :options =&gt; { :thread_id =&gt; '1', :message_id =&gt; '1' }
+      assert_simply_restful_for :threads,  :name_prefix =&gt; &quot;thread_message_author_&quot;, :path_prefix =&gt; 'threads/1/messages/1/authors/1/', :options =&gt; { :thread_id =&gt; '1', :message_id =&gt; '1', :author_id =&gt; '1' }
+    end
+  end
+
+  def test_shallow_resource_has_many_should_become_shallow_nested_resources
+    with_routing do |set|
+      set.draw do |map|
+        map.resources :messages, :has_many =&gt; [ :comments, :authors ], :shallow =&gt; true
+      end
+
+      assert_simply_restful_for :messages, :shallow =&gt; true
+      assert_simply_restful_for :comments, :name_prefix =&gt; &quot;message_&quot;, :path_prefix =&gt; 'messages/1/', :shallow =&gt; true, :options =&gt; { :message_id =&gt; '1' }
+      assert_simply_restful_for :authors,  :name_prefix =&gt; &quot;message_&quot;, :path_prefix =&gt; 'messages/1/', :shallow =&gt; true, :options =&gt; { :message_id =&gt; '1' }
+    end
+  end
+
   def test_resource_has_one_should_become_nested_resources
     with_routing do |set|
       set.draw do |map|
@@ -427,6 +491,17 @@ class ResourcesTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_shallow_resource_has_one_should_become_shallow_nested_resources
+    with_routing do |set|
+      set.draw do |map|
+        map.resources :messages, :has_one =&gt; :logo, :shallow =&gt; true
+      end
+
+      assert_simply_restful_for :messages, :shallow =&gt; true
+      assert_singleton_restful_for :logo, :name_prefix =&gt; 'message_', :path_prefix =&gt; 'messages/1/', :shallow =&gt; true, :options =&gt; { :message_id =&gt; '1' }
+    end
+  end
+
   def test_singleton_resource_with_member_action
     [:put, :post].each do |method|
       with_singleton_resources :account, :member =&gt; { :reset =&gt; method } do
@@ -731,6 +806,13 @@ class ResourcesTest &lt; Test::Unit::TestCase
       options[:options] ||= {}
       options[:options][:controller] = options[:controller] || controller_name.to_s
 
+      if options[:shallow]
+        options[:shallow_options] ||= {}
+        options[:shallow_options][:controller] = options[:options][:controller]
+      else
+        options[:shallow_options] = options[:options]
+      end
+
       new_action    = ActionController::Base.resources_path_names[:new] || &quot;new&quot;
       edit_action   = ActionController::Base.resources_path_names[:edit] || &quot;edit&quot;
       if options[:path_names]
@@ -738,8 +820,10 @@ class ResourcesTest &lt; Test::Unit::TestCase
         edit_action = options[:path_names][:edit] if options[:path_names][:edit]
       end
 
-      collection_path            = &quot;/#{options[:path_prefix]}#{options[:as] || controller_name}&quot;
-      member_path                = &quot;#{collection_path}/1&quot;
+      path                       = &quot;#{options[:as] || controller_name}&quot;
+      collection_path            = &quot;/#{options[:path_prefix]}#{path}&quot;
+      shallow_path               = &quot;/#{options[:path_prefix] unless options[:shallow]}#{path}&quot;
+      member_path                = &quot;#{shallow_path}/1&quot;
       new_path                   = &quot;#{collection_path}/#{new_action}&quot;
       edit_member_path           = &quot;#{member_path}/#{edit_action}&quot;
       formatted_edit_member_path = &quot;#{member_path}/#{edit_action}.xml&quot;
@@ -747,10 +831,13 @@ class ResourcesTest &lt; Test::Unit::TestCase
       with_options(options[:options]) do |controller|
         controller.assert_routing collection_path,            :action =&gt; 'index'
         controller.assert_routing new_path,                   :action =&gt; 'new'
-        controller.assert_routing member_path,                :action =&gt; 'show', :id =&gt; '1'
-        controller.assert_routing edit_member_path,           :action =&gt; 'edit', :id =&gt; '1'
         controller.assert_routing &quot;#{collection_path}.xml&quot;,   :action =&gt; 'index',            :format =&gt; 'xml'
         controller.assert_routing &quot;#{new_path}.xml&quot;,          :action =&gt; 'new',              :format =&gt; 'xml'
+      end
+
+      with_options(options[:shallow_options]) do |controller|
+        controller.assert_routing member_path,                :action =&gt; 'show', :id =&gt; '1'
+        controller.assert_routing edit_member_path,           :action =&gt; 'edit', :id =&gt; '1'
         controller.assert_routing &quot;#{member_path}.xml&quot;,       :action =&gt; 'show', :id =&gt; '1', :format =&gt; 'xml'
         controller.assert_routing formatted_edit_member_path, :action =&gt; 'edit', :id =&gt; '1', :format =&gt; 'xml'
       end
@@ -758,18 +845,18 @@ class ResourcesTest &lt; Test::Unit::TestCase
       assert_recognizes(options[:options].merge(:action =&gt; 'index'),               :path =&gt; collection_path,  :method =&gt; :get)
       assert_recognizes(options[:options].merge(:action =&gt; 'new'),                 :path =&gt; new_path,         :method =&gt; :get)
       assert_recognizes(options[:options].merge(:action =&gt; 'create'),              :path =&gt; collection_path,  :method =&gt; :post)
-      assert_recognizes(options[:options].merge(:action =&gt; 'show',    :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'edit',    :id =&gt; '1'), :path =&gt; edit_member_path, :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'update',  :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :put)
-      assert_recognizes(options[:options].merge(:action =&gt; 'destroy', :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :delete)
-
-      assert_recognizes(options[:options].merge(:action =&gt; 'index',               :format =&gt; 'xml'), :path =&gt; &quot;#{collection_path}.xml&quot;,   :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'new',                 :format =&gt; 'xml'), :path =&gt; &quot;#{new_path}.xml&quot;,          :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'create',              :format =&gt; 'xml'), :path =&gt; &quot;#{collection_path}.xml&quot;,   :method =&gt; :post)
-      assert_recognizes(options[:options].merge(:action =&gt; 'show',    :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'edit',    :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; formatted_edit_member_path, :method =&gt; :get)
-      assert_recognizes(options[:options].merge(:action =&gt; 'update',  :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :put)
-      assert_recognizes(options[:options].merge(:action =&gt; 'destroy', :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :delete)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'show',    :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :get)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'edit',    :id =&gt; '1'), :path =&gt; edit_member_path, :method =&gt; :get)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'update',  :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :put)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'destroy', :id =&gt; '1'), :path =&gt; member_path,      :method =&gt; :delete)
+
+      assert_recognizes(options[:options].merge(:action =&gt; 'index',  :format =&gt; 'xml'), :path =&gt; &quot;#{collection_path}.xml&quot;,   :method =&gt; :get)
+      assert_recognizes(options[:options].merge(:action =&gt; 'new',    :format =&gt; 'xml'), :path =&gt; &quot;#{new_path}.xml&quot;,          :method =&gt; :get)
+      assert_recognizes(options[:options].merge(:action =&gt; 'create', :format =&gt; 'xml'), :path =&gt; &quot;#{collection_path}.xml&quot;,   :method =&gt; :post)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'show',    :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :get)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'edit',    :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; formatted_edit_member_path, :method =&gt; :get)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'update',  :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :put)
+      assert_recognizes(options[:shallow_options].merge(:action =&gt; 'destroy', :id =&gt; '1', :format =&gt; 'xml'), :path =&gt; &quot;#{member_path}.xml&quot;,       :method =&gt; :delete)
 
       yield options[:options] if block_given?
     end
@@ -785,14 +872,24 @@ class ResourcesTest &lt; Test::Unit::TestCase
       options[:options] ||= {}
       options[:options][:controller] = options[:controller] || controller_name.to_s
 
+      if options[:shallow]
+        options[:shallow_options] ||= {}
+        options[:shallow_options][:controller] = options[:options][:controller]
+      else
+        options[:shallow_options] = options[:options]
+      end
+
       @controller = &quot;#{options[:options][:controller].camelize}Controller&quot;.constantize.new
       @request    = ActionController::TestRequest.new
       @response   = ActionController::TestResponse.new
       get :index, options[:options]
       options[:options].delete :action
 
-      full_prefix = &quot;/#{options[:path_prefix]}#{options[:as] || controller_name}&quot;
+      path = &quot;#{options[:as] || controller_name}&quot;
+      shallow_path = &quot;/#{options[:path_prefix] unless options[:shallow]}#{path}&quot;
+      full_path = &quot;/#{options[:path_prefix]}#{path}&quot;
       name_prefix = options[:name_prefix]
+      shallow_prefix = &quot;#{options[:name_prefix] unless options[:shallow]}&quot;
 
       new_action  = &quot;new&quot;
       edit_action = &quot;edit&quot;
@@ -801,15 +898,15 @@ class ResourcesTest &lt; Test::Unit::TestCase
         edit_action = options[:path_names][:edit] || &quot;edit&quot;
       end
 
-      assert_named_route &quot;#{full_prefix}&quot;,            &quot;#{name_prefix}#{controller_name}_path&quot;,              options[:options]
-      assert_named_route &quot;#{full_prefix}.xml&quot;,        &quot;formatted_#{name_prefix}#{controller_name}_path&quot;,    options[:options].merge(            :format =&gt; 'xml')
-      assert_named_route &quot;#{full_prefix}/1&quot;,          &quot;#{name_prefix}#{singular_name}_path&quot;,                options[:options].merge(:id =&gt; '1')
-      assert_named_route &quot;#{full_prefix}/1.xml&quot;,      &quot;formatted_#{name_prefix}#{singular_name}_path&quot;,      options[:options].merge(:id =&gt; '1', :format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}&quot;, &quot;#{name_prefix}#{controller_name}_path&quot;, options[:options]
+      assert_named_route &quot;#{full_path}.xml&quot;, &quot;formatted_#{name_prefix}#{controller_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{shallow_path}/1&quot;, &quot;#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1')
+      assert_named_route &quot;#{shallow_path}/1.xml&quot;, &quot;formatted_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
 
-      assert_named_route &quot;#{full_prefix}/#{new_action}&quot;,        &quot;new_#{name_prefix}#{singular_name}_path&quot;,            options[:options]
-      assert_named_route &quot;#{full_prefix}/#{new_action}.xml&quot;,    &quot;formatted_new_#{name_prefix}#{singular_name}_path&quot;,  options[:options].merge(            :format =&gt; 'xml')
-      assert_named_route &quot;#{full_prefix}/1/#{edit_action}&quot;,     &quot;edit_#{name_prefix}#{singular_name}_path&quot;,           options[:options].merge(:id =&gt; '1')
-      assert_named_route &quot;#{full_prefix}/1/#{edit_action}.xml&quot;, &quot;formatted_edit_#{name_prefix}#{singular_name}_path&quot;, options[:options].merge(:id =&gt; '1', :format =&gt; 'xml')
+      assert_named_route &quot;#{full_path}/#{new_action}&quot;, &quot;new_#{name_prefix}#{singular_name}_path&quot;, options[:options]
+      assert_named_route &quot;#{full_path}/#{new_action}.xml&quot;, &quot;formatted_new_#{name_prefix}#{singular_name}_path&quot;, options[:options].merge(:format =&gt; 'xml')
+      assert_named_route &quot;#{shallow_path}/1/#{edit_action}&quot;, &quot;edit_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1')
+      assert_named_route &quot;#{shallow_path}/1/#{edit_action}.xml&quot;, &quot;formatted_edit_#{shallow_prefix}#{singular_name}_path&quot;, options[:shallow_options].merge(:id =&gt; '1', :format =&gt; 'xml')
 
       yield options[:options] if block_given?
     end</diff>
      <filename>actionpack/test/controller/resources_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1297,6 +1297,29 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
       end
     end
 
+    def test_recognize_array_of_methods
+      Object.const_set(:BooksController, Class.new(ActionController::Base))
+      rs.draw do |r|
+        r.connect '/match', :controller =&gt; 'books', :action =&gt; 'get_or_post', :conditions =&gt; { :method =&gt; [:get, :post] }
+        r.connect '/match', :controller =&gt; 'books', :action =&gt; 'not_get_or_post'
+      end
+
+      @request = ActionController::TestRequest.new
+      @request.env[&quot;REQUEST_METHOD&quot;] = 'POST'
+      @request.request_uri = &quot;/match&quot;
+      assert_nothing_raised { rs.recognize(@request) }
+      assert_equal 'get_or_post', @request.path_parameters[:action]
+
+      # have to recreate or else the RouteSet uses a cached version:
+      @request = ActionController::TestRequest.new
+      @request.env[&quot;REQUEST_METHOD&quot;] = 'PUT'
+      @request.request_uri = &quot;/match&quot;
+      assert_nothing_raised { rs.recognize(@request) }
+      assert_equal 'not_get_or_post', @request.path_parameters[:action]
+    ensure
+      Object.send(:remove_const, :BooksController) rescue nil
+    end
+
     def test_subpath_recognized
       Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
 
@@ -1671,6 +1694,12 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
         controller.send(:multi_url, 7, &quot;hello&quot;, 5, :baz =&gt; &quot;bar&quot;)
     end
 
+    def test_named_route_url_method_with_ordered_parameters_and_empty_hash
+      controller = setup_named_route_test
+      assert_equal &quot;http://named.route.test/people/go/7/hello/joe/5&quot;,
+        controller.send(:multi_url, 7, &quot;hello&quot;, 5, {})
+    end
+
     def test_named_route_url_method_with_no_positional_arguments
       controller = setup_named_route_test
       assert_equal &quot;http://named.route.test/people?baz=bar&quot;,</diff>
      <filename>actionpack/test/controller/routing_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -531,6 +531,11 @@ XML
     assert_equal content_type, file.content_type
     assert_equal file.path, file.local_path
     assert_equal expected, file.read
+
+    new_content_type = &quot;new content_type&quot;
+    file.content_type = new_content_type
+    assert_equal new_content_type, file.content_type
+
   end
 
   def test_test_uploaded_file_with_binary</diff>
      <filename>actionpack/test/controller/test_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,37 +10,37 @@ class ActiveRecordHelperI18nTest &lt; Test::Unit::TestCase
       @object_name = 'book'
       stubs(:content_tag).returns 'content_tag'
 
-      I18n.stubs(:t).with(:'header_message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error], :count =&gt; 1, :object_name =&gt; '').returns &quot;1 error prohibited this  from being saved&quot;
-      I18n.stubs(:t).with(:'message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error]).returns 'There were problems with the following fields:'
+      I18n.stubs(:t).with(:'header', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template], :count =&gt; 1, :model =&gt; '').returns &quot;1 error prohibited this  from being saved&quot;
+      I18n.stubs(:t).with(:'body', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
     end
 
-    def test_error_messages_for_given_a_header_message_option_it_does_not_translate_header_message
-      I18n.expects(:translate).with(:'header_message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error], :count =&gt; 1, :object_name =&gt; '').never
+    def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message
+      I18n.expects(:translate).with(:'header', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template], :count =&gt; 1, :model =&gt; '').never
       error_messages_for(:object =&gt; @object, :header_message =&gt; 'header message', :locale =&gt; 'en-US')
     end
 
-    def test_error_messages_for_given_no_header_message_option_it_translates_header_message
-      I18n.expects(:t).with(:'header_message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error], :count =&gt; 1, :object_name =&gt; '').returns 'header message'
-      I18n.expects(:t).with('', :default =&gt; '').once.returns ''
+    def test_error_messages_for_given_no_header_option_it_translates_header_message
+      I18n.expects(:t).with(:'header', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template], :count =&gt; 1, :model =&gt; '').returns 'header message'
+      I18n.expects(:t).with('', :default =&gt; '', :count =&gt; 1, :scope =&gt; [:activerecord, :models]).once.returns ''
       error_messages_for(:object =&gt; @object, :locale =&gt; 'en-US')
     end
 
     def test_error_messages_for_given_a_message_option_it_does_not_translate_message
-      I18n.expects(:t).with(:'message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error]).never
-      I18n.expects(:t).with('', :default =&gt; '').once.returns ''
+      I18n.expects(:t).with(:'body', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template]).never
+      I18n.expects(:t).with('', :default =&gt; '', :count =&gt; 1, :scope =&gt; [:activerecord, :models]).once.returns ''
       error_messages_for(:object =&gt; @object, :message =&gt; 'message', :locale =&gt; 'en-US')
     end
 
     def test_error_messages_for_given_no_message_option_it_translates_message
-      I18n.expects(:t).with(:'message', :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error]).returns 'There were problems with the following fields:'
-      I18n.expects(:t).with('', :default =&gt; '').once.returns ''
+      I18n.expects(:t).with(:'body', :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template]).returns 'There were problems with the following fields:'
+      I18n.expects(:t).with('', :default =&gt; '', :count =&gt; 1, :scope =&gt; [:activerecord, :models]).once.returns ''
       error_messages_for(:object =&gt; @object, :locale =&gt; 'en-US')
     end
     
     def test_error_messages_for_given_object_name_it_translates_object_name
-      I18n.expects(:t).with(:header_message, :locale =&gt; 'en-US', :scope =&gt; [:active_record, :error], :count =&gt; 1, :object_name =&gt; @object_name).returns &quot;1 error prohibited this #{@object_name} from being saved&quot;
-      I18n.expects(:t).with(@object_name, :default =&gt; @object_name).once.returns @object_name
+      I18n.expects(:t).with(:header, :locale =&gt; 'en-US', :scope =&gt; [:activerecord, :errors, :template], :count =&gt; 1, :model =&gt; @object_name).returns &quot;1 error prohibited this #{@object_name} from being saved&quot;
+      I18n.expects(:t).with(@object_name, :default =&gt; @object_name, :count =&gt; 1, :scope =&gt; [:activerecord, :models]).once.returns @object_name
       error_messages_for(:object =&gt; @object, :locale =&gt; 'en-US', :object_name =&gt; @object_name)
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>actionpack/test/template/active_record_helper_i18n_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -74,12 +74,30 @@ class ScrollsController &lt; ActionController::Base
           end
         end
     EOT
+    FEEDS[&quot;feed_with_overridden_ids&quot;] = &lt;&lt;-EOT
+        atom_feed({:id =&gt; 'tag:test.rubyonrails.org,2008:test/'}) do |feed|
+          feed.title(&quot;My great blog!&quot;)
+          feed.updated((@scrolls.first.created_at))
+
+          for scroll in @scrolls
+            feed.entry(scroll, :id =&gt; &quot;tag:test.rubyonrails.org,2008:&quot;+scroll.id.to_s) do |entry|
+              entry.title(scroll.title)
+              entry.content(scroll.body, :type =&gt; 'html')
+              entry.tag!('app:edited', Time.now)
+
+              entry.author do |author|
+                author.name(&quot;DHH&quot;)
+              end
+            end
+          end
+        end
+    EOT
   def index
     @scrolls = [
       Scroll.new(1, &quot;1&quot;, &quot;Hello One&quot;, &quot;Something &lt;i&gt;COOL!&lt;/i&gt;&quot;, Time.utc(2007, 12, 12, 15), Time.utc(2007, 12, 12, 15)),
       Scroll.new(2, &quot;2&quot;, &quot;Hello Two&quot;, &quot;Something Boring&quot;, Time.utc(2007, 12, 12, 15)),
     ]
-    
+
     render :inline =&gt; FEEDS[params[:id]], :type =&gt; :builder
   end
 
@@ -98,21 +116,21 @@ class AtomFeedTest &lt; Test::Unit::TestCase
 
     @request.host = &quot;www.nextangle.com&quot;
   end
-  
+
   def test_feed_should_use_default_language_if_none_is_given
     with_restful_routing(:scrolls) do
       get :index, :id =&gt; &quot;defaults&quot;
       assert_match %r{xml:lang=&quot;en-US&quot;}, @response.body
     end
   end
-  
+
   def test_feed_should_include_two_entries
     with_restful_routing(:scrolls) do
       get :index, :id =&gt; &quot;defaults&quot;
       assert_select &quot;entry&quot;, 2
     end
   end
-  
+
   def test_entry_should_only_use_published_if_created_at_is_present
     with_restful_routing(:scrolls) do
       get :index, :id =&gt; &quot;defaults&quot;
@@ -167,7 +185,16 @@ class AtomFeedTest &lt; Test::Unit::TestCase
     end
   end
 
-  private
+  def test_feed_should_allow_overriding_ids
+    with_restful_routing(:scrolls) do
+      get :index, :id =&gt; &quot;feed_with_overridden_ids&quot;
+      assert_select &quot;id&quot;, :text =&gt; &quot;tag:test.rubyonrails.org,2008:test/&quot;
+      assert_select &quot;entry id&quot;, :text =&gt; &quot;tag:test.rubyonrails.org,2008:1&quot;
+      assert_select &quot;entry id&quot;, :text =&gt; &quot;tag:test.rubyonrails.org,2008:2&quot;
+    end
+  end
+
+private
     def with_restful_routing(resources)
       with_routing do |set|
         set.draw do |map|</diff>
      <filename>actionpack/test/template/atom_feed_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -47,6 +47,28 @@ class DateHelperDistanceOfTimeInWordsI18nTests &lt; Test::Unit::TestCase
       I18n.expects(:t).with(key, options)
       distance_of_time_in_words(@from, to, include_seconds, :locale =&gt; 'en-US')
     end
+
+    def test_distance_of_time_pluralizations
+      { [:'less_than_x_seconds', 1]   =&gt; 'less than 1 second',
+        [:'less_than_x_seconds', 2]   =&gt; 'less than 2 seconds',
+        [:'less_than_x_minutes', 1]   =&gt; 'less than a minute',
+        [:'less_than_x_minutes', 2]   =&gt; 'less than 2 minutes',
+        [:'x_minutes',           1]   =&gt; '1 minute',
+        [:'x_minutes',           2]   =&gt; '2 minutes',
+        [:'about_x_hours',       1]   =&gt; 'about 1 hour',
+        [:'about_x_hours',       2]   =&gt; 'about 2 hours',
+        [:'x_days',              1]   =&gt; '1 day',
+        [:'x_days',              2]   =&gt; '2 days',
+        [:'about_x_years',       1]   =&gt; 'about 1 year',
+        [:'about_x_years',       2]   =&gt; 'about 2 years',
+        [:'over_x_years',        1]   =&gt; 'over 1 year',
+        [:'over_x_years',        2]   =&gt; 'over 2 years' 
+
+        }.each do |args, expected|
+        key, count = *args
+        assert_equal expected, I18n.t(key, :count =&gt; count, :scope =&gt; 'datetime.distance_in_words')
+      end
+    end
   end
 end
 </diff>
      <filename>actionpack/test/template/date_helper_i18n_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -79,6 +79,8 @@ class PrototypeHelperTest &lt; PrototypeHelperBaseTest
       link_to_remote(&quot;Remote outauthor&quot;, :failure =&gt; &quot;alert(request.responseText)&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot;, :a =&gt; '10', :b =&gt; '20' })
     assert_dom_equal %(&lt;a href=\&quot;#\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\&quot;&gt;Remote outauthor&lt;/a&gt;),
       link_to_remote(&quot;Remote outauthor&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot; }, :type =&gt; :synchronous)
+    assert_dom_equal %(&lt;a href=\&quot;#\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, insertion:'bottom'}); return false;\&quot;&gt;Remote outauthor&lt;/a&gt;),
+      link_to_remote(&quot;Remote outauthor&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot; }, :position =&gt; :bottom)
   end
 
   def test_link_to_remote_html_options
@@ -91,6 +93,19 @@ class PrototypeHelperTest &lt; PrototypeHelperBaseTest
       link_to_remote(&quot;Remote&quot;, { :url =&gt; { :action =&gt; &quot;whatnot's&quot; } })
   end
 
+  def test_button_to_remote
+    assert_dom_equal %(&lt;input class=\&quot;fine\&quot; type=\&quot;button\&quot; value=\&quot;Remote outpost\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true});\&quot; /&gt;),
+      button_to_remote(&quot;Remote outpost&quot;, { :url =&gt; { :action =&gt; &quot;whatnot&quot;  }}, { :class =&gt; &quot;fine&quot;  })
+    assert_dom_equal %(&lt;input type=\&quot;button\&quot; value=\&quot;Remote outpost\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.reponseText)}});\&quot; /&gt;),
+      button_to_remote(&quot;Remote outpost&quot;, :complete =&gt; &quot;alert(request.reponseText)&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot;  })
+    assert_dom_equal %(&lt;input type=\&quot;button\&quot; value=\&quot;Remote outpost\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.reponseText)}});\&quot; /&gt;),
+      button_to_remote(&quot;Remote outpost&quot;, :success =&gt; &quot;alert(request.reponseText)&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot;  })
+    assert_dom_equal %(&lt;input type=\&quot;button\&quot; value=\&quot;Remote outpost\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\&quot; /&gt;),
+      button_to_remote(&quot;Remote outpost&quot;, :failure =&gt; &quot;alert(request.reponseText)&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot;  })
+    assert_dom_equal %(&lt;input type=\&quot;button\&quot; value=\&quot;Remote outpost\&quot; onclick=\&quot;new Ajax.Request('http://www.example.com/whatnot?a=10&amp;amp;b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\&quot; /&gt;),
+      button_to_remote(&quot;Remote outpost&quot;, :failure =&gt; &quot;alert(request.reponseText)&quot;, :url =&gt; { :action =&gt; &quot;whatnot&quot;, :a =&gt; '10', :b =&gt; '20' })
+  end
+
   def test_periodically_call_remote
     assert_dom_equal %(&lt;script type=&quot;text/javascript&quot;&gt;\n//&lt;![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Updater('schremser_bier', 'http://www.example.com/mehr_bier', {asynchronous:true, evalScripts:true})}, 10)\n//]]&gt;\n&lt;/script&gt;),
       periodically_call_remote(:update =&gt; &quot;schremser_bier&quot;, :url =&gt; { :action =&gt; &quot;mehr_bier&quot; })</diff>
      <filename>actionpack/test/template/prototype_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,6 +34,14 @@ class RecordTagHelperTest &lt; ActionView::TestCase
     assert_dom_equal expected, actual
   end
 
+  def test_block_not_in_erb_multiple_calls
+    expected = %(&lt;div class=&quot;post bar&quot; id=&quot;post_45&quot;&gt;#{@post.body}&lt;/div&gt;)
+    actual = div_for(@post, :class =&gt; &quot;bar&quot;) { @post.body }
+    assert_dom_equal expected, actual
+    actual = div_for(@post, :class =&gt; &quot;bar&quot;) { @post.body }
+    assert_dom_equal expected, actual
+  end
+
   def test_block_works_with_content_tag_for_in_erb
     __in_erb_template = ''
     expected = %(&lt;tr class=&quot;post&quot; id=&quot;post_45&quot;&gt;#{@post.body}&lt;/tr&gt;)</diff>
      <filename>actionpack/test/template/record_tag_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -87,6 +87,18 @@ class ViewRenderTest &lt; Test::Unit::TestCase
       @view.render(:partial =&gt; &quot;test/local_inspector&quot;, :collection =&gt; [ Customer.new(&quot;mary&quot;) ])
   end
 
+  def test_render_partial_with_empty_collection_should_return_nil
+    assert_nil @view.render(:partial =&gt; &quot;test/customer&quot;, :collection =&gt; [])
+  end
+
+  def test_render_partial_with_nil_collection_should_return_nil
+    assert_nil @view.render(:partial =&gt; &quot;test/customer&quot;, :collection =&gt; nil)
+  end
+
+  def test_render_partial_with_empty_array_should_return_nil
+    assert_nil @view.render(:partial =&gt; [])
+  end
+
   # TODO: The reason for this test is unclear, improve documentation
   def test_render_partial_and_fallback_to_layout
     assert_equal &quot;Before (Josh)\n\nAfter&quot;, @view.render(:partial =&gt; &quot;test/layout_for_partial&quot;, :locals =&gt; { :name =&gt; &quot;Josh&quot; })</diff>
      <filename>actionpack/test/template/render_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,9 +11,9 @@ class SanitizeHelperTest &lt; ActionView::TestCase
     assert_equal &quot;Dont touch me&quot;, strip_links(&quot;Dont touch me&quot;)
     assert_equal &quot;&lt;a&lt;a&quot;, strip_links(&quot;&lt;a&lt;a&quot;)
     assert_equal &quot;on my mind\nall day long&quot;, strip_links(&quot;&lt;a href='almost'&gt;on my mind&lt;/a&gt;\n&lt;A href='almost'&gt;all day long&lt;/A&gt;&quot;)
-    assert_equal &quot;0wn3d&quot;, strip_links(&quot;&lt;a href='http://www.rubyonrails.com/'&gt;&lt;a href='http://www.rubyonrails.com/' onlclick='steal()'&gt;0wn3d&lt;/a&gt;&lt;/a&gt;&quot;) 
-    assert_equal &quot;Magic&quot;, strip_links(&quot;&lt;a href='http://www.rubyonrails.com/'&gt;Mag&lt;a href='http://www.ruby-lang.org/'&gt;ic&quot;) 
-    assert_equal &quot;FrrFox&quot;, strip_links(&quot;&lt;href onlclick='steal()'&gt;FrrFox&lt;/a&gt;&lt;/href&gt;&quot;) 
+    assert_equal &quot;0wn3d&quot;, strip_links(&quot;&lt;a href='http://www.rubyonrails.com/'&gt;&lt;a href='http://www.rubyonrails.com/' onlclick='steal()'&gt;0wn3d&lt;/a&gt;&lt;/a&gt;&quot;)
+    assert_equal &quot;Magic&quot;, strip_links(&quot;&lt;a href='http://www.rubyonrails.com/'&gt;Mag&lt;a href='http://www.ruby-lang.org/'&gt;ic&quot;)
+    assert_equal &quot;FrrFox&quot;, strip_links(&quot;&lt;href onlclick='steal()'&gt;FrrFox&lt;/a&gt;&lt;/href&gt;&quot;)
     assert_equal &quot;My mind\nall &lt;b&gt;day&lt;/b&gt; long&quot;, strip_links(&quot;&lt;a href='almost'&gt;My mind&lt;/a&gt;\n&lt;A href='almost'&gt;all &lt;b&gt;day&lt;/b&gt; long&lt;/A&gt;&quot;)
     assert_equal &quot;all &lt;b&gt;day&lt;/b&gt; long&quot;, strip_links(&quot;&lt;&lt;a&gt;a href='hello'&gt;all &lt;b&gt;day&lt;/b&gt; long&lt;&lt;/A&gt;/a&gt;&quot;)
   end</diff>
      <filename>actionpack/test/template/sanitize_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -369,6 +369,40 @@ class TextHelperTest &lt; ActionView::TestCase
     assert_equal(&quot;red&quot;, cycle(&quot;red&quot;, &quot;blue&quot;, :name =&gt; &quot;colors&quot;))
   end
 
+  def test_current_cycle_with_default_name
+    cycle(&quot;even&quot;,&quot;odd&quot;)
+    assert_equal &quot;even&quot;, current_cycle
+    cycle(&quot;even&quot;,&quot;odd&quot;)
+    assert_equal &quot;odd&quot;, current_cycle
+    cycle(&quot;even&quot;,&quot;odd&quot;)
+    assert_equal &quot;even&quot;, current_cycle
+  end
+
+  def test_current_cycle_with_named_cycles
+    cycle(&quot;red&quot;, &quot;blue&quot;, :name =&gt; &quot;colors&quot;)
+    assert_equal &quot;red&quot;, current_cycle(&quot;colors&quot;)
+    cycle(&quot;red&quot;, &quot;blue&quot;, :name =&gt; &quot;colors&quot;)
+    assert_equal &quot;blue&quot;, current_cycle(&quot;colors&quot;)
+    cycle(&quot;red&quot;, &quot;blue&quot;, :name =&gt; &quot;colors&quot;)
+    assert_equal &quot;red&quot;, current_cycle(&quot;colors&quot;)
+  end
+
+  def test_current_cycle_safe_call
+    assert_nothing_raised { current_cycle }
+    assert_nothing_raised { current_cycle(&quot;colors&quot;) }
+  end
+
+  def test_current_cycle_with_more_than_two_names
+    cycle(1,2,3)
+    assert_equal &quot;1&quot;, current_cycle
+    cycle(1,2,3)
+    assert_equal &quot;2&quot;, current_cycle
+    cycle(1,2,3)
+    assert_equal &quot;3&quot;, current_cycle
+    cycle(1,2,3)
+    assert_equal &quot;1&quot;, current_cycle
+  end
+
   def test_default_named_cycle
     assert_equal(&quot;1&quot;, cycle(1, 2, 3))
     assert_equal(&quot;2&quot;, cycle(1, 2, 3, :name =&gt; &quot;default&quot;))</diff>
      <filename>actionpack/test/template/text_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+# encoding: utf-8
 require 'abstract_unit'
 
 RequestMock = Struct.new(&quot;Request&quot;, :request_uri, :protocol, :host_with_port, :env)</diff>
      <filename>actionpack/test/template/url_helper_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,15 +2,15 @@ module ActiveModel
   module StateMachine
     class Event
       attr_reader :name, :success
-      
+
       def initialize(machine, name, options = {}, &amp;block)
         @machine, @name, @transitions = machine, name, []
         if machine
-          machine.klass.send(:define_method, &quot;#{name.to_s}!&quot;) do |*args|
+          machine.klass.send(:define_method, &quot;#{name}!&quot;) do |*args|
             machine.fire_event(name, self, true, *args)
           end
 
-          machine.klass.send(:define_method, &quot;#{name.to_s}&quot;) do |*args|
+          machine.klass.send(:define_method, name.to_s) do |*args|
             machine.fire_event(name, self, false, *args)
           end
         end</diff>
      <filename>activemodel/lib/active_model/state_machine/event.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ module ActiveModel
   module Validations
     def self.included(base) # :nodoc:
       base.extend(ClassMethods)
-      base.send!(:include, ActiveSupport::Callbacks)
+      base.__send__(:include, ActiveSupport::Callbacks)
       base.define_callbacks :validate, :validate_on_create, :validate_on_update
     end
 </diff>
      <filename>activemodel/lib/active_model/validations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,7 @@ module ActiveModel
 
         enum = configuration[:in] || configuration[:within]
 
-        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(&quot;include?&quot;)
+        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(:include?)
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           record.errors.add(attr_name, configuration[:message] % value) if enum.include?(value)</diff>
      <filename>activemodel/lib/active_model/validations/exclusion.rb</filename>
    </modified>
    <modified>
      <diff>@@ -26,7 +26,7 @@ module ActiveModel
 
         enum = configuration[:in] || configuration[:within]
 
-        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(&quot;include?&quot;)
+        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(:include?)
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           record.errors.add(attr_name, configuration[:message] % value) unless enum.include?(value)</diff>
      <filename>activemodel/lib/active_model/validations/inclusion.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,7 +25,7 @@ module ActiveModel
       # Configuration options:
       # * &lt;tt&gt;:message&lt;/tt&gt; - Specifies a custom error message (default is: &quot;has already been taken&quot;)
       # * &lt;tt&gt;:scope&lt;/tt&gt; - One or more columns by which to limit the scope of the uniqueness constraint.
-      # * &lt;tt&gt;:case_sensitive&lt;/tt&gt; - Looks for an exact match.  Ignored by non-text columns (+false+ by default).
+      # * &lt;tt&gt;:case_sensitive&lt;/tt&gt; - Looks for an exact match.  Ignored by non-text columns (+true+ by default).
       # * &lt;tt&gt;:allow_nil&lt;/tt&gt; - If set to +true+, skips this validation if the attribute is +nil+ (default is: +false+)
       # * &lt;tt&gt;:allow_blank&lt;/tt&gt; - If set to +true+, skips this validation if the attribute is blank (default is: +false+)
       # * &lt;tt&gt;:if&lt;/tt&gt; - Specifies a method, proc or string to call to determine if the validation should
@@ -79,8 +79,8 @@ module ActiveModel
           results = finder_class.with_exclusive_scope do
             connection.select_all(
               construct_finder_sql(
-                :select     =&gt; &quot;#{attr_name}&quot;,
-                :from       =&gt; &quot;#{finder_class.quoted_table_name}&quot;,
+                :select     =&gt; attr_name,
+                :from       =&gt; finder_class.quoted_table_name,
                 :conditions =&gt; [condition_sql, *condition_params]
               )
             )
@@ -101,4 +101,4 @@ module ActiveModel
       end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activemodel/lib/active_model/validations/uniqueness.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,15 @@
 *Edge*
 
+* Changed benchmarks to be reported in milliseconds [DHH]
+
+* Connection pooling.  #936 [Nick Sieger]
+
+* Merge scoped :joins together instead of overwriting them. May expose scoping bugs in your code!  #501 [Andrew White]
+
+* before_save, before_validation and before_destroy callbacks that return false will now ROLLBACK the transaction.  Previously this would have been committed before the processing was aborted. #891 [Xavier Noria]
+
+* Transactional migrations for databases which support them.  #834 [divoxx, Adam Wiggins, Tarmo T&#228;nav]
+
 * Set config.active_record.timestamped_migrations = false to have migrations with numeric prefix instead of UTC timestamp. #446. [Andrew Stone, Nik Wakelin]
 
 * change_column_default preserves the not-null constraint.  #617 [Tarmo T&#228;nav]</diff>
      <filename>activerecord/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -21,17 +21,12 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
-$:.unshift(File.dirname(__FILE__)) unless
-  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-
-unless defined? ActiveSupport
-  active_support_path = File.dirname(__FILE__) + &quot;/../../activesupport/lib&quot;
-  if File.exist?(active_support_path)
-    $:.unshift active_support_path
-    require 'active_support'
-  else
-    require 'rubygems'
-    gem 'activesupport'
+begin
+  require 'active_support'
+rescue LoadError
+  activesupport_path = &quot;#{File.dirname(__FILE__)}/../../activesupport/lib&quot;
+  if File.directory?(activesupport_path)
+    $:.unshift activesupport_path
     require 'active_support'
   end
 end
@@ -56,6 +51,7 @@ require 'active_record/calculations'
 require 'active_record/serialization'
 require 'active_record/attribute_methods'
 require 'active_record/dirty'
+require 'active_record/dynamic_finder_match'
 
 ActiveRecord::Base.class_eval do
   extend ActiveRecord::QueryCache
@@ -81,7 +77,5 @@ require 'active_record/connection_adapters/abstract_adapter'
 
 require 'active_record/schema_dumper'
 
-I18n.backend.populate do
-  require 'active_record/locale/en-US.rb'
-end
+I18n.load_translations File.dirname(__FILE__) + '/active_record/locale/en-US.yml'
 </diff>
      <filename>activerecord/lib/active_record.rb</filename>
    </modified>
    <modified>
      <diff>@@ -51,9 +51,7 @@ module ActiveRecord
       
       def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record)
         parent_records.each do |parent_record|
-          association_proxy = parent_record.send(reflection_name)
-          association_proxy.loaded
-          association_proxy.target = associated_record
+          parent_record.send(&quot;set_#{reflection_name}_target&quot;, associated_record)
         end
       end
 
@@ -112,8 +110,8 @@ module ActiveRecord
       def preload_has_one_association(records, reflection, preload_options={})
         id_to_record_map, ids = construct_id_map(records)        
         options = reflection.options
+        records.each {|record| record.send(&quot;set_#{reflection.name}_target&quot;, nil)}
         if options[:through]
-          records.each {|record| record.send(reflection.name) &amp;&amp; record.send(reflection.name).loaded}
           through_records = preload_through_records(records, reflection, options[:through])
           through_reflection = reflections[options[:through]]
           through_primary_key = through_reflection.primary_key_name
@@ -126,8 +124,6 @@ module ActiveRecord
             end
           end
         else
-          records.each {|record| record.send(&quot;set_#{reflection.name}_target&quot;, nil)}
-
           set_association_single_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options), reflection.primary_key_name)
         end
       end</diff>
      <filename>activerecord/lib/active_record/association_preload.rb</filename>
    </modified>
    <modified>
      <diff>@@ -660,8 +660,8 @@ module ActiveRecord
       #
       # === Example
       #
-      # A Firm class declares &lt;tt&gt;has_many :clients&lt;/tt&gt;, which will add:
-      # * &lt;tt&gt;Firm#clients&lt;/tt&gt; (similar to &lt;tt&gt;Clients.find :all, :conditions =&gt; &quot;firm_id = #{id}&quot;&lt;/tt&gt;)
+      # Example: A Firm class declares &lt;tt&gt;has_many :clients&lt;/tt&gt;, which will add:
+      # * &lt;tt&gt;Firm#clients&lt;/tt&gt; (similar to &lt;tt&gt;Clients.find :all, :conditions =&gt; [&quot;firm_id = ?&quot;, id]&lt;/tt&gt;)
       # * &lt;tt&gt;Firm#clients&lt;&lt;&lt;/tt&gt;
       # * &lt;tt&gt;Firm#clients.delete&lt;/tt&gt;
       # * &lt;tt&gt;Firm#clients=&lt;/tt&gt;
@@ -878,10 +878,10 @@ module ActiveRecord
 
           method_name = &quot;has_one_after_save_for_#{reflection.name}&quot;.to_sym
           define_method(method_name) do
-            association = instance_variable_get(&quot;#{ivar}&quot;) if instance_variable_defined?(&quot;#{ivar}&quot;)
+            association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
 
-            if !association.nil? &amp;&amp; (new_record? || association.new_record? || association[&quot;#{reflection.primary_key_name}&quot;] != id)
-              association[&quot;#{reflection.primary_key_name}&quot;] = id
+            if !association.nil? &amp;&amp; (new_record? || association.new_record? || association[reflection.primary_key_name] != id)
+              association[reflection.primary_key_name] = id
               association.save(true)
             end
           end
@@ -994,7 +994,7 @@ module ActiveRecord
 
           method_name = &quot;polymorphic_belongs_to_before_save_for_#{reflection.name}&quot;.to_sym
           define_method(method_name) do
-            association = instance_variable_get(&quot;#{ivar}&quot;) if instance_variable_defined?(&quot;#{ivar}&quot;)
+            association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
 
             if association &amp;&amp; association.target
               if association.new_record?
@@ -1002,8 +1002,8 @@ module ActiveRecord
               end
 
               if association.updated?
-                self[&quot;#{reflection.primary_key_name}&quot;] = association.id
-                self[&quot;#{reflection.options[:foreign_type]}&quot;] = association.class.base_class.name.to_s
+                self[reflection.primary_key_name] = association.id
+                self[reflection.options[:foreign_type]] = association.class.base_class.name.to_s
               end
             end
           end
@@ -1015,7 +1015,7 @@ module ActiveRecord
 
           method_name = &quot;belongs_to_before_save_for_#{reflection.name}&quot;.to_sym
           define_method(method_name) do
-            association = instance_variable_get(&quot;#{ivar}&quot;) if instance_variable_defined?(&quot;#{ivar}&quot;)
+            association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
 
             if !association.nil?
               if association.new_record?
@@ -1023,7 +1023,7 @@ module ActiveRecord
               end
 
               if association.updated?
-                self[&quot;#{reflection.primary_key_name}&quot;] = association.id
+                self[reflection.primary_key_name] = association.id
               end
             end
           end
@@ -1038,15 +1038,15 @@ module ActiveRecord
 
           method_name = &quot;belongs_to_counter_cache_after_create_for_#{reflection.name}&quot;.to_sym
           define_method(method_name) do
-            association = send(&quot;#{reflection.name}&quot;)
-            association.class.increment_counter(&quot;#{cache_column}&quot;, send(&quot;#{reflection.primary_key_name}&quot;)) unless association.nil?
+            association = send(reflection.name)
+            association.class.increment_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
           end
           after_create method_name
 
           method_name = &quot;belongs_to_counter_cache_before_destroy_for_#{reflection.name}&quot;.to_sym
           define_method(method_name) do
-            association = send(&quot;#{reflection.name}&quot;)
-            association.class.decrement_counter(&quot;#{cache_column}&quot;, send(&quot;#{reflection.primary_key_name}&quot;)) unless association.nil?
+            association = send(reflection.name)
+            association.class.decrement_counter(cache_column, send(reflection.primary_key_name)) unless association.nil?
           end
           before_destroy method_name
 
@@ -1164,6 +1164,9 @@ module ActiveRecord
       #   If true, duplicate associated objects will be ignored by accessors and query methods.
       # [:finder_sql]
       #   Overwrite the default generated SQL statement used to fetch the association with a manual statement
+      # [:counter_sql]
+      #   Specify a complete SQL statement to fetch the size of the association. If &lt;tt&gt;:finder_sql&lt;/tt&gt; is
+      #   specified but not &lt;tt&gt;:counter_sql&lt;/tt&gt;, &lt;tt&gt;:counter_sql&lt;/tt&gt; will be generated by replacing &lt;tt&gt;SELECT ... FROM&lt;/tt&gt; with &lt;tt&gt;SELECT COUNT(*) FROM&lt;/tt&gt;.
       # [:delete_sql]
       #   Overwrite the default generated SQL statement used to remove links between the associated
       #   classes with a manual statement.
@@ -1220,12 +1223,11 @@ module ActiveRecord
       end
 
       private
-        # Generate a join table name from two provided tables names.
-        # The order of names in join name is determined by lexical precedence.
-        #   join_table_name(&quot;members&quot;, &quot;clubs&quot;)
-        #   =&gt; &quot;clubs_members&quot;
-        #   join_table_name(&quot;members&quot;, &quot;special_clubs&quot;)
-        #   =&gt; &quot;members_special_clubs&quot;
+        # Generates a join table name from two provided table names.
+        # The names in the join table namesme end up in lexicographic order.
+        #
+        #   join_table_name(&quot;members&quot;, &quot;clubs&quot;)         # =&gt; &quot;clubs_members&quot;
+        #   join_table_name(&quot;members&quot;, &quot;special_clubs&quot;) # =&gt; &quot;members_special_clubs&quot;
         def join_table_name(first_table_name, second_table_name)
           if first_table_name &lt; second_table_name
             join_table = &quot;#{first_table_name}_#{second_table_name}&quot;
@@ -1270,10 +1272,9 @@ module ActiveRecord
               association.create_through_record(new_value)
               self.send(reflection.name, new_value)
             else
-              association.replace(new_value)              
+              association.replace(new_value)
+              instance_variable_set(ivar, new_value.nil? ? nil : association)
             end
-
-            instance_variable_set(ivar, new_value.nil? ? nil : association)
           end
 
           define_method(&quot;set_#{reflection.name}_target&quot;) do |target|
@@ -1302,7 +1303,11 @@ module ActiveRecord
           end
 
           define_method(&quot;#{reflection.name.to_s.singularize}_ids&quot;) do
-            send(reflection.name).map { |record| record.id }
+            if send(reflection.name).loaded?
+              send(reflection.name).map(&amp;:id)
+            else
+              send(reflection.name).all(:select =&gt; &quot;#{reflection.quoted_table_name}.#{reflection.klass.primary_key}&quot;).map(&amp;:id)
+            end
           end
         end
 
@@ -1323,19 +1328,19 @@ module ActiveRecord
             end
           end
         end
-        
+
         def add_single_associated_validation_callbacks(association_name)
           method_name = &quot;validate_associated_records_for_#{association_name}&quot;.to_sym
           define_method(method_name) do
             association = instance_variable_get(&quot;@#{association_name}&quot;)
             if !association.nil?
-              errors.add &quot;#{association_name}&quot; unless association.target.nil? || association.valid?
+              errors.add association_name unless association.target.nil? || association.valid?
             end
           end
-        
+
           validate method_name
         end
-        
+
         def add_multiple_associated_validation_callbacks(association_name)
           method_name = &quot;validate_associated_records_for_#{association_name}&quot;.to_sym
           ivar = &quot;@#{association_name}&quot;
@@ -1351,7 +1356,7 @@ module ActiveRecord
               else
                 association.target.select { |record| record.new_record? }
               end.each do |record|
-                errors.add &quot;#{association_name}&quot; unless record.valid?
+                errors.add association_name unless record.valid?
               end
             end
           end
@@ -1371,7 +1376,7 @@ module ActiveRecord
 
           method_name = &quot;after_create_or_update_associated_records_for_#{association_name}&quot;.to_sym
           define_method(method_name) do
-            association = instance_variable_get(&quot;#{ivar}&quot;) if instance_variable_defined?(&quot;#{ivar}&quot;)
+            association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
 
             records_to_save = if @new_record_before_save
               association
@@ -1438,7 +1443,7 @@ module ActiveRecord
               when :destroy
                 method_name = &quot;has_many_dependent_destroy_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  send(&quot;#{reflection.name}&quot;).each { |o| o.destroy }
+                  send(reflection.name).each { |o| o.destroy }
                 end
                 before_destroy method_name
               when :delete_all
@@ -1457,22 +1462,22 @@ module ActiveRecord
               when :destroy
                 method_name = &quot;has_one_dependent_destroy_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  association = send(&quot;#{reflection.name}&quot;)
+                  association = send(reflection.name)
                   association.destroy unless association.nil?
                 end
                 before_destroy method_name
               when :delete
                 method_name = &quot;has_one_dependent_delete_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  association = send(&quot;#{reflection.name}&quot;)
+                  association = send(reflection.name)
                   association.class.delete(association.id) unless association.nil?
                 end
                 before_destroy method_name
               when :nullify
                 method_name = &quot;has_one_dependent_nullify_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  association = send(&quot;#{reflection.name}&quot;)
-                  association.update_attribute(&quot;#{reflection.primary_key_name}&quot;, nil) unless association.nil?
+                  association = send(reflection.name)
+                  association.update_attribute(reflection.primary_key_name, nil) unless association.nil?
                 end
                 before_destroy method_name
               else
@@ -1487,14 +1492,14 @@ module ActiveRecord
               when :destroy
                 method_name = &quot;belongs_to_dependent_destroy_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  association = send(&quot;#{reflection.name}&quot;)
+                  association = send(reflection.name)
                   association.destroy unless association.nil?
                 end
                 before_destroy method_name
               when :delete
                 method_name = &quot;belongs_to_dependent_delete_for_#{reflection.name}&quot;.to_sym
                 define_method(method_name) do
-                  association = send(&quot;#{reflection.name}&quot;)
+                  association = send(reflection.name)
                   association.class.delete(association.id) unless association.nil?
                 end
                 before_destroy method_name
@@ -1529,7 +1534,7 @@ module ActiveRecord
 
           create_reflection(:has_one, association_id, options, self)
         end
-        
+
         def create_has_one_through_reflection(association_id, options)
           options.assert_valid_keys(
             :class_name, :foreign_key, :remote, :select, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as, :through, :source, :source_type, :validate
@@ -1597,7 +1602,7 @@ module ActiveRecord
           sql = &quot;SELECT #{column_aliases(join_dependency)} FROM #{(scope &amp;&amp; scope[:from]) || options[:from] || quoted_table_name} &quot;
           sql &lt;&lt; join_dependency.join_associations.collect{|join| join.association_join }.join
 
-          add_joins!(sql, options, scope)
+          add_joins!(sql, options[:joins], scope)
           add_conditions!(sql, options[:conditions], scope)
           add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) &amp;&amp; ((scope &amp;&amp; scope[:limit]) || options[:limit])
 
@@ -1653,7 +1658,7 @@ module ActiveRecord
 
           if is_distinct
             sql &lt;&lt; distinct_join_associations.collect { |assoc| assoc.association_join }.join
-            add_joins!(sql, options, scope)
+            add_joins!(sql, options[:joins], scope)
           end
 
           add_conditions!(sql, options[:conditions], scope)
@@ -1679,19 +1684,19 @@ module ActiveRecord
               else            all &lt;&lt; cond
             end
           end
-          conditions.join(' ').scan(/([\.\w]+).?\./).flatten
+          conditions.join(' ').scan(/([\.a-zA-Z_]+).?\./).flatten
         end
 
         def order_tables(options)
           order = [options[:order], scope(:find, :order) ].join(&quot;, &quot;)
           return [] unless order &amp;&amp; order.is_a?(String)
-          order.scan(/([\.\w]+).?\./).flatten
+          order.scan(/([\.a-zA-Z_]+).?\./).flatten
         end
 
         def selects_tables(options)
           select = options[:select]
           return [] unless select &amp;&amp; select.is_a?(String)
-          select.scan(/&quot;?([\.\w]+)&quot;?.?\./).flatten
+          select.scan(/&quot;?([\.a-zA-Z_]+)&quot;?.?\./).flatten
         end
 
         # Checks if the conditions reference a table other than the current model table
@@ -1893,6 +1898,7 @@ module ActiveRecord
                   collection.target.push(association)
                 when :has_one
                   return if record.id.to_s != join.parent.record_id(row).to_s
+                  return if record.instance_variable_defined?(&quot;@#{join.reflection.name}&quot;)
                   association = join.instantiate(row) unless row[join.aliased_primary_key].nil?
                   record.send(&quot;set_#{join.reflection.name}_target&quot;, association)
                 when :belongs_to
@@ -1920,7 +1926,7 @@ module ActiveRecord
             end
 
             def aliased_primary_key
-              &quot;#{ aliased_prefix }_r0&quot;
+              &quot;#{aliased_prefix}_r0&quot;
             end
 
             def aliased_table_name
@@ -1932,7 +1938,7 @@ module ActiveRecord
                 @column_names_with_alias = []
 
                 ([primary_key] + (column_names - [primary_key])).each_with_index do |column_name, i|
-                  @column_names_with_alias &lt;&lt; [column_name, &quot;#{ aliased_prefix }_r#{ i }&quot;]
+                  @column_names_with_alias &lt;&lt; [column_name, &quot;#{aliased_prefix}_r#{i}&quot;]
                 end
               end
 
@@ -1969,12 +1975,12 @@ module ActiveRecord
               @aliased_prefix     = &quot;t#{ join_dependency.joins.size }&quot;
               @parent_table_name  = parent.active_record.table_name
               @aliased_table_name = aliased_table_name_for(table_name)
-              
+
               if reflection.macro == :has_and_belongs_to_many
                 @aliased_join_table_name = aliased_table_name_for(reflection.options[:join_table], &quot;_join&quot;)
               end
-        
-              if reflection.macro == :has_many &amp;&amp; reflection.options[:through]
+
+              if [:has_many, :has_one].include?(reflection.macro) &amp;&amp; reflection.options[:through]
                 @aliased_join_table_name = aliased_table_name_for(reflection.through_reflection.klass.table_name, &quot;_join&quot;)
               end
             end
@@ -1998,7 +2004,7 @@ module ActiveRecord
                      ]
                 when :has_many, :has_one
                   case
-                    when reflection.macro == :has_many &amp;&amp; reflection.options[:through]
+                    when reflection.options[:through]
                       through_conditions = through_reflection.options[:conditions] ? &quot;AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}&quot; : ''
 
                       jt_foreign_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil
@@ -2110,7 +2116,7 @@ module ActiveRecord
             end
 
             protected
-            
+
               def aliased_table_name_for(name, suffix = nil)
                 if !parent.table_joins.blank? &amp;&amp; parent.table_joins.to_s.downcase =~ %r{join(\s+\w+)?\s+#{name.downcase}\son}
                   @join_dependency.table_aliases[name] += 1
@@ -2128,7 +2134,7 @@ module ActiveRecord
 
                 name
               end
-              
+
               def pluralize(table_name)
                 ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
               end</diff>
      <filename>activerecord/lib/active_record/associations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,19 @@ require 'set'
 
 module ActiveRecord
   module Associations
+    # AssociationCollection is an abstract class that provides common stuff to
+    # ease the implementation of association proxies that represent
+    # collections. See the class hierarchy in AssociationProxy.
+    #
+    # You need to be careful with assumptions regarding the target: The proxy
+    # does not fetch records from the database until it needs them, but new
+    # ones created with +build+ are added to the target. So, the target may be
+    # non-empty and still lack children waiting to be read from the database.
+    # If you look directly to the database you cannot assume that's the entire
+    # collection because new records may have beed added to the target, etc.
+    #
+    # If you need to work on all current children, new and existing records,
+    # +load_target+ and the +loaded+ flag are your friends.
     class AssociationCollection &lt; AssociationProxy #:nodoc:
       def initialize(owner, reflection)
         super
@@ -128,6 +141,35 @@ module ActiveRecord
         end
       end
 
+      # Count all records using SQL. If the +:counter_sql+ option is set for the association, it will
+      # be used for the query. If no +:counter_sql+ was supplied, but +:finder_sql+ was set, the
+      # descendant's +construct_sql+ method will have set :counter_sql automatically.
+      # Otherwise, construct options and pass them with scope to the target class's +count+.
+      def count(*args)
+        if @reflection.options[:counter_sql]
+          @reflection.klass.count_by_sql(@counter_sql)
+        else
+          column_name, options = @reflection.klass.send(:construct_count_options_from_args, *args)
+          if @reflection.options[:uniq]
+            # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL.
+            column_name = &quot;#{@reflection.quoted_table_name}.#{@reflection.klass.primary_key}&quot; if column_name == :all
+            options.merge!(:distinct =&gt; true)
+          end
+
+          value = @reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, options) }
+
+          limit  = @reflection.options[:limit]
+          offset = @reflection.options[:offset]
+
+          if limit || offset
+            [ [value - offset.to_i, 0].max, limit.to_i ].min
+          else
+            value
+          end
+        end
+      end
+
+
       # Remove +records+ from this association.  Does not destroy +records+.
       def delete(*records)
         records = flatten_deeper(records)
@@ -185,9 +227,16 @@ module ActiveRecord
         end
       end
 
-      # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and
-      # calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero
-      # and you need to fetch that collection afterwards, it'll take one less SELECT query if you use length.
+      # Returns the size of the collection by executing a SELECT COUNT(*)
+      # query if the collection hasn't been loaded, and calling
+      # &lt;tt&gt;collection.size&lt;/tt&gt; if it has.
+      #
+      # If the collection has been already loaded +size+ and +length+ are
+      # equivalent. If not and you are going to need the records anyway
+      # +length+ will take one less query. Otherwise +size+ is more efficient.
+      #
+      # This method is abstract in the sense that it relies on
+      # +count_records+, which is a method descendants have to provide.
       def size
         if @owner.new_record? || (loaded? &amp;&amp; !@reflection.options[:uniq])
           @target.size
@@ -199,12 +248,18 @@ module ActiveRecord
         end
       end
 
-      # Returns the size of the collection by loading it and calling size on the array. If you want to use this method to check
-      # whether the collection is empty, use collection.length.zero? instead of collection.empty?
+      # Returns the size of the collection calling +size+ on the target.
+      #
+      # If the collection has been already loaded +length+ and +size+ are
+      # equivalent. If not and you are going to need the records anyway this
+      # method will take one less query. Otherwise +size+ is more efficient.
       def length
         load_target.size
       end
 
+      # Equivalent to &lt;tt&gt;collection.size.zero?&lt;/tt&gt;. If the collection has
+      # not been already loaded and you are going to fetch the records anyway
+      # it is better to check &lt;tt&gt;collection.length.zero?&lt;/tt&gt;.
       def empty?
         size.zero?
       end</diff>
      <filename>activerecord/lib/active_record/associations/association_collection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -39,7 +39,7 @@ module ActiveRecord
     # though the object behind &lt;tt&gt;blog.posts&lt;/tt&gt; is not an Array, but an
     # ActiveRecord::Associations::HasManyAssociation.
     #
-    # The &lt;tt&gt;@target&lt;/tt&gt; object is not loaded until needed. For example,
+    # The &lt;tt&gt;@target&lt;/tt&gt; object is not \loaded until needed. For example,
     #
     #   blog.posts.count
     #
@@ -57,76 +57,100 @@ module ActiveRecord
         reset
       end
 
+      # Returns the owner of the proxy.
       def proxy_owner
         @owner
       end
 
+      # Returns the reflection object that represents the association handled
+      # by the proxy.
       def proxy_reflection
         @reflection
       end
 
+      # Returns the \target of the proxy, same as +target+.
       def proxy_target
         @target
       end
 
-      def respond_to?(symbol, include_priv = false)
-        proxy_respond_to?(symbol, include_priv) || (load_target &amp;&amp; @target.respond_to?(symbol, include_priv))
+      # Does the proxy or its \target respond to +symbol+?
+      def respond_to?(*args)
+        proxy_respond_to?(*args) || (load_target &amp;&amp; @target.respond_to?(*args))
       end
 
-      # Explicitly proxy === because the instance method removal above
-      # doesn't catch it.
+      # Forwards &lt;tt&gt;===&lt;/tt&gt; explicitly to the \target because the instance method
+      # removal above doesn't catch it. Loads the \target if needed.
       def ===(other)
         load_target
         other === @target
       end
 
+      # Returns the name of the table of the related class:
+      #
+      #   post.comments.aliased_table_name # =&gt; &quot;comments&quot;
+      #
       def aliased_table_name
         @reflection.klass.table_name
       end
 
+      # Returns the SQL string that corresponds to the &lt;tt&gt;:conditions&lt;/tt&gt;
+      # option of the macro, if given, or +nil+ otherwise.
       def conditions
         @conditions ||= interpolate_sql(@reflection.sanitized_conditions) if @reflection.sanitized_conditions
       end
       alias :sql_conditions :conditions
 
+      # Resets the \loaded flag to +false+ and sets the \target to +nil+.
       def reset
         @loaded = false
         @target = nil
       end
 
+      # Reloads the \target and returns +self+ on success.
       def reload
         reset
         load_target
         self unless @target.nil?
       end
 
+      # Has the \target been already \loaded?
       def loaded?
         @loaded
       end
 
+      # Asserts the \target has been loaded setting the \loaded flag to +true+.
       def loaded
         @loaded = true
       end
 
+      # Returns the target of this proxy, same as +proxy_target+.
       def target
         @target
       end
 
+      # Sets the target of this proxy to &lt;tt&gt;\target&lt;/tt&gt;, and the \loaded flag to +true+.
       def target=(target)
         @target = target
         loaded
       end
 
+      # Forwards the call to the target. Loads the \target if needed.
       def inspect
         load_target
         @target.inspect
       end
 
       protected
+        # Does the association have a &lt;tt&gt;:dependent&lt;/tt&gt; option?
         def dependent?
           @reflection.options[:dependent]
         end
 
+        # Returns a string with the IDs of +records+ joined with a comma, quoted
+        # if needed. The result is ready to be inserted into a SQL IN clause.
+        #
+        #   quoted_record_ids(records) # =&gt; &quot;23,56,58,67&quot;
+        #
         def quoted_record_ids(records)
           records.map { |record| record.quoted_id }.join(',')
         end
@@ -135,10 +159,13 @@ module ActiveRecord
           @owner.send(:interpolate_sql, sql, record)
         end
 
+        # Forwards the call to the reflection class.
         def sanitize_sql(sql)
           @reflection.klass.send(:sanitize_sql, sql)
         end
 
+        # Assigns the ID of the owner to the corresponding foreign key in +record+.
+        # If the association is polymorphic the type of the owner is also set.
         def set_belongs_to_association_for(record)
           if @reflection.options[:as]
             record[&quot;#{@reflection.options[:as]}_id&quot;]   = @owner.id unless @owner.new_record?
@@ -148,6 +175,7 @@ module ActiveRecord
           end
         end
 
+        # Merges into +options+ the ones coming from the reflection.
         def merge_options_from_reflection!(options)
           options.reverse_merge!(
             :group   =&gt; @reflection.options[:group],
@@ -160,11 +188,13 @@ module ActiveRecord
           )
         end
 
+        # Forwards +with_scope+ to the reflection.
         def with_scope(*args, &amp;block)
           @reflection.klass.send :with_scope, *args, &amp;block
         end
 
       private
+        # Forwards any missing method call to the \target.
         def method_missing(method, *args)
           if load_target
             if block_given?
@@ -175,16 +205,16 @@ module ActiveRecord
           end
         end
 
-        # Loads the target if needed and returns it.
+        # Loads the \target if needed and returns it.
         #
         # This method is abstract in the sense that it relies on +find_target+,
         # which is expected to be provided by descendants.
         #
-        # If the target is already loaded it is just returned. Thus, you can call
-        # +load_target+ unconditionally to get the target.
+        # If the \target is already \loaded it is just returned. Thus, you can call
+        # +load_target+ unconditionally to get the \target.
         #
         # ActiveRecord::RecordNotFound is rescued within the method, and it is
-        # not reraised. The proxy is reset and +nil+ is the return value.
+        # not reraised. The proxy is \reset and +nil+ is the return value.
         def load_target
           return nil unless defined?(@loaded)
 
@@ -198,12 +228,17 @@ module ActiveRecord
           reset
         end
 
-        # Can be overwritten by associations that might have the foreign key available for an association without
-        # having the object itself (and still being a new record). Currently, only belongs_to presents this scenario.
+        # Can be overwritten by associations that might have the foreign key
+        # available for an association without having the object itself (and
+        # still being a new record). Currently, only +belongs_to+ presents
+        # this scenario (both vanilla and polymorphic).
         def foreign_key_present
           false
         end
 
+        # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
+        # the kind of the class of the associated objects. Meant to be used as
+        # a sanity check when you are about to assign an associated record.
         def raise_on_type_mismatch(record)
           unless record.is_a?(@reflection.klass)
             message = &quot;#{@reflection.class_name}(##{@reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})&quot;
@@ -211,11 +246,13 @@ module ActiveRecord
           end
         end
 
-        # Array#flatten has problems with recursive arrays. Going one level deeper solves the majority of the problems.
+        # Array#flatten has problems with recursive arrays. Going one level
+        # deeper solves the majority of the problems.
         def flatten_deeper(array)
-          array.collect { |element| element.respond_to?(:flatten) ? element.flatten : element }.flatten
+          array.collect { |element| (element.respond_to?(:flatten) &amp;&amp; !element.is_a?(Hash)) ? element.flatten : element }.flatten
         end
 
+        # Returns the ID of the owner, quoted if needed.
         def owner_quoted_id
           @owner.quoted_id
         end</diff>
      <filename>activerecord/lib/active_record/associations/association_proxy.rb</filename>
    </modified>
    <modified>
      <diff>@@ -78,6 +78,16 @@ module ActiveRecord
           end
 
           @join_sql = &quot;INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}&quot;
+
+          if @reflection.options[:counter_sql]
+            @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+          elsif @reflection.options[:finder_sql]
+            # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
+            @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { &quot;SELECT #{$1}COUNT(*) FROM&quot; }
+            @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
+          else
+            @counter_sql = @finder_sql
+          end
         end
 
         def construct_scope</diff>
      <filename>activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,23 +1,10 @@
 module ActiveRecord
   module Associations
+    # This is the proxy that handles a has many association.
+    #
+    # If the association has a &lt;tt&gt;:through&lt;/tt&gt; option further specialization
+    # is provided by its child HasManyThroughAssociation.
     class HasManyAssociation &lt; AssociationCollection #:nodoc:
-      # Count the number of associated records. All arguments are optional.
-      def count(*args)
-        if @reflection.options[:counter_sql]
-          @reflection.klass.count_by_sql(@counter_sql)
-        elsif @reflection.options[:finder_sql]
-          @reflection.klass.count_by_sql(@finder_sql)
-        else
-          column_name, options = @reflection.klass.send(:construct_count_options_from_args, *args)          
-          options[:conditions] = options[:conditions].blank? ?
-            @finder_sql :
-            @finder_sql + &quot; AND (#{sanitize_sql(options[:conditions])})&quot;
-          options[:include] ||= @reflection.options[:include]
-
-          @reflection.klass.count(column_name, options)
-        end
-      end
-
       protected
         def owner_quoted_id
           if @reflection.options[:primary_key]
@@ -27,6 +14,16 @@ module ActiveRecord
           end
         end
 
+        # Returns the number of records in this collection.
+        #
+        # If the association has a counter cache it gets that value. Otherwise
+        # a count via SQL is performed, bounded to &lt;tt&gt;:limit&lt;/tt&gt; if there's one.
+        # That does not depend on whether the collection has already been loaded
+        # or not. The +size+ method is the one that takes the loaded flag into
+        # account and delegates to +count_records+ if needed.
+        #
+        # If the collection is empty the target is set to an empty array and
+        # the loaded flag is set to true as well.
         def count_records
           count = if has_cached_counter?
             @owner.send(:read_attribute, cached_counter_attribute_name)
@@ -35,8 +32,11 @@ module ActiveRecord
           else
             @reflection.klass.count(:conditions =&gt; @counter_sql, :include =&gt; @reflection.options[:include])
           end
-          
-          @target = [] and loaded if count == 0
+
+          # If there's nothing in the database and @target has no new records
+          # we are certain the current target is an empty array. This is a
+          # documented side-effect of the method that may avoid an extra SELECT.
+          @target ||= [] and loaded if count == 0
           
           if @reflection.options[:limit]
             count = [ @reflection.options[:limit], count ].min</diff>
      <filename>activerecord/lib/active_record/associations/has_many_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -31,16 +31,6 @@ module ActiveRecord
         return count
       end
       
-      def count(*args)
-        column_name, options = @reflection.klass.send(:construct_count_options_from_args, *args)
-        if @reflection.options[:uniq]
-          # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL statement.
-          column_name = &quot;#{@reflection.quoted_table_name}.#{@reflection.klass.primary_key}&quot; if column_name == :all
-          options.merge!(:distinct =&gt; true) 
-        end
-        @reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, options) } 
-      end
-
       protected
         def construct_find_options!(options)
           options[:select]  = construct_select(options[:select])</diff>
      <filename>activerecord/lib/active_record/associations/has_many_through_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,8 +21,8 @@ module ActiveRecord
       def replace(obj, dont_save = false)
         load_target
 
-        unless @target.nil?
-          if dependent? &amp;&amp; !dont_save &amp;&amp; @target != obj
+        unless @target.nil? || @target == obj
+          if dependent? &amp;&amp; !dont_save
             @target.destroy unless @target.new_record?
             @owner.clear_association_cache
           else</diff>
      <filename>activerecord/lib/active_record/associations/has_one_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -22,6 +22,10 @@ module ActiveRecord
     
       def find_target
         super.first
+      end
+
+      def reset_target!
+        @target = nil
       end        
     end        
   end</diff>
      <filename>activerecord/lib/active_record/associations/has_one_through_association.rb</filename>
    </modified>
    <modified>
      <diff>@@ -214,7 +214,7 @@ module ActiveRecord
             if logger
               logger.warn &quot;Exception occurred during reader method compilation.&quot;
               logger.warn &quot;Maybe #{attr_name} is not a valid Ruby identifier?&quot;
-              logger.warn &quot;#{err.message}&quot;
+              logger.warn err.message
             end
           end
         end
@@ -330,8 +330,8 @@ module ActiveRecord
       end
     end
     
-    # A Person object with a name attribute can ask &lt;tt&gt;person.respond_to?(&quot;name&quot;)&lt;/tt&gt;,
-    # &lt;tt&gt;person.respond_to?(&quot;name=&quot;)&lt;/tt&gt;, and &lt;tt&gt;person.respond_to?(&quot;name?&quot;)&lt;/tt&gt;
+    # A Person object with a name attribute can ask &lt;tt&gt;person.respond_to?(:name)&lt;/tt&gt;,
+    # &lt;tt&gt;person.respond_to?(:name=)&lt;/tt&gt;, and &lt;tt&gt;person.respond_to?(:name?)&lt;/tt&gt;
     # which will all return +true+.
     alias :respond_to_without_attributes? :respond_to?
     def respond_to?(method, include_priv = false)</diff>
      <filename>activerecord/lib/active_record/attribute_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -452,13 +452,6 @@ module ActiveRecord #:nodoc:
     cattr_accessor :default_timezone, :instance_writer =&gt; false
     @@default_timezone = :local
 
-    # Determines whether to use a connection for each thread, or a single shared connection for all threads.
-    # Defaults to false. If you're writing a threaded application, set to true
-    # and periodically call verify_active_connections! to clear out connections
-    # assigned to stale threads.
-    cattr_accessor :allow_concurrency, :instance_writer =&gt; false
-    @@allow_concurrency = false
-
     # Specifies the format to use when dumping the database schema with Rails'
     # Rakefile.  If :sql, the schema is dumped as (potentially database-
     # specific) SQL statements.  If :ruby, the schema is dumped as an
@@ -507,7 +500,7 @@ module ActiveRecord #:nodoc:
       # * &lt;tt&gt;:include&lt;/tt&gt; - Names associations that should be loaded alongside. The symbols named refer
       #   to already defined associations. See eager loading under Associations.
       # * &lt;tt&gt;:select&lt;/tt&gt; - By default, this is &quot;*&quot; as in &quot;SELECT * FROM&quot;, but can be changed if you, for example, want to do a join but not
-      #   include the joined columns.
+      #   include the joined columns. Takes a string with the SELECT SQL fragment (e.g. &quot;id, name&quot;).
       # * &lt;tt&gt;:from&lt;/tt&gt; - By default, this is the table name of the class, but can be changed to an alternate table name (or even the name
       #   of a database view).
       # * &lt;tt&gt;:readonly&lt;/tt&gt; - Mark the returned records read-only so they cannot be saved or updated.
@@ -612,7 +605,7 @@ module ActiveRecord #:nodoc:
       #   Post.find_by_sql [&quot;SELECT title FROM posts WHERE author = ? AND created &gt; ?&quot;, author_id, start_date]
       #   &gt; [#&lt;Post:0x36bff9c @attributes={&quot;first_name&quot;=&gt;&quot;The Cheap Man Buys Twice&quot;}&gt;, ...]
       def find_by_sql(sql)
-        connection.select_all(sanitize_sql(sql), &quot;#{name} Load&quot;).map { |record| instantiate(record) }
+        connection.select_all(sanitize_sql(sql), &quot;#{name} Load&quot;).collect! { |record| instantiate(record) }
       end
 
       # Checks whether a record exists in the database that matches conditions given.  These conditions
@@ -752,13 +745,15 @@ module ActiveRecord #:nodoc:
       end
 
       # Updates all records with details given if they match a set of conditions supplied, limits and order can
-      # also be supplied.
+      # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
+      # database. It does not instantiate the involved models and it does not trigger Active Record callbacks.
       #
       # ==== Attributes
       #
-      # * +updates+ - A String of column and value pairs that will be set on any records that match conditions.
+      # * +updates+ - A string of column and value pairs that will be set on any records that match conditions.
+      #               What goes into the SET clause.
       # * +conditions+ - An SQL fragment like &quot;administrator = 1&quot; or [ &quot;user_name = ?&quot;, username ]. See conditions in the intro for more info.
-      # * +options+ - Additional options are &lt;tt&gt;:limit&lt;/tt&gt; and/or &lt;tt&gt;:order&lt;/tt&gt;, see the examples for usage.
+      # * +options+ - Additional options are &lt;tt&gt;:limit&lt;/tt&gt; and &lt;tt&gt;:order&lt;/tt&gt;, see the examples for usage.
       #
       # ==== Examples
       #
@@ -780,8 +775,8 @@ module ActiveRecord #:nodoc:
         connection.update(sql, &quot;#{name} Update&quot;)
       end
 
-      # Destroys the records matching +conditions+ by instantiating each record and calling the destroy method.
-      # This means at least 2*N database queries to destroy N records, so avoid destroy_all if you are deleting
+      # Destroys the records matching +conditions+ by instantiating each record and calling their +destroy+ method.
+      # This means at least 2*N database queries to destroy N records, so avoid +destroy_all+ if you are deleting
       # many records. If you want to simply delete records without worrying about dependent associations or
       # callbacks, use the much faster +delete_all+ method instead.
       #
@@ -800,8 +795,9 @@ module ActiveRecord #:nodoc:
       end
 
       # Deletes the records matching +conditions+ without instantiating the records first, and hence not
-      # calling the destroy method and invoking callbacks. This is a single SQL query, much more efficient
-      # than destroy_all.
+      # calling the +destroy+ method nor invoking callbacks. This is a single SQL DELETE statement that
+      # goes straight to the database, much more efficient than +destroy_all+. Careful with relations
+      # though, in particular &lt;tt&gt;:dependent&lt;/tt&gt; is not taken into account.
       #
       # ==== Attributes
       #
@@ -811,8 +807,8 @@ module ActiveRecord #:nodoc:
       #
       #   Post.delete_all &quot;person_id = 5 AND (category = 'Something' OR category = 'Else')&quot;
       #
-      # This deletes the affected posts all at once with a single DELETE query. If you need to destroy dependent
-      # associations or call your before_ or after_destroy callbacks, use the +destroy_all+ method instead.
+      # This deletes the affected posts all at once with a single DELETE statement. If you need to destroy dependent
+      # associations or call your &lt;tt&gt;before_*&lt;/tt&gt; or +after_destroy+ callbacks, use the +destroy_all+ method instead.
       def delete_all(conditions = nil)
         sql = &quot;DELETE FROM #{quoted_table_name} &quot;
         add_conditions!(sql, conditions, scope(:find))
@@ -927,12 +923,12 @@ module ActiveRecord #:nodoc:
       # To start from an all-closed default and enable attributes as needed,
       # have a look at +attr_accessible+.
       def attr_protected(*attributes)
-        write_inheritable_attribute(&quot;attr_protected&quot;, Set.new(attributes.map(&amp;:to_s)) + (protected_attributes || []))
+        write_inheritable_attribute(:attr_protected, Set.new(attributes.map(&amp;:to_s)) + (protected_attributes || []))
       end
 
       # Returns an array of all the attributes that have been protected from mass-assignment.
       def protected_attributes # :nodoc:
-        read_inheritable_attribute(&quot;attr_protected&quot;)
+        read_inheritable_attribute(:attr_protected)
       end
 
       # Specifies a white list of model attributes that can be set via
@@ -960,22 +956,22 @@ module ActiveRecord #:nodoc:
       #   customer.credit_rating = &quot;Average&quot;
       #   customer.credit_rating # =&gt; &quot;Average&quot;
       def attr_accessible(*attributes)
-        write_inheritable_attribute(&quot;attr_accessible&quot;, Set.new(attributes.map(&amp;:to_s)) + (accessible_attributes || []))
+        write_inheritable_attribute(:attr_accessible, Set.new(attributes.map(&amp;:to_s)) + (accessible_attributes || []))
       end
 
       # Returns an array of all the attributes that have been made accessible to mass-assignment.
       def accessible_attributes # :nodoc:
-        read_inheritable_attribute(&quot;attr_accessible&quot;)
+        read_inheritable_attribute(:attr_accessible)
       end
 
        # Attributes listed as readonly can be set for a new record, but will be ignored in database updates afterwards.
        def attr_readonly(*attributes)
-         write_inheritable_attribute(&quot;attr_readonly&quot;, Set.new(attributes.map(&amp;:to_s)) + (readonly_attributes || []))
+         write_inheritable_attribute(:attr_readonly, Set.new(attributes.map(&amp;:to_s)) + (readonly_attributes || []))
        end
 
        # Returns an array of all the attributes that have been specified as readonly.
        def readonly_attributes
-         read_inheritable_attribute(&quot;attr_readonly&quot;)
+         read_inheritable_attribute(:attr_readonly)
        end
 
       # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
@@ -999,7 +995,7 @@ module ActiveRecord #:nodoc:
 
       # Returns a hash of all the attributes that have been specified for serialization as keys and their class restriction as values.
       def serialized_attributes
-        read_inheritable_attribute(&quot;attr_serialized&quot;) or write_inheritable_attribute(&quot;attr_serialized&quot;, {})
+        read_inheritable_attribute(:attr_serialized) or write_inheritable_attribute(:attr_serialized, {})
       end
 
 
@@ -1220,11 +1216,46 @@ module ActiveRecord #:nodoc:
         subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information }
       end
 
+      def self_and_descendents_from_active_record#nodoc:
+        klass = self
+        classes = [klass]
+        while klass != klass.base_class  
+          classes &lt;&lt; klass = klass.superclass
+        end
+        classes
+      rescue
+        # OPTIMIZE this rescue is to fix this test: ./test/cases/reflection_test.rb:56:in `test_human_name_for_column'
+        # Appearantly the method base_class causes some trouble.
+        # It now works for sure.
+        [self]
+      end
+
       # Transforms attribute key names into a more humane format, such as &quot;First name&quot; instead of &quot;first_name&quot;. Example:
       #   Person.human_attribute_name(&quot;first_name&quot;) # =&gt; &quot;First name&quot;
-      # Deprecated in favor of just calling &quot;first_name&quot;.humanize
-      def human_attribute_name(attribute_key_name) #:nodoc:
-        attribute_key_name.humanize
+      # This used to be depricated in favor of humanize, but is now preferred, because it automatically uses the I18n
+      # module now.
+      # Specify +options+ with additional translating options.
+      def human_attribute_name(attribute_key_name, options = {})
+        defaults = self_and_descendents_from_active_record.map do |klass|
+          :&quot;#{klass.name.underscore}.#{attribute_key_name}&quot;
+        end
+        defaults &lt;&lt; options[:default] if options[:default]
+        defaults.flatten!
+        defaults &lt;&lt; attribute_key_name.humanize
+        options[:count] ||= 1
+        I18n.translate(defaults.shift, options.merge(:default =&gt; defaults, :scope =&gt; [:activerecord, :attributes]))
+      end
+
+      # Transform the modelname into a more humane format, using I18n.
+      # Defaults to the basic humanize method.
+      # Default scope of the translation is activerecord.models
+      # Specify +options+ with additional translating options.
+      def human_name(options = {})
+        defaults = self_and_descendents_from_active_record.map do |klass|
+          :&quot;#{klass.name.underscore}&quot;
+        end 
+        defaults &lt;&lt; self.name.humanize
+        I18n.translate(defaults.shift, {:scope =&gt; [:activerecord, :models], :count =&gt; 1, :default =&gt; defaults}.merge(options))
       end
 
       # True if this isn't a concrete subclass needing a STI type condition.
@@ -1282,7 +1313,7 @@ module ActiveRecord #:nodoc:
         if logger &amp;&amp; logger.level &lt;= log_level
           result = nil
           seconds = Benchmark.realtime { result = use_silence ? silence { yield } : yield }
-          logger.add(log_level, &quot;#{title} (#{'%.5f' % seconds})&quot;)
+          logger.add(log_level, &quot;#{title} (#{'%.1f' % (seconds * 1000)}ms)&quot;)
           result
         else
           yield
@@ -1319,8 +1350,8 @@ module ActiveRecord #:nodoc:
       end
 
       def respond_to?(method_id, include_private = false)
-        if match = matches_dynamic_finder?(method_id) || matches_dynamic_finder_with_initialize_or_create?(method_id)
-          return true if all_attributes_exists?(extract_attribute_names_from_match(match))
+        if match = DynamicFinderMatch.match(method_id)
+          return true if all_attributes_exists?(match.attribute_names)
         end
         super
       end
@@ -1514,7 +1545,7 @@ module ActiveRecord #:nodoc:
           sql  = &quot;SELECT #{options[:select] || (scope &amp;&amp; scope[:select]) || ((options[:joins] || (scope &amp;&amp; scope[:joins])) &amp;&amp; quoted_table_name + '.*') || '*'} &quot;
           sql &lt;&lt; &quot;FROM #{(scope &amp;&amp; scope[:from]) || options[:from] || quoted_table_name} &quot;
 
-          add_joins!(sql, options, scope)
+          add_joins!(sql, options[:joins], scope)
           add_conditions!(sql, options[:conditions], scope)
 
           add_group!(sql, options[:group], scope)
@@ -1530,6 +1561,22 @@ module ActiveRecord #:nodoc:
          (safe_to_array(first) + safe_to_array(second)).uniq
         end
 
+        def merge_joins(first, second)
+          if first.is_a?(String) &amp;&amp; second.is_a?(String)
+            &quot;#{first} #{second}&quot;
+          elsif first.is_a?(String) || second.is_a?(String)
+            if first.is_a?(String)
+              join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, second, nil)
+              &quot;#{first} #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join}&quot;
+            else
+              join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, first, nil)
+              &quot;#{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} #{second}&quot;
+            end
+          else
+            (safe_to_array(first) + safe_to_array(second)).uniq
+          end
+        end
+
         # Object#to_a is deprecated, though it does have the desired behavior
         def safe_to_array(o)
           case o
@@ -1585,16 +1632,15 @@ module ActiveRecord #:nodoc:
         end
 
         # The optional scope argument is for the current &lt;tt&gt;:find&lt;/tt&gt; scope.
-        def add_joins!(sql, options, scope = :auto)
+        def add_joins!(sql, joins, scope = :auto)
           scope = scope(:find) if :auto == scope
-          [(scope &amp;&amp; scope[:joins]), options[:joins]].each do |join|
-            case join
-            when Symbol, Hash, Array
-              join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, join, nil)
-              sql &lt;&lt; &quot; #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} &quot;
-            else
-              sql &lt;&lt; &quot; #{join} &quot;
-            end
+          merged_joins = scope &amp;&amp; scope[:joins] &amp;&amp; joins ? merge_joins(scope[:joins], joins) : (joins || scope &amp;&amp; scope[:joins])
+          case merged_joins
+          when Symbol, Hash, Array
+            join_dependency = ActiveRecord::Associations::ClassMethods::InnerJoinDependency.new(self, merged_joins, nil)
+            sql &lt;&lt; &quot; #{join_dependency.join_associations.collect { |assoc| assoc.association_join }.join} &quot;
+          when String
+            sql &lt;&lt; &quot; #{merged_joins} &quot;
           end
         end
 
@@ -1639,88 +1685,67 @@ module ActiveRecord #:nodoc:
         # Each dynamic finder or initializer/creator is also defined in the class after it is first invoked, so that future
         # attempts to use it do not run through method_missing.
         def method_missing(method_id, *arguments)
-          if match = matches_dynamic_finder?(method_id)
-            finder = determine_finder(match)
-
-            attribute_names = extract_attribute_names_from_match(match)
+          if match = DynamicFinderMatch.match(method_id)
+            attribute_names = match.attribute_names
             super unless all_attributes_exists?(attribute_names)
-
-            self.class_eval %{
-              def self.#{method_id}(*args)
-                options = args.extract_options!
-                attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
-                finder_options = { :conditions =&gt; attributes }
-                validate_find_options(options)
-                set_readonly_option!(options)
-
-                if options[:conditions]
-                  with_scope(:find =&gt; finder_options) do
-                    ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
+            if match.finder?
+              finder = match.finder
+              bang = match.bang?
+              self.class_eval %{
+                def self.#{method_id}(*args)
+                  options = args.extract_options!
+                  attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
+                  finder_options = { :conditions =&gt; attributes }
+                  validate_find_options(options)
+                  set_readonly_option!(options)
+
+                  #{'result = ' if bang}if options[:conditions]
+                    with_scope(:find =&gt; finder_options) do
+                      ActiveSupport::Deprecation.silence { send(:#{finder}, options) }
+                    end
+                  else
+                    ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
                   end
-                else
-                  ActiveSupport::Deprecation.silence { send(:#{finder}, options.merge(finder_options)) }
-                end
-              end
-            }, __FILE__, __LINE__
-            send(method_id, *arguments)
-          elsif match = matches_dynamic_finder_with_initialize_or_create?(method_id)
-            instantiator = determine_instantiator(match)
-            attribute_names = extract_attribute_names_from_match(match)
-            super unless all_attributes_exists?(attribute_names)
-
-            self.class_eval %{
-              def self.#{method_id}(*args)
-                guard_protected_attributes = false
-
-                if args[0].is_a?(Hash)
-                  guard_protected_attributes = true
-                  attributes = args[0].with_indifferent_access
-                  find_attributes = attributes.slice(*[:#{attribute_names.join(',:')}])
-                else
-                  find_attributes = attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
+                  #{'result || raise(RecordNotFound)' if bang}
                 end
+              }, __FILE__, __LINE__
+              send(method_id, *arguments)
+            elsif match.instantiator?
+              instantiator = match.instantiator
+              self.class_eval %{
+                def self.#{method_id}(*args)
+                  guard_protected_attributes = false
+
+                  if args[0].is_a?(Hash)
+                    guard_protected_attributes = true
+                    attributes = args[0].with_indifferent_access
+                    find_attributes = attributes.slice(*[:#{attribute_names.join(',:')}])
+                  else
+                    find_attributes = attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
+                  end
 
-                options = { :conditions =&gt; find_attributes }
-                set_readonly_option!(options)
+                  options = { :conditions =&gt; find_attributes }
+                  set_readonly_option!(options)
 
-                record = find_initial(options)
+                  record = find_initial(options)
 
-                 if record.nil?
-                  record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) }
-                  #{'yield(record) if block_given?'}
-                  #{'record.save' if instantiator == :create}
-                  record
-                else
-                  record
+                   if record.nil?
+                    record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) }
+                    #{'yield(record) if block_given?'}
+                    #{'record.save' if instantiator == :create}
+                    record
+                  else
+                    record
+                  end
                 end
-              end
-            }, __FILE__, __LINE__
-            send(method_id, *arguments)
+              }, __FILE__, __LINE__
+              send(method_id, *arguments)
+            end
           else
             super
           end
         end
 
-        def matches_dynamic_finder?(method_id)
-          /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s)
-        end
-
-        def matches_dynamic_finder_with_initialize_or_create?(method_id)
-          /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/.match(method_id.to_s)
-        end
-
-        def determine_finder(match)
-          match.captures.first == 'all_by' ? :find_every : :find_initial
-        end
-
-        def determine_instantiator(match)
-          match.captures.first == 'initialize' ? :new : :create
-        end
-
-        def extract_attribute_names_from_match(match)
-          match.captures.last.split('_and_')
-        end
-
         def construct_attributes_from_arguments(attribute_names, arguments)
           attributes = {}
           attribute_names.each_with_index { |name, idx| attributes[name] = arguments[idx] }
@@ -1750,7 +1775,7 @@ module ActiveRecord #:nodoc:
         def attribute_condition(argument)
           case argument
             when nil   then &quot;IS ?&quot;
-            when Array, ActiveRecord::Associations::AssociationCollection then &quot;IN (?)&quot;
+            when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope then &quot;IN (?)&quot;
             when Range then &quot;BETWEEN ? AND ?&quot;
             else            &quot;= ?&quot;
           end
@@ -1865,6 +1890,8 @@ module ActiveRecord #:nodoc:
                         hash[method][key] = merge_conditions(params[key], hash[method][key])
                       elsif key == :include &amp;&amp; merge
                         hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
+                      elsif key == :joins &amp;&amp; merge
+                        hash[method][key] = merge_joins(params[key], hash[method][key])
                       else
                         hash[method][key] = hash[method][key] || params[key]
                       end
@@ -1912,22 +1939,11 @@ module ActiveRecord #:nodoc:
           end
         end
 
-        def thread_safe_scoped_methods #:nodoc:
+        def scoped_methods #:nodoc:
           scoped_methods = (Thread.current[:scoped_methods] ||= {})
           scoped_methods[self] ||= []
         end
 
-        def single_threaded_scoped_methods #:nodoc:
-          @scoped_methods ||= []
-        end
-
-        # pick up the correct scoped_methods version from @@allow_concurrency
-        if @@allow_concurrency
-          alias_method :scoped_methods, :thread_safe_scoped_methods
-        else
-          alias_method :scoped_methods, :single_threaded_scoped_methods
-        end
-
         def current_scoped_methods #:nodoc:
           scoped_methods.last
         end
@@ -2235,20 +2251,40 @@ module ActiveRecord #:nodoc:
         defined?(@new_record) &amp;&amp; @new_record
       end
 
-      # * No record exists: Creates a new record with values matching those of the object attributes.
-      # * A record does exist: Updates the record with values matching those of the object attributes.
+      # :call-seq:
+      #   save(perform_validation = true)
+      #
+      # Saves the model.
       #
-      # Note: If your model specifies any validations then the method declaration dynamically
-      # changes to:
-      #   save(perform_validation=true)
-      # Calling save(false) saves the model without running validations.
-      # See ActiveRecord::Validations for more information.
+      # If the model is new a record gets created in the database, otherwise
+      # the existing record gets updated.
+      #
+      # If +perform_validation+ is true validations run. If any of them fail
+      # the action is cancelled and +save+ returns +false+. If the flag is
+      # false validations are bypassed altogether. See
+      # ActiveRecord::Validations for more information. 
+      #
+      # There's a series of callbacks associated with +save+. If any of the
+      # &lt;tt&gt;before_*&lt;/tt&gt; callbacks return +false+ the action is cancelled and
+      # +save+ returns +false+. See ActiveRecord::Callbacks for further
+      # details. 
       def save
         create_or_update
       end
 
-      # Attempts to save the record, but instead of just returning false if it couldn't happen, it raises a
-      # RecordNotSaved exception
+      # Saves the model.
+      #
+      # If the model is new a record gets created in the database, otherwise
+      # the existing record gets updated.
+      #
+      # With &lt;tt&gt;save!&lt;/tt&gt; validations always run. If any of them fail
+      # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations
+      # for more information. 
+      #
+      # There's a series of callbacks associated with &lt;tt&gt;save!&lt;/tt&gt;. If any of
+      # the &lt;tt&gt;before_*&lt;/tt&gt; callbacks return +false+ the action is cancelled
+      # and &lt;tt&gt;save!&lt;/tt&gt; raises ActiveRecord::RecordNotSaved. See
+      # ActiveRecord::Callbacks for further details. 
       def save!
         create_or_update || raise(RecordNotSaved)
       end
@@ -2572,11 +2608,14 @@ module ActiveRecord #:nodoc:
       end
 
       def convert_number_column_value(value)
-        case value
-          when FalseClass; 0
-          when TrueClass;  1
-          when '';         nil
-          else value
+        if value == false
+          0
+        elsif value == true
+          1
+        elsif value.is_a?(String) &amp;&amp; value.blank?
+          nil
+        else
+          value
         end
       end
 </diff>
      <filename>activerecord/lib/active_record/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,7 @@ module ActiveRecord
       #
       # The third approach, count using options, accepts an option hash as the only parameter. The options are:
       #
-      # * &lt;tt&gt;:conditions&lt;/tt&gt;: An SQL fragment like &quot;administrator = 1&quot; or [ &quot;user_name = ?&quot;, username ]. See conditions in the intro.
+      # * &lt;tt&gt;:conditions&lt;/tt&gt;: An SQL fragment like &quot;administrator = 1&quot; or [ &quot;user_name = ?&quot;, username ]. See conditions in the intro to ActiveRecord::Base.
       # * &lt;tt&gt;:joins&lt;/tt&gt;: Either an SQL fragment for additional joins like &quot;LEFT JOIN comments ON comments.post_id = id&quot; (rarely needed)
       #   or named associations in the same form used for the &lt;tt&gt;:include&lt;/tt&gt; option, which will perform an INNER JOIN on the associated table(s).
       #   If the value is a string, then the records will be returned read-only since they will have attributes that do not correspond to the table's columns.
@@ -98,7 +98,7 @@ module ActiveRecord
       #       end
       #
       # Options:
-      # * &lt;tt&gt;:conditions&lt;/tt&gt; - An SQL fragment like &quot;administrator = 1&quot; or [ &quot;user_name = ?&quot;, username ]. See conditions in the intro.
+      # * &lt;tt&gt;:conditions&lt;/tt&gt; - An SQL fragment like &quot;administrator = 1&quot; or [ &quot;user_name = ?&quot;, username ]. See conditions in the intro to ActiveRecord::Base.
       # * &lt;tt&gt;:include&lt;/tt&gt;: Eager loading, see Associations for details.  Since calculations don't load anything, the purpose of this is to access fields on joined tables in your conditions, order, or group clauses.
       # * &lt;tt&gt;:joins&lt;/tt&gt; - An SQL fragment for additional joins like &quot;LEFT JOIN comments ON comments.post_id = id&quot;. (Rarely needed).
       #   The records will be returned read-only since they will have attributes that do not correspond to the table's columns.
@@ -186,11 +186,17 @@ module ActiveRecord
             sql &lt;&lt; &quot; FROM (SELECT #{distinct}#{column_name}&quot; if use_workaround
             sql &lt;&lt; &quot; FROM #{connection.quote_table_name(table_name)} &quot;
           end
+
+          joins = &quot;&quot;
+          add_joins!(joins, options[:joins], scope)
+
           if merged_includes.any?
-            join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, options[:joins])
+            join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merged_includes, joins)
             sql &lt;&lt; join_dependency.join_associations.collect{|join| join.association_join }.join
           end
-          add_joins!(sql, options, scope)
+
+          sql &lt;&lt; joins unless joins.blank?
+
           add_conditions!(sql, options[:conditions], scope)
           add_limited_ids_condition!(sql, options, join_dependency) if join_dependency &amp;&amp; !using_limitable_reflections?(join_dependency.reflections) &amp;&amp; ((scope &amp;&amp; scope[:limit]) || options[:limit])
 
@@ -260,7 +266,14 @@ module ActiveRecord
         #   column_alias_for(&quot;count(*)&quot;)                 # =&gt; &quot;count_all&quot;
         #   column_alias_for(&quot;count&quot;, &quot;id&quot;)              # =&gt; &quot;count_id&quot;
         def column_alias_for(*keys)
-          connection.table_alias_for(keys.join(' ').downcase.gsub(/\*/, 'all').gsub(/\W+/, ' ').strip.gsub(/ +/, '_'))
+          table_name = keys.join(' ')
+          table_name.downcase!
+          table_name.gsub!(/\*/, 'all')
+          table_name.gsub!(/\W+/, ' ')
+          table_name.strip!
+          table_name.gsub!(/ +/, '_')
+
+          connection.table_alias_for(table_name)
         end
 
         def column_for(field)</diff>
      <filename>activerecord/lib/active_record/calculations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require 'observer'
 module ActiveRecord
   # Callbacks are hooks into the lifecycle of an Active Record object that allow you to trigger logic
   # before or after an alteration of the object state. This can be used to make sure that associated and
-  # dependent objects are deleted when destroy is called (by overwriting +before_destroy+) or to massage attributes
+  # dependent objects are deleted when +destroy+ is called (by overwriting +before_destroy+) or to massage attributes
   # before they're validated (by overwriting +before_validation+). As an example of the callbacks initiated, consider
   # the &lt;tt&gt;Base#save&lt;/tt&gt; call:
   #
@@ -161,7 +161,7 @@ module ActiveRecord
   # == &lt;tt&gt;before_validation*&lt;/tt&gt; returning statements
   #
   # If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be aborted and &lt;tt&gt;Base#save&lt;/tt&gt; will return +false+.
-  # If Base#save! is called it will raise a RecordNotSaved exception.
+  # If Base#save! is called it will raise a ActiveRecord::RecordInvalid exception.
   # Nothing will be appended to the errors object.
   #
   # == Canceling callbacks
@@ -169,6 +169,18 @@ module ActiveRecord
   # If a &lt;tt&gt;before_*&lt;/tt&gt; callback returns +false+, all the later callbacks and the associated action are cancelled. If an &lt;tt&gt;after_*&lt;/tt&gt; callback returns
   # +false+, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks
   # defined as methods on the model, which are called last.
+  #
+  # == Transactions
+  #
+  # The entire callback chain of a +save+, &lt;tt&gt;save!&lt;/tt&gt;, or +destroy+ call runs
+  # within a transaction. That includes &lt;tt&gt;after_*&lt;/tt&gt; hooks. If everything
+  # goes fine a COMMIT is executed once the chain has been completed.
+  #
+  # If a &lt;tt&gt;before_*&lt;/tt&gt; callback cancels the action a ROLLBACK is issued. You
+  # can also trigger a ROLLBACK raising an exception in any of the callbacks,
+  # including &lt;tt&gt;after_*&lt;/tt&gt; hooks. Note, however, that in that case the client
+  # needs to be aware of it because an ordinary +save+ will raise such exception
+  # instead of quietly returning +false+.
   module Callbacks
     CALLBACKS = %w(
       after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation
@@ -197,6 +209,8 @@ module ActiveRecord
     def before_save() end
 
     # Is called _after_ &lt;tt&gt;Base.save&lt;/tt&gt; (regardless of whether it's a +create+ or +update+ save).
+    # Note that this callback is still wrapped in the transaction around +save+. For example, if you
+    # invoke an external indexer at this point it won't see the changes in the database.
     #
     #  class Contact &lt; ActiveRecord::Base
     #    after_save { logger.info( 'New contact saved!' ) }
@@ -214,6 +228,8 @@ module ActiveRecord
     def before_create() end
 
     # Is called _after_ &lt;tt&gt;Base.save&lt;/tt&gt; on new objects that haven't been saved yet (no record exists).
+    # Note that this callback is still wrapped in the transaction around +save+. For example, if you
+    # invoke an external indexer at this point it won't see the changes in the database.
     def after_create() end
     def create_with_callbacks #:nodoc:
       return false if callback(:before_create) == false
@@ -227,6 +243,8 @@ module ActiveRecord
     def before_update() end
 
     # Is called _after_ &lt;tt&gt;Base.save&lt;/tt&gt; on existing objects that have a record.
+    # Note that this callback is still wrapped in the transaction around +save+. For example, if you
+    # invoke an external indexer at this point it won't see the changes in the database.
     def after_update() end
 
     def update_with_callbacks(*args) #:nodoc:</diff>
      <filename>activerecord/lib/active_record/callbacks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,3 @@
-require 'set'
-
 module ActiveRecord
   class Base
     class ConnectionSpecification #:nodoc:
@@ -9,163 +7,9 @@ module ActiveRecord
       end
     end
 
-    # Check for activity after at least +verification_timeout+ seconds.
-    # Defaults to 0 (always check.)
-    cattr_accessor :verification_timeout, :instance_writer =&gt; false
-    @@verification_timeout = 0
-
-    # The class -&gt; [adapter_method, config] map
-    @@defined_connections = {}
-
-    # The class -&gt; thread id -&gt; adapter cache. (class -&gt; adapter if not allow_concurrency)
-    @@active_connections = {}
-
-    class &lt;&lt; self
-      # Retrieve the connection cache.
-      def thread_safe_active_connections #:nodoc:
-        @@active_connections[Thread.current.object_id] ||= {}
-      end
-     
-      def single_threaded_active_connections #:nodoc:
-        @@active_connections
-      end
-     
-      # pick up the right active_connection method from @@allow_concurrency
-      if @@allow_concurrency
-        alias_method :active_connections, :thread_safe_active_connections
-      else
-        alias_method :active_connections, :single_threaded_active_connections
-      end
-     
-      # set concurrency support flag (not thread safe, like most of the methods in this file)
-      def allow_concurrency=(threaded) #:nodoc:
-        logger.debug &quot;allow_concurrency=#{threaded}&quot; if logger
-        return if @@allow_concurrency == threaded
-        clear_all_cached_connections!
-        @@allow_concurrency = threaded
-        method_prefix = threaded ? &quot;thread_safe&quot; : &quot;single_threaded&quot;
-        sing = (class &lt;&lt; self; self; end)
-        [:active_connections, :scoped_methods].each do |method|
-          sing.send(:alias_method, method, &quot;#{method_prefix}_#{method}&quot;)
-        end
-        log_connections if logger
-      end
-      
-      def active_connection_name #:nodoc:
-        @active_connection_name ||=
-           if active_connections[name] || @@defined_connections[name]
-             name
-           elsif self == ActiveRecord::Base
-             nil
-           else
-             superclass.active_connection_name
-           end
-      end
-
-      def clear_active_connection_name #:nodoc:
-        @active_connection_name = nil
-        subclasses.each { |klass| klass.clear_active_connection_name }
-      end
-
-      # Returns the connection currently associated with the class. This can
-      # also be used to &quot;borrow&quot; the connection to do database work unrelated
-      # to any of the specific Active Records.
-      def connection
-        if defined?(@active_connection_name) &amp;&amp; (conn = active_connections[@active_connection_name])
-          conn
-        else
-          # retrieve_connection sets the cache key.
-          conn = retrieve_connection
-          active_connections[@active_connection_name] = conn
-        end
-      end
-
-      # Clears the cache which maps classes to connections.
-      def clear_active_connections!
-        clear_cache!(@@active_connections) do |name, conn|
-          conn.disconnect!
-        end
-      end
-      
-      # Clears the cache which maps classes 
-      def clear_reloadable_connections!
-        if @@allow_concurrency
-          # With concurrent connections @@active_connections is
-          # a hash keyed by thread id.
-          @@active_connections.each do |thread_id, conns|
-            conns.each do |name, conn|
-              if conn.requires_reloading?
-                conn.disconnect!
-                @@active_connections[thread_id].delete(name)
-              end
-            end
-          end
-        else
-          @@active_connections.each do |name, conn|
-            if conn.requires_reloading?
-              conn.disconnect!
-              @@active_connections.delete(name)
-            end
-          end
-        end
-      end
-
-      # Verify active connections.
-      def verify_active_connections! #:nodoc:
-        if @@allow_concurrency
-          remove_stale_cached_threads!(@@active_connections) do |name, conn|
-            conn.disconnect!
-          end
-        end
-        
-        active_connections.each_value do |connection|
-          connection.verify!(@@verification_timeout)
-        end
-      end
-
-      private
-        def clear_cache!(cache, thread_id = nil, &amp;block)
-          if cache
-            if @@allow_concurrency
-              thread_id ||= Thread.current.object_id
-              thread_cache, cache = cache, cache[thread_id]
-              return unless cache
-            end
-
-            cache.each(&amp;block) if block_given?
-            cache.clear
-          end
-        ensure
-          if thread_cache &amp;&amp; @@allow_concurrency
-            thread_cache.delete(thread_id)
-          end
-        end
-
-        # Remove stale threads from the cache.
-        def remove_stale_cached_threads!(cache, &amp;block)
-          stale = Set.new(cache.keys)
-
-          Thread.list.each do |thread|
-            stale.delete(thread.object_id) if thread.alive?
-          end
-
-          stale.each do |thread_id|
-            clear_cache!(cache, thread_id, &amp;block)
-          end
-        end
-        
-        def clear_all_cached_connections!
-          if @@allow_concurrency
-            @@active_connections.each_value do |connection_hash_for_thread|
-              connection_hash_for_thread.each_value {|conn| conn.disconnect! }
-              connection_hash_for_thread.clear
-            end
-          else
-            @@active_connections.each_value {|conn| conn.disconnect! }
-          end
-          @@active_connections.clear          
-        end
-    end
+    # The connection handler
+    cattr_accessor :connection_handler, :instance_writer =&gt; false
+    @@connection_handler = ConnectionAdapters::ConnectionHandler.new
 
     # Returns the connection currently associated with the class. This can
     # also be used to &quot;borrow&quot; the connection to do database work that isn't
@@ -208,9 +52,7 @@ module ActiveRecord
           raise AdapterNotSpecified unless defined? RAILS_ENV
           establish_connection(RAILS_ENV)
         when ConnectionSpecification
-          clear_active_connection_name
-          @active_connection_name = name
-          @@defined_connections[name] = spec
+          @@connection_handler.establish_connection(name, spec)
         when Symbol, String
           if configuration = configurations[spec.to_s]
             establish_connection(configuration)
@@ -243,67 +85,52 @@ module ActiveRecord
       end
     end
 
-    # Locate the connection of the nearest super class. This can be an
-    # active or defined connection: if it is the latter, it will be
-    # opened and set as the active connection for the class it was defined
-    # for (not necessarily the current class).
-    def self.retrieve_connection #:nodoc:
-      # Name is nil if establish_connection hasn't been called for
-      # some class along the inheritance chain up to AR::Base yet.
-      if name = active_connection_name
-        if conn = active_connections[name]
-          # Verify the connection.
-          conn.verify!(@@verification_timeout)
-        elsif spec = @@defined_connections[name]
-          # Activate this connection specification.
-          klass = name.constantize
-          klass.connection = spec
-          conn = active_connections[name]
-        end
+    class &lt;&lt; self
+      # Deprecated and no longer has any effect.
+      def allow_concurrency
+        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Base.allow_concurrency has been deprecated and no longer has any effect. Please remove all references to allow_concurrency.&quot;)
       end
 
-      conn or raise ConnectionNotEstablished
-    end
+      # Deprecated and no longer has any effect.
+      def allow_concurrency=(flag)
+        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Base.allow_concurrency= has been deprecated and no longer has any effect. Please remove all references to allow_concurrency=.&quot;)
+      end
 
-    # Returns true if a connection that's accessible to this class has already been opened.
-    def self.connected?
-      active_connections[active_connection_name] ? true : false
-    end
+      # Deprecated and no longer has any effect.
+      def verification_timeout
+        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Base.verification_timeout has been deprecated and no longer has any effect. Please remove all references to verification_timeout.&quot;)
+      end
 
-    # Remove the connection for this class. This will close the active
-    # connection and the defined connection (if they exist). The result
-    # can be used as an argument for establish_connection, for easily
-    # re-establishing the connection.
-    def self.remove_connection(klass=self)
-      spec = @@defined_connections[klass.name]
-      konn = active_connections[klass.name]
-      @@defined_connections.delete_if { |key, value| value == spec }
-      active_connections.delete_if { |key, value| value == konn }
-      konn.disconnect! if konn
-      spec.config if spec
-    end
+      # Deprecated and no longer has any effect.
+      def verification_timeout=(flag)
+        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Base.verification_timeout= has been deprecated and no longer has any effect. Please remove all references to verification_timeout=.&quot;)
+      end
 
-    # Set the connection for the class.
-    def self.connection=(spec) #:nodoc:
-      if spec.kind_of?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
-        active_connections[name] = spec
-      elsif spec.kind_of?(ConnectionSpecification)
-        config = spec.config.reverse_merge(:allow_concurrency =&gt; @@allow_concurrency)
-        self.connection = self.send(spec.adapter_method, config)
-      elsif spec.nil?
-        raise ConnectionNotEstablished
-      else
-        establish_connection spec
+      # Returns the connection currently associated with the class. This can
+      # also be used to &quot;borrow&quot; the connection to do database work unrelated
+      # to any of the specific Active Records.
+      def connection
+        retrieve_connection
       end
-    end
 
-    # connection state logging
-    def self.log_connections #:nodoc:
-      if logger
-        logger.info &quot;Defined connections: #{@@defined_connections.inspect}&quot;
-        logger.info &quot;Active connections: #{active_connections.inspect}&quot;
-        logger.info &quot;Active connection name: #{@active_connection_name}&quot;
+      def connection_pool
+        connection_handler.retrieve_connection_pool(self)
       end
+
+      def retrieve_connection
+        connection_handler.retrieve_connection(self)
+      end
+
+      def connected?
+        connection_handler.connected?(self)
+      end
+
+      def remove_connection(klass = self)
+        connection_handler.remove_connection(klass)
+      end
+
+      delegate :clear_active_connections!, :clear_reloadable_connections!,
+        :clear_all_connections!,:verify_active_connections!, :to =&gt; :connection_handler
     end
   end
 end</diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,6 @@ module ActiveRecord
       class &lt;&lt; self
         def included(base)
           base.class_eval do
-            attr_accessor :query_cache_enabled
             alias_method_chain :columns, :query_cache
             alias_method_chain :select_all, :query_cache
           end
@@ -16,7 +15,7 @@ module ActiveRecord
           method_names.each do |method_name|
             base.class_eval &lt;&lt;-end_code, __FILE__, __LINE__
               def #{method_name}_with_query_dirty(*args)
-                clear_query_cache if @query_cache_enabled
+                clear_query_cache if query_cache_enabled
                 #{method_name}_without_query_dirty(*args)
               end
 
@@ -26,22 +25,38 @@ module ActiveRecord
         end
       end
 
+      def query_cache_enabled
+        Thread.current['query_cache_enabled']
+      end
+
+      def query_cache_enabled=(flag)
+        Thread.current['query_cache_enabled'] = flag
+      end
+
+      def query_cache
+        Thread.current['query_cache']
+      end
+
+      def query_cache=(cache)
+        Thread.current['query_cache'] = cache
+      end
+
       # Enable the query cache within the block.
       def cache
-        old, @query_cache_enabled = @query_cache_enabled, true
-        @query_cache ||= {}
+        old, self.query_cache_enabled = query_cache_enabled, true
+        self.query_cache ||= {}
         yield
       ensure
         clear_query_cache
-        @query_cache_enabled = old
+        self.query_cache_enabled = old
       end
 
       # Disable the query cache within the block.
       def uncached
-        old, @query_cache_enabled = @query_cache_enabled, false
+        old, self.query_cache_enabled = query_cache_enabled, false
         yield
       ensure
-        @query_cache_enabled = old
+        self.query_cache_enabled = old
       end
 
       # Clears the query cache.
@@ -51,11 +66,11 @@ module ActiveRecord
       # the same SQL query and repeatedly return the same result each time, silently
       # undermining the randomness you were expecting.
       def clear_query_cache
-        @query_cache.clear if @query_cache
+        query_cache.clear if query_cache
       end
 
       def select_all_with_query_cache(*args)
-        if @query_cache_enabled
+        if query_cache_enabled
           cache_sql(args.first) { select_all_without_query_cache(*args) }
         else
           select_all_without_query_cache(*args)
@@ -63,8 +78,8 @@ module ActiveRecord
       end
 
       def columns_with_query_cache(*args)
-        if @query_cache_enabled
-          @query_cache[&quot;SHOW FIELDS FROM #{args.first}&quot;] ||= columns_without_query_cache(*args)
+        if query_cache_enabled
+          query_cache[&quot;SHOW FIELDS FROM #{args.first}&quot;] ||= columns_without_query_cache(*args)
         else
           columns_without_query_cache(*args)
         end
@@ -72,12 +87,21 @@ module ActiveRecord
 
       private
         def cache_sql(sql)
-          if @query_cache.has_key?(sql)
-            log_info(sql, &quot;CACHE&quot;, 0.0)
-            @query_cache[sql]
+          result =
+            if query_cache.has_key?(sql)
+              log_info(sql, &quot;CACHE&quot;, 0.0)
+              query_cache[sql]
+            else
+              query_cache[sql] = yield
+            end
+
+          if Array === result
+            result.collect { |row| row.dup }
           else
-            @query_cache[sql] = yield.freeze
+            result.duplicable? ? result.dup : result
           end
+        rescue TypeError
+          result
         end
     end
   end</diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb</filename>
    </modified>
    <modified>
      <diff>@@ -138,7 +138,11 @@ module ActiveRecord
 
         # convert something to a boolean
         def value_to_boolean(value)
-          TRUE_VALUES.include?(value)
+          if value.is_a?(String) &amp;&amp; value.blank?
+            nil
+          else
+            TRUE_VALUES.include?(value)
+          end
         end
 
         # convert something to a BigDecimal
@@ -443,9 +447,10 @@ module ActiveRecord
 
       # Appends &lt;tt&gt;:datetime&lt;/tt&gt; columns &lt;tt&gt;:created_at&lt;/tt&gt; and
       # &lt;tt&gt;:updated_at&lt;/tt&gt; to the table.
-      def timestamps
-        column(:created_at, :datetime)
-        column(:updated_at, :datetime)
+      def timestamps(*args)
+        options = args.extract_options!
+        column(:created_at, :datetime, options)
+        column(:updated_at, :datetime, options)
       end
 
       def references(*args)</diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -384,12 +384,8 @@ module ActiveRecord
       def add_column_options!(sql, options) #:nodoc:
         sql &lt;&lt; &quot; DEFAULT #{quote(options[:default], options[:column])}&quot; if options_include_default?(options)
         # must explicitly check for :null to allow change_column to work on migrations
-        if options.has_key? :null
-          if options[:null] == false
-            sql &lt;&lt; &quot; NOT NULL&quot;
-          else
-            sql &lt;&lt; &quot; NULL&quot;
-          end
+        if options[:null] == false
+          sql &lt;&lt; &quot; NOT NULL&quot;
         end
       end
 </diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,6 +7,7 @@ require 'active_record/connection_adapters/abstract/schema_definitions'
 require 'active_record/connection_adapters/abstract/schema_statements'
 require 'active_record/connection_adapters/abstract/database_statements'
 require 'active_record/connection_adapters/abstract/quoting'
+require 'active_record/connection_adapters/abstract/connection_pool'
 require 'active_record/connection_adapters/abstract/connection_specification'
 require 'active_record/connection_adapters/abstract/query_cache'
 
@@ -24,6 +25,9 @@ module ActiveRecord
     class AbstractAdapter
       include Quoting, DatabaseStatements, SchemaStatements
       include QueryCache
+      include ActiveSupport::Callbacks
+      define_callbacks :checkout, :checkin
+      checkout :reset!
       @@row_even = true
 
       def initialize(connection, logger = nil) #:nodoc:
@@ -51,6 +55,13 @@ module ActiveRecord
         true
       end
 
+      # Does this adapter support DDL rollbacks in transactions?  That is, would
+      # CREATE TABLE or ALTER TABLE get rolled back by a transaction?  PostgreSQL,
+      # SQL Server, and others support this.  MySQL and others do not.
+      def supports_ddl_transactions?
+        false
+      end
+
       # Should primary key values be selected from their corresponding
       # sequence before the insert statement?  If true, next_sequence_value
       # is called before each insert to set the record's primary key.
@@ -95,20 +106,25 @@ module ActiveRecord
         @active = false
       end
 
+      # Reset the state of this connection, directing the DBMS to clear
+      # transactions and other connection-related server-side state. Usually a
+      # database-dependent operation; the default method simply executes a
+      # ROLLBACK and swallows any exceptions which is probably not enough to
+      # ensure the connection is clean.
+      def reset!
+        # this should be overridden by concrete adapters
+      end
+
       # Returns true if its safe to reload the connection between requests for development mode.
       # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
       def requires_reloading?
         false
       end
 
-      # Lazily verify this connection, calling &lt;tt&gt;active?&lt;/tt&gt; only if it hasn't
-      # been called for +timeout+ seconds.
-      def verify!(timeout)
-        now = Time.now.to_i
-        if (now - @last_verification) &gt; timeout
-          reconnect! unless active?
-          @last_verification = now
-        end
+      # Verify this connection by calling &lt;tt&gt;active?&lt;/tt&gt; and reconnecting if
+      # the connection is no longer active.
+      def verify!(*ignored)
+        reconnect! unless active?
       end
 
       # Provides access to the underlying database connection. Useful for
@@ -131,10 +147,10 @@ module ActiveRecord
         @open_transactions -= 1
       end
 
-      def log_info(sql, name, runtime)
+      def log_info(sql, name, seconds)
         if @logger &amp;&amp; @logger.debug?
-          name = &quot;#{name.nil? ? &quot;SQL&quot; : name} (#{sprintf(&quot;%f&quot;, runtime)})&quot;
-          @logger.debug format_log_entry(name, sql.squeeze(' '))
+          name = &quot;#{name.nil? ? &quot;SQL&quot; : name} (#{sprintf(&quot;%.1f&quot;, seconds * 1000)}ms)&quot;
+          @logger.debug(format_log_entry(name, sql.squeeze(' ')))
         end
       end
 </diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -280,6 +280,14 @@ module ActiveRecord
         @connection.close rescue nil
       end
 
+      def reset!
+        if @connection.respond_to?(:change_user)
+          # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to
+          # reset the connection is to change the user to the same user.
+          @connection.change_user(@config[:username], @config[:password], @config[:database])
+          configure_connection
+        end
+      end
 
       # DATABASE STATEMENTS ======================================
 
@@ -529,7 +537,11 @@ module ActiveRecord
           end
 
           @connection.real_connect(*@connection_options)
+          configure_connection
+        end
 
+        def configure_connection
+          encoding = @config[:encoding]
           execute(&quot;SET NAMES '#{encoding}'&quot;) if encoding
 
           # By default, MySQL 'where id is null' selects the last inserted id.</diff>
      <filename>activerecord/lib/active_record/connection_adapters/mysql_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,8 +23,8 @@ module ActiveRecord
       config = config.symbolize_keys
       host     = config[:host]
       port     = config[:port] || 5432
-      username = config[:username].to_s
-      password = config[:password].to_s
+      username = config[:username].to_s if config[:username]
+      password = config[:password].to_s if config[:password]
 
       if config.has_key?(:database)
         database = config[:database]
@@ -335,6 +335,10 @@ module ActiveRecord
         postgresql_version &gt;= 80200
       end
 
+      def supports_ddl_transactions?
+        true
+      end
+
       # Returns the configured supported identifier length supported by PostgreSQL,
       # or report the default of 63 on PostgreSQL 7.x.
       def table_alias_length
@@ -376,7 +380,7 @@ module ActiveRecord
           # There are some incorrectly compiled postgres drivers out there
           # that don't define PGconn.escape.
           self.class.instance_eval do
-            undef_method(:quote_string)
+            remove_method(:quote_string)
           end
         end
         quote_string(s)
@@ -514,6 +518,45 @@ module ActiveRecord
         execute &quot;ROLLBACK&quot;
       end
 
+      # ruby-pg defines Ruby constants for transaction status,
+      # ruby-postgres does not.
+      PQTRANS_IDLE = defined?(PGconn::PQTRANS_IDLE) ? PGconn::PQTRANS_IDLE : 0
+
+      # Check whether a transaction is active.
+      def transaction_active?
+        @connection.transaction_status != PQTRANS_IDLE
+      end
+
+      # Wrap a block in a transaction.  Returns result of block.
+      def transaction(start_db_transaction = true)
+        transaction_open = false
+        begin
+          if block_given?
+            if start_db_transaction
+              begin_db_transaction
+              transaction_open = true
+            end
+            yield
+          end
+        rescue Exception =&gt; database_transaction_rollback
+          if transaction_open &amp;&amp; transaction_active?
+            transaction_open = false
+            rollback_db_transaction
+          end
+          raise unless database_transaction_rollback.is_a? ActiveRecord::Rollback
+        end
+      ensure
+        if transaction_open &amp;&amp; transaction_active?
+          begin
+            commit_db_transaction
+          rescue Exception =&gt; database_transaction_rollback
+            rollback_db_transaction
+            raise
+          end
+        end
+      end
+
+
       # SCHEMA STATEMENTS ========================================
 
       def recreate_database(name) #:nodoc:
@@ -534,13 +577,13 @@ module ActiveRecord
         option_string = options.symbolize_keys.sum do |key, value|
           case key
           when :owner
-            &quot; OWNER = '#{value}'&quot;
+            &quot; OWNER = \&quot;#{value}\&quot;&quot;
           when :template
-            &quot; TEMPLATE = #{value}&quot;
+            &quot; TEMPLATE = \&quot;#{value}\&quot;&quot;
           when :encoding
             &quot; ENCODING = '#{value}'&quot;
           when :tablespace
-            &quot; TABLESPACE = #{value}&quot;
+            &quot; TABLESPACE = \&quot;#{value}\&quot;&quot;
           when :connection_limit
             &quot; CONNECTION LIMIT = #{value}&quot;
           else
@@ -761,7 +804,8 @@ module ActiveRecord
 
         begin
           execute &quot;ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}&quot;
-        rescue ActiveRecord::StatementInvalid
+        rescue ActiveRecord::StatementInvalid =&gt; e
+          raise e if postgresql_version &gt; 80000
           # This is PostgreSQL 7.x, so we have to use a more arcane way of doing it.
           begin
             begin_db_transaction</diff>
      <filename>activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -123,7 +123,10 @@ module ActiveRecord
         attr = attr.to_s
 
         # The attribute already has an unsaved change.
-        unless changed_attributes.include?(attr)
+        if changed_attributes.include?(attr)
+          old = changed_attributes[attr]
+          changed_attributes.delete(attr) unless field_changed?(attr, old, value)
+        else
           old = clone_attribute_value(:read_attribute, attr)
           changed_attributes[attr] = old if field_changed?(attr, old, value)
         end</diff>
      <filename>activerecord/lib/active_record/dirty.rb</filename>
    </modified>
    <modified>
      <diff>@@ -955,7 +955,7 @@ module Test #:nodoc:
           ActiveRecord::Base.connection.rollback_db_transaction
           ActiveRecord::Base.connection.decrement_open_transactions
         end
-        ActiveRecord::Base.verify_active_connections!
+        ActiveRecord::Base.clear_active_connections!
       end
 
       private</diff>
      <filename>activerecord/lib/active_record/fixtures.rb</filename>
    </modified>
    <modified>
      <diff>@@ -406,11 +406,17 @@ module ActiveRecord
         Base.table_name_prefix + 'schema_migrations' + Base.table_name_suffix
       end
 
+      def get_all_versions
+        Base.connection.select_values(&quot;SELECT version FROM #{schema_migrations_table_name}&quot;).map(&amp;:to_i).sort
+      end
+
       def current_version
-        version = Base.connection.select_values(
-          &quot;SELECT version FROM #{schema_migrations_table_name}&quot;
-        ).map(&amp;:to_i).max rescue nil
-        version || 0
+        sm_table = schema_migrations_table_name
+        if Base.connection.table_exists?(sm_table)
+          get_all_versions.max || 0
+        else
+          0
+        end
       end
 
       def proper_table_name(name)
@@ -426,7 +432,7 @@ module ActiveRecord
     end
 
     def current_version
-      self.class.current_version
+      migrated.last || 0
     end
     
     def current_migration
@@ -461,14 +467,22 @@ module ActiveRecord
         Base.logger.info &quot;Migrating to #{migration.name} (#{migration.version})&quot;
 
         # On our way up, we skip migrating the ones we've already migrated
-        # On our way down, we skip reverting the ones we've never migrated
         next if up? &amp;&amp; migrated.include?(migration.version.to_i)
 
+        # On our way down, we skip reverting the ones we've never migrated
         if down? &amp;&amp; !migrated.include?(migration.version.to_i)
           migration.announce 'never migrated, skipping'; migration.write
-        else
-          migration.migrate(@direction)
-          record_version_state_after_migrating(migration.version)
+          next
+        end
+
+        begin
+          ddl_transaction do
+            migration.migrate(@direction)
+            record_version_state_after_migrating(migration.version)
+          end
+        rescue =&gt; e
+          canceled_msg = Base.connection.supports_ddl_transactions? ? &quot;this and &quot; : &quot;&quot;
+          raise StandardError, &quot;An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}&quot;, e.backtrace
         end
       end
     end
@@ -509,17 +523,19 @@ module ActiveRecord
     end
 
     def migrated
-      sm_table = self.class.schema_migrations_table_name
-      Base.connection.select_values(&quot;SELECT version FROM #{sm_table}&quot;).map(&amp;:to_i).sort
+      @migrated_versions ||= self.class.get_all_versions
     end
 
     private
       def record_version_state_after_migrating(version)
         sm_table = self.class.schema_migrations_table_name
 
+        @migrated_versions ||= []
         if down?
+          @migrated_versions.delete(version.to_i)
           Base.connection.update(&quot;DELETE FROM #{sm_table} WHERE version = '#{version}'&quot;)
         else
+          @migrated_versions.push(version.to_i).sort!
           Base.connection.insert(&quot;INSERT INTO #{sm_table} (version) VALUES ('#{version}')&quot;)
         end
       end
@@ -531,5 +547,14 @@ module ActiveRecord
       def down?
         @direction == :down
       end
+
+      # Wrap the migration in a transaction only if supported by the adapter.
+      def ddl_transaction(&amp;block)
+        if Base.connection.supports_ddl_transactions?
+          Base.transaction { block.call }
+        else
+          block.call
+        end
+      end
   end
 end</diff>
      <filename>activerecord/lib/active_record/migration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,10 @@
 module ActiveRecord
   module NamedScope
-    # All subclasses of ActiveRecord::Base have two named_scopes:
-    # * &lt;tt&gt;all&lt;/tt&gt;, which is similar to a &lt;tt&gt;find(:all)&lt;/tt&gt; query, and
-    # * &lt;tt&gt;scoped&lt;/tt&gt;, which allows for the creation of anonymous scopes, on the fly: &lt;tt&gt;Shirt.scoped(:conditions =&gt; {:color =&gt; 'red'}).scoped(:include =&gt; :washing_instructions)&lt;/tt&gt;
+    # All subclasses of ActiveRecord::Base have two named \scopes:
+    # * &lt;tt&gt;all&lt;/tt&gt; - which is similar to a &lt;tt&gt;find(:all)&lt;/tt&gt; query, and
+    # * &lt;tt&gt;scoped&lt;/tt&gt; - which allows for the creation of anonymous \scopes, on the fly: &lt;tt&gt;Shirt.scoped(:conditions =&gt; {:color =&gt; 'red'}).scoped(:include =&gt; :washing_instructions)&lt;/tt&gt;
     #
-    # These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
+    # These anonymous \scopes tend to be useful when procedurally generating complex queries, where passing
     # intermediate values (scopes) around as first-class objects is convenient.
     def self.included(base)
       base.class_eval do
@@ -26,20 +26,20 @@ module ActiveRecord
       #     named_scope :dry_clean_only, :joins =&gt; :washing_instructions, :conditions =&gt; ['washing_instructions.dry_clean_only = ?', true]
       #   end
       # 
-      # The above calls to &lt;tt&gt;named_scope&lt;/tt&gt; define class methods &lt;tt&gt;Shirt.red&lt;/tt&gt; and &lt;tt&gt;Shirt.dry_clean_only&lt;/tt&gt;. &lt;tt&gt;Shirt.red&lt;/tt&gt;, 
+      # The above calls to &lt;tt&gt;named_scope&lt;/tt&gt; define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red, 
       # in effect, represents the query &lt;tt&gt;Shirt.find(:all, :conditions =&gt; {:color =&gt; 'red'})&lt;/tt&gt;.
       #
-      # Unlike Shirt.find(...), however, the object returned by &lt;tt&gt;Shirt.red&lt;/tt&gt; is not an Array; it resembles the association object
+      # Unlike &lt;tt&gt;Shirt.find(...)&lt;/tt&gt;, however, the object returned by Shirt.red is not an Array; it resembles the association object
       # constructed by a &lt;tt&gt;has_many&lt;/tt&gt; declaration. For instance, you can invoke &lt;tt&gt;Shirt.red.find(:first)&lt;/tt&gt;, &lt;tt&gt;Shirt.red.count&lt;/tt&gt;,
       # &lt;tt&gt;Shirt.red.find(:all, :conditions =&gt; {:size =&gt; 'small'})&lt;/tt&gt;. Also, just
-      # as with the association objects, name scopes acts like an Array, implementing Enumerable; &lt;tt&gt;Shirt.red.each(&amp;block)&lt;/tt&gt;,
-      # &lt;tt&gt;Shirt.red.first&lt;/tt&gt;, and &lt;tt&gt;Shirt.red.inject(memo, &amp;block)&lt;/tt&gt; all behave as if Shirt.red really were an Array.
+      # as with the association objects, named \scopes act like an Array, implementing Enumerable; &lt;tt&gt;Shirt.red.each(&amp;block)&lt;/tt&gt;,
+      # &lt;tt&gt;Shirt.red.first&lt;/tt&gt;, and &lt;tt&gt;Shirt.red.inject(memo, &amp;block)&lt;/tt&gt; all behave as if Shirt.red really was an Array.
       #
-      # These named scopes are composable. For instance, &lt;tt&gt;Shirt.red.dry_clean_only&lt;/tt&gt; will produce all shirts that are both red and dry clean only.
+      # These named \scopes are composable. For instance, &lt;tt&gt;Shirt.red.dry_clean_only&lt;/tt&gt; will produce all shirts that are both red and dry clean only.
       # Nested finds and calculations also work with these compositions: &lt;tt&gt;Shirt.red.dry_clean_only.count&lt;/tt&gt; returns the number of garments
       # for which these criteria obtain. Similarly with &lt;tt&gt;Shirt.red.dry_clean_only.average(:thread_count)&lt;/tt&gt;.
       #
-      # All scopes are available as class methods on the ActiveRecord::Base descendent upon which the scopes were defined. But they are also available to
+      # All \scopes are available as class methods on the ActiveRecord::Base descendent upon which the \scopes were defined. But they are also available to
       # &lt;tt&gt;has_many&lt;/tt&gt; associations. If,
       #
       #   class Person &lt; ActiveRecord::Base
@@ -49,7 +49,7 @@ module ActiveRecord
       # then &lt;tt&gt;elton.shirts.red.dry_clean_only&lt;/tt&gt; will return all of Elton's red, dry clean
       # only shirts.
       #
-      # Named scopes can also be procedural.
+      # Named \scopes can also be procedural:
       #
       #   class Shirt &lt; ActiveRecord::Base
       #     named_scope :colored, lambda { |color|
@@ -59,7 +59,7 @@ module ActiveRecord
       #
       # In this example, &lt;tt&gt;Shirt.colored('puce')&lt;/tt&gt; finds all puce shirts.
       #
-      # Named scopes can also have extensions, just as with &lt;tt&gt;has_many&lt;/tt&gt; declarations:
+      # Named \scopes can also have extensions, just as with &lt;tt&gt;has_many&lt;/tt&gt; declarations:
       #
       #   class Shirt &lt; ActiveRecord::Base
       #     named_scope :red, :conditions =&gt; {:color =&gt; 'red'} do
@@ -70,7 +70,7 @@ module ActiveRecord
       #   end
       #
       #
-      # For testing complex named scopes, you can examine the scoping options using the
+      # For testing complex named \scopes, you can examine the scoping options using the
       # &lt;tt&gt;proxy_options&lt;/tt&gt; method on the proxy itself.
       #
       #   class Shirt &lt; ActiveRecord::Base
@@ -101,9 +101,9 @@ module ActiveRecord
     
     class Scope
       attr_reader :proxy_scope, :proxy_options
-
+      NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set
       [].methods.each do |m|
-        unless m =~ /(^__|^nil\?|^send|^object_id$|class|extend|find|count|sum|average|maximum|minimum|paginate|first|last|empty?|any?|respond_to?)/
+        unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
           delegate m, :to =&gt; :proxy_found
         end
       end
@@ -136,12 +136,16 @@ module ActiveRecord
         end
       end
 
+      def size
+        @found ? @found.length : count
+      end
+
       def empty?
         @found ? @found.empty? : count.zero?
       end
 
-      def respond_to?(method)
-        super || @proxy_scope.respond_to?(method)
+      def respond_to?(method, include_private = false)
+        super || @proxy_scope.respond_to?(method, include_private)
       end
 
       def any?</diff>
      <filename>activerecord/lib/active_record/named_scope.rb</filename>
    </modified>
    <modified>
      <diff>@@ -37,11 +37,26 @@ module ActiveRecord
       $queries_executed = []
       yield
     ensure
-      assert_equal num, $queries_executed.size, &quot;#{$queries_executed.size} instead of #{num} queries were executed.&quot;
+      assert_equal num, $queries_executed.size, &quot;#{$queries_executed.size} instead of #{num} queries were executed.#{$queries_executed.size == 0 ? '' : &quot;\nQueries:\n#{$queries_executed.join(&quot;\n&quot;)}&quot;}&quot;
     end
 
     def assert_no_queries(&amp;block)
       assert_queries(0, &amp;block)
     end
+
+    def self.use_concurrent_connections
+      setup :connection_allow_concurrency_setup
+      teardown :connection_allow_concurrency_teardown
+    end
+
+    def connection_allow_concurrency_setup
+      @connection = ActiveRecord::Base.remove_connection
+      ActiveRecord::Base.establish_connection(@connection.merge({:allow_concurrency =&gt; true}))
+    end
+
+    def connection_allow_concurrency_teardown
+      ActiveRecord::Base.clear_all_connections!
+      ActiveRecord::Base.establish_connection(@connection)
+    end
   end
 end</diff>
      <filename>activerecord/lib/active_record/test_case.rb</filename>
    </modified>
    <modified>
      <diff>@@ -64,7 +64,7 @@ module ActiveRecord
     #
     # Both Base#save and Base#destroy come wrapped in a transaction that ensures that whatever you do in validations or callbacks
     # will happen under the protected cover of a transaction. So you can use validations to check for values that the transaction
-    # depends on or you can raise exceptions in the callbacks to rollback.
+    # depends on or you can raise exceptions in the callbacks to rollback, including &lt;tt&gt;after_*&lt;/tt&gt; callbacks.
     #
     # == Exception handling and rolling back
     #
@@ -91,11 +91,11 @@ module ActiveRecord
     end
 
     def destroy_with_transactions #:nodoc:
-      transaction { destroy_without_transactions }
+      with_transaction_returning_status(:destroy_without_transactions)
     end
 
     def save_with_transactions(perform_validation = true) #:nodoc:
-      rollback_active_record_state! { transaction { save_without_transactions(perform_validation) } }
+      rollback_active_record_state! { with_transaction_returning_status(:save_without_transactions, perform_validation) }
     end
 
     def save_with_transactions! #:nodoc:
@@ -118,5 +118,17 @@ module ActiveRecord
       end
       raise
     end
+
+    # Executes +method+ within a transaction and captures its return value as a
+    # status flag. If the status is true the transaction is committed, otherwise
+    # a ROLLBACK is issued. In any case the status flag is returned.
+    def with_transaction_returning_status(method, *args)
+      status = nil
+      transaction do
+        status = send(method, *args)
+        raise ActiveRecord::Rollback unless status
+      end
+      status
+    end
   end
 end</diff>
      <filename>activerecord/lib/active_record/transactions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,8 +21,8 @@ module ActiveRecord
     
     class &lt;&lt; self
       def default_error_messages
-        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Errors.default_error_messages has been deprecated. Please use I18n.translate('active_record.error_messages').&quot;)
-        I18n.translate 'active_record.error_messages'
+        ActiveSupport::Deprecation.warn(&quot;ActiveRecord::Errors.default_error_messages has been deprecated. Please use I18n.translate('activerecord.errors.messages').&quot;)
+        I18n.translate 'activerecord.errors.messages'
       end
     end
 
@@ -38,22 +38,24 @@ module ActiveRecord
       add(:base, msg)
     end
 
-    # Adds an error message (+msg+) to the +attribute+, which will be returned on a call to &lt;tt&gt;on(attribute)&lt;/tt&gt;
+    # Adds an error message (+messsage+) to the +attribute+, which will be returned on a call to &lt;tt&gt;on(attribute)&lt;/tt&gt;
     # for the same attribute and ensure that this error object returns false when asked if &lt;tt&gt;empty?&lt;/tt&gt;. More than one
     # error can be added to the same +attribute+ in which case an array will be returned on a call to &lt;tt&gt;on(attribute)&lt;/tt&gt;.
-    # If no +msg+ is supplied, &quot;invalid&quot; is assumed.
-    def add(attribute, message = nil)
-      message ||= I18n.translate :&quot;active_record.error_messages.invalid&quot;
+    # If no +messsage+ is supplied, :invalid is assumed.
+    # If +message+ is a Symbol, it will be translated, using the appropriate scope (see translate_error).
+    def add(attribute, message = nil, options = {})
+      message ||= :invalid
+      message = generate_message(attribute, message, options) if message.is_a?(Symbol)
       @errors[attribute.to_s] ||= []
       @errors[attribute.to_s] &lt;&lt; message
-    end    
+    end
 
     # Will add an error message to each of the attributes in +attributes+ that is empty.
     def add_on_empty(attributes, custom_message = nil)
       for attr in [attributes].flatten
         value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s]
-        is_empty = value.respond_to?(&quot;empty?&quot;) ? value.empty? : false        
-        add(attr, generate_message(attr, :empty, :default =&gt; custom_message)) unless !value.nil? &amp;&amp; !is_empty
+        is_empty = value.respond_to?(:empty?) ? value.empty? : false
+        add(attr, :empty, :default =&gt; custom_message) unless !value.nil? &amp;&amp; !is_empty
       end
     end
 
@@ -61,16 +63,51 @@ module ActiveRecord
     def add_on_blank(attributes, custom_message = nil)
       for attr in [attributes].flatten
         value = @base.respond_to?(attr.to_s) ? @base.send(attr.to_s) : @base[attr.to_s]
-        add(attr, generate_message(attr, :blank, :default =&gt; custom_message)) if value.blank?
+        add(attr, :blank, :default =&gt; custom_message) if value.blank?
       end
     end
     
-    def generate_message(attr, key, options = {})
-      msgs = base_classes(@base.class).map{|klass| :&quot;custom.#{klass.name.underscore}.#{attr}.#{key}&quot;} 
-      msgs &lt;&lt; options[:default] if options[:default]
-      msgs &lt;&lt; key
+    # Translates an error message in it's default scope (&lt;tt&gt;activerecord.errrors.messages&lt;/tt&gt;).
+    # Error messages are first looked up in &lt;tt&gt;models.MODEL.attributes.ATTRIBUTE.MESSAGE&lt;/tt&gt;, if it's not there, 
+    # it's looked up in &lt;tt&gt;models.MODEL.MESSAGE&lt;/tt&gt; and if that is not there it returns the translation of the 
+    # default message (e.g. &lt;tt&gt;activerecord.errors.messages.MESSAGE&lt;/tt&gt;). The translated model name, 
+    # translated attribute name and the value are available for interpolation.
+    #
+    # When using inheritence in your models, it will check all the inherited models too, but only if the model itself
+    # hasn't been found. Say you have &lt;tt&gt;class Admin &lt; User; end&lt;/tt&gt; and you wanted the translation for the &lt;tt&gt;:blank&lt;/tt&gt;
+    # error +message+ for the &lt;tt&gt;title&lt;/tt&gt; +attribute+, it looks for these translations:
+    # 
+    # &lt;ol&gt;
+    # &lt;li&gt;&lt;tt&gt;activerecord.errors.models.admin.attributes.title.blank&lt;/tt&gt;&lt;/li&gt;
+    # &lt;li&gt;&lt;tt&gt;activerecord.errors.models.admin.blank&lt;/tt&gt;&lt;/li&gt;
+    # &lt;li&gt;&lt;tt&gt;activerecord.errors.models.user.attributes.title.blank&lt;/tt&gt;&lt;/li&gt;
+    # &lt;li&gt;&lt;tt&gt;activerecord.errors.models.user.blank&lt;/tt&gt;&lt;/li&gt;
+    # &lt;li&gt;&lt;tt&gt;activerecord.errors.messages.blank&lt;/tt&gt;&lt;/li&gt;
+    # &lt;li&gt;any default you provided through the +options+ hash (in the activerecord.errors scope)&lt;/li&gt;
+    # &lt;/ol&gt;
+    def generate_message(attribute, message = :invalid, options = {})
+
+      message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
+
+      defaults = @base.class.self_and_descendents_from_active_record.map do |klass| 
+        [ :&quot;models.#{klass.name.underscore}.attributes.#{attribute}.#{message}&quot;, 
+          :&quot;models.#{klass.name.underscore}.#{message}&quot; ]
+      end
+      
+      defaults &lt;&lt; options.delete(:default)
+      defaults = defaults.compact.flatten &lt;&lt; :&quot;messages.#{message}&quot;
+
+      key = defaults.shift
+      value = @base.respond_to?(attribute) ? @base.send(attribute) : nil
 
-      I18n.t nil, options.merge(:default =&gt; msgs, :scope =&gt; [:active_record, :error_messages])
+      options = { :default =&gt; defaults,
+        :model =&gt; @base.class.human_name,
+        :attribute =&gt; @base.class.human_attribute_name(attribute.to_s),
+        :value =&gt; value,
+        :scope =&gt; [:activerecord, :errors]
+      }.merge(options)
+
+      I18n.translate(key, options)
     end
 
     # Returns true if the specified +attribute+ has errors associated with it.
@@ -166,9 +203,9 @@ module ActiveRecord
           if attr == &quot;base&quot;
             full_messages &lt;&lt; message
           else
-            key = :&quot;active_record.human_attribute_names.#{@base.class.name.underscore.to_sym}.#{attr}&quot; 
-            attr_name = I18n.translate(key, :locale =&gt; options[:locale], :default =&gt; @base.class.human_attribute_name(attr))
-            full_messages &lt;&lt; attr_name + &quot; &quot; + message
+            #key = :&quot;activerecord.att.#{@base.class.name.underscore.to_sym}.#{attr}&quot; 
+            attr_name = @base.class.human_attribute_name(attr)
+            full_messages &lt;&lt; attr_name + ' ' + message
           end
         end
       end
@@ -219,16 +256,6 @@ module ActiveRecord
       end
     end
     
-    protected
-      
-      # TODO maybe this should be on ActiveRecord::Base, maybe #self_and_descendents_from_active_record
-      def base_classes(klass)
-        classes = [klass]
-        while klass != klass.base_class  
-          classes &lt;&lt; klass = klass.superclass
-        end
-        classes
-      end
   end
 
 
@@ -398,8 +425,7 @@ module ActiveRecord
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           unless record.send(&quot;#{attr_name}_confirmation&quot;).nil? or value == record.send(&quot;#{attr_name}_confirmation&quot;)
-            message = record.errors.generate_message(attr_name, :confirmation, :default =&gt; configuration[:message])
-            record.errors.add(attr_name, message) 
+            record.errors.add(attr_name, :confirmation, :default =&gt; configuration[:message]) 
           end
         end
       end
@@ -441,8 +467,7 @@ module ActiveRecord
 
         validates_each(attr_names,configuration) do |record, attr_name, value|
           unless value == configuration[:accept]
-            message = record.errors.generate_message(attr_name, :accepted, :default =&gt; configuration[:message])
-            record.errors.add(attr_name, message) 
+            record.errors.add(attr_name, :accepted, :default =&gt; configuration[:message]) 
           end
         end
       end
@@ -544,11 +569,9 @@ module ActiveRecord
             validates_each(attrs, options) do |record, attr, value|
               value = options[:tokenizer].call(value) if value.kind_of?(String)
               if value.nil? or value.size &lt; option_value.begin
-                message = record.errors.generate_message(attr, :too_short, :default =&gt; options[:too_short], :count =&gt; option_value.begin)                
-                record.errors.add(attr, message)
+                record.errors.add(attr, :too_short, :default =&gt; options[:too_short], :count =&gt; option_value.begin)
               elsif value.size &gt; option_value.end
-                message = record.errors.generate_message(attr, :too_long, :default =&gt; options[:too_long], :count =&gt; option_value.end)
-                record.errors.add(attr, message)
+                record.errors.add(attr, :too_long, :default =&gt; options[:too_long], :count =&gt; option_value.end)
               end
             end
           when :is, :minimum, :maximum
@@ -563,8 +586,7 @@ module ActiveRecord
               unless !value.nil? and value.size.method(validity_checks[option])[option_value]
                 key = message_options[option]
                 custom_message = options[:message] || options[key]
-                message = record.errors.generate_message(attr, key, :default =&gt; custom_message, :count =&gt; option_value)
-                record.errors.add(attr, message) 
+                record.errors.add(attr, key, :default =&gt; custom_message, :count =&gt; option_value) 
               end
             end
         end
@@ -597,7 +619,7 @@ module ActiveRecord
       # Configuration options:
       # * &lt;tt&gt;:message&lt;/tt&gt; - Specifies a custom error message (default is: &quot;has already been taken&quot;).
       # * &lt;tt&gt;:scope&lt;/tt&gt; - One or more columns by which to limit the scope of the uniqueness constraint.
-      # * &lt;tt&gt;:case_sensitive&lt;/tt&gt; - Looks for an exact match.  Ignored by non-text columns (+false+ by default).
+      # * &lt;tt&gt;:case_sensitive&lt;/tt&gt; - Looks for an exact match. Ignored by non-text columns (+true+ by default).
       # * &lt;tt&gt;:allow_nil&lt;/tt&gt; - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
       # * &lt;tt&gt;:allow_blank&lt;/tt&gt; - If set to true, skips this validation if the attribute is blank (default is +false+).
       # * &lt;tt&gt;:if&lt;/tt&gt; - Specifies a method, proc or string to call to determine if the validation should
@@ -643,7 +665,7 @@ module ActiveRecord
             condition_params = [value]
           else
             condition_sql = &quot;LOWER(#{sql_attribute}) #{comparison_operator}&quot;
-            condition_params = [value.downcase]
+            condition_params = [value.chars.downcase]
           end
 
           if scope = configuration[:scope]
@@ -661,8 +683,7 @@ module ActiveRecord
 
           finder_class.with_exclusive_scope do
             if finder_class.exists?([condition_sql, *condition_params])
-              message = record.errors.generate_message(attr_name, :taken, :default =&gt; configuration[:message])
-              record.errors.add(attr_name, message)
+              record.errors.add(attr_name, :taken, :default =&gt; configuration[:message], :value =&gt; value)
             end
           end
         end
@@ -700,8 +721,7 @@ module ActiveRecord
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           unless value.to_s =~ configuration[:with]
-            message = record.errors.generate_message(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value)
-            record.errors.add(attr_name, message) 
+            record.errors.add(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value) 
           end
         end
       end
@@ -731,12 +751,11 @@ module ActiveRecord
 
         enum = configuration[:in] || configuration[:within]
 
-        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(&quot;include?&quot;)
+        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(:include?)
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           unless enum.include?(value)
-            message = record.errors.generate_message(attr_name, :inclusion, :default =&gt; configuration[:message], :value =&gt; value)
-            record.errors.add(attr_name, message) 
+            record.errors.add(attr_name, :inclusion, :default =&gt; configuration[:message], :value =&gt; value) 
           end
         end
       end
@@ -766,12 +785,11 @@ module ActiveRecord
 
         enum = configuration[:in] || configuration[:within]
 
-        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(&quot;include?&quot;)
+        raise(ArgumentError, &quot;An object with the method include? is required must be supplied as the :in option of the configuration hash&quot;) unless enum.respond_to?(:include?)
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           if enum.include?(value)
-            message = record.errors.generate_message(attr_name, :exclusion, :default =&gt; configuration[:message], :value =&gt; value)
-            record.errors.add(attr_name, message) 
+            record.errors.add(attr_name, :exclusion, :default =&gt; configuration[:message], :value =&gt; value) 
           end
         end
       end
@@ -813,8 +831,7 @@ module ActiveRecord
 
         validates_each(attr_names, configuration) do |record, attr_name, value|
           unless (value.is_a?(Array) ? value : [value]).inject(true) { |v, r| (r.nil? || r.valid?) &amp;&amp; v }
-            message = record.errors.generate_message(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value)
-            record.errors.add(attr_name, message)
+            record.errors.add(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value)
           end
         end
       end
@@ -863,8 +880,7 @@ module ActiveRecord
 
           if configuration[:only_integer]
             unless raw_value.to_s =~ /\A[+-]?\d+\Z/
-              message = record.errors.generate_message(attr_name, :not_a_number, :value =&gt; raw_value, :default =&gt; configuration[:message])
-              record.errors.add(attr_name, message)
+              record.errors.add(attr_name, :not_a_number, :value =&gt; raw_value, :default =&gt; configuration[:message])
               next
             end
             raw_value = raw_value.to_i
@@ -872,8 +888,7 @@ module ActiveRecord
             begin
               raw_value = Kernel.Float(raw_value)
             rescue ArgumentError, TypeError
-              message = record.errors.generate_message(attr_name, :not_a_number, :value =&gt; raw_value, :default =&gt; configuration[:message])
-              record.errors.add(attr_name, message)
+              record.errors.add(attr_name, :not_a_number, :value =&gt; raw_value, :default =&gt; configuration[:message])
               next
             end
           end
@@ -882,12 +897,10 @@ module ActiveRecord
             case option
               when :odd, :even
                 unless raw_value.to_i.method(ALL_NUMERICALITY_CHECKS[option])[]
-                  message = record.errors.generate_message(attr_name, option, :value =&gt; raw_value, :default =&gt; configuration[:message])
-                  record.errors.add(attr_name, message) 
+                  record.errors.add(attr_name, option, :value =&gt; raw_value, :default =&gt; configuration[:message]) 
                 end
               else
-                message = record.errors.generate_message(attr_name, option, :default =&gt; configuration[:message], :value =&gt; raw_value, :count =&gt; configuration[option])
-                record.errors.add(attr_name, message) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]]
+                record.errors.add(attr_name, option, :default =&gt; configuration[:message], :value =&gt; raw_value, :count =&gt; configuration[option]) unless raw_value.method(ALL_NUMERICALITY_CHECKS[option])[configuration[option]]
             end
           end
         end</diff>
      <filename>activerecord/lib/active_record/validations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,20 @@
 require 'cases/helper'
 
+module Remembered
+  def self.included(base)
+    base.extend ClassMethods
+    base.class_eval do
+      after_create :remember
+    protected
+      def remember; self.class.remembered &lt;&lt; self; end
+    end
+  end
+
+  module ClassMethods
+    def remembered; @@remembered ||= []; end
+    def rand; @@remembered.rand; end
+  end
+end
 
 class ShapeExpression &lt; ActiveRecord::Base
   belongs_to :shape, :polymorphic =&gt; true
@@ -8,26 +23,33 @@ end
 
 class Circle &lt; ActiveRecord::Base
   has_many :shape_expressions, :as =&gt; :shape
+  include Remembered
 end
 class Square &lt; ActiveRecord::Base
   has_many :shape_expressions, :as =&gt; :shape
+  include Remembered
 end
 class Triangle &lt; ActiveRecord::Base
   has_many :shape_expressions, :as =&gt; :shape
+  include Remembered
 end
 class PaintColor  &lt; ActiveRecord::Base
   has_many   :shape_expressions, :as =&gt; :paint
   belongs_to :non_poly, :foreign_key =&gt; &quot;non_poly_one_id&quot;, :class_name =&gt; &quot;NonPolyOne&quot;
+  include Remembered
 end
 class PaintTexture &lt; ActiveRecord::Base
   has_many   :shape_expressions, :as =&gt; :paint
   belongs_to :non_poly, :foreign_key =&gt; &quot;non_poly_two_id&quot;, :class_name =&gt; &quot;NonPolyTwo&quot;
+  include Remembered
 end
 class NonPolyOne &lt; ActiveRecord::Base
   has_many :paint_colors
+  include Remembered
 end
 class NonPolyTwo &lt; ActiveRecord::Base
   has_many :paint_textures
+  include Remembered
 end
 
 
@@ -49,23 +71,19 @@ class EagerLoadPolyAssocsTest &lt; ActiveRecord::TestCase
   end
 
 
-  # meant to be supplied as an ID, never returns 0
-  def rand_simple
-    val = (NUM_SIMPLE_OBJS * rand).round
-    val == 0 ? 1 : val
-  end
-
   def generate_test_object_graphs
     1.upto(NUM_SIMPLE_OBJS) do
       [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&amp;:create!)
     end
-    1.upto(NUM_SIMPLE_OBJS) do |i|
-      PaintColor.create!(:non_poly_one_id =&gt; rand_simple)
-      PaintTexture.create!(:non_poly_two_id =&gt; rand_simple)
+    1.upto(NUM_SIMPLE_OBJS) do
+      PaintColor.create!(:non_poly_one_id =&gt; NonPolyOne.rand.id)
+      PaintTexture.create!(:non_poly_two_id =&gt; NonPolyTwo.rand.id)
     end
-    1.upto(NUM_SHAPE_EXPRESSIONS) do |i|
-      ShapeExpression.create!(:shape_type =&gt; [Circle, Square, Triangle].rand.to_s, :shape_id =&gt; rand_simple,
-                              :paint_type =&gt; [PaintColor, PaintTexture].rand.to_s, :paint_id =&gt; rand_simple)
+    1.upto(NUM_SHAPE_EXPRESSIONS) do
+      shape_type = [Circle, Square, Triangle].rand
+      paint_type = [PaintColor, PaintTexture].rand
+      ShapeExpression.create!(:shape_type =&gt; shape_type.to_s, :shape_id =&gt; shape_type.rand.id,
+                              :paint_type =&gt; paint_type.to_s, :paint_id =&gt; paint_type.rand.id)
     end
   end
 </diff>
      <filename>activerecord/test/cases/associations/eager_load_nested_include_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,12 @@ class EagerAssociationTest &lt; ActiveRecord::TestCase
     assert_equal Post.find(1).last_comment, post.last_comment
   end
 
+  def test_loading_with_one_association_with_non_preload
+    posts = Post.find(:all, :include =&gt; :last_comment, :order =&gt; 'comments.id DESC')
+    post = posts.find { |p| p.id == 1 }
+    assert_equal Post.find(1).last_comment, post.last_comment
+  end
+
   def test_loading_conditions_with_or
     posts = authors(:david).posts.find(:all, :include =&gt; :comments, :conditions =&gt; &quot;comments.body like 'Normal%' OR comments.#{QUOTED_TYPE} = 'SpecialComment'&quot;)
     assert_nil posts.detect { |p| p.author_id != authors(:david).id },
@@ -254,9 +260,9 @@ class EagerAssociationTest &lt; ActiveRecord::TestCase
   end
 
   def test_eager_with_has_many_through
-    posts_with_comments = people(:michael).posts.find(:all, :include =&gt; :comments)
-    posts_with_author = people(:michael).posts.find(:all, :include =&gt; :author )
-    posts_with_comments_and_author = people(:michael).posts.find(:all, :include =&gt; [ :comments, :author ])
+    posts_with_comments = people(:michael).posts.find(:all, :include =&gt; :comments, :order =&gt; 'posts.id')
+    posts_with_author = people(:michael).posts.find(:all, :include =&gt; :author, :order =&gt; 'posts.id')
+    posts_with_comments_and_author = people(:michael).posts.find(:all, :include =&gt; [ :comments, :author ], :order =&gt; 'posts.id')
     assert_equal 2, posts_with_comments.inject(0) { |sum, post| sum += post.comments.size }
     assert_equal authors(:david), assert_no_queries { posts_with_author.first.author }
     assert_equal authors(:david), assert_no_queries { posts_with_comments_and_author.first.author }
@@ -559,6 +565,13 @@ class EagerAssociationTest &lt; ActiveRecord::TestCase
     assert_nothing_raised { Post.find(:all, :include =&gt; 'comments') }
   end
 
+  def test_eager_with_floating_point_numbers
+    assert_queries(2) do
+      # Before changes, the floating point numbers will be interpreted as table names and will cause this to run in one query
+      Comment.find :all, :conditions =&gt; &quot;123.456 = 123.456&quot;, :include =&gt; :post
+    end
+  end
+
   def test_preconfigured_includes_with_belongs_to
     author = posts(:welcome).author_with_posts
     assert_no_queries {assert_equal 5, author.posts.size}</diff>
      <filename>activerecord/test/cases/associations/eager_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -223,10 +223,10 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     devel = Developer.find(1)
     proj = assert_no_queries { devel.projects.build(&quot;name&quot; =&gt; &quot;Projekt&quot;) }
     assert !devel.projects.loaded?
-    
+
     assert_equal devel.projects.last, proj
     assert devel.projects.loaded?
-    
+
     assert proj.new_record?
     devel.save
     assert !proj.new_record?
@@ -251,10 +251,10 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     devel = Developer.find(1)
     proj = devel.projects.create(&quot;name&quot; =&gt; &quot;Projekt&quot;)
     assert !devel.projects.loaded?
-    
+
     assert_equal devel.projects.last, proj
     assert devel.projects.loaded?
-    
+
     assert !proj.new_record?
     assert_equal Developer.find(1).projects.sort_by(&amp;:id).last, proj  # prove join table is updated
   end
@@ -274,10 +274,10 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
 
   def test_creation_respects_hash_condition
     post = categories(:general).post_with_conditions.build(:body =&gt; '')
-    
+
     assert        post.save
     assert_equal  'Yet Another Testing Title', post.title
-    
+
     another_post = categories(:general).post_with_conditions.create(:body =&gt; '')
 
     assert        !another_post.new_record?
@@ -288,7 +288,7 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     dev = developers(:jamis)
     dev.projects &lt;&lt; projects(:active_record)
     dev.projects &lt;&lt; projects(:active_record)
-    
+
     assert_equal 3, dev.projects.size
     assert_equal 1, dev.projects.uniq.size
   end
@@ -415,13 +415,13 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     project.developers.class # force load target
 
     developer = project.developers.first
-    
+
     assert_no_queries do
       assert project.developers.loaded?
       assert project.developers.include?(developer)
     end
   end
-  
+
   def test_include_checks_if_record_exists_if_target_not_loaded
     project = projects(:active_record)
     developer = project.developers.first
@@ -452,7 +452,7 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
 
   def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
     # interpolate once:
-    assert_equal [developers(:david), developers(:poor_jamis), developers(:jamis)], projects(:active_record).developers_with_finder_sql, &quot;first interpolation&quot;
+    assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, &quot;first interpolation&quot;
     # interpolate again, for a different project id
     assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, &quot;second interpolation&quot;
   end
@@ -641,14 +641,29 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     assert_equal [projects(:active_record).id], developers(:jamis).project_ids
   end
 
+  def test_get_ids_for_loaded_associations
+    developer = developers(:david)
+    developer.projects(true)
+    assert_queries(0) do
+      developer.project_ids
+      developer.project_ids
+    end
+  end
+
+  def test_get_ids_for_unloaded_associations_does_not_load_them
+    developer = developers(:david)
+    assert !developer.projects.loaded?
+    assert_equal projects(:active_record, :action_controller).map(&amp;:id).sort, developer.project_ids.sort
+    assert !developer.projects.loaded?
+  end
+
   def test_assign_ids
     developer = Developer.new(&quot;name&quot; =&gt; &quot;Joe&quot;)
     developer.project_ids = projects(:active_record, :action_controller).map(&amp;:id)
     developer.save
     developer.reload
     assert_equal 2, developer.projects.length
-    assert_equal projects(:active_record), developer.projects[0]
-    assert_equal projects(:action_controller), developer.projects[1]
+    assert_equal [projects(:active_record), projects(:action_controller)].map(&amp;:id).sort, developer.project_ids.sort
   end
 
   def test_assign_ids_ignoring_blanks
@@ -657,8 +672,7 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     developer.save
     developer.reload
     assert_equal 2, developer.projects.length
-    assert_equal projects(:active_record), developer.projects[0]
-    assert_equal projects(:action_controller), developer.projects[1]
+    assert_equal [projects(:active_record), projects(:action_controller)].map(&amp;:id).sort, developer.project_ids.sort
   end
 
   def test_select_limited_ids_list
@@ -705,4 +719,11 @@ class HasAndBelongsToManyAssociationsTest &lt; ActiveRecord::TestCase
     # due to Unknown column 'authors.id'
     assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
   end
+
+  def test_counting_on_habtm_association_and_not_array
+    david = Developer.find(1)
+    # Extra parameter just to make sure we aren't falling back to
+    # Array#count in Ruby &gt;=1.8.7, which would raise an ArgumentError
+    assert_nothing_raised { david.projects.count(:all, :conditions =&gt; '1=1') }
+  end
 end</diff>
      <filename>activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -48,6 +48,12 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
     assert_equal 2, Firm.find(:first).plain_clients.count(:name)
   end
 
+  def test_counting_with_association_limit
+    firm = companies(:first_firm)
+    assert_equal firm.limited_clients.length, firm.limited_clients.size
+    assert_equal firm.limited_clients.length, firm.limited_clients.count
+  end
+
   def test_finding
     assert_equal 2, Firm.find(:first).clients.length
   end
@@ -378,7 +384,7 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
     company = companies(:first_firm)
     new_client = assert_no_queries { company.clients_of_firm.build(&quot;name&quot; =&gt; &quot;Another Client&quot;) }
     assert !company.clients_of_firm.loaded?
-    
+
     assert_equal &quot;Another Client&quot;, new_client.name
     assert new_client.new_record?
     assert_equal new_client, company.clients_of_firm.last
@@ -395,10 +401,22 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
     assert_equal 3, company.clients_of_firm.size
   end
 
+  def test_collection_size_twice_for_regressions
+    post = posts(:thinking)
+    assert_equal 0, post.readers.size
+    # This test needs a post that has no readers, we assert it to ensure it holds,
+    # but need to reload the post because the very call to #size hides the bug.
+    post.reload
+    post.readers.build
+    size1 = post.readers.size
+    size2 = post.readers.size
+    assert_equal size1, size2
+  end
+
   def test_build_many
     company = companies(:first_firm)
     new_clients = assert_no_queries { company.clients_of_firm.build([{&quot;name&quot; =&gt; &quot;Another Client&quot;}, {&quot;name&quot; =&gt; &quot;Another Client II&quot;}]) }
-    
+
     assert_equal 2, new_clients.size
     company.name += '-changed'
     assert_queries(3) { assert company.save }
@@ -637,10 +655,10 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
 
   def test_creation_respects_hash_condition
     ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.build
-    
+
     assert        ms_client.save
     assert_equal  'Microsoft', ms_client.name
-    
+
     another_ms_client = companies(:first_firm).clients_like_ms_with_hash_conditions.create
 
     assert        !another_ms_client.new_record?
@@ -812,6 +830,22 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
     assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
   end
 
+  def test_get_ids_for_loaded_associations
+    company = companies(:first_firm)
+    company.clients(true)
+    assert_queries(0) do
+      company.client_ids
+      company.client_ids
+    end
+  end
+
+  def test_get_ids_for_unloaded_associations_does_not_load_them
+    company = companies(:first_firm)
+    assert !company.clients.loaded?
+    assert_equal [companies(:first_client).id, companies(:second_client).id], company.client_ids
+    assert !company.clients.loaded?
+  end
+
   def test_assign_ids
     firm = Firm.new(&quot;name&quot; =&gt; &quot;Apple&quot;)
     firm.client_ids = [companies(:first_client).id, companies(:second_client).id]
@@ -882,7 +916,7 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
     assert_equal 4, authors(:david).limited_comments.find(:all, :conditions =&gt; &quot;comments.type = 'SpecialComment'&quot;, :limit =&gt; 9_000).length
     assert_equal 4, authors(:david).limited_comments.find_all_by_type('SpecialComment', :limit =&gt; 9_000).length
   end
-  
+
   def test_find_all_include_over_the_same_table_for_through
     assert_equal 2, people(:michael).posts.find(:all, :include =&gt; :people).length
   end
@@ -919,13 +953,13 @@ class HasManyAssociationsTest &lt; ActiveRecord::TestCase
   def test_include_loads_collection_if_target_uses_finder_sql
     firm = companies(:first_firm)
     client = firm.clients_using_sql.first
-    
+
     firm.reload
     assert ! firm.clients_using_sql.loaded?
     assert firm.clients_using_sql.include?(client)
     assert firm.clients_using_sql.loaded?
   end
-  
+
 
   def test_include_returns_false_for_non_matching_record_to_verify_scoping
     firm = companies(:first_firm)</diff>
      <filename>activerecord/test/cases/associations/has_many_associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -196,4 +196,28 @@ class HasManyThroughAssociationsTest &lt; ActiveRecord::TestCase
     # due to Unknown column 'comments.id'
     assert Person.find(1).posts_with_comments_sorted_by_comment_id.find_by_title('Welcome to the weblog')
   end
+
+  def test_count_with_include_should_alias_join_table
+    assert_equal 2, people(:michael).posts.count(:include =&gt; :readers)
+  end
+
+  def test_get_ids
+    assert_equal [posts(:welcome).id, posts(:authorless).id].sort, people(:michael).post_ids.sort
+  end
+
+  def test_get_ids_for_loaded_associations
+    person = people(:michael)
+    person.posts(true)
+    assert_queries(0) do
+      person.post_ids
+      person.post_ids
+    end
+  end
+
+  def test_get_ids_for_unloaded_associations_does_not_load_them
+    person = people(:michael)
+    assert !person.posts.loaded?
+    assert_equal [posts(:welcome).id, posts(:authorless).id].sort, person.post_ids.sort
+    assert !person.posts.loaded?
+  end
 end</diff>
      <filename>activerecord/test/cases/associations/has_many_through_associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -79,6 +79,16 @@ class HasOneAssociationsTest &lt; ActiveRecord::TestCase
     assert_raises(ActiveRecord::RecordNotFound) { Account.find(old_account_id) }
   end
 
+  def test_natural_assignment_to_already_associated_record
+    company = companies(:first_firm)
+    account = accounts(:signals37)
+    assert_equal company.account, account
+    company.account = account
+    company.reload
+    account.reload
+    assert_equal company.account, account
+  end
+
   def test_assignment_without_replacement
     apple = Firm.create(&quot;name&quot; =&gt; &quot;Apple&quot;)
     citibank = Account.create(&quot;credit_limit&quot; =&gt; 10)</diff>
      <filename>activerecord/test/cases/associations/has_one_associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -44,19 +44,23 @@ class HasOneThroughAssociationsTest &lt; ActiveRecord::TestCase
   def test_has_one_through_polymorphic
     assert_equal clubs(:moustache_club), @member.sponsor_club
   end
-  
+
   def has_one_through_to_has_many
     assert_equal 2, @member.fellow_members.size
   end
-  
+
   def test_has_one_through_eager_loading
-    members = Member.find(:all, :include =&gt; :club, :conditions =&gt; [&quot;name = ?&quot;, &quot;Groucho Marx&quot;])
+    members = assert_queries(3) do #base table, through table, clubs table
+      Member.find(:all, :include =&gt; :club, :conditions =&gt; [&quot;name = ?&quot;, &quot;Groucho Marx&quot;])
+    end
     assert_equal 1, members.size
     assert_not_nil assert_no_queries {members[0].club}
   end
-  
+
   def test_has_one_through_eager_loading_through_polymorphic
-    members = Member.find(:all, :include =&gt; :sponsor_club, :conditions =&gt; [&quot;name = ?&quot;, &quot;Groucho Marx&quot;])
+    members = assert_queries(3) do #base table, through table, clubs table
+      Member.find(:all, :include =&gt; :sponsor_club, :conditions =&gt; [&quot;name = ?&quot;, &quot;Groucho Marx&quot;])
+    end
     assert_equal 1, members.size
     assert_not_nil assert_no_queries {members[0].sponsor_club}    
   end
@@ -71,4 +75,39 @@ class HasOneThroughAssociationsTest &lt; ActiveRecord::TestCase
     assert_not_nil assert_no_queries {clubs[0].sponsored_member}
   end
 
+  def test_has_one_through_nonpreload_eagerloading
+    members = assert_queries(1) do
+      Member.find(:all, :include =&gt; :club, :conditions =&gt; [&quot;members.name = ?&quot;, &quot;Groucho Marx&quot;], :order =&gt; 'clubs.name') #force fallback
+    end
+    assert_equal 1, members.size
+    assert_not_nil assert_no_queries {members[0].club}
+  end
+
+  def test_has_one_through_nonpreload_eager_loading_through_polymorphic
+    members = assert_queries(1) do
+      Member.find(:all, :include =&gt; :sponsor_club, :conditions =&gt; [&quot;members.name = ?&quot;, &quot;Groucho Marx&quot;], :order =&gt; 'clubs.name') #force fallback
+    end
+    assert_equal 1, members.size
+    assert_not_nil assert_no_queries {members[0].sponsor_club}
+  end
+
+  def test_has_one_through_nonpreload_eager_loading_through_polymorphic_with_more_than_one_through_record
+    Sponsor.new(:sponsor_club =&gt; clubs(:crazy_club), :sponsorable =&gt; members(:groucho)).save!
+    members = assert_queries(1) do
+      Member.find(:all, :include =&gt; :sponsor_club, :conditions =&gt; [&quot;members.name = ?&quot;, &quot;Groucho Marx&quot;], :order =&gt; 'clubs.name DESC') #force fallback
+    end
+    assert_equal 1, members.size
+    assert_not_nil assert_no_queries { members[0].sponsor_club }
+    assert_equal clubs(:crazy_club), members[0].sponsor_club
+  end
+
+  def test_uninitialized_has_one_through_should_return_nil_for_unsaved_record
+    assert_nil Member.new.club
+  end
+
+  def test_assigning_association_correctly_assigns_target
+    new_member = Member.create(:name =&gt; &quot;Chris&quot;)
+    new_member.club = new_club = Club.create(:name =&gt; &quot;LRUG&quot;)
+    assert_equal new_club, new_member.club.target
+  end
 end</diff>
      <filename>activerecord/test/cases/associations/has_one_through_associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ require 'models/sponsor'
 
 class AssociationsTest &lt; ActiveRecord::TestCase
   fixtures :accounts, :companies, :developers, :projects, :developers_projects,
-           :computers
+           :computers, :people, :readers
 
   def test_include_with_order_works
     assert_nothing_raised {Account.find(:first, :order =&gt; 'id', :include =&gt; :firm)}
@@ -45,7 +45,7 @@ class AssociationsTest &lt; ActiveRecord::TestCase
     assert_equal [], person.readers.find(:all)
     person.save!
     reader = Reader.create! :person =&gt; person, :post =&gt; Post.new(:title =&gt; &quot;foo&quot;, :body =&gt; &quot;bar&quot;)
-    assert_equal [reader], person.readers.find(:all)
+    assert person.readers.find(reader.id)
   end
 
   def test_force_reload</diff>
      <filename>activerecord/test/cases/associations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -138,7 +138,7 @@ class BasicsTest &lt; ActiveRecord::TestCase
   if current_adapter?(:MysqlAdapter)
     def test_read_attributes_before_type_cast_on_boolean
       bool = Booleantest.create({ &quot;value&quot; =&gt; false })
-      assert_equal 0, bool.attributes_before_type_cast[&quot;value&quot;]
+      assert_equal &quot;0&quot;, bool.reload.attributes_before_type_cast[&quot;value&quot;]
     end
   end
 
@@ -616,7 +616,7 @@ class BasicsTest &lt; ActiveRecord::TestCase
   end
 
   def test_update_counter
-    category = Category.first
+    category = categories(:general)
     assert_nil category.categorizations_count
     assert_equal 2, category.categorizations.count
 
@@ -880,7 +880,7 @@ class BasicsTest &lt; ActiveRecord::TestCase
 
   def test_mass_assignment_protection_against_class_attribute_writers
     [:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :colorize_logging,
-      :default_timezone, :allow_concurrency, :schema_format, :verification_timeout, :lock_optimistically, :record_timestamps].each do |method|
+      :default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method|
       assert  Task.respond_to?(method)
       assert  Task.respond_to?(&quot;#{method}=&quot;)
       assert  Task.new.respond_to?(method)
@@ -1114,11 +1114,15 @@ class BasicsTest &lt; ActiveRecord::TestCase
   end
 
   def test_boolean
+    b_nil = Booleantest.create({ &quot;value&quot; =&gt; nil })
+    nil_id = b_nil.id
     b_false = Booleantest.create({ &quot;value&quot; =&gt; false })
     false_id = b_false.id
     b_true = Booleantest.create({ &quot;value&quot; =&gt; true })
     true_id = b_true.id
 
+    b_nil = Booleantest.find(nil_id)
+    assert_nil b_nil.value
     b_false = Booleantest.find(false_id)
     assert !b_false.value?
     b_true = Booleantest.find(true_id)
@@ -1126,11 +1130,15 @@ class BasicsTest &lt; ActiveRecord::TestCase
   end
 
   def test_boolean_cast_from_string
+    b_blank = Booleantest.create({ &quot;value&quot; =&gt; &quot;&quot; })
+    blank_id = b_blank.id
     b_false = Booleantest.create({ &quot;value&quot; =&gt; &quot;0&quot; })
     false_id = b_false.id
     b_true = Booleantest.create({ &quot;value&quot; =&gt; &quot;1&quot; })
     true_id = b_true.id
 
+    b_blank = Booleantest.find(blank_id)
+    assert_nil b_blank.value
     b_false = Booleantest.find(false_id)
     assert !b_false.value?
     b_true = Booleantest.find(true_id)</diff>
      <filename>activerecord/test/cases/base_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,13 +9,13 @@ class ColumnDefinitionTest &lt; ActiveRecord::TestCase
   end
 
   # Avoid column definitions in create table statements like:
-  # `title` varchar(255) DEFAULT NULL NULL
+  # `title` varchar(255) DEFAULT NULL
   def test_should_not_include_default_clause_when_default_is_null
     column = ActiveRecord::ConnectionAdapters::Column.new(&quot;title&quot;, nil, &quot;varchar(20)&quot;)
     column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
       @adapter, column.name, &quot;string&quot;,
       column.limit, column.precision, column.scale, column.default, column.null)
-    assert_equal &quot;title varchar(20) NULL&quot;, column_def.to_sql
+    assert_equal &quot;title varchar(20)&quot;, column_def.to_sql
   end
 
   def test_should_include_default_clause_when_default_is_present
@@ -23,7 +23,7 @@ class ColumnDefinitionTest &lt; ActiveRecord::TestCase
     column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
       @adapter, column.name, &quot;string&quot;,
       column.limit, column.precision, column.scale, column.default, column.null)
-    assert_equal %Q{title varchar(20) DEFAULT 'Hello' NULL}, column_def.to_sql
+    assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, column_def.to_sql
   end
 
   def test_should_specify_not_null_if_null_option_is_false
@@ -33,4 +33,4 @@ class ColumnDefinitionTest &lt; ActiveRecord::TestCase
       column.limit, column.precision, column.scale, column.default, column.null)
     assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, column_def.to_sql
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activerecord/test/cases/column_definition_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -24,7 +24,7 @@ class MysqlConnectionTest &lt; ActiveRecord::TestCase
     assert @connection.active?
     @connection.update('set @@wait_timeout=1')
     sleep 2
-    @connection.verify!(0)
+    @connection.verify!
     assert @connection.active?
   end
 end</diff>
      <filename>activerecord/test/cases/connection_test_mysql.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ require 'models/entrant'
 class DefaultTest &lt; ActiveRecord::TestCase
   def test_nil_defaults_for_not_null_columns
     column_defaults =
-      if current_adapter?(:MysqlAdapter) &amp;&amp; Mysql.client_version &lt; 50051
+      if current_adapter?(:MysqlAdapter) &amp;&amp; (Mysql.client_version &lt; 50051 || (50100..50122).include?(Mysql.client_version))
         { 'id' =&gt; nil, 'name' =&gt; '',  'course_id' =&gt; nil }
       else
         { 'id' =&gt; nil, 'name' =&gt; nil, 'course_id' =&gt; nil }</diff>
      <filename>activerecord/test/cases/defaults_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -191,6 +191,42 @@ class DirtyTest &lt; ActiveRecord::TestCase
     assert !pirate.changed?
   end
 
+  def test_reverted_changes_are_not_dirty
+    phrase = &quot;shiver me timbers&quot;
+    pirate = Pirate.create!(:catchphrase =&gt; phrase)
+    pirate.catchphrase = &quot;*hic*&quot;
+    assert pirate.changed?
+    pirate.catchphrase = phrase
+    assert !pirate.changed?
+  end
+
+  def test_reverted_changes_are_not_dirty_after_multiple_changes
+    phrase = &quot;shiver me timbers&quot;
+    pirate = Pirate.create!(:catchphrase =&gt; phrase)
+    10.times do |i|
+      pirate.catchphrase = &quot;*hic*&quot; * i
+      assert pirate.changed?
+    end
+    assert pirate.changed?
+    pirate.catchphrase = phrase
+    assert !pirate.changed?
+  end
+
+
+  def test_reverted_changes_are_not_dirty_going_from_nil_to_value_and_back
+    pirate = Pirate.create!(:catchphrase =&gt; &quot;Yar!&quot;)
+
+    pirate.parrot_id = 1
+    assert pirate.changed?
+    assert pirate.parrot_id_changed?
+    assert !pirate.catchphrase_changed?
+
+    pirate.parrot_id = nil
+    assert !pirate.changed?
+    assert !pirate.parrot_id_changed?
+    assert !pirate.catchphrase_changed?
+  end
+
   def test_save_should_store_serialized_attributes_even_with_partial_updates
     with_partial_updates(Topic) do
       topic = Topic.create!(:content =&gt; {:a =&gt; &quot;a&quot;})</diff>
      <filename>activerecord/test/cases/dirty_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,6 +12,57 @@ require 'models/customer'
 require 'models/job'
 require 'models/categorization'
 
+class DynamicFinderMatchTest &lt; ActiveRecord::TestCase
+  def test_find_no_match
+    assert_nil ActiveRecord::DynamicFinderMatch.match(&quot;not_a_finder&quot;)
+  end
+
+  def test_find_by
+    match = ActiveRecord::DynamicFinderMatch.match(&quot;find_by_age_and_sex_and_location&quot;)
+    assert_not_nil match
+    assert match.finder?
+    assert_equal :find_initial, match.finder
+    assert_equal %w(age sex location), match.attribute_names
+  end
+
+  def find_by_bang
+    match = ActiveRecord::DynamicFinderMatch.match(&quot;find_by_age_and_sex_and_location!&quot;)
+    assert_not_nil match
+    assert match.finder?
+    assert match.bang?
+    assert_equal :find_initial, match.finder
+    assert_equal %w(age sex location), match.attribute_names
+  end
+
+  def test_find_all_by
+    match = ActiveRecord::DynamicFinderMatch.match(&quot;find_all_by_age_and_sex_and_location&quot;)
+    assert_not_nil match
+    assert match.finder?
+    assert_equal :find_every, match.finder
+    assert_equal %w(age sex location), match.attribute_names
+  end
+
+  def test_find_or_initialize_by
+    match = ActiveRecord::DynamicFinderMatch.match(&quot;find_or_initialize_by_age_and_sex_and_location&quot;)
+    assert_not_nil match
+    assert !match.finder?
+    assert match.instantiator?
+    assert_equal :find_initial, match.finder
+    assert_equal :new, match.instantiator
+    assert_equal %w(age sex location), match.attribute_names
+  end
+
+  def test_find_or_create_by
+    match = ActiveRecord::DynamicFinderMatch.match(&quot;find_or_create_by_age_and_sex_and_location&quot;)
+    assert_not_nil match
+    assert !match.finder?
+    assert match.instantiator?
+    assert_equal :find_initial, match.finder
+    assert_equal :create, match.instantiator
+    assert_equal %w(age sex location), match.attribute_names
+  end
+end
+
 class FinderTest &lt; ActiveRecord::TestCase
   fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers
 
@@ -440,6 +491,11 @@ class FinderTest &lt; ActiveRecord::TestCase
     assert_nil Topic.find_by_title(&quot;The First Topic!&quot;)
   end
 
+  def test_find_by_one_attribute_bang
+    assert_equal topics(:first), Topic.find_by_title!(&quot;The First Topic&quot;)
+    assert_raises(ActiveRecord::RecordNotFound) { Topic.find_by_title!(&quot;The First Topic!&quot;) }
+  end
+
   def test_find_by_one_attribute_caches_dynamic_finder
     # ensure this test can run independently of order
     class &lt;&lt; Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }</diff>
      <filename>activerecord/test/cases/finder_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 $:.unshift(File.dirname(__FILE__) + '/../../lib')
+$:.unshift(File.dirname(__FILE__) + '/../../../activesupport/lib')
 
 require 'config'
 require 'test/unit'</diff>
      <filename>activerecord/test/cases/helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -210,13 +210,6 @@ unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :OpenBaseAdapter)
     def setup
       # Avoid introspection queries during tests.
       Person.columns; Reader.columns
-
-      @allow_concurrency = ActiveRecord::Base.allow_concurrency
-      ActiveRecord::Base.allow_concurrency = true
-    end
-
-    def teardown
-      ActiveRecord::Base.allow_concurrency = @allow_concurrency
     end
 
     # Test typical find.
@@ -264,6 +257,8 @@ unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :OpenBaseAdapter)
     end
 
     if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)
+      use_concurrent_connections
+
       def test_no_locks_no_wait
         first, second = duel { Person.find 1 }
         assert first.end &gt; second.end</diff>
      <filename>activerecord/test/cases/locking_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 require &quot;cases/helper&quot;
+require 'models/author'
 require 'models/developer'
 require 'models/project'
 require 'models/comment'
@@ -6,7 +7,7 @@ require 'models/post'
 require 'models/category'
 
 class MethodScopingTest &lt; ActiveRecord::TestCase
-  fixtures :developers, :projects, :comments, :posts, :developers_projects
+  fixtures :authors, :developers, :projects, :comments, :posts, :developers_projects
 
   def test_set_conditions
     Developer.with_scope(:find =&gt; { :conditions =&gt; 'just a test...' }) do
@@ -97,6 +98,46 @@ class MethodScopingTest &lt; ActiveRecord::TestCase
     assert_equal developers(:david).attributes, scoped_developers.first.attributes
   end
 
+  def test_scoped_find_using_new_style_joins
+    scoped_developers = Developer.with_scope(:find =&gt; { :joins =&gt; :projects }) do
+      Developer.find(:all, :conditions =&gt; 'projects.id = 2')
+    end
+    assert scoped_developers.include?(developers(:david))
+    assert !scoped_developers.include?(developers(:jamis))
+    assert_equal 1, scoped_developers.size
+    assert_equal developers(:david).attributes, scoped_developers.first.attributes
+  end
+
+  def test_scoped_find_merges_old_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; 'INNER JOIN posts ON authors.id = posts.author_id ' }) do
+      Author.find(:all, :select =&gt; 'DISTINCT authors.*', :joins =&gt; 'INNER JOIN comments ON posts.id = comments.post_id', :conditions =&gt; 'comments.id = 1')
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
+
+  def test_scoped_find_merges_new_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; :posts }) do
+      Author.find(:all, :select =&gt; 'DISTINCT authors.*', :joins =&gt; :comments, :conditions =&gt; 'comments.id = 1')
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
+
+  def test_scoped_find_merges_new_and_old_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; :posts }) do
+      Author.find(:all, :select =&gt; 'DISTINCT authors.*', :joins =&gt; 'JOIN comments ON posts.id = comments.post_id', :conditions =&gt; 'comments.id = 1')
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
+
   def test_scoped_count_include
     # with the include, will retrieve only developers for the given project
     Developer.with_scope(:find =&gt; { :include =&gt; :projects }) do
@@ -152,7 +193,7 @@ class MethodScopingTest &lt; ActiveRecord::TestCase
 end
 
 class NestedScopingTest &lt; ActiveRecord::TestCase
-  fixtures :developers, :projects, :comments, :posts
+  fixtures :authors, :developers, :projects, :comments, :posts
 
   def test_merge_options
     Developer.with_scope(:find =&gt; { :conditions =&gt; 'salary = 80000' }) do
@@ -357,6 +398,42 @@ class NestedScopingTest &lt; ActiveRecord::TestCase
       assert_equal scoped_methods, Developer.instance_eval('current_scoped_methods')
     end
   end
+
+  def test_nested_scoped_find_merges_old_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; 'INNER JOIN posts ON authors.id = posts.author_id' }) do
+      Author.with_scope(:find =&gt; { :joins =&gt; 'INNER JOIN comments ON posts.id = comments.post_id' }) do
+        Author.find(:all, :select =&gt; 'DISTINCT authors.*', :conditions =&gt; 'comments.id = 1')
+      end
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
+
+  def test_nested_scoped_find_merges_new_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; :posts }) do
+      Author.with_scope(:find =&gt; { :joins =&gt; :comments }) do
+        Author.find(:all, :select =&gt; 'DISTINCT authors.*', :conditions =&gt; 'comments.id = 1')
+      end
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
+
+  def test_nested_scoped_find_merges_new_and_old_style_joins
+    scoped_authors = Author.with_scope(:find =&gt; { :joins =&gt; :posts }) do
+      Author.with_scope(:find =&gt; { :joins =&gt; 'INNER JOIN comments ON posts.id = comments.post_id' }) do
+        Author.find(:all, :select =&gt; 'DISTINCT authors.*', :joins =&gt; '', :conditions =&gt; 'comments.id = 1')
+      end
+    end
+    assert scoped_authors.include?(authors(:david))
+    assert !scoped_authors.include?(authors(:mary))
+    assert_equal 1, scoped_authors.size
+    assert_equal authors(:david).attributes, scoped_authors.first.attributes
+  end
 end
 
 class HasManyScopingTest&lt; ActiveRecord::TestCase</diff>
      <filename>activerecord/test/cases/method_scoping_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -237,6 +237,39 @@ if ActiveRecord::Base.connection.supports_migrations?
       end
     end
 
+    def test_create_table_with_timestamps_should_create_datetime_columns
+      table_name = :testings
+
+      Person.connection.create_table table_name do |t|
+        t.timestamps
+      end
+      created_columns = Person.connection.columns(table_name)
+
+      created_at_column = created_columns.detect {|c| c.name == 'created_at' }
+      updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
+
+      assert created_at_column.null
+      assert updated_at_column.null
+    ensure
+      Person.connection.drop_table table_name rescue nil
+    end
+
+    def test_create_table_with_timestamps_should_create_datetime_columns_with_options
+      table_name = :testings
+
+      Person.connection.create_table table_name do |t|
+        t.timestamps :null =&gt; false
+      end
+      created_columns = Person.connection.columns(table_name)
+
+      created_at_column = created_columns.detect {|c| c.name == 'created_at' }
+      updated_at_column = created_columns.detect {|c| c.name == 'updated_at' }
+
+      assert !created_at_column.null
+      assert !updated_at_column.null
+    ensure
+      Person.connection.drop_table table_name rescue nil
+    end
 
     # SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL
     # column to a table without a default value.
@@ -409,10 +442,7 @@ if ActiveRecord::Base.connection.supports_migrations?
 
         ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint
         Person.reset_column_information
-        Person.create :intelligence_quotient =&gt; 300
-        jonnyg = Person.find(:first)
-        assert_equal 127, jonnyg.intelligence_quotient
-        jonnyg.destroy
+        assert_match /tinyint/, Person.columns_hash['intelligence_quotient'].sql_type
       ensure
         ActiveRecord::Migration.remove_column :people, :intelligence_quotient rescue nil
       end
@@ -904,6 +934,21 @@ if ActiveRecord::Base.connection.supports_migrations?
       assert_equal(0, ActiveRecord::Migrator.current_version)
     end
 
+    if current_adapter?(:PostgreSQLAdapter)
+      def test_migrator_one_up_with_exception_and_rollback
+        assert !Person.column_methods_hash.include?(:last_name)
+
+        e = assert_raises(StandardError) do
+          ActiveRecord::Migrator.up(MIGRATIONS_ROOT + &quot;/broken&quot;, 100)
+        end
+
+        assert_equal &quot;An error has occurred, this and all later migrations canceled:\n\nSomething broke&quot;, e.message
+
+        Person.reset_column_information
+        assert !Person.column_methods_hash.include?(:last_name)
+      end
+    end
+
     def test_finds_migrations
       migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + &quot;/valid&quot;).migrations
       [['1', 'people_have_last_names'],
@@ -1192,8 +1237,8 @@ if ActiveRecord::Base.connection.supports_migrations?
 
       def test_timestamps_creates_updated_at_and_created_at
         with_new_table do |t|
-          t.expects(:column).with(:created_at, :datetime)
-          t.expects(:column).with(:updated_at, :datetime)
+          t.expects(:column).with(:created_at, :datetime, kind_of(Hash))
+          t.expects(:column).with(:updated_at, :datetime, kind_of(Hash))
           t.timestamps
         end
       end</diff>
      <filename>activerecord/test/cases/migration_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,7 @@ require 'models/topic'
 require 'models/comment'
 require 'models/reply'
 require 'models/author'
+require 'models/developer'
 
 class NamedScopeTest &lt; ActiveRecord::TestCase
   fixtures :posts, :authors, :topics, :comments, :author_addresses
@@ -51,6 +52,11 @@ class NamedScopeTest &lt; ActiveRecord::TestCase
     assert Topic.approved.respond_to?(:length)
   end
 
+  def test_respond_to_respects_include_private_parameter
+    assert !Topic.approved.respond_to?(:load_found)
+    assert Topic.approved.respond_to?(:load_found, true)
+  end
+
   def test_subclasses_inherit_scopes
     assert Topic.scopes.include?(:base)
 
@@ -238,4 +244,31 @@ class NamedScopeTest &lt; ActiveRecord::TestCase
     assert topic.approved
     assert_equal 'lifo', topic.author_name
   end
+
+  def test_find_all_should_behave_like_select
+    assert_equal Topic.base.select(&amp;:approved), Topic.base.find_all(&amp;:approved)
+  end
+
+  def test_rand_should_select_a_random_object_from_proxy
+    assert Topic.approved.rand.is_a?(Topic)
+  end
+
+  def test_should_use_where_in_query_for_named_scope
+    assert_equal Developer.find_all_by_name('Jamis'), Developer.find_all_by_id(Developer.jamises)
+  end
+
+  def test_size_should_use_count_when_results_are_not_loaded
+    topics = Topic.base
+    assert_queries(1) do
+      assert_sql(/COUNT/i) { topics.size }
+    end
+  end
+
+  def test_size_should_use_length_when_results_are_loaded
+    topics = Topic.base
+    topics.reload # force load
+    assert_no_queries do
+      topics.size # use loaded (no query)
+    end
+  end
 end</diff>
      <filename>activerecord/test/cases/named_scope_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -116,8 +116,9 @@ class QueryCacheExpiryTest &lt; ActiveRecord::TestCase
   def test_cache_is_expired_by_habtm_delete
     ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
     ActiveRecord::Base.cache do
-      c = Category.find(:first)
-      p = Post.find(:first)
+      c = Category.find(1)
+      p = Post.find(1)
+      assert p.categories.any?
       p.categories.delete_all
     end
   end</diff>
      <filename>activerecord/test/cases/query_cache_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,8 +18,8 @@ class SchemaAuthorizationTest &lt; ActiveRecord::TestCase
     @connection.execute &quot;SET search_path TO '$user',public&quot;
     set_session_auth
     USERS.each do |u|
-      @connection.execute &quot;CREATE USER #{u}&quot;
-      @connection.execute &quot;CREATE SCHEMA AUTHORIZATION #{u}&quot;
+      @connection.execute &quot;CREATE USER #{u}&quot; rescue nil
+      @connection.execute &quot;CREATE SCHEMA AUTHORIZATION #{u}&quot; rescue nil
       set_session_auth u
       @connection.execute &quot;CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})&quot;
       @connection.execute &quot;INSERT INTO #{TABLE_NAME} (name) VALUES ('#{u}')&quot;</diff>
      <filename>activerecord/test/cases/schema_authorization_test_postgresql.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,7 @@ require &quot;cases/helper&quot;
 require 'models/topic'
 require 'models/reply'
 require 'models/developer'
+require 'models/book'
 
 class TransactionTest &lt; ActiveRecord::TestCase
   self.use_transactional_fixtures = false
@@ -86,8 +87,7 @@ class TransactionTest &lt; ActiveRecord::TestCase
     assert Topic.find(2).approved?, &quot;Second should still be approved&quot;
   end
 
-
-  def test_callback_rollback_in_save
+  def test_raising_exception_in_callback_rollbacks_in_save
     add_exception_raising_after_save_callback_to_topic
 
     begin
@@ -102,6 +102,54 @@ class TransactionTest &lt; ActiveRecord::TestCase
     end
   end
 
+  def test_cancellation_from_before_destroy_rollbacks_in_destroy
+    add_cancelling_before_destroy_with_db_side_effect_to_topic
+    begin
+      nbooks_before_destroy = Book.count
+      status = @first.destroy
+      assert !status
+      assert_nothing_raised(ActiveRecord::RecordNotFound) { @first.reload }
+      assert_equal nbooks_before_destroy, Book.count
+    ensure
+      remove_cancelling_before_destroy_with_db_side_effect_to_topic
+    end
+  end
+
+  def test_cancellation_from_before_filters_rollbacks_in_save
+    %w(validation save).each do |filter|
+      send(&quot;add_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;)
+      begin
+        nbooks_before_save = Book.count
+        original_author_name = @first.author_name
+        @first.author_name += '_this_should_not_end_up_in_the_db'
+        status = @first.save
+        assert !status
+        assert_equal original_author_name, @first.reload.author_name
+        assert_equal nbooks_before_save, Book.count
+      ensure
+        send(&quot;remove_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;)
+      end
+    end
+  end
+
+  def test_cancellation_from_before_filters_rollbacks_in_save!
+    %w(validation save).each do |filter|
+      send(&quot;add_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;)
+      begin
+        nbooks_before_save = Book.count
+        original_author_name = @first.author_name
+        @first.author_name += '_this_should_not_end_up_in_the_db'
+        @first.save!
+        flunk
+      rescue =&gt; e
+        assert_equal original_author_name, @first.reload.author_name
+        assert_equal nbooks_before_save, Book.count
+      ensure
+        send(&quot;remove_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;)
+      end
+    end
+  end
+
   def test_callback_rollback_in_create
     new_topic = Topic.new(
       :title =&gt; &quot;A new topic&quot;,
@@ -168,6 +216,7 @@ class TransactionTest &lt; ActiveRecord::TestCase
   uses_mocha 'mocking connection.commit_db_transaction' do
     def test_rollback_when_commit_raises
       Topic.connection.expects(:begin_db_transaction)
+      Topic.connection.expects(:transaction_active?).returns(true) if current_adapter?(:PostgreSQLAdapter)
       Topic.connection.expects(:commit_db_transaction).raises('OH NOES')
       Topic.connection.expects(:rollback_db_transaction)
 
@@ -221,20 +270,21 @@ class TransactionTest &lt; ActiveRecord::TestCase
     def remove_exception_raising_after_create_callback_to_topic
       Topic.class_eval { remove_method :after_create }
     end
+
+    %w(validation save destroy).each do |filter|
+      define_method(&quot;add_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;) do
+        Topic.class_eval &quot;def before_#{filter}() Book.create; false end&quot;
+      end
+
+      define_method(&quot;remove_cancelling_before_#{filter}_with_db_side_effect_to_topic&quot;) do
+        Topic.class_eval &quot;remove_method :before_#{filter}&quot;
+      end
+    end
 end
 
 if current_adapter?(:PostgreSQLAdapter)
   class ConcurrentTransactionTest &lt; TransactionTest
-    def setup
-      @allow_concurrency = ActiveRecord::Base.allow_concurrency
-      ActiveRecord::Base.allow_concurrency = true
-      super
-    end
-
-    def teardown
-      super
-      ActiveRecord::Base.allow_concurrency = @allow_concurrency
-    end
+    use_concurrent_connections
 
     # This will cause transactions to overlap and fail unless they are performed on
     # separate database connections.</diff>
      <filename>activerecord/test/cases/transactions_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,18 +6,18 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
   def setup
     reset_callbacks Topic
     @topic = Topic.new
-    I18n.backend.store_translations('en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; nil}})
+    I18n.backend.store_translations('en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:custom =&gt; nil}}})
   end
-  
+
   def teardown
     reset_callbacks Topic
-    load 'active_record/locale/en-US.rb'
+    I18n.load_translations File.dirname(__FILE__) + '/../../lib/active_record/locale/en-US.yml'
   end
-  
+
   def unique_topic
     @unique ||= Topic.create :title =&gt; 'unique!'
   end
-  
+
   def replied_topic
     @replied_topic ||= begin
       topic = Topic.create(:title =&gt; &quot;topic&quot;)
@@ -25,7 +25,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       topic
     end
   end
-  
+
   def reset_callbacks(*models)
     models.each do |model|
       model.instance_variable_set(&quot;@validate_callbacks&quot;, ActiveSupport::Callbacks::CallbackChain.new)
@@ -33,28 +33,83 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       model.instance_variable_set(&quot;@validate_on_update_callbacks&quot;, ActiveSupport::Callbacks::CallbackChain.new)
     end
   end
-  
+
   def test_default_error_messages_is_deprecated
     assert_deprecated('ActiveRecord::Errors.default_error_messages') do
       ActiveRecord::Errors.default_error_messages
     end
   end
-  
+
   # ActiveRecord::Errors
   uses_mocha 'ActiveRecord::Errors' do
+
     def test_errors_generate_message_translates_custom_model_attribute_key
-      global_scope = [:active_record, :error_messages]
-      custom_scope = global_scope + [:custom, 'topic', :title]
 
-      I18n.expects(:t).with nil, :scope =&gt; [:active_record, :error_messages], :default =&gt; [:&quot;custom.topic.title.invalid&quot;, 'default from class def', :invalid]
-      @topic.errors.generate_message :title, :invalid, :default =&gt; 'default from class def'
+      I18n.expects(:translate).with(
+        :topic,
+        { :count =&gt; 1,
+          :default =&gt; ['Topic'],
+          :scope =&gt; [:activerecord, :models]
+        }
+      ).returns('Topic')
+
+      I18n.expects(:translate).with(
+        :&quot;topic.title&quot;,
+        { :count =&gt; 1,
+          :default =&gt; ['Title'],
+          :scope =&gt; [:activerecord, :attributes]
+        }
+      ).returns('Title')
+
+      I18n.expects(:translate).with(
+        :&quot;models.topic.attributes.title.invalid&quot;,
+        :value =&gt; nil,
+        :scope =&gt; [:activerecord, :errors],
+        :default =&gt; [
+          :&quot;models.topic.invalid&quot;,
+          'default from class def error 1',
+          :&quot;messages.invalid&quot;],
+        :attribute =&gt; &quot;Title&quot;,
+        :model =&gt; &quot;Topic&quot;
+      ).returns('default from class def error 1')
+
+      @topic.errors.generate_message :title, :invalid, :default =&gt; 'default from class def error 1'
     end
 
     def test_errors_generate_message_translates_custom_model_attribute_keys_with_sti
-      custom_scope = [:active_record, :error_messages, :custom, 'topic', :title]
 
-      I18n.expects(:t).with nil, :scope =&gt; [:active_record, :error_messages], :default =&gt; [:&quot;custom.reply.title.invalid&quot;, :&quot;custom.topic.title.invalid&quot;, 'default from class def', :invalid]
+      I18n.expects(:translate).with(
+        :reply,
+        { :count =&gt; 1,
+          :default =&gt; [:topic, 'Reply'],
+          :scope =&gt; [:activerecord, :models]
+        }
+      ).returns('Reply')
+
+      I18n.expects(:translate).with(
+        :&quot;reply.title&quot;,
+        { :count =&gt; 1,
+          :default =&gt; [:'topic.title', 'Title'],
+          :scope =&gt; [:activerecord, :attributes]
+        }
+      ).returns('Title')
+
+      I18n.expects(:translate).with(
+        :&quot;models.reply.attributes.title.invalid&quot;,
+        :value =&gt; nil,
+        :scope =&gt; [:activerecord, :errors],
+        :default =&gt; [
+          :&quot;models.reply.invalid&quot;,
+          :&quot;models.topic.attributes.title.invalid&quot;,
+          :&quot;models.topic.invalid&quot;,
+          'default from class def',
+          :&quot;messages.invalid&quot;],
+        :model =&gt; 'Reply',
+        :attribute =&gt; 'Title'
+      ).returns(&quot;default from class def&quot;)
+
       Reply.new.errors.generate_message :title, :invalid, :default =&gt; 'default from class def'
+
     end
 
     def test_errors_add_on_empty_generates_message
@@ -78,12 +133,12 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
     end
 
     def test_errors_full_messages_translates_human_attribute_name_for_model_attributes
-      @topic.errors.instance_variable_set :@errors, { 'title' =&gt; 'empty' }
-      I18n.expects(:translate).with(:&quot;active_record.human_attribute_names.topic.title&quot;, :locale =&gt; 'en-US', :default =&gt; 'Title').returns('Title')
+      @topic.errors.instance_variable_set :@errors, { 'title' =&gt; ['empty'] }
+      I18n.expects(:translate).with(:&quot;topic.title&quot;, :default =&gt; ['Title'], :scope =&gt; [:activerecord, :attributes], :count =&gt; 1).returns('Title')
       @topic.errors.full_messages :locale =&gt; 'en-US'
     end
-  end  
-  
+  end
+
   # ActiveRecord::Validations
   uses_mocha 'ActiveRecord::Validations' do
     # validates_confirmation_of w/ mocha
@@ -101,7 +156,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :confirmation, {:default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_acceptance_of w/ mocha
 
     def test_validates_acceptance_of_generates_message
@@ -115,9 +170,9 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :accepted, {:default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_presence_of w/ mocha
-    
+
     def test_validates_presence_of_generates_message
       Topic.validates_presence_of :title
       @topic.errors.expects(:generate_message).with(:title, :blank, {:default =&gt; nil})
@@ -129,7 +184,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :blank, {:default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     def test_validates_length_of_within_generates_message_with_title_too_short
       Topic.validates_length_of :title, :within =&gt; 3..5
       @topic.errors.expects(:generate_message).with(:title, :too_short, {:count =&gt; 3, :default =&gt; nil})
@@ -183,7 +238,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :too_long, {:count =&gt; 5, :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_length_of :is w/ mocha
 
     def test_validates_length_of_is_generates_message
@@ -197,23 +252,23 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :wrong_length, {:count =&gt; 5, :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_uniqueness_of w/ mocha
 
     def test_validates_uniqueness_of_generates_message
       Topic.validates_uniqueness_of :title
       @topic.title = unique_topic.title
-      @topic.errors.expects(:generate_message).with(:title, :taken, {:default =&gt; nil})
+      @topic.errors.expects(:generate_message).with(:title, :taken, {:default =&gt; nil, :value =&gt; 'unique!'})
       @topic.valid?
     end
 
     def test_validates_uniqueness_of_generates_message_with_custom_default_message
       Topic.validates_uniqueness_of :title, :message =&gt; 'custom'
       @topic.title = unique_topic.title
-      @topic.errors.expects(:generate_message).with(:title, :taken, {:default =&gt; 'custom'})
+      @topic.errors.expects(:generate_message).with(:title, :taken, {:default =&gt; 'custom', :value =&gt; 'unique!'})
       @topic.valid?
     end
-    
+
     # validates_format_of w/ mocha
 
     def test_validates_format_of_generates_message
@@ -229,7 +284,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :invalid, {:value =&gt; '72x', :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_inclusion_of w/ mocha
 
     def test_validates_inclusion_of_generates_message
@@ -245,7 +300,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :inclusion, {:value =&gt; 'z', :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_exclusion_of w/ mocha
 
     def test_validates_exclusion_of_generates_message
@@ -261,7 +316,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :exclusion, {:value =&gt; 'a', :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_numericality_of without :only_integer w/ mocha
 
     def test_validates_numericality_of_generates_message
@@ -277,7 +332,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value =&gt; 'a', :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_numericality_of with :only_integer w/ mocha
 
     def test_validates_numericality_of_only_integer_generates_message
@@ -293,7 +348,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :not_a_number, {:value =&gt; 'a', :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_numericality_of :odd w/ mocha
 
     def test_validates_numericality_of_odd_generates_message
@@ -309,7 +364,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :odd, {:value =&gt; 0, :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_numericality_of :less_than w/ mocha
 
     def test_validates_numericality_of_less_than_generates_message
@@ -325,7 +380,7 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       @topic.errors.expects(:generate_message).with(:title, :less_than, {:value =&gt; 1, :count =&gt; 0, :default =&gt; 'custom'})
       @topic.valid?
     end
-    
+
     # validates_associated w/ mocha
 
     def test_validates_associated_generates_message
@@ -340,284 +395,497 @@ class ActiveRecordValidationsI18nTests &lt; Test::Unit::TestCase
       replied_topic.valid?
     end
   end
-  
+
   # validates_confirmation_of w/o mocha
-  
+
   def test_validates_confirmation_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:confirmation =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:confirmation =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:confirmation =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:confirmation =&gt; 'global message'}}}
+
     Topic.validates_confirmation_of :title
     @topic.title_confirmation = 'foo'
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_confirmation_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:confirmation =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:confirmation =&gt; 'global message'}}}
+
     Topic.validates_confirmation_of :title
     @topic.title_confirmation = 'foo'
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_acceptance_of w/o mocha
-  
+
   def test_validates_acceptance_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:accepted =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:accepted =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:accepted =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:accepted =&gt; 'global message'}}}
+
     Topic.validates_acceptance_of :title, :allow_nil =&gt; false
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_acceptance_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:accepted =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:accepted =&gt; 'global message'}}}
+
     Topic.validates_acceptance_of :title, :allow_nil =&gt; false
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_presence_of w/o mocha
-    
+
   def test_validates_presence_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:blank =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:blank =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:blank =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:blank =&gt; 'global message'}}}
+
     Topic.validates_presence_of :title
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_presence_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:blank =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:blank =&gt; 'global message'}}}
+
     Topic.validates_presence_of :title
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_length_of :within w/o mocha
-  
+
   def test_validates_length_of_within_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:too_short =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:too_short =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:too_short =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:too_short =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :within =&gt; 3..5
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_length_of_within_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:too_short =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:too_short =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :within =&gt; 3..5
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_length_of :is w/o mocha
-  
+
   def test_validates_length_of_within_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:wrong_length =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:wrong_length =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:wrong_length =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:wrong_length =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :is =&gt; 5
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_length_of_within_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:wrong_length =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:wrong_length =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :is =&gt; 5
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_uniqueness_of w/o mocha
-  
+
   def test_validates_length_of_within_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:wrong_length =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:wrong_length =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:wrong_length =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:wrong_length =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :is =&gt; 5
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_length_of_within_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:wrong_length =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:wrong_length =&gt; 'global message'}}}
+
     Topic.validates_length_of :title, :is =&gt; 5
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
-  
+
+
   # validates_format_of w/o mocha
-  
+
   def test_validates_format_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:invalid =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:invalid =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:invalid =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:invalid =&gt; 'global message'}}}
+
     Topic.validates_format_of :title, :with =&gt; /^[1-9][0-9]*$/
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_format_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:invalid =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:invalid =&gt; 'global message'}}}
+
     Topic.validates_format_of :title, :with =&gt; /^[1-9][0-9]*$/
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_inclusion_of w/o mocha
-  
+
   def test_validates_inclusion_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:inclusion =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:inclusion =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:inclusion =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:inclusion =&gt; 'global message'}}}
+
     Topic.validates_inclusion_of :title, :in =&gt; %w(a b c)
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_inclusion_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:inclusion =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:inclusion =&gt; 'global message'}}}
+
     Topic.validates_inclusion_of :title, :in =&gt; %w(a b c)
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_exclusion_of w/o mocha
-  
+
   def test_validates_exclusion_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:exclusion =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:exclusion =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:exclusion =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:exclusion =&gt; 'global message'}}}
+
     Topic.validates_exclusion_of :title, :in =&gt; %w(a b c)
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_exclusion_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:exclusion =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:exclusion =&gt; 'global message'}}}
+
     Topic.validates_exclusion_of :title, :in =&gt; %w(a b c)
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_numericality_of without :only_integer w/o mocha
-  
+
   def test_validates_numericality_of_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:not_a_number =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:not_a_number =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:not_a_number =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:not_a_number =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_numericality_of_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:not_a_number =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:not_a_number =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_numericality_of with :only_integer w/o mocha
-  
+
   def test_validates_numericality_of_only_integer_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:not_a_number =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:not_a_number =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:not_a_number =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:not_a_number =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_numericality_of_only_integer_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:not_a_number =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:not_a_number =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true
     @topic.title = 'a'
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_numericality_of :odd w/o mocha
-  
+
   def test_validates_numericality_of_odd_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:odd =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:odd =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:odd =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:odd =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true, :odd =&gt; true
     @topic.title = 0
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_numericality_of_odd_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:odd =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:odd =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true, :odd =&gt; true
     @topic.title = 0
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
+
   # validates_numericality_of :less_than w/o mocha
-  
+
   def test_validates_numericality_of_less_than_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:title =&gt; {:less_than =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:less_than =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:less_than =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:less_than =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true, :less_than =&gt; 0
     @topic.title = 1
     @topic.valid?
     assert_equal 'custom message', @topic.errors.on(:title)
   end
-  
+
   def test_validates_numericality_of_less_than_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:less_than =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:less_than =&gt; 'global message'}}}
+
     Topic.validates_numericality_of :title, :only_integer =&gt; true, :less_than =&gt; 0
     @topic.title = 1
     @topic.valid?
     assert_equal 'global message', @topic.errors.on(:title)
   end
-  
-  
+
+
   # validates_associated w/o mocha
-  
+
   def test_validates_associated_finds_custom_model_key_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:custom =&gt; {:topic =&gt; {:replies =&gt; {:invalid =&gt; 'custom message'}}}}}
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:invalid =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:replies =&gt; {:invalid =&gt; 'custom message'}}}}}}
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:invalid =&gt; 'global message'}}}
+
     Topic.validates_associated :replies
     replied_topic.valid?
     assert_equal 'custom message', replied_topic.errors.on(:replies)
   end
-  
+
   def test_validates_associated_finds_global_default_translation
-    I18n.backend.store_translations 'en-US', :active_record =&gt; {:error_messages =&gt; {:invalid =&gt; 'global message'}}
-  
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:invalid =&gt; 'global message'}}}
+
     Topic.validates_associated :replies
     replied_topic.valid?
     assert_equal 'global message', replied_topic.errors.on(:replies)
   end
-end
\ No newline at end of file
+
+  def test_validations_with_message_symbol_must_translate
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:messages =&gt; {:custom_error =&gt; &quot;I am a custom error&quot;}}}
+    Topic.validates_presence_of :title, :message =&gt; :custom_error
+    @topic.title = nil
+    @topic.valid?
+    assert_equal &quot;I am a custom error&quot;, @topic.errors.on(:title)
+  end
+
+  def test_validates_with_message_symbol_must_translate_per_attribute
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:attributes =&gt; {:title =&gt; {:custom_error =&gt; &quot;I am a custom error&quot;}}}}}}
+    Topic.validates_presence_of :title, :message =&gt; :custom_error
+    @topic.title = nil
+    @topic.valid?
+    assert_equal &quot;I am a custom error&quot;, @topic.errors.on(:title)
+  end
+
+  def test_validates_with_message_symbol_must_translate_per_model
+    I18n.backend.store_translations 'en-US', :activerecord =&gt; {:errors =&gt; {:models =&gt; {:topic =&gt; {:custom_error =&gt; &quot;I am a custom error&quot;}}}}
+    Topic.validates_presence_of :title, :message =&gt; :custom_error
+    @topic.title = nil
+    @topic.valid?
+    assert_equal &quot;I am a custom error&quot;, @topic.errors.on(:title)
+  end
+
+  def test_validates_with_message_string
+    Topic.validates_presence_of :title, :message =&gt; &quot;I am a custom error&quot;
+    @topic.title = nil
+    @topic.valid?
+    assert_equal &quot;I am a custom error&quot;, @topic.errors.on(:title)
+  end
+
+end
+
+class ActiveRecordValidationsGenerateMessageI18nTests &lt; Test::Unit::TestCase
+  def setup
+    reset_callbacks Topic
+    @topic = Topic.new
+    I18n.backend.store_translations :'en-US', {
+      :activerecord =&gt; {
+        :errors =&gt; {
+          :messages =&gt; {
+            :inclusion =&gt; &quot;is not included in the list&quot;,
+            :exclusion =&gt; &quot;is reserved&quot;,
+            :invalid =&gt; &quot;is invalid&quot;,
+            :confirmation =&gt; &quot;doesn't match confirmation&quot;,
+            :accepted  =&gt; &quot;must be accepted&quot;,
+            :empty =&gt; &quot;can't be empty&quot;,
+            :blank =&gt; &quot;can't be blank&quot;,
+            :too_long =&gt; &quot;is too long (maximum is {{count}} characters)&quot;,
+            :too_short =&gt; &quot;is too short (minimum is {{count}} characters)&quot;,
+            :wrong_length =&gt; &quot;is the wrong length (should be {{count}} characters)&quot;,
+            :taken =&gt; &quot;has already been taken&quot;,
+            :not_a_number =&gt; &quot;is not a number&quot;,
+            :greater_than =&gt; &quot;must be greater than {{count}}&quot;,
+            :greater_than_or_equal_to =&gt; &quot;must be greater than or equal to {{count}}&quot;,
+            :equal_to =&gt; &quot;must be equal to {{count}}&quot;,
+            :less_than =&gt; &quot;must be less than {{count}}&quot;,
+            :less_than_or_equal_to =&gt; &quot;must be less than or equal to {{count}}&quot;,
+            :odd =&gt; &quot;must be odd&quot;,
+            :even =&gt; &quot;must be even&quot;
+          }
+        }
+      }
+    }
+  end
+
+  def reset_callbacks(*models)
+    models.each do |model|
+      model.instance_variable_set(&quot;@validate_callbacks&quot;, ActiveSupport::Callbacks::CallbackChain.new)
+      model.instance_variable_set(&quot;@validate_on_create_callbacks&quot;, ActiveSupport::Callbacks::CallbackChain.new)
+      model.instance_variable_set(&quot;@validate_on_update_callbacks&quot;, ActiveSupport::Callbacks::CallbackChain.new)
+    end
+  end
+
+  # validates_inclusion_of: generate_message(attr_name, :inclusion, :default =&gt; configuration[:message], :value =&gt; value)
+  def test_generate_message_inclusion_with_default_message
+    assert_equal 'is not included in the list', @topic.errors.generate_message(:title, :inclusion, :default =&gt; nil, :value =&gt; 'title')
+  end
+
+  def test_generate_message_inclusion_with_custom_message
+    assert_equal 'custom message title', @topic.errors.generate_message(:title, :inclusion, :default =&gt; 'custom message {{value}}', :value =&gt; 'title')
+  end
+
+  # validates_exclusion_of: generate_message(attr_name, :exclusion, :default =&gt; configuration[:message], :value =&gt; value)
+  def test_generate_message_exclusion_with_default_message
+    assert_equal 'is reserved', @topic.errors.generate_message(:title, :exclusion, :default =&gt; nil, :value =&gt; 'title')
+  end
+
+  def test_generate_message_exclusion_with_custom_message
+    assert_equal 'custom message title', @topic.errors.generate_message(:title, :exclusion, :default =&gt; 'custom message {{value}}', :value =&gt; 'title')
+  end
+
+  # validates_associated: generate_message(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value)
+  # validates_format_of:  generate_message(attr_name, :invalid, :default =&gt; configuration[:message], :value =&gt; value)
+  def test_generate_message_invalid_with_default_message
+    assert_equal 'is invalid', @topic.errors.generate_message(:title, :invalid, :default =&gt; nil, :value =&gt; 'title')
+  end
+
+  def test_generate_message_invalid_with_custom_message
+    assert_equal 'custom message title', @topic.errors.generate_message(:title, :invalid, :default =&gt; 'custom message {{value}}', :value =&gt; 'title')
+  end
+
+  # validates_confirmation_of: generate_message(attr_name, :confirmation, :default =&gt; configuration[:message])
+  def test_generate_message_confirmation_with_default_message
+    assert_equal &quot;doesn't match confirmation&quot;, @topic.errors.generate_message(:title, :confirmation, :default =&gt; nil)
+  end
+
+  def test_generate_message_confirmation_with_custom_message
+    assert_equal 'custom message', @topic.errors.generate_message(:title, :confirmation, :default =&gt; 'custom message')
+  end
+
+  # validates_acceptance_of: generate_message(attr_name, :accepted, :default =&gt; configuration[:message])
+  def test_generate_message_accepted_with_default_message
+    assert_equal &quot;must be accepted&quot;, @topic.errors.generate_message(:title, :accepted, :default =&gt; nil)
+  end
+
+  def test_generate_message_accepted_with_custom_message
+    assert_equal 'custom message', @topic.errors.generate_message(:title, :accepted, :default =&gt; 'custom message')
+  end
+
+  # add_on_empty: generate_message(attr, :empty, :default =&gt; custom_message)
+  def test_generate_message_empty_with_default_message
+    assert_equal &quot;can't be empty&quot;, @topic.errors.generate_message(:title, :empty, :default =&gt; nil)
+  end
+
+  def test_generate_message_empty_with_custom_message
+    assert_equal 'custom message', @topic.errors.generate_message(:title, :empty, :default =&gt; 'custom message')
+  end
+
+  # add_on_blank: generate_message(attr, :blank, :default =&gt; custom_message)
+  def test_generate_message_blank_with_default_message
+    assert_equal &quot;can't be blank&quot;, @topic.errors.generate_message(:title, :blank, :default =&gt; nil)
+  end
+
+  def test_generate_message_blank_with_custom_message
+    assert_equal 'custom message', @topic.errors.generate_message(:title, :blank, :default =&gt; 'custom message')
+  end
+
+  # validates_length_of: generate_message(attr, :too_long, :default =&gt; options[:too_long], :count =&gt; option_value.end)
+  def test_generate_message_too_long_with_default_message
+    assert_equal &quot;is too long (maximum is 10 characters)&quot;, @topic.errors.generate_message(:title, :too_long, :default =&gt; nil, :count =&gt; 10)
+  end
+
+  def test_generate_message_too_long_with_custom_message
+    assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_long, :default =&gt; 'custom message {{count}}', :count =&gt; 10)
+  end
+
+  # validates_length_of: generate_message(attr, :too_short, :default =&gt; options[:too_short], :count =&gt; option_value.begin)
+  def test_generate_message_too_short_with_default_message
+    assert_equal &quot;is too short (minimum is 10 characters)&quot;, @topic.errors.generate_message(:title, :too_short, :default =&gt; nil, :count =&gt; 10)
+  end
+
+  def test_generate_message_too_short_with_custom_message
+    assert_equal 'custom message 10', @topic.errors.generate_message(:title, :too_short, :default =&gt; 'custom message {{count}}', :count =&gt; 10)
+  end
+
+  # validates_length_of: generate_message(attr, key, :default =&gt; custom_message, :count =&gt; option_value)
+  def test_generate_message_wrong_length_with_default_message
+    assert_equal &quot;is the wrong length (should be 10 characters)&quot;, @topic.errors.generate_message(:title, :wrong_length, :default =&gt; nil, :count =&gt; 10)
+  end
+
+  def test_generate_message_wrong_length_with_custom_message
+    assert_equal 'custom message 10', @topic.errors.generate_message(:title, :wrong_length, :default =&gt; 'custom message {{count}}', :count =&gt; 10)
+  end
+
+  # validates_uniqueness_of: generate_message(attr_name, :taken, :default =&gt; configuration[:message])
+  def test_generate_message_taken_with_default_message
+    assert_equal &quot;has already been taken&quot;, @topic.errors.generate_message(:title, :taken, :default =&gt; nil, :value =&gt; 'title')
+  end
+
+  def test_generate_message_taken_with_custom_message
+    assert_equal 'custom message title', @topic.errors.generate_message(:title, :taken, :default =&gt; 'custom message {{value}}', :value =&gt; 'title')
+  end
+
+  # validates_numericality_of: generate_message(attr_name, :not_a_number, :value =&gt; raw_value, :default =&gt; configuration[:message])
+  def test_generate_message_not_a_number_with_default_message
+    assert_equal &quot;is not a number&quot;, @topic.errors.generate_message(:title, :not_a_number, :default =&gt; nil, :value =&gt; 'title')
+  end
+
+  def test_generate_message_not_a_number_with_custom_message
+    assert_equal 'custom message title', @topic.errors.generate_message(:title, :not_a_number, :default =&gt; 'custom message {{value}}', :value =&gt; 'title')
+  end
+
+  # validates_numericality_of: generate_message(attr_name, option, :value =&gt; raw_value, :default =&gt; configuration[:message])
+  def test_generate_message_greater_than_with_default_message
+    assert_equal &quot;must be greater than 10&quot;, @topic.errors.generate_message(:title, :greater_than, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_greater_than_or_equal_to_with_default_message
+    assert_equal &quot;must be greater than or equal to 10&quot;, @topic.errors.generate_message(:title, :greater_than_or_equal_to, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_equal_to_with_default_message
+    assert_equal &quot;must be equal to 10&quot;, @topic.errors.generate_message(:title, :equal_to, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_less_than_with_default_message
+    assert_equal &quot;must be less than 10&quot;, @topic.errors.generate_message(:title, :less_than, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_less_than_or_equal_to_with_default_message
+    assert_equal &quot;must be less than or equal to 10&quot;, @topic.errors.generate_message(:title, :less_than_or_equal_to, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_odd_with_default_message
+    assert_equal &quot;must be odd&quot;, @topic.errors.generate_message(:title, :odd, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+  def test_generate_message_even_with_default_message
+    assert_equal &quot;must be even&quot;, @topic.errors.generate_message(:title, :even, :default =&gt; nil, :value =&gt; 'title', :count =&gt; 10)
+  end
+
+end</diff>
      <filename>activerecord/test/cases/validations_i18n_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -451,6 +451,18 @@ class ValidationsTest &lt; ActiveRecord::TestCase
     t2.title = nil
     assert t2.valid?, &quot;should validate with nil&quot;
     assert t2.save, &quot;should save with nil&quot;
+
+    with_kcode('UTF8') do
+      t_utf8 = Topic.new(&quot;title&quot; =&gt; &quot;&#1071; &#1090;&#1086;&#1078;&#1077; &#1091;&#1085;&#1080;&#1082;&#1072;&#1083;&#1100;&#1085;&#1099;&#1081;!&quot;)
+      assert t_utf8.save, &quot;Should save t_utf8 as unique&quot;
+
+      # If database hasn't UTF-8 character set, this test fails
+      if Topic.find(t_utf8, :select =&gt; 'LOWER(title) AS title').title == &quot;&#1103; &#1090;&#1086;&#1078;&#1077; &#1091;&#1085;&#1080;&#1082;&#1072;&#1083;&#1100;&#1085;&#1099;&#1081;!&quot;
+        t2_utf8 = Topic.new(&quot;title&quot; =&gt; &quot;&#1103; &#1090;&#1086;&#1078;&#1077; &#1059;&#1053;&#1048;&#1050;&#1040;&#1051;&#1068;&#1053;&#1067;&#1049;!&quot;)
+        assert !t2_utf8.valid?, &quot;Shouldn't be valid&quot;
+        assert !t2_utf8.save, &quot;Shouldn't save t2_utf8 as unique&quot;
+      end
+    end
   end
 
   def test_validate_case_sensitive_uniqueness
@@ -1420,8 +1432,8 @@ class ValidatesNumericalityTest &lt; ActiveRecord::TestCase
   def test_validates_numericality_of_with_nil_allowed
     Topic.validates_numericality_of :approved, :allow_nil =&gt; true
 
-    invalid!(BLANK + JUNK)
-    valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL + INFINITY)
+    invalid!(JUNK)
+    valid!(NIL + BLANK + FLOATS + INTEGERS + BIGDECIMAL + INFINITY)
   end
 
   def test_validates_numericality_of_with_integer_only
@@ -1434,8 +1446,8 @@ class ValidatesNumericalityTest &lt; ActiveRecord::TestCase
   def test_validates_numericality_of_with_integer_only_and_nil_allowed
     Topic.validates_numericality_of :approved, :only_integer =&gt; true, :allow_nil =&gt; true
 
-    invalid!(BLANK + JUNK + FLOATS + BIGDECIMAL + INFINITY)
-    valid!(NIL + INTEGERS)
+    invalid!(JUNK + FLOATS + BIGDECIMAL + INFINITY)
+    valid!(NIL + BLANK + INTEGERS)
   end
 
   def test_validates_numericality_with_greater_than</diff>
      <filename>activerecord/test/cases/validations_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -43,6 +43,8 @@ class Developer &lt; ActiveRecord::Base
 
   has_many :audit_logs
 
+  named_scope :jamises, :conditions =&gt; {:name =&gt; 'Jamis'}
+
   validates_inclusion_of :salary, :in =&gt; 50000..200000
   validates_length_of    :name, :within =&gt; 3..20
 </diff>
      <filename>activerecord/test/models/developer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ class Project &lt; ActiveRecord::Base
   has_and_belongs_to_many :developers_named_david, :class_name =&gt; &quot;Developer&quot;, :conditions =&gt; &quot;name = 'David'&quot;, :uniq =&gt; true
   has_and_belongs_to_many :developers_named_david_with_hash_conditions, :class_name =&gt; &quot;Developer&quot;, :conditions =&gt; { :name =&gt; 'David' }, :uniq =&gt; true
   has_and_belongs_to_many :salaried_developers, :class_name =&gt; &quot;Developer&quot;, :conditions =&gt; &quot;salary &gt; 0&quot;
-  has_and_belongs_to_many :developers_with_finder_sql, :class_name =&gt; &quot;Developer&quot;, :finder_sql =&gt; 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id}'
+  has_and_belongs_to_many :developers_with_finder_sql, :class_name =&gt; &quot;Developer&quot;, :finder_sql =&gt; 'SELECT t.*, j.* FROM developers_projects j, developers t WHERE t.id = j.developer_id AND j.project_id = #{id} ORDER BY t.id'
   has_and_belongs_to_many :developers_by_sql, :class_name =&gt; &quot;Developer&quot;, :delete_sql =&gt; &quot;DELETE FROM developers_projects WHERE project_id = \#{id} AND developer_id = \#{record.id}&quot;
   has_and_belongs_to_many :developers_with_callbacks, :class_name =&gt; &quot;Developer&quot;, :before_add =&gt; Proc.new {|o, r| o.developers_log &lt;&lt; &quot;before_adding#{r.id || '&lt;new&gt;'}&quot;},
                             :after_add =&gt; Proc.new {|o, r| o.developers_log &lt;&lt; &quot;after_adding#{r.id || '&lt;new&gt;'}&quot;},</diff>
      <filename>activerecord/test/models/project.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 ActiveRecord::Schema.define do
-  create_table :binary_fields, :force =&gt; true do |t|
+  create_table :binary_fields, :force =&gt; true, :options =&gt; 'CHARACTER SET latin1' do |t|
     t.binary :tiny_blob,   :limit =&gt; 255
     t.binary :normal_blob, :limit =&gt; 65535
     t.binary :medium_blob, :limit =&gt; 16777215
@@ -9,4 +9,4 @@ ActiveRecord::Schema.define do
     t.text   :medium_text, :limit =&gt; 16777215
     t.text   :long_text,   :limit =&gt; 2147483647
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activerecord/test/schema/mysql_specific_schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -60,7 +60,7 @@ ActiveRecord::Schema.define do
   end
 
   create_table :booleantests, :force =&gt; true do |t|
-    t.integer :value
+    t.boolean :value
   end
 
   create_table :categories, :force =&gt; true do |t|</diff>
      <filename>activerecord/test/schema/schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,7 @@
 *Edge*
 
+* Add ActiveResource::Base.find(:last). [#754 state:resolved] (Adrian Mugnolo)
+
 * Fixed problems with the logger used if the logging string included %'s [#840 state:resolved] (Jamis Buck)
 
 * Fixed Base#exists? to check status code as integer [#299 state:resolved] (Wes Oldenbeuving)</diff>
      <filename>activeresource/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -21,16 +21,13 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
-$:.unshift(File.dirname(__FILE__)) unless
-  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
-
-unless defined?(ActiveSupport)
-  begin
-    $:.unshift(File.dirname(__FILE__) + &quot;/../../activesupport/lib&quot;)  
+begin
+  require 'active_support'
+rescue LoadError
+  activesupport_path = &quot;#{File.dirname(__FILE__)}/../../activesupport/lib&quot;
+  if File.directory?(activesupport_path)
+    $:.unshift activesupport_path
     require 'active_support'
-  rescue LoadError
-    require 'rubygems'
-    gem 'activesupport'
   end
 end
 
@@ -44,4 +41,4 @@ module ActiveResource
     include Validations
     include CustomMethods
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activeresource/lib/active_resource.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,48 +13,48 @@ module ActiveResource
   # to Ruby objects, Active Resource only needs a class name that corresponds to the resource name (e.g., the class
   # Person maps to the resources people, very similarly to Active Record) and a +site+ value, which holds the
   # URI of the resources.
-  # 
+  #
   #   class Person &lt; ActiveResource::Base
   #     self.site = &quot;http://api.people.com:3000/&quot;
   #   end
-  # 
+  #
   # Now the Person class is mapped to RESTful resources located at &lt;tt&gt;http://api.people.com:3000/people/&lt;/tt&gt;, and
-  # you can now use Active Resource's lifecycles methods to manipulate resources. In the case where you already have 
+  # you can now use Active Resource's lifecycles methods to manipulate resources. In the case where you already have
   # an existing model with the same name as the desired RESTful resource you can set the +element_name+ value.
   #
   #   class PersonResource &lt; ActiveResource::Base
   #     self.site = &quot;http://api.people.com:3000/&quot;
   #     self.element_name = &quot;person&quot;
   #   end
-  #  
-  # 
+  #
+  #
   # == Lifecycle methods
   #
   # Active Resource exposes methods for creating, finding, updating, and deleting resources
   # from REST web services.
-  # 
+  #
   #   ryan = Person.new(:first =&gt; 'Ryan', :last =&gt; 'Daigle')
   #   ryan.save                # =&gt; true
   #   ryan.id                  # =&gt; 2
   #   Person.exists?(ryan.id)  # =&gt; true
   #   ryan.exists?             # =&gt; true
-  # 
+  #
   #   ryan = Person.find(1)
   #   # Resource holding our newly created Person object
-  # 
+  #
   #   ryan.first = 'Rizzle'
   #   ryan.save                # =&gt; true
-  # 
+  #
   #   ryan.destroy             # =&gt; true
   #
   # As you can see, these are very similar to Active Record's lifecycle methods for database records.
   # You can read more about each of these methods in their respective documentation.
-  # 
+  #
   # === Custom REST methods
   #
   # Since simple CRUD/lifecycle methods can't accomplish every task, Active Resource also supports
   # defining your own custom REST methods. To invoke them, Active Resource provides the &lt;tt&gt;get&lt;/tt&gt;,
-  # &lt;tt&gt;post&lt;/tt&gt;, &lt;tt&gt;put&lt;/tt&gt; and &lt;tt&gt;delete&lt;/tt&gt; methods where you can specify a custom REST method
+  # &lt;tt&gt;post&lt;/tt&gt;, &lt;tt&gt;put&lt;/tt&gt; and &lt;tt&gt;\delete&lt;/tt&gt; methods where you can specify a custom REST method
   # name to invoke.
   #
   #   # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
@@ -71,14 +71,14 @@ module ActiveResource
   #
   #   # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
   #   Person.find(1).delete(:fire)
-  # 
+  #
   # For more information on using custom REST methods, see the
   # ActiveResource::CustomMethods documentation.
   #
   # == Validations
   #
   # You can validate resources client side by overriding validation methods in the base class.
-  # 
+  #
   #   class Person &lt; ActiveResource::Base
   #      self.site = &quot;http://api.people.com:3000/&quot;
   #      protected
@@ -86,19 +86,19 @@ module ActiveResource
   #          errors.add(&quot;last&quot;, &quot;has invalid characters&quot;) unless last =~ /[a-zA-Z]*/
   #        end
   #   end
-  # 
+  #
   # See the ActiveResource::Validations documentation for more information.
   #
   # == Authentication
-  # 
+  #
   # Many REST APIs will require authentication, usually in the form of basic
   # HTTP authentication.  Authentication can be specified by:
   # * putting the credentials in the URL for the +site+ variable.
-  # 
+  #
   #    class Person &lt; ActiveResource::Base
   #      self.site = &quot;http://ryan:password@api.people.com:3000/&quot;
   #    end
-  # 
+  #
   # * defining +user+ and/or +password+ variables
   #
   #    class Person &lt; ActiveResource::Base
@@ -107,35 +107,41 @@ module ActiveResource
   #      self.password = &quot;password&quot;
   #    end
   #
-  # For obvious security reasons, it is probably best if such services are available 
+  # For obvious security reasons, it is probably best if such services are available
   # over HTTPS.
-  # 
-  # Note: Some values cannot be provided in the URL passed to site.  e.g. email addresses 
+  #
+  # Note: Some values cannot be provided in the URL passed to site.  e.g. email addresses
   # as usernames.  In those situations you should use the separate user and password option.
   # == Errors &amp; Validation
   #
   # Error handling and validation is handled in much the same manner as you're used to seeing in
   # Active Record.  Both the response code in the HTTP response and the body of the response are used to
   # indicate that an error occurred.
-  # 
+  #
   # === Resource errors
-  # 
+  #
   # When a GET is requested for a resource that does not exist, the HTTP &lt;tt&gt;404&lt;/tt&gt; (Resource Not Found)
   # response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
   # exception.
-  # 
+  #
   #   # GET http://api.people.com:3000/people/999.xml
   #   ryan = Person.find(999) # 404, raises ActiveResource::ResourceNotFound
-  # 
+  #
   # &lt;tt&gt;404&lt;/tt&gt; is just one of the HTTP error response codes that Active Resource will handle with its own exception. The
   # following HTTP response codes will also result in these exceptions:
   # 
-  # * 200..399 - Valid response, no exception
+  # * 200..399 - Valid response, no exception (other than 301, 302)
+  # * 301, 302 - ActiveResource::Redirection
+  # * 400 - ActiveResource::BadRequest
+  # * 401 - ActiveResource::UnauthorizedAccess
+  # * 403 - ActiveResource::ForbiddenAccess
   # * 404 - ActiveResource::ResourceNotFound
+  # * 405 - ActiveResource::MethodNotAllowed
   # * 409 - ActiveResource::ResourceConflict
   # * 422 - ActiveResource::ResourceInvalid (rescued by save as validation errors)
   # * 401..499 - ActiveResource::ClientError
   # * 500..599 - ActiveResource::ServerError
+  # * Other - ActiveResource::ConnectionError
   #
   # These custom exceptions allow you to deal with resource errors more naturally and with more precision
   # rather than returning a general HTTP error.  For example:
@@ -149,17 +155,17 @@ module ActiveResource
   #   end
   #
   # === Validation errors
-  # 
+  #
   # Active Resource supports validations on resources and will return errors if any these validations fail
-  # (e.g., &quot;First name can not be blank&quot; and so on).  These types of errors are denoted in the response by 
+  # (e.g., &quot;First name can not be blank&quot; and so on).  These types of errors are denoted in the response by
   # a response code of &lt;tt&gt;422&lt;/tt&gt; and an XML representation of the validation errors.  The save operation will
   # then fail (with a &lt;tt&gt;false&lt;/tt&gt; return value) and the validation errors can be accessed on the resource in question.
-  # 
+  #
   #   ryan = Person.find(1)
   #   ryan.first # =&gt; ''
   #   ryan.save  # =&gt; false
   #
-  #   # When 
+  #   # When
   #   # PUT http://api.people.com:3000/people/1.xml
   #   # is requested with invalid values, the response is:
   #   #
@@ -169,13 +175,13 @@ module ActiveResource
   #
   #   ryan.errors.invalid?(:first)  # =&gt; true
   #   ryan.errors.full_messages     # =&gt; ['First cannot be empty']
-  # 
+  #
   # Learn more about Active Resource's validation features in the ActiveResource::Validations documentation.
   #
   # === Timeouts
   #
   # Active Resource relies on HTTP to access RESTful APIs and as such is inherently susceptible to slow or
-  # unresponsive servers. In such cases, your Active Resource method calls could timeout. You can control the
+  # unresponsive servers. In such cases, your Active Resource method calls could \timeout. You can control the
   # amount of time before Active Resource times out with the +timeout+ variable.
   #
   #   class Person &lt; ActiveResource::Base
@@ -189,7 +195,7 @@ module ActiveResource
   # http://en.wikipedia.org/wiki/Fail-fast) rather than cause cascading failures that could incapacitate your
   # server.
   #
-  # When a timeout occurs, an ActiveResource::TimeoutError is raised. You should rescue from
+  # When a \timeout occurs, an ActiveResource::TimeoutError is raised. You should rescue from
   # ActiveResource::TimeoutError in your Active Resource method calls.
   #
   # Internally, Active Resource relies on Ruby's Net::HTTP library to make HTTP requests. Setting +timeout+
@@ -238,7 +244,7 @@ module ActiveResource
         end
       end
 
-      # Gets the user for REST HTTP authentication.
+      # Gets the \user for REST HTTP authentication.
       def user
         # Not using superclass_delegating_reader. See +site+ for explanation
         if defined?(@user)
@@ -248,13 +254,13 @@ module ActiveResource
         end
       end
 
-      # Sets the user for REST HTTP authentication.
+      # Sets the \user for REST HTTP authentication.
       def user=(user)
         @connection = nil
         @user = user
       end
 
-      # Gets the password for REST HTTP authentication.
+      # Gets the \password for REST HTTP authentication.
       def password
         # Not using superclass_delegating_reader. See +site+ for explanation
         if defined?(@password)
@@ -264,7 +270,7 @@ module ActiveResource
         end
       end
 
-      # Sets the password for REST HTTP authentication.
+      # Sets the \password for REST HTTP authentication.
       def password=(password)
         @connection = nil
         @password = password
@@ -280,16 +286,16 @@ module ActiveResource
       #
       # Default format is &lt;tt&gt;:xml&lt;/tt&gt;.
       def format=(mime_type_reference_or_format)
-        format = mime_type_reference_or_format.is_a?(Symbol) ? 
+        format = mime_type_reference_or_format.is_a?(Symbol) ?
           ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
 
-        write_inheritable_attribute(&quot;format&quot;, format)
+        write_inheritable_attribute(:format, format)
         connection.format = format if site
       end
 
       # Returns the current format, default is ActiveResource::Formats::XmlFormat.
       def format
-        read_inheritable_attribute(&quot;format&quot;) || ActiveResource::Formats[:xml]
+        read_inheritable_attribute(:format) || ActiveResource::Formats[:xml]
       end
 
       # Sets the number of seconds after which requests to the REST API should time out.
@@ -307,8 +313,8 @@ module ActiveResource
         end
       end
 
-      # An instance of ActiveResource::Connection that is the base connection to the remote service.
-      # The +refresh+ parameter toggles whether or not the connection is refreshed at every request
+      # An instance of ActiveResource::Connection that is the base \connection to the remote service.
+      # The +refresh+ parameter toggles whether or not the \connection is refreshed at every request
       # or not (defaults to &lt;tt&gt;false&lt;/tt&gt;).
       def connection(refresh = false)
         if defined?(@connection) || superclass == Object
@@ -333,8 +339,8 @@ module ActiveResource
       attr_accessor_with_default(:collection_name) { element_name.pluralize } #:nodoc:
       attr_accessor_with_default(:primary_key, 'id') #:nodoc:
       
-      # Gets the prefix for a resource's nested URL (e.g., &lt;tt&gt;prefix/collectionname/1.xml&lt;/tt&gt;)
-      # This method is regenerated at runtime based on what the prefix is set to.
+      # Gets the \prefix for a resource's nested URL (e.g., &lt;tt&gt;prefix/collectionname/1.xml&lt;/tt&gt;)
+      # This method is regenerated at runtime based on what the \prefix is set to.
       def prefix(options={})
         default = site.path
         default &lt;&lt; '/' unless default[-1..-1] == '/'
@@ -343,19 +349,22 @@ module ActiveResource
         prefix(options)
       end
 
-      # An attribute reader for the source string for the resource path prefix.  This
-      # method is regenerated at runtime based on what the prefix is set to.
+      # An attribute reader for the source string for the resource path \prefix.  This
+      # method is regenerated at runtime based on what the \prefix is set to.
       def prefix_source
         prefix # generate #prefix and #prefix_source methods first
         prefix_source
       end
 
-      # Sets the prefix for a resource's nested URL (e.g., &lt;tt&gt;prefix/collectionname/1.xml&lt;/tt&gt;).
+      # Sets the \prefix for a resource's nested URL (e.g., &lt;tt&gt;prefix/collectionname/1.xml&lt;/tt&gt;).
       # Default value is &lt;tt&gt;site.path&lt;/tt&gt;.
       def prefix=(value = '/')
         # Replace :placeholders with '#{embedded options[:lookups]}'
         prefix_call = value.gsub(/:\w+/) { |key| &quot;\#{options[#{key}]}&quot; }
 
+        # Clear prefix parameters in case they have been cached
+        @prefix_parameters = nil
+
         # Redefine the new methods.
         code = &lt;&lt;-end_code
           def prefix_source() &quot;#{value}&quot; end
@@ -373,29 +382,29 @@ module ActiveResource
       alias_method :set_collection_name, :collection_name=  #:nodoc:
 
       # Gets the element path for the given ID in +id+.  If the +query_options+ parameter is omitted, Rails
-      # will split from the prefix options.
+      # will split from the \prefix options.
       #
       # ==== Options
-      # +prefix_options+ - A hash to add a prefix to the request for nested URLs (e.g., &lt;tt&gt;:account_id =&gt; 19&lt;/tt&gt;
+      # +prefix_options+ - A \hash to add a \prefix to the request for nested URLs (e.g., &lt;tt&gt;:account_id =&gt; 19&lt;/tt&gt;
       #                    would yield a URL like &lt;tt&gt;/accounts/19/purchases.xml&lt;/tt&gt;).
-      # +query_options+ - A hash to add items to the query string for the request.
+      # +query_options+ - A \hash to add items to the query string for the request.
       #
       # ==== Examples
-      #   Post.element_path(1) 
+      #   Post.element_path(1)
       #   # =&gt; /posts/1.xml
       #
-      #   Comment.element_path(1, :post_id =&gt; 5) 
+      #   Comment.element_path(1, :post_id =&gt; 5)
       #   # =&gt; /posts/5/comments/1.xml
       #
-      #   Comment.element_path(1, :post_id =&gt; 5, :active =&gt; 1) 
+      #   Comment.element_path(1, :post_id =&gt; 5, :active =&gt; 1)
       #   # =&gt; /posts/5/comments/1.xml?active=1
       #
-      #   Comment.element_path(1, {:post_id =&gt; 5}, {:active =&gt; 1}) 
+      #   Comment.element_path(1, {:post_id =&gt; 5}, {:active =&gt; 1})
       #   # =&gt; /posts/5/comments/1.xml?active=1
       #
       def element_path(id, prefix_options = {}, query_options = nil)
         prefix_options, query_options = split_options(prefix_options) if query_options.nil?
-        &quot;#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}&quot;        
+        &quot;#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}&quot;
       end
 
       # Gets the collection path for the REST resources.  If the +query_options+ parameter is omitted, Rails
@@ -410,13 +419,13 @@ module ActiveResource
       #   Post.collection_path
       #   # =&gt; /posts.xml
       #
-      #   Comment.collection_path(:post_id =&gt; 5) 
+      #   Comment.collection_path(:post_id =&gt; 5)
       #   # =&gt; /posts/5/comments.xml
       #
-      #   Comment.collection_path(:post_id =&gt; 5, :active =&gt; 1) 
+      #   Comment.collection_path(:post_id =&gt; 5, :active =&gt; 1)
       #   # =&gt; /posts/5/comments.xml?active=1
       #
-      #   Comment.collection_path({:post_id =&gt; 5}, {:active =&gt; 1}) 
+      #   Comment.collection_path({:post_id =&gt; 5}, {:active =&gt; 1})
       #   # =&gt; /posts/5/comments.xml?active=1
       #
       def collection_path(prefix_options = {}, query_options = nil)
@@ -451,50 +460,54 @@ module ActiveResource
       #   that_guy.valid? # =&gt; false
       #   that_guy.new?   # =&gt; true
       def create(attributes = {})
-        returning(self.new(attributes)) { |res| res.save }        
+        returning(self.new(attributes)) { |res| res.save }
       end
 
       # Core method for finding resources.  Used similarly to Active Record's +find+ method.
       #
       # ==== Arguments
-      # The first argument is considered to be the scope of the query.  That is, how many 
+      # The first argument is considered to be the scope of the query.  That is, how many
       # resources are returned from the request.  It can be one of the following.
       #
       # * &lt;tt&gt;:one&lt;/tt&gt; - Returns a single resource.
       # * &lt;tt&gt;:first&lt;/tt&gt; - Returns the first resource found.
+      # * &lt;tt&gt;:last&lt;/tt&gt; - Returns the last resource found.
       # * &lt;tt&gt;:all&lt;/tt&gt; - Returns every resource that matches the request.
-      # 
+      #
       # ==== Options
       #
       # * &lt;tt&gt;:from&lt;/tt&gt; - Sets the path or custom method that resources will be fetched from.
-      # * &lt;tt&gt;:params&lt;/tt&gt; - Sets query and prefix (nested URL) parameters.
+      # * &lt;tt&gt;:params&lt;/tt&gt; - Sets query and \prefix (nested URL) parameters.
       #
       # ==== Examples
-      #   Person.find(1)                                         
+      #   Person.find(1)
       #   # =&gt; GET /people/1.xml
       #
-      #   Person.find(:all)                                      
+      #   Person.find(:all)
       #   # =&gt; GET /people.xml
       #
-      #   Person.find(:all, :params =&gt; { :title =&gt; &quot;CEO&quot; })      
+      #   Person.find(:all, :params =&gt; { :title =&gt; &quot;CEO&quot; })
       #   # =&gt; GET /people.xml?title=CEO
       #
-      #   Person.find(:first, :from =&gt; :managers)                  
+      #   Person.find(:first, :from =&gt; :managers)
+      #   # =&gt; GET /people/managers.xml
+      #
+      #   Person.find(:last, :from =&gt; :managers)
       #   # =&gt; GET /people/managers.xml
       #
-      #   Person.find(:all, :from =&gt; &quot;/companies/1/people.xml&quot;)  
+      #   Person.find(:all, :from =&gt; &quot;/companies/1/people.xml&quot;)
       #   # =&gt; GET /companies/1/people.xml
       #
-      #   Person.find(:one, :from =&gt; :leader)                    
+      #   Person.find(:one, :from =&gt; :leader)
       #   # =&gt; GET /people/leader.xml
       #
       #   Person.find(:all, :from =&gt; :developers, :params =&gt; { :language =&gt; 'ruby' })
       #   # =&gt; GET /people/developers.xml?language=ruby
       #
-      #   Person.find(:one, :from =&gt; &quot;/companies/1/manager.xml&quot;) 
+      #   Person.find(:one, :from =&gt; &quot;/companies/1/manager.xml&quot;)
       #   # =&gt; GET /companies/1/manager.xml
       #
-      #   StreetAddress.find(1, :params =&gt; { :person_id =&gt; 1 })  
+      #   StreetAddress.find(1, :params =&gt; { :person_id =&gt; 1 })
       #   # =&gt; GET /people/1/street_addresses/1.xml
       def find(*arguments)
         scope   = arguments.slice!(0)
@@ -503,6 +516,7 @@ module ActiveResource
         case scope
           when :all   then find_every(options)
           when :first then find_every(options).first
+          when :last  then find_every(options).last
           when :one   then find_one(options)
           else             find_single(scope, options)
         end
@@ -511,7 +525,7 @@ module ActiveResource
       # Deletes the resources with the ID in the +id+ parameter.
       #
       # ==== Options
-      # All options specify prefix and query parameters.
+      # All options specify \prefix and query parameters.
       #
       # ==== Examples
       #   Event.delete(2) # sends DELETE /events/2
@@ -560,7 +574,7 @@ module ActiveResource
             instantiate_collection( (connection.get(path, headers) || []), prefix_options )
           end
         end
-        
+
         # Find a single resource from a one-off URL
         def find_one(options)
           case from = options[:from]
@@ -578,7 +592,7 @@ module ActiveResource
           path = element_path(scope, prefix_options, query_options)
           instantiate_record(connection.get(path, headers), prefix_options)
         end
-        
+
         def instantiate_collection(collection, prefix_options = {})
           collection.collect! { |record| instantiate_record(record, prefix_options) }
         end
@@ -602,10 +616,10 @@ module ActiveResource
 
         # Builds the query string for the request.
         def query_string(options)
-          &quot;?#{options.to_query}&quot; unless options.nil? || options.empty? 
+          &quot;?#{options.to_query}&quot; unless options.nil? || options.empty?
         end
 
-        # split an option hash into two hashes, one containing the prefix options, 
+        # split an option hash into two hashes, one containing the prefix options,
         # and the other containing the leftovers.
         def split_options(options = {})
           prefix_options, query_options = {}, {}
@@ -622,8 +636,8 @@ module ActiveResource
     attr_accessor :attributes #:nodoc:
     attr_accessor :prefix_options #:nodoc:
 
-    # Constructor method for new resources; the optional +attributes+ parameter takes a hash
-    # of attributes for the new resource.
+    # Constructor method for \new resources; the optional +attributes+ parameter takes a \hash
+    # of attributes for the \new resource.
     #
     # ==== Examples
     #   my_course = Course.new
@@ -639,8 +653,8 @@ module ActiveResource
       load(attributes)
     end
 
-    # Returns a clone of the resource that hasn't been assigned an +id+ yet and
-    # is treated as a new resource.
+    # Returns a \clone of the resource that hasn't been assigned an +id+ yet and
+    # is treated as a \new resource.
     #
     #   ryan = Person.find(1)
     #   not_ryan = ryan.clone
@@ -654,7 +668,7 @@ module ActiveResource
     #   ryan = Person.find(1)
     #   ryan.address = StreetAddress.find(1, :person_id =&gt; ryan.id)
     #   ryan.hash = {:not =&gt; &quot;an ARes instance&quot;}
-    #   
+    #
     #   not_ryan = ryan.clone
     #   not_ryan.new?            # =&gt; true
     #   not_ryan.address         # =&gt; NoMethodError
@@ -675,7 +689,7 @@ module ActiveResource
     end
 
 
-    # A method to determine if the resource a new object (i.e., it has not been POSTed to the remote service yet).
+    # A method to determine if the resource a \new object (i.e., it has not been POSTed to the remote service yet).
     #
     # ==== Examples
     #   not_new = Computer.create(:brand =&gt; 'Apple', :make =&gt; 'MacBook', :vendor =&gt; 'MacMall')
@@ -691,12 +705,12 @@ module ActiveResource
       id.nil?
     end
 
-    # Get the +id+ attribute of the resource.
+    # Gets the &lt;tt&gt;\id&lt;/tt&gt; attribute of the resource.
     def id
       attributes[self.class.primary_key]
     end
 
-    # Set the +id+ attribute of the resource.
+    # Sets the &lt;tt&gt;\id&lt;/tt&gt; attribute of the resource.
     def id=(id)
       attributes[self.class.primary_key] = id
     end
@@ -706,7 +720,7 @@ module ActiveResource
       id &amp;&amp; id.to_s
     end
 
-    # Test for equality.  Resource are equal if and only if +other+ is the same object or 
+    # Test for equality.  Resource are equal if and only if +other+ is the same object or
     # is an instance of the same class, is not &lt;tt&gt;new?&lt;/tt&gt;, and has the same +id+.
     #
     # ==== Examples
@@ -737,12 +751,12 @@ module ActiveResource
       self == other
     end
 
-    # Delegates to id in order to allow two resources of the same type and id to work with something like:
+    # Delegates to id in order to allow two resources of the same type and \id to work with something like:
     #   [Person.find(1), Person.find(2)] &amp; [Person.find(1), Person.find(4)] # =&gt; [Person.find(1)]
     def hash
       id.hash
     end
-    
+
     # Duplicate the current resource without saving it.
     #
     # ==== Examples
@@ -762,9 +776,9 @@ module ActiveResource
       end
     end
 
-    # A method to save (+POST+) or update (+PUT+) a resource.  It delegates to +create+ if a new object, 
-    # +update+ if it is existing. If the response to the save includes a body, it will be assumed that this body
-    # is XML for the final object as it looked after the save (which would include attributes like +created_at+
+    # A method to \save (+POST+) or \update (+PUT+) a resource.  It delegates to +create+ if a \new object, 
+    # +update+ if it is existing. If the response to the \save includes a body, it will be assumed that this body
+    # is XML for the final object as it looked after the \save (which would include attributes like +created_at+
     # that weren't part of the original submit).
     #
     # ==== Examples
@@ -786,7 +800,7 @@ module ActiveResource
     #   my_person = Person.find(my_id)
     #   my_person.destroy
     #   Person.find(my_id) # 404 (Resource Not Found)
-    #   
+    #
     #   new_person = Person.create(:name =&gt; 'James')
     #   new_id = new_person.id # =&gt; 7
     #   new_person.destroy
@@ -825,7 +839,7 @@ module ActiveResource
     # * &lt;tt&gt;:indent&lt;/tt&gt; - Set the indent level for the XML output (default is +2+).
     # * &lt;tt&gt;:dasherize&lt;/tt&gt; - Boolean option to determine whether or not element names should
     #   replace underscores with dashes (default is &lt;tt&gt;false&lt;/tt&gt;).
-    # * &lt;tt&gt;:skip_instruct&lt;/tt&gt; - Toggle skipping the +instruct!+ call on the XML builder 
+    # * &lt;tt&gt;:skip_instruct&lt;/tt&gt; - Toggle skipping the +instruct!+ call on the XML builder
     #   that generates the XML declaration (default is &lt;tt&gt;false&lt;/tt&gt;).
     #
     # ==== Examples
@@ -840,16 +854,21 @@ module ActiveResource
     #
     #   my_group.to_xml(:skip_instruct =&gt; true)
     #   # =&gt; &lt;subsidiary_group&gt; [...] &lt;/subsidiary_group&gt;
-    def to_xml(options={})
-      attributes.to_xml({:root =&gt; self.class.element_name}.merge(options))
+    def encode(options={})
+      case self.class.format
+        when ActiveResource::Formats[:xml]
+          self.class.format.encode(attributes, {:root =&gt; self.class.element_name}.merge(options))
+        else
+          self.class.format.encode(attributes, options)
+      end
     end
 
-    # A method to reload the attributes of this object from the remote web service.
+    # A method to \reload the attributes of this object from the remote web service.
     #
     # ==== Examples
     #   my_branch = Branch.find(:first)
     #   my_branch.name # =&gt; &quot;Wislon Raod&quot;
-    #   
+    #
     #   # Another client fixes the typo...
     #
     #   my_branch.name # =&gt; &quot;Wislon Raod&quot;
@@ -859,8 +878,8 @@ module ActiveResource
       self.load(self.class.find(to_param, :params =&gt; @prefix_options).attributes)
     end
 
-    # A method to manually load attributes from a hash. Recursively loads collections of
-    # resources.  This method is called in +initialize+ and +create+ when a hash of attributes
+    # A method to manually load attributes from a \hash. Recursively loads collections of
+    # resources.  This method is called in +initialize+ and +create+ when a \hash of attributes
     # is provided.
     #
     # ==== Examples
@@ -897,19 +916,19 @@ module ActiveResource
       end
       self
     end
-    
+
     # For checking &lt;tt&gt;respond_to?&lt;/tt&gt; without searching the attributes (which is faster).
     alias_method :respond_to_without_attributes?, :respond_to?
 
     # A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a Person object with a
-    # +name+ attribute can answer &lt;tt&gt;true&lt;/tt&gt; to &lt;tt&gt;my_person.respond_to?(&quot;name&quot;)&lt;/tt&gt;, &lt;tt&gt;my_person.respond_to?(&quot;name=&quot;)&lt;/tt&gt;, and
-    # &lt;tt&gt;my_person.respond_to?(&quot;name?&quot;)&lt;/tt&gt;.
+    # +name+ attribute can answer &lt;tt&gt;true&lt;/tt&gt; to &lt;tt&gt;my_person.respond_to?(:name)&lt;/tt&gt;, &lt;tt&gt;my_person.respond_to?(:name=)&lt;/tt&gt;, and
+    # &lt;tt&gt;my_person.respond_to?(:name?)&lt;/tt&gt;.
     def respond_to?(method, include_priv = false)
       method_name = method.to_s
       if attributes.nil?
         return super
       elsif attributes.has_key?(method_name)
-        return true 
+        return true
       elsif ['?','='].include?(method_name.last) &amp;&amp; attributes.has_key?(method_name.first(-1))
         return true
       end
@@ -917,7 +936,7 @@ module ActiveResource
       # would return true for generated readers, even if the attribute wasn't present
       super
     end
-    
+
 
     protected
       def connection(refresh = false)
@@ -926,19 +945,19 @@ module ActiveResource
 
       # Update the resource on the remote service.
       def update
-        returning connection.put(element_path(prefix_options), to_xml, self.class.headers) do |response|
+        returning connection.put(element_path(prefix_options), encode, self.class.headers) do |response|
           load_attributes_from_response(response)
         end
       end
 
-      # Create (i.e., save to the remote service) the new resource.
+      # Create (i.e., \save to the remote service) the \new resource.
       def create
-        returning connection.post(collection_path, to_xml, self.class.headers) do |response|
+        returning connection.post(collection_path, encode, self.class.headers) do |response|
           self.id = id_from_response(response)
           load_attributes_from_response(response)
         end
       end
-      
+
       def load_attributes_from_response(response)
         if response['Content-Length'] != &quot;0&quot; &amp;&amp; response.body.strip.size &gt; 0
           load(self.class.format.decode(response.body))
@@ -963,7 +982,7 @@ module ActiveResource
       def find_or_create_resource_for_collection(name)
         find_or_create_resource_for(name.to_s.singularize)
       end
-      
+
       # Tries to find a resource in a non empty list of nested modules
       # Raises a NameError if it was not found in any of the given nested modules
       def find_resource_in_modules(resource_name, module_names)
@@ -999,7 +1018,7 @@ module ActiveResource
       end
 
       def split_options(options = {})
-        self.class.send!(:split_options, options)
+        self.class.__send__(:split_options, options)
       end
 
       def method_missing(method_symbol, *arguments) #:nodoc:</diff>
      <filename>activeresource/lib/active_resource/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -63,6 +63,13 @@ module ActiveResource
   # This class is used by ActiveResource::Base to interface with REST
   # services.
   class Connection
+
+    HTTP_FORMAT_HEADER_NAMES = {  :get =&gt; 'Accept',
+      :put =&gt; 'Content-Type',
+      :post =&gt; 'Content-Type',
+      :delete =&gt; 'Accept'
+    }
+
     attr_reader :site, :user, :password, :timeout
     attr_accessor :format
 
@@ -106,25 +113,25 @@ module ActiveResource
     # Execute a GET request.
     # Used to get (find) resources.
     def get(path, headers = {})
-      format.decode(request(:get, path, build_request_headers(headers)).body)
+      format.decode(request(:get, path, build_request_headers(headers, :get)).body)
     end
 
     # Execute a DELETE request (see HTTP protocol documentation if unfamiliar).
     # Used to delete resources.
     def delete(path, headers = {})
-      request(:delete, path, build_request_headers(headers))
+      request(:delete, path, build_request_headers(headers, :delete))
     end
 
     # Execute a PUT request (see HTTP protocol documentation if unfamiliar).
     # Used to update resources.
     def put(path, body = '', headers = {})
-      request(:put, path, body.to_s, build_request_headers(headers))
+      request(:put, path, body.to_s, build_request_headers(headers, :put))
     end
 
     # Execute a POST request.
     # Used to create new resources.
     def post(path, body = '', headers = {})
-      request(:post, path, body.to_s, build_request_headers(headers))
+      request(:post, path, body.to_s, build_request_headers(headers, :post))
     end
 
     # Execute a HEAD request.
@@ -187,12 +194,12 @@ module ActiveResource
       end
 
       def default_header
-        @default_header ||= { 'Content-Type' =&gt; format.mime_type }
+        @default_header ||= {}
       end
 
       # Builds headers for request to remote service.
-      def build_request_headers(headers)
-        authorization_header.update(default_header).update(headers)
+      def build_request_headers(headers, http_method=nil)
+        authorization_header.update(default_header).update(headers).update(http_format_header(http_method))
       end
 
       # Sets authorization header
@@ -200,6 +207,10 @@ module ActiveResource
         (@user || @password ? { 'Authorization' =&gt; 'Basic ' + [&quot;#{@user}:#{ @password}&quot;].pack('m').delete(&quot;\r\n&quot;) } : {})
       end
 
+      def http_format_header(http_method)
+        {HTTP_FORMAT_HEADER_NAMES[http_method] =&gt; format.mime_type}
+      end
+
       def logger #:nodoc:
         Base.logger
       end</diff>
      <filename>activeresource/lib/active_resource/connection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,7 +30,7 @@ module ActiveResource
   #   Person.get(:active)  # GET /people/active.xml
   #   # =&gt; [{:id =&gt; 1, :name =&gt; 'Ryan'}, {:id =&gt; 2, :name =&gt; 'Joe'}]
   #
-  module CustomMethods 
+  module CustomMethods
     def self.included(base)
       base.class_eval do
         extend ActiveResource::CustomMethods::ClassMethods
@@ -83,24 +83,25 @@ module ActiveResource
         &quot;#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}&quot;
       end
     end
-    
+
     module InstanceMethods
       def get(method_name, options = {})
         connection.get(custom_method_element_url(method_name, options), self.class.headers)
       end
-      
-      def post(method_name, options = {}, body = '')
+
+      def post(method_name, options = {}, body = nil)
+        request_body = body.nil? ? encode : body
         if new?
-          connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body), self.class.headers)
+          connection.post(custom_method_new_element_url(method_name, options), request_body, self.class.headers)
         else
-          connection.post(custom_method_element_url(method_name, options), body, self.class.headers)
+          connection.post(custom_method_element_url(method_name, options), request_body, self.class.headers)
         end
       end
-      
+
       def put(method_name, options = {}, body = '')
         connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
       end
-      
+
       def delete(method_name, options = {})
         connection.delete(custom_method_element_url(method_name, options), self.class.headers)
       end
@@ -108,11 +109,11 @@ module ActiveResource
 
       private
         def custom_method_element_url(method_name, options = {})
-          &quot;#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}&quot;
+          &quot;#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.__send__(:query_string, options)}&quot;
         end
-      
+
         def custom_method_new_element_url(method_name, options = {})
-          &quot;#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}&quot;
+          &quot;#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.__send__(:query_string, options)}&quot;
         end
     end
   end</diff>
      <filename>activeresource/lib/active_resource/custom_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,22 +2,22 @@ module ActiveResource
   module Formats
     module JsonFormat
       extend self
-      
+
       def extension
         &quot;json&quot;
       end
-      
+
       def mime_type
         &quot;application/json&quot;
       end
-      
-      def encode(hash)
+
+      def encode(hash, options={})
         hash.to_json
       end
-      
+
       def decode(json)
         ActiveSupport::JSON.decode(json)
       end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activeresource/lib/active_resource/formats/json_format.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,23 +2,23 @@ module ActiveResource
   module Formats
     module XmlFormat
       extend self
-      
+
       def extension
         &quot;xml&quot;
       end
-      
+
       def mime_type
         &quot;application/xml&quot;
       end
-      
-      def encode(hash)
-        hash.to_xml
+
+      def encode(hash, options={})
+        hash.to_xml(options)
       end
-      
+
       def decode(xml)
         from_xml_data(Hash.from_xml(xml))
       end
-      
+
       private
         # Manipulate from_xml Hash, because xml_simple is not exactly what we
         # want for Active Resource.
@@ -28,7 +28,7 @@ module ActiveResource
           else
             data
           end
-        end      
+        end
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>activeresource/lib/active_resource/formats/xml_format.rb</filename>
    </modified>
    <modified>
      <diff>@@ -146,7 +146,7 @@ module ActiveResource
     attr_accessor :path, :method, :body, :headers
 
     def initialize(method, path, body = nil, headers = {})
-      @method, @path, @body, @headers = method, path, body, headers.reverse_merge('Content-Type' =&gt; 'application/xml')
+      @method, @path, @body, @headers = method, path, body, headers.merge(ActiveResource::Connection::HTTP_FORMAT_HEADER_NAMES[method] =&gt; 'application/xml')
     end
 
     def ==(other_request)</diff>
      <filename>activeresource/lib/active_resource/http_mock.rb</filename>
    </modified>
    <modified>
      <diff>@@ -216,39 +216,25 @@ module ActiveResource
     end
   end
   
-  # Module to allow validation of Active Resource objects, which creates an Errors instance for every resource.
-  # Methods are implemented by overriding Base#validate or its variants   Each of these methods can inspect 
-  # the state of the object, which usually means  ensuring that a number of attributes have a certain value 
-  # (such as not empty, within a given range, matching a certain regular expression and so on).
+  # Module to support validation and errors with Active Resource objects. The module overrides
+  # Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned 
+  # in the web service response. The module also adds an +errors+ collection that mimics the interface 
+  # of the errors provided by ActiveRecord::Errors.
   #
   # ==== Example
   #
-  #   class Person &lt; ActiveResource::Base
-  #      self.site = &quot;http://www.localhost.com:3000/&quot;
-  #      protected
-  #        def validate
-  #          errors.add_on_empty %w( first_name last_name )
-  #          errors.add(&quot;phone_number&quot;, &quot;has invalid format&quot;) unless phone_number =~ /[0-9]*/
-  #        end
+  # Consider a Person resource on the server requiring both a +first_name+ and a +last_name+ with a 
+  # &lt;tt&gt;validates_presence_of :first_name, :last_name&lt;/tt&gt; declaration in the model:
   #
-  #        def validate_on_create # is only run the first time a new object is saved
-  #          unless valid_member?(self)
-  #            errors.add(&quot;membership_discount&quot;, &quot;has expired&quot;)
-  #          end
-  #        end
-  #
-  #        def validate_on_update
-  #          errors.add_to_base(&quot;No changes have occurred&quot;) if unchanged_attributes?
-  #        end
-  #   end
-  #   
-  #   person = Person.new(&quot;first_name&quot; =&gt; &quot;Jim&quot;, &quot;phone_number&quot; =&gt; &quot;I will not tell you.&quot;)
-  #   person.save                         # =&gt; false (and doesn't do the save)
-  #   person.errors.empty?                # =&gt; false
-  #   person.errors.count                 # =&gt; 2
-  #   person.errors.on &quot;last_name&quot;        # =&gt; &quot;can't be empty&quot;
-  #   person.attributes = { &quot;last_name&quot; =&gt; &quot;Halpert&quot;, &quot;phone_number&quot; =&gt; &quot;555-5555&quot; }
-  #   person.save                         # =&gt; true (and person is now saved to the remote service)
+  #   person = Person.new(:first_name =&gt; &quot;Jim&quot;, :last_name =&gt; &quot;&quot;)
+  #   person.save                   # =&gt; false (server returns an HTTP 422 status code and errors)
+  #   person.valid?                 # =&gt; false
+  #   person.errors.empty?          # =&gt; false
+  #   person.errors.count           # =&gt; 1
+  #   person.errors.full_messages   # =&gt; [&quot;Last name can't be empty&quot;]
+  #   person.errors.on(:last_name)  # =&gt; &quot;can't be empty&quot;
+  #   person.last_name = &quot;Halpert&quot;  
+  #   person.save                   # =&gt; true (and person is now saved to the remote service)
   #
   module Validations
     def self.included(base) # :nodoc:</diff>
      <filename>activeresource/lib/active_resource/validations.rb</filename>
    </modified>
    <modified>
      <diff>@@ -19,7 +19,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   end
 
   def test_authorization_header
-    authorization_header = @authenticated_conn.send!(:authorization_header)
+    authorization_header = @authenticated_conn.__send__(:authorization_header)
     assert_equal @authorization_request_header['Authorization'], authorization_header['Authorization']
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
     
@@ -29,7 +29,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   
   def test_authorization_header_with_username_but_no_password
     @conn = ActiveResource::Connection.new(&quot;http://david:@localhost&quot;)
-    authorization_header = @conn.send!(:authorization_header)
+    authorization_header = @conn.__send__(:authorization_header)
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
     
     assert_equal &quot;Basic&quot;, authorization[0]
@@ -38,7 +38,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   
   def test_authorization_header_with_password_but_no_username
     @conn = ActiveResource::Connection.new(&quot;http://:test123@localhost&quot;)
-    authorization_header = @conn.send!(:authorization_header)
+    authorization_header = @conn.__send__(:authorization_header)
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
     
     assert_equal &quot;Basic&quot;, authorization[0]
@@ -47,7 +47,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   
   def test_authorization_header_with_decoded_credentials_from_url
     @conn = ActiveResource::Connection.new(&quot;http://my%40email.com:%31%32%33@localhost&quot;)
-    authorization_header = @conn.send!(:authorization_header)
+    authorization_header = @conn.__send__(:authorization_header)
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
 
     assert_equal &quot;Basic&quot;, authorization[0]
@@ -58,7 +58,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
     @authenticated_conn = ActiveResource::Connection.new(&quot;http://@localhost&quot;)
     @authenticated_conn.user = 'david'
     @authenticated_conn.password = 'test123'
-    authorization_header = @authenticated_conn.send!(:authorization_header)
+    authorization_header = @authenticated_conn.__send__(:authorization_header)
     assert_equal @authorization_request_header['Authorization'], authorization_header['Authorization']
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
 
@@ -69,7 +69,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   def test_authorization_header_explicitly_setting_username_but_no_password
     @conn = ActiveResource::Connection.new(&quot;http://@localhost&quot;)
     @conn.user = &quot;david&quot;
-    authorization_header = @conn.send!(:authorization_header)
+    authorization_header = @conn.__send__(:authorization_header)
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
 
     assert_equal &quot;Basic&quot;, authorization[0]
@@ -79,7 +79,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   def test_authorization_header_explicitly_setting_password_but_no_username
     @conn = ActiveResource::Connection.new(&quot;http://@localhost&quot;)
     @conn.password = &quot;test123&quot;
-    authorization_header = @conn.send!(:authorization_header)
+    authorization_header = @conn.__send__(:authorization_header)
     authorization = authorization_header[&quot;Authorization&quot;].to_s.split
 
     assert_equal &quot;Basic&quot;, authorization[0]
@@ -116,7 +116,7 @@ class AuthorizationTest &lt; Test::Unit::TestCase
   protected
     def assert_response_raises(klass, code)
       assert_raise(klass, &quot;Expected response code #{code} to raise #{klass}&quot;) do
-        @conn.send!(:handle_response, Response.new(code))
+        @conn.__send__(:handle_response, Response.new(code))
       end
     end
 end</diff>
      <filename>activeresource/test/authorization_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,8 +10,7 @@ class CustomMethodsTest &lt; Test::Unit::TestCase
     @ryan  = { :name =&gt; 'Ryan' }.to_xml(:root =&gt; 'person')
     @addy  = { :id =&gt; 1, :street =&gt; '12345 Street' }.to_xml(:root =&gt; 'address')
     @addy_deep  = { :id =&gt; 1, :street =&gt; '12345 Street', :zip =&gt; &quot;27519&quot; }.to_xml(:root =&gt; 'address')
-    @default_request_headers = { 'Content-Type' =&gt; 'application/xml' }
-    
+
     ActiveResource::HttpMock.respond_to do |mock|
       mock.get    &quot;/people/1.xml&quot;,             {}, @matz
       mock.get    &quot;/people/1/shallow.xml&quot;, {}, @matz</diff>
      <filename>activeresource/test/base/custom_methods_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -84,7 +84,7 @@ class BaseLoadTest &lt; Test::Unit::TestCase
   end
 
   def test_load_collection_with_unknown_resource
-    Person.send!(:remove_const, :Address) if Person.const_defined?(:Address)
+    Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
     assert !Person.const_defined?(:Address), &quot;Address shouldn't exist until autocreated&quot;
     addresses = silence_warnings { @person.load(:addresses =&gt; @addresses).addresses }
     assert Person.const_defined?(:Address), &quot;Address should have been autocreated&quot;
@@ -100,7 +100,7 @@ class BaseLoadTest &lt; Test::Unit::TestCase
   end
 
   def test_load_collection_with_single_unknown_resource
-    Person.send!(:remove_const, :Address) if Person.const_defined?(:Address)
+    Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
     assert !Person.const_defined?(:Address), &quot;Address shouldn't exist until autocreated&quot;
     addresses = silence_warnings { @person.load(:addresses =&gt; [ @first_address ]).addresses }
     assert Person.const_defined?(:Address), &quot;Address should have been autocreated&quot;</diff>
      <filename>activeresource/test/base/load_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ class BaseTest &lt; Test::Unit::TestCase
   def setup
     @matz  = { :id =&gt; 1, :name =&gt; 'Matz' }.to_xml(:root =&gt; 'person')
     @david = { :id =&gt; 2, :name =&gt; 'David' }.to_xml(:root =&gt; 'person')
-    @greg  = { :id =&gt; 3, :name =&gt; 'Greg' }.to_xml(:root =&gt; 'person')    
+    @greg  = { :id =&gt; 3, :name =&gt; 'Greg' }.to_xml(:root =&gt; 'person')
     @addy  = { :id =&gt; 1, :street =&gt; '12345 Street' }.to_xml(:root =&gt; 'address')
     @default_request_headers = { 'Content-Type' =&gt; 'application/xml' }
     @rick = { :name =&gt; &quot;Rick&quot;, :age =&gt; 25 }.to_xml(:root =&gt; &quot;person&quot;)
@@ -50,7 +50,7 @@ class BaseTest &lt; Test::Unit::TestCase
     ActiveResource::HttpMock.respond_to do |mock|
       mock.get    &quot;/people/1.xml&quot;,                {}, @matz
       mock.get    &quot;/people/2.xml&quot;,                {}, @david
-      mock.get    &quot;/people/Greg.xml&quot;,             {}, @greg      
+      mock.get    &quot;/people/Greg.xml&quot;,             {}, @greg
       mock.get    &quot;/people/4.xml&quot;,                {'key' =&gt; 'value'}, nil, 404
       mock.put    &quot;/people/1.xml&quot;,                {}, nil, 204
       mock.delete &quot;/people/1.xml&quot;,                {}, nil, 200
@@ -62,7 +62,7 @@ class BaseTest &lt; Test::Unit::TestCase
       mock.get    &quot;/people/1/addresses/1.xml&quot;,    {}, @addy
       mock.get    &quot;/people/1/addresses/2.xml&quot;,    {}, nil, 404
       mock.get    &quot;/people/2/addresses/1.xml&quot;,    {}, nil, 404
-      mock.get    &quot;/people/Greg/addresses/1.xml&quot;, {}, @addy      
+      mock.get    &quot;/people/Greg/addresses/1.xml&quot;, {}, @addy
       mock.put    &quot;/people/1/addresses/1.xml&quot;,    {}, nil, 204
       mock.delete &quot;/people/1/addresses/1.xml&quot;,    {}, nil, 200
       mock.post   &quot;/people/1/addresses.xml&quot;,      {}, nil, 201, 'Location' =&gt; '/people/1/addresses/5'
@@ -101,13 +101,13 @@ class BaseTest &lt; Test::Unit::TestCase
     assert_equal 'http://foo:bar@beast.caboo.se', Forum.site.to_s
     assert_equal 'http://foo:bar@beast.caboo.se/forums/:forum_id', Topic.site.to_s
   end
-  
+
   def test_site_variable_can_be_reset
-    actor = Class.new(ActiveResource::Base)    
+    actor = Class.new(ActiveResource::Base)
     assert_nil actor.site
     actor.site = 'http://localhost:31337'
     actor.site = nil
-    assert_nil actor.site    
+    assert_nil actor.site
   end
 
   def test_should_accept_setting_user
@@ -194,18 +194,18 @@ class BaseTest &lt; Test::Unit::TestCase
     actor.site = 'http://nomad'
     assert_equal actor.site, jester.site
     assert jester.site.frozen?
-    
-    # Subclasses are always equal to superclass site when not overridden    
+
+    # Subclasses are always equal to superclass site when not overridden
     fruit = Class.new(ActiveResource::Base)
     apple = Class.new(fruit)
-    
+
     fruit.site = 'http://market'
     assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
-    
+
     fruit.site = 'http://supermarket'
     assert_equal fruit.site, apple.site, 'subclass did not adopt changes from parent class'
   end
-  
+
   def test_user_reader_uses_superclass_user_until_written
     # Superclass is Object so returns nil.
     assert_nil ActiveResource::Base.user
@@ -317,14 +317,14 @@ class BaseTest &lt; Test::Unit::TestCase
   end
 
   def test_updating_baseclass_site_object_wipes_descendent_cached_connection_objects
-    # Subclasses are always equal to superclass site when not overridden    
+    # Subclasses are always equal to superclass site when not overridden
     fruit = Class.new(ActiveResource::Base)
     apple = Class.new(fruit)
-    
+
     fruit.site = 'http://market'
     assert_equal fruit.connection.site, apple.connection.site
     first_connection = apple.connection.object_id
-    
+
     fruit.site = 'http://supermarket'
     assert_equal fruit.connection.site, apple.connection.site
     second_connection = apple.connection.object_id
@@ -393,34 +393,34 @@ class BaseTest &lt; Test::Unit::TestCase
     assert_equal '/people.xml?gender=', Person.collection_path(:gender =&gt; nil)
 
     assert_equal '/people.xml?gender=male', Person.collection_path('gender' =&gt; 'male')
-    
+
     # Use includes? because ordering of param hash is not guaranteed
     assert Person.collection_path(:gender =&gt; 'male', :student =&gt; true).include?('/people.xml?')
     assert Person.collection_path(:gender =&gt; 'male', :student =&gt; true).include?('gender=male')
     assert Person.collection_path(:gender =&gt; 'male', :student =&gt; true).include?('student=true')
 
     assert_equal '/people.xml?name%5B%5D=bob&amp;name%5B%5D=your+uncle%2Bme&amp;name%5B%5D=&amp;name%5B%5D=false', Person.collection_path(:name =&gt; ['bob', 'your uncle+me', nil, false])
-    
+
     assert_equal '/people.xml?struct%5Ba%5D%5B%5D=2&amp;struct%5Ba%5D%5B%5D=1&amp;struct%5Bb%5D=fred', Person.collection_path(:struct =&gt; {:a =&gt; [2,1], 'b' =&gt; 'fred'})
   end
 
   def test_custom_element_path
     assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, :person_id =&gt; 1)
     assert_equal '/people/1/addresses/1.xml', StreetAddress.element_path(1, 'person_id' =&gt; 1)
-    assert_equal '/people/Greg/addresses/1.xml', StreetAddress.element_path(1, 'person_id' =&gt; 'Greg')    
+    assert_equal '/people/Greg/addresses/1.xml', StreetAddress.element_path(1, 'person_id' =&gt; 'Greg')
   end
-  
+
   def test_custom_element_path_with_redefined_to_param
     Person.module_eval do
       alias_method :original_to_param_element_path, :to_param
-       def to_param  
+       def to_param
          name
        end
     end
 
     # Class method.
     assert_equal '/people/Greg.xml', Person.element_path('Greg')
-    
+
     # Protected Instance method.
     assert_equal '/people/Greg.xml', Person.find('Greg').send(:element_path)
 
@@ -468,23 +468,32 @@ class BaseTest &lt; Test::Unit::TestCase
 
   def test_prefix
     assert_equal &quot;/&quot;, Person.prefix
-    assert_equal Set.new, Person.send!(:prefix_parameters)
+    assert_equal Set.new, Person.__send__(:prefix_parameters)
   end
-  
+
   def test_set_prefix
     SetterTrap.rollback_sets(Person) do |person_class|
       person_class.prefix = &quot;the_prefix&quot;
       assert_equal &quot;the_prefix&quot;, person_class.prefix
     end
   end
-  
+
   def test_set_prefix_with_inline_keys
     SetterTrap.rollback_sets(Person) do |person_class|
       person_class.prefix = &quot;the_prefix:the_param&quot;
       assert_equal &quot;the_prefixthe_param_value&quot;, person_class.prefix(:the_param =&gt; &quot;the_param_value&quot;)
     end
   end
-  
+
+  def test_set_prefix_twice_should_clear_params
+    SetterTrap.rollback_sets(Person) do |person_class|
+      person_class.prefix = &quot;the_prefix/:the_param1&quot;
+      assert_equal Set.new([:the_param1]), person_class.prefix_parameters
+      person_class.prefix = &quot;the_prefix/:the_param2&quot;
+      assert_equal Set.new([:the_param2]), person_class.prefix_parameters
+    end
+  end
+
   def test_set_prefix_with_default_value
     SetterTrap.rollback_sets(Person) do |person_class|
       person_class.set_prefix
@@ -495,7 +504,7 @@ class BaseTest &lt; Test::Unit::TestCase
   def test_custom_prefix
     assert_equal '/people//', StreetAddress.prefix
     assert_equal '/people/1/', StreetAddress.prefix(:person_id =&gt; 1)
-    assert_equal [:person_id].to_set, StreetAddress.send!(:prefix_parameters)
+    assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters)
   end
 
   def test_find_by_id
@@ -504,7 +513,7 @@ class BaseTest &lt; Test::Unit::TestCase
     assert_equal &quot;Matz&quot;, matz.name
     assert matz.name?
   end
-  
+
   def test_respond_to
     matz = Person.find(1)
     assert matz.respond_to?(:name)
@@ -533,6 +542,12 @@ class BaseTest &lt; Test::Unit::TestCase
     assert_equal &quot;Matz&quot;, matz.name
   end
 
+  def test_find_last
+    david = Person.find(:last)
+    assert_kind_of Person, david
+    assert_equal 'David', david.name
+  end
+
   def test_custom_header
     Person.headers['key'] = 'value'
     assert_raises(ActiveResource::ResourceNotFound) { Person.find(4) }
@@ -547,7 +562,7 @@ class BaseTest &lt; Test::Unit::TestCase
 
   def test_find_all_by_from
     ActiveResource::HttpMock.respond_to { |m| m.get &quot;/companies/1/people.xml&quot;, {}, @people_david }
-  
+
     people = Person.find(:all, :from =&gt; &quot;/companies/1/people.xml&quot;)
     assert_equal 1, people.size
     assert_equal &quot;David&quot;, people.first.name
@@ -555,7 +570,7 @@ class BaseTest &lt; Test::Unit::TestCase
 
   def test_find_all_by_from_with_options
     ActiveResource::HttpMock.respond_to { |m| m.get &quot;/companies/1/people.xml&quot;, {}, @people_david }
-  
+
     people = Person.find(:all, :from =&gt; &quot;/companies/1/people.xml&quot;)
     assert_equal 1, people.size
     assert_equal &quot;David&quot;, people.first.name
@@ -563,7 +578,7 @@ class BaseTest &lt; Test::Unit::TestCase
 
   def test_find_all_by_symbol_from
     ActiveResource::HttpMock.respond_to { |m| m.get &quot;/people/managers.xml&quot;, {}, @people_david }
-  
+
     people = Person.find(:all, :from =&gt; :managers)
     assert_equal 1, people.size
     assert_equal &quot;David&quot;, people.first.name
@@ -592,10 +607,10 @@ class BaseTest &lt; Test::Unit::TestCase
   def test_id_from_response
     p = Person.new
     resp = {'Location' =&gt; '/foo/bar/1'}
-    assert_equal '1', p.send!(:id_from_response, resp)
-    
+    assert_equal '1', p.__send__(:id_from_response, resp)
+
     resp['Location'] &lt;&lt; '.xml'
-    assert_equal '1', p.send!(:id_from_response, resp)
+    assert_equal '1', p.__send__(:id_from_response, resp)
   end
 
   def test_create_with_custom_prefix
@@ -610,16 +625,16 @@ class BaseTest &lt; Test::Unit::TestCase
     ryan = Person.new(:id =&gt; 1, :name =&gt; 'Ryan', :address =&gt; address)
     assert_equal address.prefix_options, ryan.address.prefix_options
   end
-  
+
   def test_reload_works_with_prefix_options
     address = StreetAddress.find(1, :params =&gt; { :person_id =&gt; 1 })
     assert_equal address, address.reload
   end
-  
+
   def test_reload_with_redefined_to_param
     Person.module_eval do
       alias_method :original_to_param_reload, :to_param
-       def to_param  
+       def to_param
          name
        end
     end
@@ -634,13 +649,13 @@ class BaseTest &lt; Test::Unit::TestCase
         alias_method :reload_to_param, :to_param
         alias_method :to_param, :original_to_param_reload
       end
-  end  
-  
-  def test_reload_works_without_prefix_options    
+  end
+
+  def test_reload_works_without_prefix_options
     person = Person.find(:first)
     assert_equal person, person.reload
   end
-    
+
 
   def test_create
     rick = Person.create(:name =&gt; 'Rick')
@@ -650,11 +665,11 @@ class BaseTest &lt; Test::Unit::TestCase
 
     # test additional attribute returned on create
     assert_equal 25, rick.age
-    
+
     # Test that save exceptions get bubbled up too
     ActiveResource::HttpMock.respond_to do |mock|
       mock.post   &quot;/people.xml&quot;, {}, nil, 409
-    end    
+    end
     assert_raises(ActiveResource::ResourceConflict) { Person.create(:name =&gt; 'Rick') }
   end
 
@@ -716,7 +731,7 @@ class BaseTest &lt; Test::Unit::TestCase
     assert_equal &quot;54321 Lane&quot;, addy.street
     addy.save
   end
-  
+
   def test_update_conflict
     ActiveResource::HttpMock.respond_to do |mock|
       mock.get &quot;/people/2.xml&quot;, {}, @david
@@ -748,7 +763,7 @@ class BaseTest &lt; Test::Unit::TestCase
     end
     assert_raises(ActiveResource::ResourceNotFound) { Person.find(1) }
   end
-  
+
   def test_delete_with_custom_prefix
     assert StreetAddress.delete(1, :person_id =&gt; 1)
     ActiveResource::HttpMock.respond_to do |mock|
@@ -778,23 +793,23 @@ class BaseTest &lt; Test::Unit::TestCase
     assert !StreetAddress.new({:id =&gt; 1, :person_id =&gt; 2}).exists?
     assert !StreetAddress.new({:id =&gt; 2, :person_id =&gt; 1}).exists?
   end
-  
+
   def test_exists_with_redefined_to_param
     Person.module_eval do
       alias_method :original_to_param_exists, :to_param
-       def to_param  
+       def to_param
          name
        end
     end
 
     # Class method.
-    assert Person.exists?('Greg')    
+    assert Person.exists?('Greg')
 
     # Instance method.
-    assert Person.find('Greg').exists?    
+    assert Person.find('Greg').exists?
 
     # Nested class method.
-    assert StreetAddress.exists?(1,  :params =&gt; { :person_id =&gt; Person.find('Greg').to_param })    
+    assert StreetAddress.exists?(1,  :params =&gt; { :person_id =&gt; Person.find('Greg').to_param })
 
     # Nested instance method.
     assert StreetAddress.find(1, :params =&gt; { :person_id =&gt; Person.find('Greg').to_param }).exists?
@@ -806,11 +821,11 @@ class BaseTest &lt; Test::Unit::TestCase
         alias_method :exists_to_param, :to_param
         alias_method :to_param, :original_to_param_exists
       end
-  end  
-  
+  end
+
   def test_to_xml
     matz = Person.find(1)
-    xml = matz.to_xml
+    xml = matz.encode
     assert xml.starts_with?('&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;')
     assert xml.include?('&lt;name&gt;Matz&lt;/name&gt;')
     assert xml.include?('&lt;id type=&quot;integer&quot;&gt;1&lt;/id&gt;')</diff>
      <filename>activeresource/test/base_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -185,6 +185,6 @@ class ConnectionTest &lt; Test::Unit::TestCase
     end
 
     def handle_response(response)
-      @conn.send!(:handle_response, response)
+      @conn.__send__(:handle_response, response)
     end
 end</diff>
      <filename>activeresource/test/connection_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,14 +5,22 @@ class FormatTest &lt; Test::Unit::TestCase
   def setup
     @matz  = { :id =&gt; 1, :name =&gt; 'Matz' }
     @david = { :id =&gt; 2, :name =&gt; 'David' }
-    
+
     @programmers = [ @matz, @david ]
   end
-  
+
+  def test_http_format_header_name
+    header_name = ActiveResource::Connection::HTTP_FORMAT_HEADER_NAMES[:get]
+    assert_equal 'Accept', header_name
+
+    headers_names = [ActiveResource::Connection::HTTP_FORMAT_HEADER_NAMES[:put], ActiveResource::Connection::HTTP_FORMAT_HEADER_NAMES[:post]]
+    headers_names.each{|header_name| assert_equal 'Content-Type', header_name}
+  end
+
   def test_formats_on_single_element
     for format in [ :json, :xml ]
       using_format(Person, format) do
-        ActiveResource::HttpMock.respond_to.get &quot;/people/1.#{format}&quot;, {}, ActiveResource::Formats[format].encode(@david)
+        ActiveResource::HttpMock.respond_to.get &quot;/people/1.#{format}&quot;, {'Accept' =&gt; ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@david)
         assert_equal @david[:name], Person.find(1).name
       end
     end
@@ -21,7 +29,7 @@ class FormatTest &lt; Test::Unit::TestCase
   def test_formats_on_collection
     for format in [ :json, :xml ]
       using_format(Person, format) do
-        ActiveResource::HttpMock.respond_to.get &quot;/people.#{format}&quot;, {}, ActiveResource::Formats[format].encode(@programmers)
+        ActiveResource::HttpMock.respond_to.get &quot;/people.#{format}&quot;, {'Accept' =&gt; ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@programmers)
         remote_programmers = Person.find(:all)
         assert_equal 2, remote_programmers.size
         assert remote_programmers.select { |p| p.name == 'David' }
@@ -32,7 +40,7 @@ class FormatTest &lt; Test::Unit::TestCase
   def test_formats_on_custom_collection_method
     for format in [ :json, :xml ]
       using_format(Person, format) do
-        ActiveResource::HttpMock.respond_to.get &quot;/people/retrieve.#{format}?name=David&quot;, {}, ActiveResource::Formats[format].encode([@david])
+        ActiveResource::HttpMock.respond_to.get &quot;/people/retrieve.#{format}?name=David&quot;, {'Accept' =&gt; ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode([@david])
         remote_programmers = Person.get(:retrieve, :name =&gt; 'David')
         assert_equal 1, remote_programmers.size
         assert_equal @david[:id], remote_programmers[0]['id']
@@ -40,13 +48,13 @@ class FormatTest &lt; Test::Unit::TestCase
       end
     end
   end
-  
+
   def test_formats_on_custom_element_method
     for format in [ :json, :xml ]
       using_format(Person, format) do
         ActiveResource::HttpMock.respond_to do |mock|
-          mock.get &quot;/people/2.#{format}&quot;, {}, ActiveResource::Formats[format].encode(@david)
-          mock.get &quot;/people/2/shallow.#{format}&quot;, {}, ActiveResource::Formats[format].encode(@david)
+          mock.get &quot;/people/2.#{format}&quot;, {'Accept' =&gt; ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@david)
+          mock.get &quot;/people/2/shallow.#{format}&quot;, {'Accept' =&gt; ActiveResource::Formats[format].mime_type}, ActiveResource::Formats[format].encode(@david)
         end
         remote_programmer = Person.find(2).get(:shallow)
         assert_equal @david[:id], remote_programmer['id']
@@ -57,20 +65,24 @@ class FormatTest &lt; Test::Unit::TestCase
     for format in [ :json, :xml ]
       ryan = ActiveResource::Formats[format].encode({ :name =&gt; 'Ryan' })
       using_format(Person, format) do
-        ActiveResource::HttpMock.respond_to.post &quot;/people/new/register.#{format}&quot;, {}, ryan, 201, 'Location' =&gt; &quot;/people/5.#{format}&quot;
         remote_ryan = Person.new(:name =&gt; 'Ryan')
+        ActiveResource::HttpMock.respond_to.post &quot;/people.#{format}&quot;, {'Content-Type' =&gt; ActiveResource::Formats[format].mime_type}, ryan, 201, {'Location' =&gt; &quot;/people/5.#{format}&quot;}
+        remote_ryan.save
+
+        remote_ryan = Person.new(:name =&gt; 'Ryan')
+        ActiveResource::HttpMock.respond_to.post &quot;/people/new/register.#{format}&quot;, {'Content-Type' =&gt; ActiveResource::Formats[format].mime_type}, ryan, 201, {'Location' =&gt; &quot;/people/5.#{format}&quot;}
         assert_equal ActiveResource::Response.new(ryan, 201, {'Location' =&gt; &quot;/people/5.#{format}&quot;}), remote_ryan.post(:register)
       end
     end
   end
-  
+
   def test_setting_format_before_site
     resource = Class.new(ActiveResource::Base)
     resource.format = :json
     resource.site   = 'http://37s.sunrise.i:3000'
     assert_equal ActiveResource::Formats[:json], resource.connection.format
   end
-  
+
   private
     def using_format(klass, mime_type_reference)
       previous_format = klass.format</diff>
      <filename>activeresource/test/format_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,9 @@
 *Edge*
 
+* Changed cache benchmarking to be reported in milliseconds [DHH]
+
+* Fix Ruby's Time marshaling bug in pre-1.9 versions of Ruby: utc instances are now correctly unmarshaled with a utc zone instead of the system local zone [#900 state:resolved] [Luca Guidi, Geoff Buesing]
+
 * Add Array#in_groups which splits or iterates over the array in specified number of groups. #579. [Adrian Mugnolo] Example:
   
   a = (1..10).to_a</diff>
      <filename>activesupport/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -21,8 +21,6 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #++
 
-$:.unshift(File.dirname(__FILE__))
-
 require 'active_support/vendor'
 require 'active_support/basic_object'
 require 'active_support/inflector'
@@ -30,7 +28,6 @@ require 'active_support/callbacks'
 
 require 'active_support/core_ext'
 
-require 'active_support/clean_logger'
 require 'active_support/buffered_logger'
 
 require 'active_support/gzip'
@@ -39,7 +36,6 @@ require 'active_support/cache'
 require 'active_support/dependencies'
 require 'active_support/deprecation'
 
-require 'active_support/typed_array'
 require 'active_support/ordered_hash'
 require 'active_support/ordered_options'
 require 'active_support/option_merger'
@@ -58,9 +54,9 @@ require 'active_support/base64'
 
 require 'active_support/time_with_zone'
 
-I18n.backend.populate do
-  require 'active_support/locale/en-US.rb'
-end
+require 'active_support/secure_random'
+
+I18n.load_translations File.dirname(__FILE__) + '/active_support/locale/en-US.yml'
 
 Inflector = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Inflector', 'ActiveSupport::Inflector')
 Dependencies = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Dependencies', 'ActiveSupport::Dependencies')</diff>
      <filename>activesupport/lib/active_support.rb</filename>
    </modified>
    <modified>
      <diff>@@ -62,7 +62,7 @@ module ActiveSupport
           write(key, value, options)
           @logger_off = false
 
-          log(&quot;write (will save #{'%.5f' % seconds})&quot;, key, nil)
+          log(&quot;write (will save #{'%.2f' % (seconds * 1000)}ms)&quot;, key, nil)
 
           value
         end</diff>
      <filename>activesupport/lib/active_support/cache.rb</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,7 @@ module ActiveSupport
       def write(name, value, options = nil)
         @guard.synchronize do
           super
-          @data[name] = value
+          @data[name] = value.freeze
         end
       end
 </diff>
      <filename>activesupport/lib/active_support/cache/memory_store.rb</filename>
    </modified>
    <modified>
      <diff>@@ -96,15 +96,12 @@ module ActiveSupport
         end
       end
 
-      def |(chain)
-        if chain.is_a?(CallbackChain)
-          chain.each { |callback| self | callback }
+      # TODO: Decompose into more Array like behavior
+      def replace_or_append!(chain)
+        if index = index(chain)
+          self[index] = chain
         else
-          if (found_callback = find(chain)) &amp;&amp; (index = index(chain))
-            self[index] = chain
-          else
-            self &lt;&lt; chain
-          end
+          self &lt;&lt; chain
         end
         self
       end
@@ -157,6 +154,14 @@ module ActiveSupport
         self.class.new(@kind, @method, @options.dup)
       end
 
+      def hash
+        if @identifier
+          @identifier.hash
+        else
+          @method.hash
+        end
+      end
+
       def call(*args, &amp;block)
         evaluate_method(method, *args, &amp;block) if should_run_callback?(*args)
       rescue LocalJumpError</diff>
      <filename>activesupport/lib/active_support/callbacks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -91,14 +91,14 @@ class Class # :nodoc:
   def inheritable_attributes
     @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
   end
-  
+
   def write_inheritable_attribute(key, value)
     if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
       @inheritable_attributes = {}
     end
     inheritable_attributes[key] = value
   end
-  
+
   def write_inheritable_array(key, elements)
     write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
     write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
@@ -112,7 +112,7 @@ class Class # :nodoc:
   def read_inheritable_attribute(key)
     inheritable_attributes[key]
   end
-  
+
   def reset_inheritable_attributes
     @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
   end
@@ -123,7 +123,7 @@ class Class # :nodoc:
 
     def inherited_with_inheritable_attributes(child)
       inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
-      
+
       if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
         new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
       else
@@ -131,7 +131,7 @@ class Class # :nodoc:
           memo.update(key =&gt; value.duplicable? ? value.dup : value)
         end
       end
-      
+
       child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
     end
 </diff>
      <filename>activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+require 'date'
+
 module ActiveSupport #:nodoc:
   module CoreExtensions #:nodoc:
     module Date #:nodoc:
@@ -7,6 +9,33 @@ module ActiveSupport #:nodoc:
         def acts_like_date?
           true
         end
+
+        # Date memoizes some instance methods using metaprogramming to wrap
+        # the methods with one that caches the result in an instance variable.
+        #
+        # If a Date is frozen but the memoized method hasn't been called, the
+        # first call will result in a frozen object error since the memo
+        # instance variable is uninitialized.
+        #
+        # Work around by eagerly memoizing before freezing.
+        #
+        # Ruby 1.9 uses a preinitialized instance variable so it's unaffected.
+        # This hack is as close as we can get to feature detection:
+        begin
+          ::Date.today.freeze.jd
+        rescue =&gt; frozen_object_error
+          if frozen_object_error.message =~ /frozen/
+            def freeze #:nodoc:
+              self.class.private_instance_methods(false).each do |m|
+                if m.to_s =~ /\A__\d+__\Z/
+                  instance_variable_set(:&quot;@#{m}&quot;, [send(m)])
+                end
+              end
+
+              super
+            end
+          end
+        end
       end
     end
   end</diff>
      <filename>activesupport/lib/active_support/core_ext/date/behavior.rb</filename>
    </modified>
    <modified>
      <diff>@@ -35,3 +35,9 @@ class Numeric #:nodoc:
     false
   end
 end
+
+class Class #:nodoc:
+  def duplicable?
+    false
+  end
+end</diff>
      <filename>activesupport/lib/active_support/core_ext/duplicable.rb</filename>
    </modified>
    <modified>
      <diff>@@ -64,8 +64,28 @@ module Enumerable
     end
   end
 
+  # Iterates over a collection, passing the current element *and* the
+  # +memo+ to the block. Handy for building up hashes or
+  # reducing collections down to one object. Examples:
+  #
+  #   %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=&gt; {'foo' =&gt; 'FOO', 'bar' =&gt; 'BAR'}
+  #
+  # *Note* that you can't use immutable objects like numbers, true or false as
+  # the memo. You would think the following returns 120, but since the memo is
+  # never changed, it does not.
+  #
+  #   (1..5).each_with_object(1) { |value, memo| memo *= value } # =&gt; 1
+  #
+  def each_with_object(memo, &amp;block)
+    returning memo do |memo|
+      each do |element|
+        block.call(element, memo)
+      end
+    end
+  end unless [].respond_to?(:each_with_object)
+
   # Convert an enumerable to a hash. Examples:
-  # 
+  #
   #   people.index_by(&amp;:login)
   #     =&gt; { &quot;nextangle&quot; =&gt; &lt;Person ...&gt;, &quot;chade-&quot; =&gt; &lt;Person ...&gt;, ...}
   #   people.index_by { |person| &quot;#{person.first_name} #{person.last_name}&quot; }</diff>
      <filename>activesupport/lib/active_support/core_ext/enumerable.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,5 +12,132 @@ class Logger
     end_eval
   end
   [:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
+end
 
-end
\ No newline at end of file
+
+require 'logger'
+
+# Extensions to the built in Ruby logger.
+#
+# If you want to use the default log formatter as defined in the Ruby core, then you
+# will need to set the formatter for the logger as in:
+#
+#   logger.formatter = Formatter.new
+#
+# You can then specify the datetime format, for example:
+#
+#   logger.datetime_format = &quot;%Y-%m-%d&quot;
+#
+# Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
+class Logger
+  # Set to false to disable the silencer
+  cattr_accessor :silencer
+  self.silencer = true
+
+  # Silences the logger for the duration of the block.
+  def silence(temporary_level = Logger::ERROR)
+    if silencer
+      begin
+        old_logger_level, self.level = level, temporary_level
+        yield self
+      ensure
+        self.level = old_logger_level
+      end
+    else
+      yield self
+    end
+  end
+
+  alias :old_datetime_format= :datetime_format=
+  # Logging date-time format (string passed to +strftime+). Ignored if the formatter
+  # does not respond to datetime_format=.
+  def datetime_format=(datetime_format)
+    formatter.datetime_format = datetime_format if formatter.respond_to?(:datetime_format=)
+  end
+
+  alias :old_datetime_format :datetime_format
+  # Get the logging datetime format. Returns nil if the formatter does not support
+  # datetime formatting.
+  def datetime_format
+    formatter.datetime_format if formatter.respond_to?(:datetime_format)
+  end
+
+  alias :old_formatter :formatter if method_defined?(:formatter)
+  # Get the current formatter. The default formatter is a SimpleFormatter which only
+  # displays the log message
+  def formatter
+    @formatter ||= SimpleFormatter.new
+  end
+
+  unless const_defined? :Formatter
+    class Formatter
+      Format = &quot;%s, [%s#%d] %5s -- %s: %s\n&quot;
+
+      attr_accessor :datetime_format
+
+      def initialize
+        @datetime_format = nil
+      end
+
+      def call(severity, time, progname, msg)
+        Format % [severity[0..0], format_datetime(time), $$, severity, progname,
+        msg2str(msg)]
+      end
+
+      private
+        def format_datetime(time)
+          if @datetime_format.nil?
+            time.strftime(&quot;%Y-%m-%dT%H:%M:%S.&quot;) &lt;&lt; &quot;%06d &quot; % time.usec
+          else
+            time.strftime(@datetime_format)
+          end
+        end
+
+        def msg2str(msg)
+          case msg
+          when ::String
+            msg
+          when ::Exception
+            &quot;#{ msg.message } (#{ msg.class })\n&quot; &lt;&lt;
+            (msg.backtrace || []).join(&quot;\n&quot;)
+          else
+            msg.inspect
+          end
+        end
+    end
+  end
+
+  # Simple formatter which only displays the message.
+  class SimpleFormatter &lt; Logger::Formatter
+    # This method is invoked when a log event occurs
+    def call(severity, timestamp, progname, msg)
+      &quot;#{String === msg ? msg : msg.inspect}\n&quot;
+    end
+  end
+
+  private
+    alias old_format_message format_message
+
+    # Ruby 1.8.3 transposed the msg and progname arguments to format_message.
+    # We can't test RUBY_VERSION because some distributions don't keep Ruby
+    # and its standard library in sync, leading to installations of Ruby 1.8.2
+    # with Logger from 1.8.3 and vice versa.
+    if method_defined?(:formatter=)
+      def format_message(severity, timestamp, progname, msg)
+        formatter.call(severity, timestamp, progname, msg)
+      end
+    else
+      def format_message(severity, timestamp, msg, progname)
+        formatter.call(severity, timestamp, progname, msg)
+      end
+
+      attr_writer :formatter
+      public :formatter=
+
+      alias old_format_datetime format_datetime
+      def format_datetime(datetime) datetime end
+
+      alias old_msg2str msg2str
+      def msg2str(msg) msg end
+    end
+end</diff>
      <filename>activesupport/lib/active_support/core_ext/logger.rb</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,17 @@ require 'active_support/core_ext/module/introspection'
 require 'active_support/core_ext/module/loading'
 require 'active_support/core_ext/module/aliasing'
 require 'active_support/core_ext/module/model_naming'
+require 'active_support/core_ext/module/synchronization'
+
+module ActiveSupport
+  module CoreExtensions
+    # Various extensions for the Ruby core Module class.
+    module Module
+      # Nothing here. Only defined for API documentation purposes.
+    end
+  end
+end
 
 class Module
-  include ActiveSupport::CoreExt::Module::ModelNaming
+  include ActiveSupport::CoreExtensions::Module
 end</diff>
      <filename>activesupport/lib/active_support/core_ext/module.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,70 +1,74 @@
-class Module
-  # Encapsulates the common pattern of:
-  #
-  #   alias_method :foo_without_feature, :foo
-  #   alias_method :foo, :foo_with_feature
-  #
-  # With this, you simply do:
-  #
-  #   alias_method_chain :foo, :feature
-  #
-  # And both aliases are set up for you.
-  #
-  # Query and bang methods (foo?, foo!) keep the same punctuation:
-  #
-  #   alias_method_chain :foo?, :feature
-  #
-  # is equivalent to
-  #
-  #   alias_method :foo_without_feature?, :foo?
-  #   alias_method :foo?, :foo_with_feature?
-  #
-  # so you can safely chain foo, foo?, and foo! with the same feature.
-  def alias_method_chain(target, feature)
-    # Strip out punctuation on predicates or bang methods since
-    # e.g. target?_without_feature is not a valid method name.
-    aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
-    yield(aliased_target, punctuation) if block_given?
-    
-    with_method, without_method = &quot;#{aliased_target}_with_#{feature}#{punctuation}&quot;, &quot;#{aliased_target}_without_#{feature}#{punctuation}&quot;
-    
-    alias_method without_method, target
-    alias_method target, with_method
-    
-    case
-      when public_method_defined?(without_method)
-        public target
-      when protected_method_defined?(without_method)
-        protected target
-      when private_method_defined?(without_method)
-        private target
-    end
-  end
+module ActiveSupport
+  module CoreExtensions
+    module Module
+      # Encapsulates the common pattern of:
+      #
+      #   alias_method :foo_without_feature, :foo
+      #   alias_method :foo, :foo_with_feature
+      #
+      # With this, you simply do:
+      #
+      #   alias_method_chain :foo, :feature
+      #
+      # And both aliases are set up for you.
+      #
+      # Query and bang methods (foo?, foo!) keep the same punctuation:
+      #
+      #   alias_method_chain :foo?, :feature
+      #
+      # is equivalent to
+      #
+      #   alias_method :foo_without_feature?, :foo?
+      #   alias_method :foo?, :foo_with_feature?
+      #
+      # so you can safely chain foo, foo?, and foo! with the same feature.
+      def alias_method_chain(target, feature)
+        # Strip out punctuation on predicates or bang methods since
+        # e.g. target?_without_feature is not a valid method name.
+        aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
+        yield(aliased_target, punctuation) if block_given?
+
+        with_method, without_method = &quot;#{aliased_target}_with_#{feature}#{punctuation}&quot;, &quot;#{aliased_target}_without_#{feature}#{punctuation}&quot;
 
-  # Allows you to make aliases for attributes, which includes 
-  # getter, setter, and query methods.
-  #
-  # Example:
-  #
-  #   class Content &lt; ActiveRecord::Base
-  #     # has a title attribute
-  #   end
-  #
-  #   class Email &lt; Content
-  #     alias_attribute :subject, :title
-  #   end
-  #
-  #   e = Email.find(1)
-  #   e.title    # =&gt; &quot;Superstars&quot;
-  #   e.subject  # =&gt; &quot;Superstars&quot;
-  #   e.subject? # =&gt; true
-  #   e.subject = &quot;Megastars&quot;
-  #   e.title    # =&gt; &quot;Megastars&quot;
-  def alias_attribute(new_name, old_name)
-    module_eval &lt;&lt;-STR, __FILE__, __LINE__+1
-      def #{new_name}; self.#{old_name}; end
-      def #{new_name}?; self.#{old_name}?; end
-      def #{new_name}=(v); self.#{old_name} = v; end
-    STR
+        alias_method without_method, target
+        alias_method target, with_method
+
+        case
+          when public_method_defined?(without_method)
+            public target
+          when protected_method_defined?(without_method)
+            protected target
+          when private_method_defined?(without_method)
+            private target
+        end
+      end
+
+      # Allows you to make aliases for attributes, which includes
+      # getter, setter, and query methods.
+      #
+      # Example:
+      #
+      #   class Content &lt; ActiveRecord::Base
+      #     # has a title attribute
+      #   end
+      #
+      #   class Email &lt; Content
+      #     alias_attribute :subject, :title
+      #   end
+      #
+      #   e = Email.find(1)
+      #   e.title    # =&gt; &quot;Superstars&quot;
+      #   e.subject  # =&gt; &quot;Superstars&quot;
+      #   e.subject? # =&gt; true
+      #   e.subject = &quot;Megastars&quot;
+      #   e.title    # =&gt; &quot;Megastars&quot;
+      def alias_attribute(new_name, old_name)
+        module_eval &lt;&lt;-STR, __FILE__, __LINE__+1
+          def #{new_name}; self.#{old_name}; end
+          def #{new_name}?; self.#{old_name}?; end
+          def #{new_name}=(v); self.#{old_name} = v; end
+        STR
+      end
+    end
   end
 end</diff>
      <filename>activesupport/lib/active_support/core_ext/module/aliasing.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,86 +1,90 @@
-class Module
-  # Returns the name of the module containing this one.
-  #
-  #   p M::N.parent_name # =&gt; &quot;M&quot;
-  def parent_name
-    unless defined? @parent_name
-      @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
-    end
-    @parent_name
-  end
+module ActiveSupport
+  module CoreExtensions
+    module Module
+      # Returns the name of the module containing this one.
+      #
+      #   p M::N.parent_name # =&gt; &quot;M&quot;
+      def parent_name
+        unless defined? @parent_name
+          @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
+        end
+        @parent_name
+      end
 
-  # Returns the module which contains this one according to its name.
-  #
-  #   module M
-  #     module N
-  #     end
-  #   end
-  #   X = M::N
-  #   
-  #   p M::N.parent # =&gt; M
-  #   p X.parent    # =&gt; M
-  #
-  # The parent of top-level and anonymous modules is Object.
-  #
-  #   p M.parent          # =&gt; Object
-  #   p Module.new.parent # =&gt; Object
-  #
-  def parent
-    parent_name ? parent_name.constantize : Object
-  end
+      # Returns the module which contains this one according to its name.
+      #
+      #   module M
+      #     module N
+      #     end
+      #   end
+      #   X = M::N
+      #
+      #   p M::N.parent # =&gt; M
+      #   p X.parent    # =&gt; M
+      #
+      # The parent of top-level and anonymous modules is Object.
+      #
+      #   p M.parent          # =&gt; Object
+      #   p Module.new.parent # =&gt; Object
+      #
+      def parent
+        parent_name ? parent_name.constantize : Object
+      end
 
-  # Returns all the parents of this module according to its name, ordered from
-  # nested outwards. The receiver is not contained within the result.
-  #
-  #   module M
-  #     module N
-  #     end
-  #   end
-  #   X = M::N
-  #   
-  #   p M.parents    # =&gt; [Object]
-  #   p M::N.parents # =&gt; [M, Object]
-  #   p X.parents    # =&gt; [M, Object]
-  #
-  def parents
-    parents = []
-    if parent_name
-      parts = parent_name.split('::')
-      until parts.empty?
-        parents &lt;&lt; (parts * '::').constantize
-        parts.pop
+      # Returns all the parents of this module according to its name, ordered from
+      # nested outwards. The receiver is not contained within the result.
+      #
+      #   module M
+      #     module N
+      #     end
+      #   end
+      #   X = M::N
+      #
+      #   p M.parents    # =&gt; [Object]
+      #   p M::N.parents # =&gt; [M, Object]
+      #   p X.parents    # =&gt; [M, Object]
+      #
+      def parents
+        parents = []
+        if parent_name
+          parts = parent_name.split('::')
+          until parts.empty?
+            parents &lt;&lt; (parts * '::').constantize
+            parts.pop
+          end
+        end
+        parents &lt;&lt; Object unless parents.include? Object
+        parents
       end
-    end
-    parents &lt;&lt; Object unless parents.include? Object
-    parents
-  end
 
-  if RUBY_VERSION &lt; '1.9'
-    # Returns the constants that have been defined locally by this object and
-    # not in an ancestor. This method is exact if running under Ruby 1.9. In
-    # previous versions it may miss some constants if their definition in some
-    # ancestor is identical to their definition in the receiver.
-    def local_constants
-      inherited = {}
+      if RUBY_VERSION &lt; '1.9'
+        # Returns the constants that have been defined locally by this object and
+        # not in an ancestor. This method is exact if running under Ruby 1.9. In
+        # previous versions it may miss some constants if their definition in some
+        # ancestor is identical to their definition in the receiver.
+        def local_constants
+          inherited = {}
+
+          ancestors.each do |anc|
+            next if anc == self
+            anc.constants.each { |const| inherited[const] = anc.const_get(const) }
+          end
 
-      ancestors.each do |anc|
-        next if anc == self
-        anc.constants.each { |const| inherited[const] = anc.const_get(const) }
+          constants.select do |const|
+            !inherited.key?(const) || inherited[const].object_id != const_get(const).object_id
+          end
+        end
+      else
+        def local_constants #:nodoc:
+          constants(false)
+        end
       end
 
-      constants.select do |const|
-        !inherited.key?(const) || inherited[const].object_id != const_get(const).object_id
+      # Returns the names of the constants defined locally rather than the
+      # constants themselves. See &lt;tt&gt;local_constants&lt;/tt&gt;.
+      def local_constant_names
+        local_constants.map { |c| c.to_s }
       end
     end
-  else
-    def local_constants #:nodoc:
-      constants(false)
-    end
-  end
-
-  # Returns the names of the constants defined locally rather than the
-  # constants themselves. See &lt;tt&gt;local_constants&lt;/tt&gt;.
-  def local_constant_names
-    local_constants.map { |c| c.to_s }
   end
 end</diff>
      <filename>activesupport/lib/active_support/core_ext/module/introspection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,12 +11,12 @@ module ActiveSupport
     end
   end
 
-  module CoreExt
+  module CoreExtensions
     module Module
-      module ModelNaming
-        def model_name
-          @model_name ||= ModelName.new(name)
-        end
+      # Returns an ActiveSupport::ModelName object for module. It can be
+      # used to retrieve all kinds of naming-related information.
+      def model_name
+        @model_name ||= ModelName.new(name)
       end
     end
   end</diff>
      <filename>activesupport/lib/active_support/core_ext/module/model_naming.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,4 @@
 class Object
-  unless respond_to?(:send!)
-    # Anticipating Ruby 1.9 neutering send
-    alias send! send
-  end
-
   # A Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.
   #
   #   def foo</diff>
      <filename>activesupport/lib/active_support/core_ext/object/misc.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ module ActiveSupport #:nodoc:
         end
 
         if RUBY_VERSION &lt; '1.9'
-          def step_with_blockless(value, &amp;block)
+          def step_with_blockless(value = 1, &amp;block)
             if block_given?
               step_without_blockless(value, &amp;block)
             else
@@ -18,7 +18,7 @@ module ActiveSupport #:nodoc:
             end
           end
         else
-          def step_with_blockless(value, &amp;block)
+          def step_with_blockless(value = 1, &amp;block)
             if block_given?
               step_without_blockless(value, &amp;block)
             else</diff>
      <filename>activesupport/lib/active_support/core_ext/range/blockless_step.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,32 @@
 require 'date'
 require 'time'
 
-# Ruby 1.8-cvs and 1.9 define private Time#to_date
 class Time
+  # Ruby 1.8-cvs and 1.9 define private Time#to_date
   %w(to_date to_datetime).each do |method|
     public method if private_instance_methods.include?(method)
   end
+
+  # Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
+  # unmarshaled in the local zone, instead of utc. We're layering behavior on the _dump and _load
+  # methods so that utc instances can be flagged on dump, and coerced back to utc on load.
+  if RUBY_VERSION &lt; '1.9'
+    class &lt;&lt; self
+      alias_method :_original_load, :_load
+      def _load(marshaled_time)
+        time = _original_load(marshaled_time)
+        utc = time.instance_variable_get('@marshal_with_utc_coercion')
+        utc ? time.utc : time
+      end
+    end
+    
+    alias_method :_original_dump, :_dump
+    def _dump(*args)
+      obj = self.frozen? ? self.dup : self
+      obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
+      obj._original_dump(*args)
+    end
+  end
 end
 
 require 'active_support/core_ext/time/behavior'</diff>
      <filename>activesupport/lib/active_support/core_ext/time.rb</filename>
    </modified>
    <modified>
      <diff>@@ -78,7 +78,7 @@ module ActiveSupport #:nodoc:
         #
         #   Time.utc(2000).in_time_zone('Alaska')  # =&gt; Fri, 31 Dec 1999 15:00:00 AKST -09:00
         def in_time_zone(zone = ::Time.zone)
-          ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.send!(:get_zone, zone))
+          ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
         end
       end
     end</diff>
      <filename>activesupport/lib/active_support/core_ext/time/zones.rb</filename>
    </modified>
    <modified>
      <diff>@@ -109,7 +109,7 @@ module ActiveSupport
       end
 
       def deprecation_horizon
-        '2.0'
+        '2.3'
       end
     end
 
@@ -162,6 +162,22 @@ module ActiveSupport
         end
     end
 
+    class DeprecatedObjectProxy &lt; DeprecationProxy
+      def initialize(object, message)
+        @object = object
+        @message = message
+      end
+
+      private
+        def target
+          @object
+        end
+
+        def warn(callstack, called, args)
+          ActiveSupport::Deprecation.warn(@message, callstack)
+        end
+    end
+
     # Stand-in for &lt;tt&gt;@request&lt;/tt&gt;, &lt;tt&gt;@attributes&lt;/tt&gt;, &lt;tt&gt;@params&lt;/tt&gt;, etc.
     # which emits deprecation warnings on any method call (except +inspect+).
     class DeprecatedInstanceVariableProxy &lt; DeprecationProxy #:nodoc:
@@ -185,6 +201,10 @@ module ActiveSupport
         @new_const = new_const
       end
 
+      def class
+        target.class
+      end
+
       private
         def target
           @new_const.to_s.constantize</diff>
      <filename>activesupport/lib/active_support/deprecation.rb</filename>
    </modified>
    <modified>
      <diff>@@ -39,12 +39,16 @@ module ActiveSupport
       # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
       # The replacement should always be a string that may include references to the matched data from the rule.
       def plural(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
         @plurals.insert(0, [rule, replacement])
       end
 
       # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
       # The replacement should always be a string that may include references to the matched data from the rule.
       def singular(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
         @singulars.insert(0, [rule, replacement])
       end
 
@@ -55,6 +59,8 @@ module ActiveSupport
       #   irregular 'octopus', 'octopi'
       #   irregular 'person', 'people'
       def irregular(singular, plural)
+        @uncountables.delete(singular)
+        @uncountables.delete(plural)
         if singular[0,1].upcase == plural[0,1].upcase
           plural(Regexp.new(&quot;(#{singular[0,1]})#{singular[1..-1]}$&quot;, &quot;i&quot;), '\1' + plural[1..-1])
           singular(Regexp.new(&quot;(#{plural[0,1]})#{plural[1..-1]}$&quot;, &quot;i&quot;), '\1' + singular[1..-1])
@@ -173,7 +179,7 @@ module ActiveSupport
       if first_letter_in_uppercase
         lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { &quot;::#{$1.upcase}&quot; }.gsub(/(?:^|_)(.)/) { $1.upcase }
       else
-        lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
+        lower_case_and_underscored_word.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
       end
     end
 
@@ -273,32 +279,47 @@ module ActiveSupport
       underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? &quot;_id&quot; : &quot;id&quot;)
     end
 
-    # Tries to find a constant with the name specified in the argument string:
-    #
-    #   &quot;Module&quot;.constantize     # =&gt; Module
-    #   &quot;Test::Unit&quot;.constantize # =&gt; Test::Unit
-    #
-    # The name is assumed to be the one of a top-level constant, no matter whether
-    # it starts with &quot;::&quot; or not. No lexical context is taken into account:
-    #
-    #   C = 'outside'
-    #   module M
-    #     C = 'inside'
-    #     C               # =&gt; 'inside'
-    #     &quot;C&quot;.constantize # =&gt; 'outside', same as ::C
-    #   end
-    #
-    # NameError is raised when the name is not in CamelCase or the constant is
-    # unknown.
-    def constantize(camel_cased_word)
-      names = camel_cased_word.split('::')
-      names.shift if names.empty? || names.first.empty?
+    # Ruby 1.9 introduces an inherit argument for Module#const_get and
+    # #const_defined? and changes their default behavior.
+    if Module.method(:const_get).arity == 1
+      # Tries to find a constant with the name specified in the argument string:
+      #
+      #   &quot;Module&quot;.constantize     # =&gt; Module
+      #   &quot;Test::Unit&quot;.constantize # =&gt; Test::Unit
+      #
+      # The name is assumed to be the one of a top-level constant, no matter whether
+      # it starts with &quot;::&quot; or not. No lexical context is taken into account:
+      #
+      #   C = 'outside'
+      #   module M
+      #     C = 'inside'
+      #     C               # =&gt; 'inside'
+      #     &quot;C&quot;.constantize # =&gt; 'outside', same as ::C
+      #   end
+      #
+      # NameError is raised when the name is not in CamelCase or the constant is
+      # unknown.
+      def constantize(camel_cased_word)
+        names = camel_cased_word.split('::')
+        names.shift if names.empty? || names.first.empty?
+
+        constant = Object
+        names.each do |name|
+          constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
+        end
+        constant
+      end
+    else
+      def constantize(camel_cased_word) #:nodoc:
+        names = camel_cased_word.split('::')
+        names.shift if names.empty? || names.first.empty?
 
-      constant = Object
-      names.each do |name|
-        constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
+        constant = Object
+        names.each do |name|
+          constant = constant.const_get(name, false) || constant.const_missing(name)
+        end
+        constant
       end
-      constant
     end
 
     # Turns a number into an ordinal string used to denote the position in an</diff>
      <filename>activesupport/lib/active_support/inflector.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,7 +11,7 @@ module ActiveSupport
     private
       def method_missing(method, *arguments, &amp;block)
         arguments &lt;&lt; (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
-        @context.send!(method, *arguments, &amp;block)
+        @context.__send__(method, *arguments, &amp;block)
       end
   end
 end</diff>
      <filename>activesupport/lib/active_support/option_merger.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,14 @@
 module ActiveSupport
+  # Wrapping a string in this class gives you a prettier way to test
+  # for equality. The value returned by &lt;tt&gt;Rails.env&lt;/tt&gt; is wrapped
+  # in a StringInquirer object so instead of calling this:
+  #
+  #   Rails.env == &quot;production&quot;
+  #
+  # you can call this:
+  #
+  #   Rails.env.production?
+  #
   class StringInquirer &lt; String
     def method_missing(method_name, *arguments)
       if method_name.to_s.ends_with?(&quot;?&quot;)</diff>
      <filename>activesupport/lib/active_support/string_inquirer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,11 @@ module Test
       #     post :delete, :id =&gt; ...
       #   end
       def assert_difference(expressions, difference = 1, message = nil, &amp;block)
-        expression_evaluations = Array(expressions).collect{ |expression| lambda { eval(expression, block.send!(:binding)) } }
+        expression_evaluations = Array(expressions).map do |expression|
+          lambda do
+            eval(expression, block.__send__(:binding))
+          end
+        end
 
         original_values = expression_evaluations.inject([]) { |memo, expression| memo &lt;&lt; expression.call }
         yield</diff>
      <filename>activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,14 +17,14 @@ module ActiveSupport
         else
           { :benchmark =&gt; false,
             :runs =&gt; 1,
-            :min_percent =&gt; 0.02,
+            :min_percent =&gt; 0.01,
             :metrics =&gt; [:process_time, :memory, :objects],
             :formats =&gt; [:flat, :graph_html, :call_tree],
             :output =&gt; 'tmp/performance' }
-        end
+        end.freeze
 
       def self.included(base)
-        base.class_inheritable_hash :profile_options
+        base.superclass_delegating_accessor :profile_options
         base.profile_options = DEFAULTS
       end
 
@@ -34,16 +34,17 @@ module ActiveSupport
 
       def run(result)
         return if method_name =~ /^default_test$/
-        self.profile_options ||= DEFAULTS
 
         yield(self.class::STARTED, name)
         @_result = result
 
         run_warmup
-        profile_options[:metrics].each do |metric_name|
-          if klass = Metrics[metric_name.to_sym]
-            run_profile(klass.new)
-            result.add_run
+        if profile_options &amp;&amp; metrics = profile_options[:metrics]
+          metrics.each do |metric_name|
+            if klass = Metrics[metric_name.to_sym]
+              run_profile(klass.new)
+              result.add_run
+            end
           end
         end
 </diff>
      <filename>activesupport/lib/active_support/testing/performance.rb</filename>
    </modified>
    <modified>
      <diff>@@ -275,7 +275,7 @@ module ActiveSupport
     end
     
     def marshal_load(variables)
-      initialize(variables[0].utc, ::Time.send!(:get_zone, variables[1]), variables[2].utc)
+      initialize(variables[0].utc, ::Time.__send__(:get_zone, variables[1]), variables[2].utc)
     end
 
     # Ensure proxy class responds to all methods that underlying time instance responds to.</diff>
      <filename>activesupport/lib/active_support/time_with_zone.rb</filename>
    </modified>
    <modified>
      <diff>@@ -29,6 +29,6 @@ end
 # begin
 #   gem 'i18n', '~&gt; 0.0.1'
 # rescue Gem::LoadError
-  $:.unshift &quot;#{File.dirname(__FILE__)}/vendor/i18n-0.0.1/lib&quot;
+  $:.unshift &quot;#{File.dirname(__FILE__)}/vendor/i18n-0.0.1&quot;
   require 'i18n'
 # end
\ No newline at end of file</diff>
      <filename>activesupport/lib/active_support/vendor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -134,6 +134,7 @@ class BufferedLoggerTest &lt; Test::Unit::TestCase
     a.join
     b.join
 
-    assert_equal &quot;a\nb\nc\nx\ny\nz\n&quot;, @output.string
+    assert @output.string.include?(&quot;a\nb\nc\n&quot;)
+    assert @output.string.include?(&quot;x\ny\nz\n&quot;)
   end
 end</diff>
      <filename>activesupport/test/buffered_logger_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -120,4 +120,10 @@ class MemoryStoreTest &lt; Test::Unit::TestCase
   def test_fetch_with_forced_cache_miss
     @cache.fetch('foo', :force =&gt; true) { 'bar' }
   end
+
+  def test_store_objects_should_be_immutable
+    @cache.write('foo', 'bar')
+    assert_raise(ActiveSupport::FrozenObjectError) { @cache.read('foo').gsub!(/.*/, 'baz') }
+    assert_equal 'bar', @cache.read('foo')
+  end
 end</diff>
      <filename>activesupport/test/caching_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -134,10 +134,10 @@ class CallbackChainTest &lt; Test::Unit::TestCase
     assert_equal :bacon, @chain.find(:bacon).method
   end
 
-  def test_union
-    assert_equal [:bacon, :lettuce, :tomato], (@chain | Callback.new(:make, :bacon)).map(&amp;:method)
-    assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain | CallbackChain.build(:make, :bacon, :lettuce, :tomato, :turkey)).map(&amp;:method)
-    assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain | Callback.new(:make, :mayo)).map(&amp;:method)
+  def test_replace_or_append
+    assert_equal [:bacon, :lettuce, :tomato], (@chain.replace_or_append!(Callback.new(:make, :bacon))).map(&amp;:method)
+    assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain.replace_or_append!(Callback.new(:make, :turkey))).map(&amp;:method)
+    assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain.replace_or_append!(Callback.new(:make, :mayo))).map(&amp;:method)
   end
 
   def test_delete</diff>
      <filename>activesupport/test/callbacks_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -198,10 +198,6 @@ class DateExtCalculationsTest &lt; Test::Unit::TestCase
     assert_equal Time.local(2005,2,21,23,59,59), Date.new(2005,2,21).end_of_day
   end
 
-  def test_date_acts_like_date
-    assert Date.new.acts_like_date?
-  end
-
   def test_xmlschema
     with_env_tz 'US/Eastern' do
       assert_match(/^1980-02-28T00:00:00-05:?00$/, Date.new(1980, 2, 28).xmlschema)
@@ -245,3 +241,15 @@ class DateExtCalculationsTest &lt; Test::Unit::TestCase
       old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
     end
 end
+
+class DateExtBehaviorTest &lt; Test::Unit::TestCase
+  def test_date_acts_like_date
+    assert Date.new.acts_like_date?
+  end
+
+  def test_freeze_doesnt_clobber_memoized_instance_methods
+    assert_nothing_raised do
+      Date.today.freeze.inspect
+    end
+  end
+end</diff>
      <filename>activesupport/test/core_ext/date_ext_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 require 'abstract_unit'
 
 class DuplicableTest &lt; Test::Unit::TestCase
-  NO  = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56')]
+  NO  = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56'), Class.new]
   YES = ['1', Object.new, /foo/, [], {}, Time.now]
 
   def test_duplicable</diff>
      <filename>activesupport/test/core_ext/duplicable_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -58,6 +58,11 @@ class EnumerableTests &lt; Test::Unit::TestCase
     assert_equal Payment.new(0), [].sum(Payment.new(0))
   end
 
+  def test_each_with_object
+    result = %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase }
+    assert_equal({'foo' =&gt; 'FOO', 'bar' =&gt; 'BAR'}, result)
+  end
+
   def test_index_by
     payments = [ Payment.new(5), Payment.new(15), Payment.new(10) ]
     assert_equal({ 5 =&gt; payments[0], 15 =&gt; payments[1], 10 =&gt; payments[2] },</diff>
      <filename>activesupport/test/core_ext/enumerable_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -62,7 +62,7 @@ class HashExtTest &lt; Test::Unit::TestCase
     @symbols = @symbols.with_indifferent_access
     @mixed   = @mixed.with_indifferent_access
 
-    assert_equal 'a', @strings.send!(:convert_key, :a)
+    assert_equal 'a', @strings.__send__(:convert_key, :a)
 
     assert_equal 1, @strings.fetch('a')
     assert_equal 1, @strings.fetch(:a.to_s)
@@ -75,9 +75,9 @@ class HashExtTest &lt; Test::Unit::TestCase
 
     hashes.each do |name, hash|
       method_map.sort_by { |m| m.to_s }.each do |meth, expected|
-        assert_equal(expected, hash.send!(meth, 'a'),
+        assert_equal(expected, hash.__send__(meth, 'a'),
                      &quot;Calling #{name}.#{meth} 'a'&quot;)
-        assert_equal(expected, hash.send!(meth, :a),
+        assert_equal(expected, hash.__send__(meth, :a),
                      &quot;Calling #{name}.#{meth} :a&quot;)
       end
     end
@@ -733,7 +733,7 @@ class HashToXmlTest &lt; Test::Unit::TestCase
   
   def test_empty_string_works_for_typecast_xml_value    
     assert_nothing_raised do
-      Hash.send!(:typecast_xml_value, &quot;&quot;)
+      Hash.__send__(:typecast_xml_value, &quot;&quot;)
     end
   end
   
@@ -839,6 +839,27 @@ class QueryTest &lt; Test::Unit::TestCase
       :person =&gt; {:id =&gt; [20, 10]}
   end
 
+  def test_expansion_count_is_limited
+    assert_raises RuntimeError do
+      attack_xml = &lt;&lt;-EOT
+      &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+      &lt;!DOCTYPE member [
+        &lt;!ENTITY a &quot;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&amp;b;&quot;&gt;
+        &lt;!ENTITY b &quot;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&amp;c;&quot;&gt;
+        &lt;!ENTITY c &quot;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&amp;d;&quot;&gt;
+        &lt;!ENTITY d &quot;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&amp;e;&quot;&gt;
+        &lt;!ENTITY e &quot;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&amp;f;&quot;&gt;
+        &lt;!ENTITY f &quot;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&amp;g;&quot;&gt;
+        &lt;!ENTITY g &quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;&gt;
+      ]&gt;
+      &lt;member&gt;
+      &amp;a;
+      &lt;/member&gt;
+      EOT
+      Hash.from_xml(attack_xml)
+    end
+  end
+
   private
     def assert_query_equal(expected, actual, message = nil)
       assert_equal expected.split('&amp;'), actual.to_query.split('&amp;')</diff>
      <filename>activesupport/test/core_ext/hash_ext_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -108,11 +108,6 @@ class ClassExtTest &lt; Test::Unit::TestCase
 end
 
 class ObjectTests &lt; Test::Unit::TestCase
-  def test_send_bang_aliases_send_before_19
-    assert_respond_to 'a', :send!
-    assert_equal 1, 'a'.send!(:size)
-  end
-
   def test_suppress_re_raises
     assert_raises(LoadError) { suppress(ArgumentError) {raise LoadError} }
   end</diff>
      <filename>activesupport/test/core_ext/object_and_class_ext_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -32,6 +32,10 @@ class StringInflectionsTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_camelize_lower
+    assert_equal('capital', 'Capital'.camelize(:lower))
+  end
+
   def test_underscore
     CamelToUnderscore.each do |camel, underscore|
       assert_equal(underscore, camel.underscore)</diff>
      <filename>activesupport/test/core_ext/string_ext_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -524,13 +524,12 @@ class TimeExtCalculationsTest &lt; Test::Unit::TestCase
     assert_equal Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30), DateTime.civil(2039, 2, 21, 17, 44, 30, 0, 0)
     assert_equal Time.time_with_datetime_fallback(:local, 2039, 2, 21, 17, 44, 30), DateTime.civil(2039, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
     assert_equal Time.time_with_datetime_fallback(:utc, 1900, 2, 21, 17, 44, 30), DateTime.civil(1900, 2, 21, 17, 44, 30, 0, 0)
-    assert_equal Time.time_with_datetime_fallback(:local, 1900, 2, 21, 17, 44, 30), DateTime.civil(1900, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
     assert_equal Time.time_with_datetime_fallback(:utc, 2005), Time.utc(2005)
     assert_equal Time.time_with_datetime_fallback(:utc, 2039), DateTime.civil(2039, 1, 1, 0, 0, 0, 0, 0)
     assert_equal Time.time_with_datetime_fallback(:utc, 2005, 2, 21, 17, 44, 30, 1), Time.utc(2005, 2, 21, 17, 44, 30, 1) #with usec
     # This won't overflow on 64bit linux
-    expected_to_overflow = Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30, 1)
-    unless expected_to_overflow.is_a?(Time)
+    unless time_is_64bits?
+      assert_equal Time.time_with_datetime_fallback(:local, 1900, 2, 21, 17, 44, 30), DateTime.civil(1900, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
       assert_equal Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30, 1),
                    DateTime.civil(2039, 2, 21, 17, 44, 30, 0, 0)
       assert_equal ::Date::ITALY, Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30, 1).start # use Ruby's default start value
@@ -546,7 +545,10 @@ class TimeExtCalculationsTest &lt; Test::Unit::TestCase
   def test_local_time
     assert_equal Time.local_time(2005, 2, 21, 17, 44, 30), Time.local(2005, 2, 21, 17, 44, 30)
     assert_equal Time.local_time(2039, 2, 21, 17, 44, 30), DateTime.civil(2039, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
-    assert_equal Time.local_time(1901, 2, 21, 17, 44, 30), DateTime.civil(1901, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
+
+    unless time_is_64bits?
+      assert_equal Time.local_time(1901, 2, 21, 17, 44, 30), DateTime.civil(1901, 2, 21, 17, 44, 30, DateTime.local_offset, 0)
+    end
   end
 
   def test_next_month_on_31st
@@ -624,4 +626,42 @@ class TimeExtCalculationsTest &lt; Test::Unit::TestCase
     ensure
       old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
     end
+
+    def time_is_64bits?
+      Time.time_with_datetime_fallback(:utc, 2039, 2, 21, 17, 44, 30, 1).is_a?(Time)
+    end
+end
+
+class TimeExtMarshalingTest &lt; Test::Unit::TestCase
+  def test_marshaling_with_utc_instance
+    t = Time.utc(2000)
+    marshaled = Marshal.dump t
+    unmarshaled = Marshal.load marshaled
+    assert_equal t, unmarshaled
+    assert_equal t.zone, unmarshaled.zone
+  end
+  
+  def test_marshaling_with_local_instance  
+    t = Time.local(2000)
+    marshaled = Marshal.dump t
+    unmarshaled = Marshal.load marshaled
+    assert_equal t, unmarshaled
+    assert_equal t.zone, unmarshaled.zone
+  end
+    
+  def test_marshaling_with_frozen_utc_instance  
+    t = Time.utc(2000).freeze
+    marshaled = Marshal.dump t
+    unmarshaled = Marshal.load marshaled
+    assert_equal t, unmarshaled
+    assert_equal t.zone, unmarshaled.zone
+  end
+  
+  def test_marshaling_with_frozen_local_instance  
+    t = Time.local(2000).freeze
+    marshaled = Marshal.dump t
+    unmarshaled = Marshal.load marshaled
+    assert_equal t, unmarshaled
+    assert_equal t.zone, unmarshaled.zone
+  end
 end</diff>
      <filename>activesupport/test/core_ext/time_ext_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -146,42 +146,42 @@ class DependenciesTest &lt; Test::Unit::TestCase
   def test_directories_manifest_as_modules_unless_const_defined
     with_loading 'autoloading_fixtures' do
       assert_kind_of Module, ModuleFolder
-      Object.send! :remove_const, :ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
     end
   end
 
   def test_module_with_nested_class
     with_loading 'autoloading_fixtures' do
       assert_kind_of Class, ModuleFolder::NestedClass
-      Object.send! :remove_const, :ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
     end
   end
 
   def test_module_with_nested_inline_class
     with_loading 'autoloading_fixtures' do
       assert_kind_of Class, ModuleFolder::InlineClass
-      Object.send! :remove_const, :ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
     end
   end
 
   def test_directories_may_manifest_as_nested_classes
     with_loading 'autoloading_fixtures' do
       assert_kind_of Class, ClassFolder
-      Object.send! :remove_const, :ClassFolder
+      Object.__send__ :remove_const, :ClassFolder
     end
   end
 
   def test_class_with_nested_class
     with_loading 'autoloading_fixtures' do
       assert_kind_of Class, ClassFolder::NestedClass
-      Object.send! :remove_const, :ClassFolder
+      Object.__send__ :remove_const, :ClassFolder
     end
   end
 
   def test_class_with_nested_inline_class
     with_loading 'autoloading_fixtures' do
       assert_kind_of Class, ClassFolder::InlineClass
-      Object.send! :remove_const, :ClassFolder
+      Object.__send__ :remove_const, :ClassFolder
     end
   end
 
@@ -190,7 +190,7 @@ class DependenciesTest &lt; Test::Unit::TestCase
       assert_kind_of Class, ClassFolder::ClassFolderSubclass
       assert_kind_of Class, ClassFolder
       assert_equal 'indeed', ClassFolder::ClassFolderSubclass::ConstantInClassFolder
-      Object.send! :remove_const, :ClassFolder
+      Object.__send__ :remove_const, :ClassFolder
     end
   end
 
@@ -199,7 +199,7 @@ class DependenciesTest &lt; Test::Unit::TestCase
       sibling = ModuleFolder::NestedClass.class_eval &quot;NestedSibling&quot;
       assert defined?(ModuleFolder::NestedSibling)
       assert_equal ModuleFolder::NestedSibling, sibling
-      Object.send! :remove_const, :ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
     end
   end
 
@@ -208,7 +208,7 @@ class DependenciesTest &lt; Test::Unit::TestCase
       assert ! defined?(ModuleFolder)
       assert_raises(NameError) { ModuleFolder::Object }
       assert_raises(NameError) { ModuleFolder::NestedClass::Object }
-      Object.send! :remove_const, :ModuleFolder
+      Object.__send__ :remove_const, :ModuleFolder
     end
   end
 </diff>
      <filename>activesupport/test/dependencies_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,6 +34,13 @@ class InflectorTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_overwrite_previous_inflectors
+    assert_equal(&quot;series&quot;, ActiveSupport::Inflector.singularize(&quot;series&quot;))
+    ActiveSupport::Inflector.inflections.singular &quot;series&quot;, &quot;serie&quot;
+    assert_equal(&quot;serie&quot;, ActiveSupport::Inflector.singularize(&quot;series&quot;))
+    ActiveSupport::Inflector.inflections.uncountable &quot;series&quot; # Return to normal
+  end
+
   MixtureToTitleCase.each do |before, titleized|
     define_method &quot;test_titleize_#{before}&quot; do
       assert_equal(titleized, ActiveSupport::Inflector.titleize(before))
@@ -46,6 +53,10 @@ class InflectorTest &lt; Test::Unit::TestCase
     end
   end
 
+  def test_camelize_with_lower_downcases_the_first_letter
+    assert_equal('capital', ActiveSupport::Inflector.camelize('Capital', false))
+  end
+
   def test_underscore
     CamelToUnderscore.each do |camel, underscore|
       assert_equal(underscore, ActiveSupport::Inflector.underscore(camel))</diff>
      <filename>activesupport/test/inflector_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -40,7 +40,7 @@ Rails::Initializer.run do |config|
 
   # Make Time.zone default to the specified zone, and make Active Record store time values
   # in the database in UTC, and return them converted to the specified local zone.
-  # Run &quot;rake -D time&quot; for a list of tasks for finding time zone names. Uncomment to use default local time.
+  # Run &quot;rake -D time&quot; for a list of tasks for finding time zone names. Comment line to use default local time.
   config.time_zone = 'UTC'
 
   # Your secret key for verifying cookie session data integrity.
@@ -63,5 +63,6 @@ Rails::Initializer.run do |config|
   # config.active_record.schema_format = :sql
 
   # Activate observers that should always be running
-  # config.active_record.observers = :cacher, :garbage_collector
+  # Please note that observers generated using script/generate observer need to have an _observer suffix
+  # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
 end</diff>
      <filename>railties/environments/environment.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,9 @@
   &lt;div class=&quot;dialog&quot;&gt;
     &lt;h1&gt;We're sorry, but something went wrong.&lt;/h1&gt;
     &lt;p&gt;We've been notified about this issue and we'll take a look at it shortly.&lt;/p&gt;
+    &lt;p&gt;&lt;small&gt;(If you're the administrator of this website, then please read
+    the log file &quot;&lt;%= &quot;&lt;%s&gt;&quot; % &quot;%=h RAILS_ENV %&quot; %&gt;.log&quot;
+    to find out what went wrong.)&lt;/small&gt;&lt;/p&gt;
   &lt;/div&gt;
 &lt;/body&gt;
-&lt;/html&gt;
\ No newline at end of file
+&lt;/html&gt;</diff>
      <filename>railties/html/500.html</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ include_password = false
 
 OptionParser.new do |opt|
   opt.banner = &quot;Usage: dbconsole [options] [environment]&quot;
-  opt.on(&quot;-p&quot;, &quot;--include-password&quot;, &quot;Automatically provide the database from database.yml&quot;) do |v|
+  opt.on(&quot;-p&quot;, &quot;--include-password&quot;, &quot;Automatically provide the password from database.yml&quot;) do |v|
     include_password = true
   end
   opt.parse!(ARGV)
@@ -47,7 +47,7 @@ when &quot;mysql&quot;
 
   args &lt;&lt; config['database']
 
-  exec(find_cmd('mysql5', 'mysql'), *args)
+  exec(find_cmd('mysql', 'mysql5'), *args)
 
 when &quot;postgresql&quot;
   ENV['PGUSER']     = config[&quot;username&quot;] if config[&quot;username&quot;]</diff>
      <filename>railties/lib/commands/dbconsole.rb</filename>
    </modified>
    <modified>
      <diff>@@ -49,6 +49,7 @@ module Rails
     end
 
     def env
+      require 'active_support/string_inquirer'
       ActiveSupport::StringInquirer.new(RAILS_ENV)
     end
 
@@ -356,7 +357,7 @@ Run `rake gems:install` to install the missing gems.
       if configuration.cache_classes
         configuration.eager_load_paths.each do |load_path|
           matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
-          Dir.glob(&quot;#{load_path}/**/*.rb&quot;).each do |file|
+          Dir.glob(&quot;#{load_path}/**/*.rb&quot;).sort.each do |file|
             require_dependency file.sub(matcher, '\1')
           end
         end
@@ -487,7 +488,7 @@ Run `rake gems:install` to install the missing gems.
     # If assigned value cannot be matched to a TimeZone, an exception will be raised.
     def initialize_time_zone
       if configuration.time_zone
-        zone_default = Time.send!(:get_zone, configuration.time_zone)
+        zone_default = Time.__send__(:get_zone, configuration.time_zone)
         unless zone_default
           raise %{Value assigned to config.time_zone not recognized. Run &quot;rake -D time&quot; for a list of tasks for finding appropriate time zone names.}
         end
@@ -783,7 +784,6 @@ Run `rake gems:install` to install the missing gems.
     def threadsafe!
       self.cache_classes = true
       self.dependency_loading = false
-      self.active_record.allow_concurrency = true
       self.action_controller.allow_concurrency = true
       self
     end</diff>
      <filename>railties/lib/initializer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -37,6 +37,10 @@ module Rails
             &quot;&quot;
         end      
       end
+
+      def reference?
+        [ :references, :belongs_to ].include?(self.type)
+      end
     end
   end
 end</diff>
      <filename>railties/lib/rails_generator/generated_attribute.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,5 @@
 require 'rbconfig'
 require 'digest/md5' 
-require 'rails_generator/secret_key_generator'
 
 class AppGenerator &lt; Rails::Generator::Base
   DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
@@ -36,7 +35,7 @@ class AppGenerator &lt; Rails::Generator::Base
     md5 &lt;&lt; @app_name
 
     # Do our best to generate a secure secret key for CookieStore
-    secret = Rails::SecretKeyGenerator.new(@app_name).generate_secret
+    secret = ActiveSupport::SecureRandom.hex(64)
 
     record do |m|
       # Root directory and all subdirectories.
@@ -46,7 +45,6 @@ class AppGenerator &lt; Rails::Generator::Base
       # Root
       m.file &quot;fresh_rakefile&quot;, &quot;Rakefile&quot;
       m.file &quot;README&quot;,         &quot;README&quot;
-      m.file &quot;config.ru&quot;,      &quot;config.ru&quot;
 
       # Application
       m.template &quot;helpers/application.rb&quot;,        &quot;app/controllers/application.rb&quot;, :assigns =&gt; { :app_name =&gt; @app_name, :app_secret =&gt; md5.hexdigest }</diff>
      <filename>railties/lib/rails_generator/generators/applications/app/app_generator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,5 @@
 class &lt;%= class_name %&gt; &lt; ActiveRecord::Base
+&lt;% attributes.select(&amp;:reference?).each do |attribute| -%&gt;
+  belongs_to :&lt;%= attribute.name %&gt;
+&lt;% end -%&gt;
 end</diff>
      <filename>railties/lib/rails_generator/generators/components/model/templates/model.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,160 +5,18 @@ module Rails
   #
   #   generator = Rails::SecretKeyGenerator(&quot;some unique identifier, such as the application name&quot;)
   #   generator.generate_secret     # =&gt; &quot;f3f1be90053fa851... (some long string)&quot;
+  #
+  # This class is *deprecated* in Rails 2.2 in favor of ActiveSupport::SecureRandom.
+  # It is currently a wrapper around ActiveSupport::SecureRandom.
   class SecretKeyGenerator
-    GENERATORS = [ :secure_random, :win32_api, :urandom, :openssl, :prng ].freeze
-
     def initialize(identifier)
-      @identifier = identifier
     end
 
     # Generate a random secret key with the best possible method available on
     # the current platform.
     def generate_secret
-      generator = GENERATORS.find do |g|
-        self.class.send(&quot;supports_#{g}?&quot;)
-      end
-      send(&quot;generate_secret_with_#{generator}&quot;)
-    end
-
-    # Generate a random secret key by using the Win32 API. Raises LoadError
-    # if the current platform cannot make use of the Win32 API. Raises
-    # SystemCallError if some other error occurred.
-    def generate_secret_with_win32_api
-      # Following code is based on David Garamond's GUID library for Ruby.
-      require 'Win32API'
-
-      crypt_acquire_context = Win32API.new(&quot;advapi32&quot;, &quot;CryptAcquireContext&quot;,
-                                           'PPPII', 'L')
-      crypt_gen_random = Win32API.new(&quot;advapi32&quot;, &quot;CryptGenRandom&quot;,
-                                      'LIP', 'L')
-      crypt_release_context = Win32API.new(&quot;advapi32&quot;, &quot;CryptReleaseContext&quot;,
-                                         'LI', 'L')
-      prov_rsa_full       = 1
-      crypt_verifycontext = 0xF0000000
-
-      hProvStr = &quot; &quot; * 4
-      if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full,
-                                    crypt_verifycontext) == 0
-        raise SystemCallError, &quot;CryptAcquireContext failed: #{lastWin32ErrorMessage}&quot;
-      end
-      hProv, = hProvStr.unpack('L')
-      bytes = &quot; &quot; * 64
-      if crypt_gen_random.call(hProv, bytes.size, bytes) == 0
-        raise SystemCallError, &quot;CryptGenRandom failed: #{lastWin32ErrorMessage}&quot;
-      end
-      if crypt_release_context.call(hProv, 0) == 0
-        raise SystemCallError, &quot;CryptReleaseContext failed: #{lastWin32ErrorMessage}&quot;
-      end
-      bytes.unpack(&quot;H*&quot;)[0]
-    end
-
-    # Generate a random secret key with Ruby 1.9's SecureRandom module.
-    # Raises LoadError if the current Ruby version does not support
-    # SecureRandom.
-    def generate_secret_with_secure_random
-      require 'securerandom'
-      return SecureRandom.hex(64)
-    end
-
-    # Generate a random secret key with OpenSSL. If OpenSSL is not
-    # already loaded, then this method will attempt to load it.
-    # LoadError will be raised if that fails.
-    def generate_secret_with_openssl
-      require 'openssl'
-      if !File.exist?(&quot;/dev/urandom&quot;)
-        # OpenSSL transparently seeds the random number generator with
-        # data from /dev/urandom. On platforms where that is not
-        # available, such as Windows, we have to provide OpenSSL with
-        # our own seed. Unfortunately there's no way to provide a
-        # secure seed without OS support, so we'll have to do with
-        # rand() and Time.now.usec().
-        OpenSSL::Random.seed(rand(0).to_s + Time.now.usec.to_s)
-      end
-      data = OpenSSL::BN.rand(2048, -1, false).to_s
-
-      if OpenSSL::OPENSSL_VERSION_NUMBER &gt; 0x00908000
-        OpenSSL::Digest::SHA512.new(data).hexdigest
-      else
-        generate_secret_with_prng
-      end
+      ActiveSupport::SecureRandom.hex(64)
     end
-
-    # Generate a random secret key with /dev/urandom.
-    # Raises SystemCallError on failure.
-    def generate_secret_with_urandom
-      return File.read(&quot;/dev/urandom&quot;, 64).unpack(&quot;H*&quot;)[0]
-    end
-
-    # Generate a random secret key with Ruby's pseudo random number generator,
-    # as well as some environment information.
-    #
-    # This is the least cryptographically secure way to generate a secret key,
-    # and should be avoided whenever possible.
-    def generate_secret_with_prng
-      require 'digest/sha2'
-      sha = Digest::SHA2.new(512)
-      now = Time.now
-      sha &lt;&lt; now.to_s
-      sha &lt;&lt; String(now.usec)
-      sha &lt;&lt; String(rand(0))
-      sha &lt;&lt; String($$)
-      sha &lt;&lt; @identifier
-      return sha.hexdigest
-    end
-
-    private
-      def lastWin32ErrorMessage
-        # Following code is based on David Garamond's GUID library for Ruby.
-        get_last_error = Win32API.new(&quot;kernel32&quot;, &quot;GetLastError&quot;, '', 'L')
-        format_message = Win32API.new(&quot;kernel32&quot;, &quot;FormatMessageA&quot;,
-                                      'LPLLPLPPPPPPPP', 'L')
-        format_message_ignore_inserts  = 0x00000200
-        format_message_from_system     = 0x00001000
-
-        code = get_last_error.call
-        msg = &quot;\0&quot; * 1024
-        len = format_message.call(format_message_ignore_inserts +
-                                  format_message_from_system, 0,
-                                  code, 0, msg, 1024, nil, nil,
-                                  nil, nil, nil, nil, nil, nil)
-        msg[0, len].tr(&quot;\r&quot;, '').chomp
-      end
-
-      def self.supports_secure_random?
-        begin
-          require 'securerandom'
-          true
-        rescue LoadError
-          false
-        end
-      end
-
-      def self.supports_win32_api?
-        return false unless RUBY_PLATFORM =~ /(:?mswin|mingw)/
-        begin
-          require 'Win32API'
-          true
-        rescue LoadError
-          false
-        end
-      end
-
-      def self.supports_urandom?
-        File.exist?('/dev/urandom')
-      end
-
-      def self.supports_openssl?
-        begin
-          require 'openssl'
-          true
-        rescue LoadError
-          false
-        end
-      end
-
-      def self.supports_prng?
-        true
-      end
+    deprecate :generate_secret=&gt;&quot;You should use ActiveSupport::SecureRandom.hex(64)&quot;
   end
 end</diff>
      <filename>railties/lib/rails_generator/secret_key_generator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
 namespace :doc do
-  desc &quot;Generate documentation for the application. Set custom template with TEMPLATE=/path/to/rdoc/template.rb&quot;
+  desc &quot;Generate documentation for the application. Set custom template with TEMPLATE=/path/to/rdoc/template.rb or title with TITLE=\&quot;Custom Title\&quot;&quot;
   Rake::RDocTask.new(&quot;app&quot;) { |rdoc|
     rdoc.rdoc_dir = 'doc/app'
     rdoc.template = ENV['template'] if ENV['template']
-    rdoc.title    = &quot;Rails Application Documentation&quot;
+    rdoc.title    = ENV['title'] || &quot;Rails Application Documentation&quot;
     rdoc.options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source'
     rdoc.options &lt;&lt; '--charset' &lt;&lt; 'utf-8'
     rdoc.rdoc_files.include('doc/README_FOR_APP')
@@ -62,6 +62,7 @@ namespace :doc do
         options &lt;&lt; &quot;-o doc/plugins/#{plugin}&quot;
         options &lt;&lt; &quot;--title '#{plugin.titlecase} Plugin Documentation'&quot;
         options &lt;&lt; '--line-numbers' &lt;&lt; '--inline-source'
+        options &lt;&lt; '--charset' &lt;&lt; 'utf-8'
         options &lt;&lt; '-T html'
 
         files.include(&quot;#{plugin_base}/lib/**/*.rb&quot;)</diff>
      <filename>railties/lib/tasks/documentation.rake</filename>
    </modified>
    <modified>
      <diff>@@ -43,9 +43,12 @@ namespace :rails do
       require 'open-uri'
       version = ENV[&quot;RELEASE&quot;] || &quot;edge&quot;
       target  = &quot;rails_#{version}.zip&quot;
+      commits = &quot;http://github.com/api/v1/yaml/rails/rails/commits/master&quot;
       url     = &quot;http://dev.rubyonrails.org/archives/#{target}&quot;
 
       chdir 'vendor' do
+        latest_revision = YAML.load(open(commits))[&quot;commits&quot;].first[&quot;id&quot;]
+
         puts &quot;Downloading Rails from #{url}&quot;
         File.open('rails.zip', 'wb') do |dst|
           open url do |src|
@@ -61,6 +64,8 @@ namespace :rails do
         %w(rails.zip rails/Rakefile rails/cleanlogs.sh rails/pushgems.rb rails/release.rb).each do |goner|
           rm_f goner
         end
+
+        touch &quot;rails/REVISION_#{latest_revision}&quot;
       end
 
       puts 'Updating current scripts, javascripts, and configuration settings'</diff>
      <filename>railties/lib/tasks/framework.rake</filename>
    </modified>
    <modified>
      <diff>@@ -3,10 +3,9 @@ task :environment do
   require(File.join(RAILS_ROOT, 'config', 'environment'))
 end
 
-require 'rails_generator/secret_key_generator'
-desc 'Generate a crytographically secure secret key. This is typically used to generate a secret for cookie sessions. Pass a unique identifier to the generator using ID=&quot;some unique identifier&quot; for greater security.'
+desc 'Generate a crytographically secure secret key. This is typically used to generate a secret for cookie sessions.'
 task :secret do
-  puts Rails::SecretKeyGenerator.new(ENV['ID']).generate_secret
+  puts ActiveSupport::SecureRandom.hex(64)
 end
 
 require 'active_support'
@@ -54,4 +53,4 @@ namespace :time do
       puts &quot;\n&quot;
     end
   end
-end
\ No newline at end of file
+end</diff>
      <filename>railties/lib/tasks/misc.rake</filename>
    </modified>
    <modified>
      <diff>@@ -29,4 +29,20 @@ class RailsModelGeneratorTest &lt; GeneratorTestCase
       assert_generated_column t, :created_at, :timestamp
     end
   end
+
+  def test_model_with_reference_attributes_generates_belongs_to_associations
+    run_generator('model', %w(Product name:string supplier:references))
+
+    assert_generated_model_for :product do |body|
+      assert body =~ /^\s+belongs_to :supplier/, &quot;#{body.inspect} should contain 'belongs_to :supplier'&quot;
+    end
+  end
+
+  def test_model_with_belongs_to_attributes_generates_belongs_to_associations
+    run_generator('model', %w(Product name:string supplier:belongs_to))
+
+    assert_generated_model_for :product do |body|
+      assert body =~ /^\s+belongs_to :supplier/, &quot;#{body.inspect} should contain 'belongs_to :supplier'&quot;
+    end
+  end
 end</diff>
      <filename>railties/test/generators/rails_model_generator_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -30,6 +30,24 @@ class Initializer_load_environment_Test &lt; Test::Unit::TestCase
 
 end
 
+class Initializer_eager_loading_Test &lt; Test::Unit::TestCase
+  def setup
+    @config = ConfigurationMock.new(&quot;&quot;)
+    @config.cache_classes = true
+    @config.load_paths = [File.expand_path(File.dirname(__FILE__) + &quot;/fixtures/eager&quot;)]
+    @config.eager_load_paths = [File.expand_path(File.dirname(__FILE__) + &quot;/fixtures/eager&quot;)]
+    @initializer = Rails::Initializer.new(@config)
+    @initializer.set_load_path
+    @initializer.set_autoload_paths
+  end
+
+  def test_eager_loading_loads_parent_classes_before_children
+    assert_nothing_raised do
+      @initializer.load_application_classes
+    end
+  end
+end
+
 uses_mocha 'Initializer after_initialize' do
   class Initializer_after_initialize_with_blocks_environment_Test &lt; Test::Unit::TestCase
     def setup</diff>
      <filename>railties/test/initializer_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -31,14 +31,8 @@ class SecretKeyGenerationTest &lt; Test::Unit::TestCase
   end
 
   def test_secret_key_generation
-    assert @generator.generate_secret.length &gt;= SECRET_KEY_MIN_LENGTH
-  end
-
-  Rails::SecretKeyGenerator::GENERATORS.each do |generator|
-    if Rails::SecretKeyGenerator.send(&quot;supports_#{generator}?&quot;)
-      define_method(&quot;test_secret_key_generation_with_#{generator}&quot;) do
-        assert @generator.send(&quot;generate_secret_with_#{generator}&quot;).length &gt;= SECRET_KEY_MIN_LENGTH
-      end
+    assert_deprecated /ActiveSupport::SecureRandom\.hex\(64\)/ do
+      assert @generator.generate_secret.length &gt;= SECRET_KEY_MIN_LENGTH
     end
   end
 end</diff>
      <filename>railties/test/secret_key_generation_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,8 +3,11 @@
 VERSION  = ARGV.first
 PACKAGES = %w(activesupport activerecord actionpack actionmailer activeresource)
 
-# Checkout source
-# `rm -rf release &amp;&amp; svn export http://dev.rubyonrails.org/svn/rails/trunk release`
+# Copy source
+`mkdir release`
+(PACKAGES + %w(railties)).each do |p| 
+  `cp -R #{p} release/#{p}`
+end
 
 # Create Rails packages
 `cd release/railties &amp;&amp; rake template=jamis package`</diff>
      <filename>release.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>actionpack/lib/action_view/locale/en-US.rb</filename>
    </removed>
    <removed>
      <filename>actionpack/test/controller/new_render_test.rb</filename>
    </removed>
    <removed>
      <filename>activerecord/lib/active_record/locale/en-US.rb</filename>
    </removed>
    <removed>
      <filename>activerecord/test/cases/threaded_connections_test.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/clean_logger.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/locale/en-US.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/typed_array.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/MIT-LICENSE</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/README.textile</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/i18n.gemspec</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/lib/i18n.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/lib/i18n/backend/simple.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/lib/i18n/exceptions.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/test/all.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/test/i18n_exceptions_test.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/test/i18n_test.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/lib/active_support/vendor/i18n-0.0.1/test/simple_backend_test.rb</filename>
    </removed>
    <removed>
      <filename>activesupport/test/typed_array_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>949018a0a8d366c9b375db55ca7d8672ed64edec</id>
    </parent>
    <parent>
      <id>227ee2ecb46f1609938a83ed82abde1a45ebe2eb</id>
    </parent>
  </parents>
  <author>
    <name>Miles Georgi</name>
    <email>azimux@gmail.com</email>
  </author>
  <url>http://github.com/azimux/rails/commit/ed758017a0142a627313e52bfb20c2324e659493</url>
  <id>ed758017a0142a627313e52bfb20c2324e659493</id>
  <committed-date>2008-09-06T20:03:21-07:00</committed-date>
  <authored-date>2008-09-06T20:03:21-07:00</authored-date>
  <message>Merge branch 'master' of git://github.com/rails/rails

Conflicts:

	activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb</message>
  <tree>9d0b24236cd1b8c4214c5682503a8618bb3640e1</tree>
  <committer>
    <name>Miles Georgi</name>
    <email>azimux@gmail.com</email>
  </committer>
</commit>
