From e1b5e3cc709df12d2d8495737e524f60015e6f5c Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@mobile-166-129-139-135.mycingular.net>
Date: Sat, 7 Nov 2009 11:23:21 -0800
Subject: Break up inflector to reduce the dependency burden on dependency-les
 methods like constantize.

---
 .../lib/active_support/core_ext/string/access.rb   |   2 +
 activesupport/lib/active_support/inflector.rb      | 411 +--------------------
 .../lib/active_support/inflector/inflections.rb    | 213 +++++++++++
 .../lib/active_support/inflector/methods.rb        | 139 +++++++
 .../lib/active_support/inflector/transliterate.rb  |  61 +++
 5 files changed, 419 insertions(+), 407 deletions(-)
 create mode 100644 activesupport/lib/active_support/inflector/inflections.rb
 create mode 100644 activesupport/lib/active_support/inflector/methods.rb
 create mode 100644 activesupport/lib/active_support/inflector/transliterate.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/access.rb b/activesupport/lib/active_support/core_ext/string/access.rb
index 57385d86d2..182b3e745d 100644
--- a/activesupport/lib/active_support/core_ext/string/access.rb
+++ b/activesupport/lib/active_support/core_ext/string/access.rb
@@ -1,3 +1,5 @@
+require "active_support/multibyte"
+
 class String
   unless '1.9'.respond_to?(:force_encoding)
     # Returns the character at the +position+ treating the string as an array (where 0 is the first character).
diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb
index 67aea2782f..215a60eba7 100644
--- a/activesupport/lib/active_support/inflector.rb
+++ b/activesupport/lib/active_support/inflector.rb
@@ -1,410 +1,7 @@
-# encoding: utf-8
-require 'iconv'
-require 'active_support/core_ext/object/blank'
-require 'active_support/core_ext/string/access'
-require 'active_support/core_ext/string/multibyte'
-
-module ActiveSupport
-  # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
-  # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
-  # in inflections.rb.
-  #
-  # The Rails core team has stated patches for the inflections library will not be accepted
-  # in order to avoid breaking legacy applications which may be relying on errant inflections.
-  # If you discover an incorrect inflection and require it for your application, you'll need
-  # to correct it yourself (explained below).
-  module Inflector
-    extend self
-
-    # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
-    # inflection rules. Examples:
-    #
-    #   ActiveSupport::Inflector.inflections do |inflect|
-    #     inflect.plural /^(ox)$/i, '\1\2en'
-    #     inflect.singular /^(ox)en/i, '\1'
-    #
-    #     inflect.irregular 'octopus', 'octopi'
-    #
-    #     inflect.uncountable "equipment"
-    #   end
-    #
-    # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
-    # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
-    # already have been loaded.
-    class Inflections
-      def self.instance
-        @__instance__ ||= new
-      end
-
-      attr_reader :plurals, :singulars, :uncountables, :humans
-
-      def initialize
-        @plurals, @singulars, @uncountables, @humans = [], [], [], []
-      end
-
-      # 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
-
-      # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
-      # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
-      #
-      # Examples:
-      #   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("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
-          plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
-          singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
-        else
-          plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
-          plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
-          plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
-          plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
-          singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
-          singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
-        end
-      end
-
-      # Add uncountable words that shouldn't be attempted inflected.
-      #
-      # Examples:
-      #   uncountable "money"
-      #   uncountable "money", "information"
-      #   uncountable %w( money information rice )
-      def uncountable(*words)
-        (@uncountables << words).flatten!
-      end
-
-      # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
-      # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
-      # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
-      #
-      # Examples:
-      #   human /_cnt$/i, '\1_count'
-      #   human "legacy_col_person_name", "Name"
-      def human(rule, replacement)
-        @humans.insert(0, [rule, replacement])
-      end
-
-      # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
-      # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
-      # <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
-      #
-      # Examples:
-      #   clear :all
-      #   clear :plurals
-      def clear(scope = :all)
-        case scope
-          when :all
-            @plurals, @singulars, @uncountables = [], [], []
-          else
-            instance_variable_set "@#{scope}", []
-        end
-      end
-    end
-
-    # Yields a singleton instance of Inflector::Inflections so you can specify additional
-    # inflector rules.
-    #
-    # Example:
-    #   ActiveSupport::Inflector.inflections do |inflect|
-    #     inflect.uncountable "rails"
-    #   end
-    def inflections
-      if block_given?
-        yield Inflections.instance
-      else
-        Inflections.instance
-      end
-    end
-
-    # Returns the plural form of the word in the string.
-    #
-    # Examples:
-    #   "post".pluralize             # => "posts"
-    #   "octopus".pluralize          # => "octopi"
-    #   "sheep".pluralize            # => "sheep"
-    #   "words".pluralize            # => "words"
-    #   "CamelOctopus".pluralize     # => "CamelOctopi"
-    def pluralize(word)
-      result = word.to_s.dup
-
-      if word.empty? || inflections.uncountables.include?(result.downcase)
-        result
-      else
-        inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
-        result
-      end
-    end
-
-    # The reverse of +pluralize+, returns the singular form of a word in a string.
-    #
-    # Examples:
-    #   "posts".singularize            # => "post"
-    #   "octopi".singularize           # => "octopus"
-    #   "sheep".singularize            # => "sheep"
-    #   "word".singularize             # => "word"
-    #   "CamelOctopi".singularize      # => "CamelOctopus"
-    def singularize(word)
-      result = word.to_s.dup
-
-      if inflections.uncountables.include?(result.downcase)
-        result
-      else
-        inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
-        result
-      end
-    end
-
-    # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
-    # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
-    #
-    # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
-    #
-    # Examples:
-    #   "active_record".camelize                # => "ActiveRecord"
-    #   "active_record".camelize(:lower)        # => "activeRecord"
-    #   "active_record/errors".camelize         # => "ActiveRecord::Errors"
-    #   "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
-    def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
-      if first_letter_in_uppercase
-        lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
-      else
-        lower_case_and_underscored_word.to_s.first.downcase + camelize(lower_case_and_underscored_word)[1..-1]
-      end
-    end
-
-    # Capitalizes all the words and replaces some characters in the string to create
-    # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
-    # used in the Rails internals.
-    #
-    # +titleize+ is also aliased as as +titlecase+.
-    #
-    # Examples:
-    #   "man from the boondocks".titleize # => "Man From The Boondocks"
-    #   "x-men: the last stand".titleize  # => "X Men: The Last Stand"
-    def titleize(word)
-      humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
-    end
-
-    # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
-    #
-    # Changes '::' to '/' to convert namespaces to paths.
-    #
-    # Examples:
-    #   "ActiveRecord".underscore         # => "active_record"
-    #   "ActiveRecord::Errors".underscore # => active_record/errors
-    def underscore(camel_cased_word)
-      camel_cased_word.to_s.gsub(/::/, '/').
-        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
-        gsub(/([a-z\d])([A-Z])/,'\1_\2').
-        tr("-", "_").
-        downcase
-    end
-
-    # Replaces underscores with dashes in the string.
-    #
-    # Example:
-    #   "puni_puni" # => "puni-puni"
-    def dasherize(underscored_word)
-      underscored_word.gsub(/_/, '-')
-    end
-
-    # Capitalizes the first word and turns underscores into spaces and strips a
-    # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
-    #
-    # Examples:
-    #   "employee_salary" # => "Employee salary"
-    #   "author_id"       # => "Author"
-    def humanize(lower_case_and_underscored_word)
-      result = lower_case_and_underscored_word.to_s.dup
-
-      inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
-      result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
-    end
-
-    # Removes the module part from the expression in the string.
-    #
-    # Examples:
-    #   "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
-    #   "Inflections".demodulize                                       # => "Inflections"
-    def demodulize(class_name_in_module)
-      class_name_in_module.to_s.gsub(/^.*::/, '')
-    end
-
-    # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
-    #
-    # ==== Examples
-    #
-    #   class Person
-    #     def to_param
-    #       "#{id}-#{name.parameterize}"
-    #     end
-    #   end
-    #
-    #   @person = Person.find(1)
-    #   # => #<Person id: 1, name: "Donald E. Knuth">
-    #
-    #   <%= link_to(@person.name, person_path(@person)) %>
-    #   # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
-    def parameterize(string, sep = '-')
-      # replace accented chars with their ascii equivalents
-      parameterized_string = transliterate(string)
-      # Turn unwanted chars into the separator
-      parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
-      unless sep.blank?
-        re_sep = Regexp.escape(sep)
-        # No more than one of the separator in a row.
-        parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
-        # Remove leading/trailing separator.
-        parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
-      end
-      parameterized_string.downcase
-    end
-
-
-    # Replaces accented characters with their ascii equivalents.
-    def transliterate(string)
-      Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
-    end
-
-    if RUBY_VERSION >= '1.9'
-      undef_method :transliterate
-      def transliterate(string)
-        warn "Ruby 1.9 doesn't support Unicode normalization yet"
-        string.dup
-      end
-
-    # The iconv transliteration code doesn't function correctly
-    # on some platforms, but it's very fast where it does function.
-    elsif "foo" != (Inflector.transliterate("föö") rescue nil)
-      undef_method :transliterate
-      def transliterate(string)
-        string.mb_chars.normalize(:kd). # Decompose accented characters
-          gsub(/[^\x00-\x7F]+/, '')     # Remove anything non-ASCII entirely (e.g. diacritics).
-      end
-    end
-
-    # Create the name of a table like Rails does for models to table names. This method
-    # uses the +pluralize+ method on the last word in the string.
-    #
-    # Examples
-    #   "RawScaledScorer".tableize # => "raw_scaled_scorers"
-    #   "egg_and_ham".tableize     # => "egg_and_hams"
-    #   "fancyCategory".tableize   # => "fancy_categories"
-    def tableize(class_name)
-      pluralize(underscore(class_name))
-    end
-
-    # Create a class name from a plural table name like Rails does for table names to models.
-    # Note that this returns a string and not a Class. (To convert to an actual class
-    # follow +classify+ with +constantize+.)
-    #
-    # Examples:
-    #   "egg_and_hams".classify # => "EggAndHam"
-    #   "posts".classify        # => "Post"
-    #
-    # Singular names are not handled correctly:
-    #   "business".classify     # => "Busines"
-    def classify(table_name)
-      # strip out any leading schema name
-      camelize(singularize(table_name.to_s.sub(/.*\./, '')))
-    end
-
-    # Creates a foreign key name from a class name.
-    # +separate_class_name_and_id_with_underscore+ sets whether
-    # the method should put '_' between the name and 'id'.
-    #
-    # Examples:
-    #   "Message".foreign_key        # => "message_id"
-    #   "Message".foreign_key(false) # => "messageid"
-    #   "Admin::Post".foreign_key    # => "post_id"
-    def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
-      underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
-    end
-
-    # 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:
-      #
-      #   "Module".constantize     # => Module
-      #   "Test::Unit".constantize # => Test::Unit
-      #
-      # The name is assumed to be the one of a top-level constant, no matter whether
-      # it starts with "::" or not. No lexical context is taken into account:
-      #
-      #   C = 'outside'
-      #   module M
-      #     C = 'inside'
-      #     C               # => 'inside'
-      #     "C".constantize # => '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_get(name, false) || constant.const_missing(name)
-        end
-        constant
-      end
-    end
-
-    # Turns a number into an ordinal string used to denote the position in an
-    # ordered sequence such as 1st, 2nd, 3rd, 4th.
-    #
-    # Examples:
-    #   ordinalize(1)     # => "1st"
-    #   ordinalize(2)     # => "2nd"
-    #   ordinalize(1002)  # => "1002nd"
-    #   ordinalize(1003)  # => "1003rd"
-    def ordinalize(number)
-      if (11..13).include?(number.to_i % 100)
-        "#{number}th"
-      else
-        case number.to_i % 10
-          when 1; "#{number}st"
-          when 2; "#{number}nd"
-          when 3; "#{number}rd"
-          else    "#{number}th"
-        end
-      end
-    end
-  end
-end
-
 # in case active_support/inflector is required without the rest of active_support
+require 'active_support/inflector/inflections'
+require 'active_support/inflector/transliterate'
+require 'active_support/inflector/methods'
+
 require 'active_support/inflections'
 require 'active_support/core_ext/string/inflections'
diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
new file mode 100644
index 0000000000..24ce58e5c2
--- /dev/null
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -0,0 +1,213 @@
+# require "active_support/core_ext/string/access"
+
+module ActiveSupport
+  module Inflector
+    # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
+    # inflection rules. Examples:
+    #
+    #   ActiveSupport::Inflector.inflections do |inflect|
+    #     inflect.plural /^(ox)$/i, '\1\2en'
+    #     inflect.singular /^(ox)en/i, '\1'
+    #
+    #     inflect.irregular 'octopus', 'octopi'
+    #
+    #     inflect.uncountable "equipment"
+    #   end
+    #
+    # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
+    # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
+    # already have been loaded.
+    class Inflections
+      def self.instance
+        @__instance__ ||= new
+      end
+
+      attr_reader :plurals, :singulars, :uncountables, :humans
+
+      def initialize
+        @plurals, @singulars, @uncountables, @humans = [], [], [], []
+      end
+
+      # 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
+
+      # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
+      # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
+      #
+      # Examples:
+      #   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("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
+          plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
+          singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
+        else
+          plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
+          plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
+          plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
+          plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
+          singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
+          singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
+        end
+      end
+
+      # Add uncountable words that shouldn't be attempted inflected.
+      #
+      # Examples:
+      #   uncountable "money"
+      #   uncountable "money", "information"
+      #   uncountable %w( money information rice )
+      def uncountable(*words)
+        (@uncountables << words).flatten!
+      end
+
+      # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
+      # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
+      # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
+      #
+      # Examples:
+      #   human /_cnt$/i, '\1_count'
+      #   human "legacy_col_person_name", "Name"
+      def human(rule, replacement)
+        @humans.insert(0, [rule, replacement])
+      end
+
+      # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
+      # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
+      # <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
+      #
+      # Examples:
+      #   clear :all
+      #   clear :plurals
+      def clear(scope = :all)
+        case scope
+          when :all
+            @plurals, @singulars, @uncountables = [], [], []
+          else
+            instance_variable_set "@#{scope}", []
+        end
+      end
+    end
+
+    # Yields a singleton instance of Inflector::Inflections so you can specify additional
+    # inflector rules.
+    #
+    # Example:
+    #   ActiveSupport::Inflector.inflections do |inflect|
+    #     inflect.uncountable "rails"
+    #   end
+    def inflections
+      if block_given?
+        yield Inflections.instance
+      else
+        Inflections.instance
+      end
+    end
+
+    # Returns the plural form of the word in the string.
+    #
+    # Examples:
+    #   "post".pluralize             # => "posts"
+    #   "octopus".pluralize          # => "octopi"
+    #   "sheep".pluralize            # => "sheep"
+    #   "words".pluralize            # => "words"
+    #   "CamelOctopus".pluralize     # => "CamelOctopi"
+    def pluralize(word)
+      result = word.to_s.dup
+
+      if word.empty? || inflections.uncountables.include?(result.downcase)
+        result
+      else
+        inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+        result
+      end
+    end
+
+    # The reverse of +pluralize+, returns the singular form of a word in a string.
+    #
+    # Examples:
+    #   "posts".singularize            # => "post"
+    #   "octopi".singularize           # => "octopus"
+    #   "sheep".singularize            # => "sheep"
+    #   "word".singularize             # => "word"
+    #   "CamelOctopi".singularize      # => "CamelOctopus"
+    def singularize(word)
+      result = word.to_s.dup
+
+      if inflections.uncountables.include?(result.downcase)
+        result
+      else
+        inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+        result
+      end
+    end
+
+    # Capitalizes the first word and turns underscores into spaces and strips a
+    # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
+    #
+    # Examples:
+    #   "employee_salary" # => "Employee salary"
+    #   "author_id"       # => "Author"
+    def humanize(lower_case_and_underscored_word)
+      result = lower_case_and_underscored_word.to_s.dup
+
+      inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
+      result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
+    end
+
+    # Capitalizes all the words and replaces some characters in the string to create
+    # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
+    # used in the Rails internals.
+    #
+    # +titleize+ is also aliased as as +titlecase+.
+    #
+    # Examples:
+    #   "man from the boondocks".titleize # => "Man From The Boondocks"
+    #   "x-men: the last stand".titleize  # => "X Men: The Last Stand"
+    def titleize(word)
+      humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
+    end
+
+    # Create the name of a table like Rails does for models to table names. This method
+    # uses the +pluralize+ method on the last word in the string.
+    #
+    # Examples
+    #   "RawScaledScorer".tableize # => "raw_scaled_scorers"
+    #   "egg_and_ham".tableize     # => "egg_and_hams"
+    #   "fancyCategory".tableize   # => "fancy_categories"
+    def tableize(class_name)
+      pluralize(underscore(class_name))
+    end
+
+    # Create a class name from a plural table name like Rails does for table names to models.
+    # Note that this returns a string and not a Class. (To convert to an actual class
+    # follow +classify+ with +constantize+.)
+    #
+    # Examples:
+    #   "egg_and_hams".classify # => "EggAndHam"
+    #   "posts".classify        # => "Post"
+    #
+    # Singular names are not handled correctly:
+    #   "business".classify     # => "Busines"
+    def classify(table_name)
+      # strip out any leading schema name
+      camelize(singularize(table_name.to_s.sub(/.*\./, '')))
+    end
+  end
+end
\ No newline at end of file
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
new file mode 100644
index 0000000000..41277893e3
--- /dev/null
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -0,0 +1,139 @@
+module ActiveSupport
+  # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
+  # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
+  # in inflections.rb.
+  #
+  # The Rails core team has stated patches for the inflections library will not be accepted
+  # in order to avoid breaking legacy applications which may be relying on errant inflections.
+  # If you discover an incorrect inflection and require it for your application, you'll need
+  # to correct it yourself (explained below).
+  module Inflector
+    extend self
+
+    # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
+    # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
+    #
+    # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
+    #
+    # Examples:
+    #   "active_record".camelize                # => "ActiveRecord"
+    #   "active_record".camelize(:lower)        # => "activeRecord"
+    #   "active_record/errors".camelize         # => "ActiveRecord::Errors"
+    #   "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
+    def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
+      if first_letter_in_uppercase
+        lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
+      else
+        lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
+      end
+    end
+
+    # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
+    #
+    # Changes '::' to '/' to convert namespaces to paths.
+    #
+    # Examples:
+    #   "ActiveRecord".underscore         # => "active_record"
+    #   "ActiveRecord::Errors".underscore # => active_record/errors
+    def underscore(camel_cased_word)
+      camel_cased_word.to_s.gsub(/::/, '/').
+        gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
+        gsub(/([a-z\d])([A-Z])/,'\1_\2').
+        tr("-", "_").
+        downcase
+    end
+
+    # Replaces underscores with dashes in the string.
+    #
+    # Example:
+    #   "puni_puni" # => "puni-puni"
+    def dasherize(underscored_word)
+      underscored_word.gsub(/_/, '-')
+    end
+
+    # Removes the module part from the expression in the string.
+    #
+    # Examples:
+    #   "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
+    #   "Inflections".demodulize                                       # => "Inflections"
+    def demodulize(class_name_in_module)
+      class_name_in_module.to_s.gsub(/^.*::/, '')
+    end
+
+    # Creates a foreign key name from a class name.
+    # +separate_class_name_and_id_with_underscore+ sets whether
+    # the method should put '_' between the name and 'id'.
+    #
+    # Examples:
+    #   "Message".foreign_key        # => "message_id"
+    #   "Message".foreign_key(false) # => "messageid"
+    #   "Admin::Post".foreign_key    # => "post_id"
+    def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
+      underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
+    end
+
+    # 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:
+      #
+      #   "Module".constantize     # => Module
+      #   "Test::Unit".constantize # => Test::Unit
+      #
+      # The name is assumed to be the one of a top-level constant, no matter whether
+      # it starts with "::" or not. No lexical context is taken into account:
+      #
+      #   C = 'outside'
+      #   module M
+      #     C = 'inside'
+      #     C               # => 'inside'
+      #     "C".constantize # => '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_get(name, false) || constant.const_missing(name)
+        end
+        constant
+      end
+    end
+
+    # Turns a number into an ordinal string used to denote the position in an
+    # ordered sequence such as 1st, 2nd, 3rd, 4th.
+    #
+    # Examples:
+    #   ordinalize(1)     # => "1st"
+    #   ordinalize(2)     # => "2nd"
+    #   ordinalize(1002)  # => "1002nd"
+    #   ordinalize(1003)  # => "1003rd"
+    def ordinalize(number)
+      if (11..13).include?(number.to_i % 100)
+        "#{number}th"
+      else
+        case number.to_i % 10
+          when 1; "#{number}st"
+          when 2; "#{number}nd"
+          when 3; "#{number}rd"
+          else    "#{number}th"
+        end
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/activesupport/lib/active_support/inflector/transliterate.rb b/activesupport/lib/active_support/inflector/transliterate.rb
new file mode 100644
index 0000000000..30a9072ee1
--- /dev/null
+++ b/activesupport/lib/active_support/inflector/transliterate.rb
@@ -0,0 +1,61 @@
+# encoding: utf-8
+require 'iconv'
+require 'active_support/core_ext/string/multibyte'
+
+module ActiveSupport
+  module Inflector
+    extend self
+    
+    # Replaces accented characters with their ascii equivalents.
+    def transliterate(string)
+      Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
+    end
+
+    if RUBY_VERSION >= '1.9'
+      undef_method :transliterate
+      def transliterate(string)
+        warn "Ruby 1.9 doesn't support Unicode normalization yet"
+        string.dup
+      end
+
+    # The iconv transliteration code doesn't function correctly
+    # on some platforms, but it's very fast where it does function.
+    elsif "foo" != (Inflector.transliterate("föö") rescue nil)
+      undef_method :transliterate
+      def transliterate(string)
+        string.mb_chars.normalize(:kd). # Decompose accented characters
+          gsub(/[^\x00-\x7F]+/, '')     # Remove anything non-ASCII entirely (e.g. diacritics).
+      end
+    end
+
+    # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
+    #
+    # ==== Examples
+    #
+    #   class Person
+    #     def to_param
+    #       "#{id}-#{name.parameterize}"
+    #     end
+    #   end
+    #
+    #   @person = Person.find(1)
+    #   # => #<Person id: 1, name: "Donald E. Knuth">
+    #
+    #   <%= link_to(@person.name, person_path(@person)) %>
+    #   # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
+    def parameterize(string, sep = '-')
+      # replace accented chars with their ascii equivalents
+      parameterized_string = transliterate(string)
+      # Turn unwanted chars into the separator
+      parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
+      unless sep.nil? || sep.empty?
+        re_sep = Regexp.escape(sep)
+        # No more than one of the separator in a row.
+        parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
+        # Remove leading/trailing separator.
+        parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
+      end
+      parameterized_string.downcase
+    end    
+  end
+end
\ No newline at end of file
-- 
cgit v1.2.3


From 103b29831e6d6a6c4363fd0e59ffcc6c343a14aa Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@mobile-166-129-139-135.mycingular.net>
Date: Sat, 7 Nov 2009 11:23:34 -0800
Subject: Since we require 1.8.7 we don't need to shim instance_exec anymore

---
 .../active_support/core_ext/object/extending.rb    | 27 ----------------------
 1 file changed, 27 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/object/extending.rb b/activesupport/lib/active_support/core_ext/object/extending.rb
index bbf6f8563b..0cc74c8298 100644
--- a/activesupport/lib/active_support/core_ext/object/extending.rb
+++ b/activesupport/lib/active_support/core_ext/object/extending.rb
@@ -50,31 +50,4 @@ class Object
   def extend_with_included_modules_from(object) #:nodoc:
     object.extended_by.each { |mod| extend mod }
   end
-
-  unless defined? instance_exec # 1.9
-    module InstanceExecMethods #:nodoc:
-    end
-    include InstanceExecMethods
-
-    # Evaluate the block with the given arguments within the context of
-    # this object, so self is set to the method receiver.
-    #
-    # From Mauricio's http://eigenclass.org/hiki/bounded+space+instance_exec
-    def instance_exec(*args, &block)
-      begin
-        old_critical, Thread.critical = Thread.critical, true
-        n = 0
-        n += 1 while respond_to?(method_name = "__instance_exec#{n}")
-        InstanceExecMethods.module_eval { define_method(method_name, &block) }
-      ensure
-        Thread.critical = old_critical
-      end
-
-      begin
-        send(method_name, *args)
-      ensure
-        InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil
-      end
-    end
-  end
 end
-- 
cgit v1.2.3


From c44fb4ced5cbe61adb12f3431db05afa492bd176 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 21:30:34 -0800
Subject: Ruby 1.9: use method_name to work around miniunit API changes

---
 activesupport/lib/active_support/testing/setup_and_teardown.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb
index 7952eb50c3..0e998d2dbe 100644
--- a/activesupport/lib/active_support/testing/setup_and_teardown.rb
+++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb
@@ -21,12 +21,12 @@ module ActiveSupport
             run_callbacks :setup
             result = super
           rescue Exception => e
-            result = runner.puke(self.class, self.name, e)
+            result = runner.puke(self.class, method_name, e)
           ensure
             begin
               run_callbacks :teardown, :enumerator => :reverse_each
             rescue Exception => e
-              result = runner.puke(self.class, self.name, e)
+              result = runner.puke(self.class, method_name, e)
             end
           end
           result
-- 
cgit v1.2.3


From 7ad461b44dabb586fbad190493ac4ecd96104597 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 21:31:06 -0800
Subject: Ruby 1.9.2: avoid Array#to_s and Array(nil)

---
 .../lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb    | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
index 1b49debc05..7487b96b8c 100755
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
@@ -195,10 +195,19 @@ module I18n
     # Merges the given locale, key and scope into a single array of keys.
     # Splits keys that contain dots into multiple keys. Makes sure all
     # keys are Symbols.
-    def normalize_translation_keys(locale, key, scope)
-      keys = [locale] + Array(scope) + [key]
-      keys = keys.map { |k| k.to_s.split(/\./) }
-      keys.flatten.map { |k| k.to_sym }
+    def normalize_translation_keys(*keys)
+      normalized = []
+      keys.each do |key|
+        case key
+        when Array
+          normalized.concat normalize_translation_keys(*key)
+        when nil
+          # skip
+        else
+          normalized.concat key.to_s.split('.').map { |sub| sub.to_sym }
+        end
+      end
+      normalized
     end
   end
 end
-- 
cgit v1.2.3


From 20cdaddfd27dfeef5c853e85fafa4e13b6da05f3 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 21:55:43 -0800
Subject: Ruby 1.9.2: work around changes to flatten and nil.to_str

---
 activesupport/lib/active_support/cache.rb           |  3 ++-
 .../lib/active_support/core_ext/hash/conversions.rb |  3 ++-
 activesupport/lib/active_support/dependencies.rb    |  2 +-
 .../lib/active_support/deprecated_callbacks.rb      |  5 +++--
 .../lib/active_support/json/backends/jsongem.rb     | 21 ++++++++++++---------
 activesupport/test/multibyte_chars_test.rb          |  6 +++---
 6 files changed, 23 insertions(+), 17 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index b91ae65e9f..2f714c62ee 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -43,7 +43,8 @@ module ActiveSupport
     #   ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
     #   # => returns MyOwnCacheStore.new
     def self.lookup_store(*store_option)
-      store, *parameters = *([ store_option ].flatten)
+      store = store_option.shift
+      parameters = store_option
 
       case store
       when Symbol
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 190173f8a0..35ccec5df4 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -1,4 +1,5 @@
 require 'active_support/time'
+require 'active_support/core_ext/array/wrap'
 require 'active_support/core_ext/hash/reverse_merge'
 
 class Hash
@@ -138,7 +139,7 @@ class Hash
         case value.class.to_s
           when 'Hash'
             if value['type'] == 'array'
-              child_key, entries = value.detect { |k,v| k != 'type' }   # child_key is throwaway
+              child_key, entries = Array.wrap(value.detect { |k,v| k != 'type' })   # child_key is throwaway
               if entries.nil? || (c = value['__content__'] && c.blank?)
                 []
               else
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 7f6f012721..e858bcdc80 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -339,7 +339,7 @@ module ActiveSupport #:nodoc:
           next
         end
         [ nesting_camel ]
-      end.flatten.compact.uniq
+      end.compact.flatten.compact.uniq
     end
 
     # Search for a file in load_paths matching the provided suffix.
diff --git a/activesupport/lib/active_support/deprecated_callbacks.rb b/activesupport/lib/active_support/deprecated_callbacks.rb
index 20fb03cbeb..f56fef0b6d 100644
--- a/activesupport/lib/active_support/deprecated_callbacks.rb
+++ b/activesupport/lib/active_support/deprecated_callbacks.rb
@@ -1,4 +1,5 @@
 require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/array/wrap'
 
 module ActiveSupport
   # Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
@@ -194,8 +195,8 @@ module ActiveSupport
         end
 
         def should_run_callback?(*args)
-          [options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
-          ![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
+          Array.wrap(options[:if]).flatten.compact.all? { |a| evaluate_method(a, *args) } &&
+          !Array.wrap(options[:unless]).flatten.compact.any? { |a| evaluate_method(a, *args) }
         end
     end
 
diff --git a/activesupport/lib/active_support/json/backends/jsongem.rb b/activesupport/lib/active_support/json/backends/jsongem.rb
index c6c17a3c4e..cfe28d7bb9 100644
--- a/activesupport/lib/active_support/json/backends/jsongem.rb
+++ b/activesupport/lib/active_support/json/backends/jsongem.rb
@@ -23,15 +23,18 @@ module ActiveSupport
       private
         def convert_dates_from(data)
           case data
-            when DATE_REGEX
-              DateTime.parse(data)
-            when Array
-              data.map! { |d| convert_dates_from(d) }
-            when Hash
-              data.each do |key, value|
-                data[key] = convert_dates_from(value)
-              end
-            else data
+          when nil
+            nil
+          when DATE_REGEX
+            DateTime.parse(data)
+          when Array
+            data.map! { |d| convert_dates_from(d) }
+          when Hash
+            data.each do |key, value|
+              data[key] = convert_dates_from(value)
+            end
+          else
+            data
           end
         end
       end
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 4ff74abf61..9245263270 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -228,8 +228,8 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
     assert !@chars.include?('a')
   end
 
-  def test_include_raises_type_error_when_nil_is_passed
-    assert_raise(TypeError) do
+  def test_include_raises_when_nil_is_passed
+    assert_raise(RUBY_VERSION >= '1.9.2' ? NoMethodError : TypeError) do
       @chars.include?(nil)
     end
   end
@@ -659,4 +659,4 @@ class MultibyteInternalsTest < ActiveSupport::TestCase
         "Expected byte offset #{byte_offset} to translate to #{character_offset}"
     end
   end
-end
\ No newline at end of file
+end
-- 
cgit v1.2.3


From deddd55086ad3e9ae43bb0fa44911a77c8ee4495 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 22:01:50 -0800
Subject: Work around assert_raise limitation

---
 activesupport/test/multibyte_chars_test.rb | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 9245263270..0e489c10e1 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -229,9 +229,9 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
   end
 
   def test_include_raises_when_nil_is_passed
-    assert_raise(RUBY_VERSION >= '1.9.2' ? NoMethodError : TypeError) do
-      @chars.include?(nil)
-    end
+    @chars.include?(nil)
+    flunk "Expected chars.include?(nil) to raise TypeError or NoMethodError"
+  rescue Exception => e
   end
 
   def test_index_should_return_character_offset
-- 
cgit v1.2.3


From 8e32830412c051d97613ea4b84c0d8b64e612538 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 22:31:54 -0800
Subject: Fix unresolved string extension dependencies

---
 activesupport/lib/active_support/multibyte/chars.rb  | 5 +++--
 activesupport/lib/active_support/values/time_zone.rb | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index d372b0ab1f..c7225fec06 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -1,4 +1,5 @@
 # encoding: utf-8
+require 'active_support/core_ext/string/access'
 require 'active_support/core_ext/string/behavior'
 
 module ActiveSupport #:nodoc:
@@ -197,7 +198,7 @@ module ActiveSupport #:nodoc:
       #   'Café périferôl'.mb_chars.index('ô') #=> 12
       #   'Café périferôl'.mb_chars.index(/\w/u) #=> 0
       def index(needle, offset=0)
-        wrapped_offset = self.first(offset).wrapped_string.length
+        wrapped_offset = first(offset).wrapped_string.length
         index = @wrapped_string.index(needle, wrapped_offset)
         index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
       end
@@ -211,7 +212,7 @@ module ActiveSupport #:nodoc:
       #   'Café périferôl'.mb_chars.rindex(/\w/u) #=> 13
       def rindex(needle, offset=nil)
         offset ||= length
-        wrapped_offset = self.first(offset).wrapped_string.length
+        wrapped_offset = first(offset).wrapped_string.length
         index = @wrapped_string.rindex(needle, wrapped_offset)
         index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
       end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 53a4c7acf5..e7583bef1b 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/object/blank'
 require 'active_support/core_ext/time'
 require 'active_support/core_ext/date'
 require 'active_support/core_ext/date_time'
-- 
cgit v1.2.3


From b1164adda12268b38bba9b0d81c0d26b7251b8bb Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sun, 8 Nov 2009 23:29:33 -0800
Subject: Fix arg destructure

---
 activesupport/lib/active_support/cache.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 2f714c62ee..f2d957f154 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -1,4 +1,5 @@
 require 'benchmark'
+require 'active_support/core_ext/array/wrap'
 require 'active_support/core_ext/benchmark'
 require 'active_support/core_ext/exception'
 require 'active_support/core_ext/class/attribute_accessors'
@@ -43,8 +44,7 @@ module ActiveSupport
     #   ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
     #   # => returns MyOwnCacheStore.new
     def self.lookup_store(*store_option)
-      store = store_option.shift
-      parameters = store_option
+      store, *parameters = *Array.wrap(store_option).flatten
 
       case store
       when Symbol
-- 
cgit v1.2.3


From ee0d41c38d06802bec420d4e0948249146c92cd9 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 03:18:54 -0800
Subject: Remove string access core extension dependency

---
 activesupport/lib/active_support/inflector/inflections.rb | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/inflector/inflections.rb b/activesupport/lib/active_support/inflector/inflections.rb
index 24ce58e5c2..785e245ea4 100644
--- a/activesupport/lib/active_support/inflector/inflections.rb
+++ b/activesupport/lib/active_support/inflector/inflections.rb
@@ -1,5 +1,3 @@
-# require "active_support/core_ext/string/access"
-
 module ActiveSupport
   module Inflector
     # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
@@ -210,4 +208,4 @@ module ActiveSupport
       camelize(singularize(table_name.to_s.sub(/.*\./, '')))
     end
   end
-end
\ No newline at end of file
+end
-- 
cgit v1.2.3


From 7f0fcadd3650eaee5bd6a8ab8032ed3c5627385b Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 04:05:22 -0800
Subject: Revert "Ruby 1.9.2: avoid Array#to_s and Array(nil)"

This reverts commit 7ad461b44dabb586fbad190493ac4ecd96104597.
---
 .../lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb    | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
index 7487b96b8c..1b49debc05 100755
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
@@ -195,19 +195,10 @@ module I18n
     # Merges the given locale, key and scope into a single array of keys.
     # Splits keys that contain dots into multiple keys. Makes sure all
     # keys are Symbols.
-    def normalize_translation_keys(*keys)
-      normalized = []
-      keys.each do |key|
-        case key
-        when Array
-          normalized.concat normalize_translation_keys(*key)
-        when nil
-          # skip
-        else
-          normalized.concat key.to_s.split('.').map { |sub| sub.to_sym }
-        end
-      end
-      normalized
+    def normalize_translation_keys(locale, key, scope)
+      keys = [locale] + Array(scope) + [key]
+      keys = keys.map { |k| k.to_s.split(/\./) }
+      keys.flatten.map { |k| k.to_sym }
     end
   end
 end
-- 
cgit v1.2.3


From 303991288633effea5a1d1774dbd861951303fe5 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 05:09:04 -0800
Subject: Silence spurious warning

---
 activesupport/lib/active_support/notifications.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 9eae3bebe2..6304f496f5 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -111,7 +111,7 @@ module ActiveSupport
 
       def subscribe
         @queue.subscribe(@pattern) do |*args|
-          yield *args
+          yield(*args)
         end
       end
     end
-- 
cgit v1.2.3


From 83f329f5f30567a10bc96410da230bf986db8ad4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com>
Date: Mon, 9 Nov 2009 16:19:47 -0200
Subject: Bundle I18n 0.2.0.

---
 .../core_ext/string/interpolation.rb               |   2 +-
 activesupport/lib/active_support/vendor.rb         |   2 +-
 .../active_support/vendor/i18n-0.1.3/MIT-LICENSE   |  20 -
 .../vendor/i18n-0.1.3/README.textile               |  20 -
 .../lib/active_support/vendor/i18n-0.1.3/Rakefile  |   5 -
 .../active_support/vendor/i18n-0.1.3/i18n.gemspec  |  27 -
 .../active_support/vendor/i18n-0.1.3/lib/i18n.rb   | 204 --------
 .../vendor/i18n-0.1.3/lib/i18n/backend/simple.rb   | 215 --------
 .../vendor/i18n-0.1.3/lib/i18n/exceptions.rb       |  53 --
 .../active_support/vendor/i18n-0.1.3/test/all.rb   |   5 -
 .../vendor/i18n-0.1.3/test/i18n_exceptions_test.rb |  99 ----
 .../vendor/i18n-0.1.3/test/i18n_test.rb            | 124 -----
 .../vendor/i18n-0.1.3/test/locale/en.rb            |   1 -
 .../vendor/i18n-0.1.3/test/locale/en.yml           |   3 -
 .../vendor/i18n-0.1.3/test/simple_backend_test.rb  | 567 ---------------------
 15 files changed, 2 insertions(+), 1345 deletions(-)
 delete mode 100755 activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
 delete mode 100755 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
 delete mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
index d9159b690a..c4a5c0ca35 100644
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ b/activesupport/lib/active_support/core_ext/string/interpolation.rb
@@ -5,7 +5,7 @@
   You may redistribute it and/or modify it under the same license terms as Ruby.
 =end
 
-if RUBY_VERSION < '1.9'
+if RUBY_VERSION < '1.9' && !"".respond_to?(:interpolate_without_ruby_19_syntax)
   require 'active_support/core_ext/string/bytesize'
 
   # KeyError is raised by String#% when the string contains a named placeholder
diff --git a/activesupport/lib/active_support/vendor.rb b/activesupport/lib/active_support/vendor.rb
index 4a711b7e25..15898d153c 100644
--- a/activesupport/lib/active_support/vendor.rb
+++ b/activesupport/lib/active_support/vendor.rb
@@ -4,7 +4,7 @@ def ActiveSupport.requirable?(file)
   $LOAD_PATH.any? { |p| Dir.glob("#{p}/#{file}.*").any? }
 end
 
-[%w(builder 2.1.2), %w(i18n 0.1.3), %w(memcache-client 1.7.5), %w(tzinfo 0.3.15)].each do |lib, version|
+[%w(builder 2.1.2), %w(memcache-client 1.7.5), %w(tzinfo 0.3.15)].each do |lib, version|
   # If the lib is not already requirable
   unless ActiveSupport.requirable? lib
     # Try to activate a gem ~> satisfying the requested version first.
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE b/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
deleted file mode 100755
index ed8e9ee66d..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2008 The Ruby I18n team
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile b/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
deleted file mode 100644
index a07fc8426d..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
+++ /dev/null
@@ -1,20 +0,0 @@
-h1. Ruby I18n gem
-
-I18n and localization solution for Ruby.
-
-For information please refer to http://rails-i18n.org
-
-h2. Authors
-
-* "Matt Aimonetti":http://railsontherun.com
-* "Sven Fuchs":http://www.artweb-design.de
-* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
-* "Saimon Moore":http://saimonmoore.net
-* "Stephan Soller":http://www.arkanis-development.de
-
-h2. License
-
-MIT License. See the included MIT-LICENCE file.
-
-
-
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile b/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
deleted file mode 100644
index 2164e13e69..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
+++ /dev/null
@@ -1,5 +0,0 @@
-task :default => [:test]
-
-task :test do
-  ruby "test/all.rb"
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec b/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
deleted file mode 100644
index f102689a6f..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
+++ /dev/null
@@ -1,27 +0,0 @@
-Gem::Specification.new do |s|
-  s.name = "i18n"
-  s.version = "0.1.3"
-  s.date = "2009-01-09"
-  s.summary = "Internationalization support for Ruby"
-  s.email = "rails-i18n@googlegroups.com"
-  s.homepage = "http://rails-i18n.org"
-  s.description = "Add Internationalization support to your Ruby application."
-  s.has_rdoc = false
-  s.authors = ['Sven Fuchs', 'Joshua Harvey', 'Matt Aimonetti', 'Stephan Soller', 'Saimon Moore']
-  s.files = [
-    'i18n.gemspec',
-    'lib/i18n/backend/simple.rb',
-    'lib/i18n/exceptions.rb',
-    'lib/i18n.rb',
-    'MIT-LICENSE',
-    'README.textile'
-  ]
-  s.test_files = [
-    'test/all.rb',
-    'test/i18n_exceptions_test.rb',
-    'test/i18n_test.rb',
-    'test/locale/en.rb',
-    'test/locale/en.yml',
-    'test/simple_backend_test.rb'
-  ]
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
deleted file mode 100755
index 1b49debc05..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
+++ /dev/null
@@ -1,204 +0,0 @@
-#--
-# Authors::   Matt Aimonetti (http://railsontherun.com/),
-#             Sven Fuchs (http://www.artweb-design.de),
-#             Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
-#             Saimon Moore (http://saimonmoore.net),
-#             Stephan Soller (http://www.arkanis-development.de/)
-# Copyright:: Copyright (c) 2008 The Ruby i18n Team
-# License::   MIT
-#++
-
-module I18n
-  autoload :ArgumentError, 'i18n/exceptions'
-  module Backend
-    autoload :Simple, 'i18n/backend/simple'
-  end
-
-  @@backend = nil
-  @@load_path = nil
-  @@default_locale = :'en'
-  @@exception_handler = :default_exception_handler
-
-  class << self
-    # Returns the current backend. Defaults to +Backend::Simple+.
-    def backend
-      @@backend ||= Backend::Simple.new
-    end
-
-    # Sets the current backend. Used to set a custom backend.
-    def backend=(backend)
-      @@backend = backend
-    end
-
-    # Returns the current default locale. Defaults to :'en'
-    def default_locale
-      @@default_locale
-    end
-
-    # Sets the current default locale. Used to set a custom default locale.
-    def default_locale=(locale)
-      @@default_locale = locale
-    end
-
-    # Returns the current locale. Defaults to I18n.default_locale.
-    def locale
-      Thread.current[:locale] ||= default_locale
-    end
-
-    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
-    def locale=(locale)
-      Thread.current[:locale] = locale
-    end
-
-    # Returns an array of locales for which translations are available
-    def available_locales
-      backend.available_locales
-    end
-
-    # Sets the exception handler.
-    def exception_handler=(exception_handler)
-      @@exception_handler = exception_handler
-    end
-
-    # Allow clients to register paths providing translation data sources. The
-    # backend defines acceptable sources.
-    #
-    # E.g. the provided SimpleBackend accepts a list of paths to translation
-    # files which are either named *.rb and contain plain Ruby Hashes or are
-    # named *.yml and contain YAML data. So for the SimpleBackend clients may
-    # register translation files like this:
-    #   I18n.load_path << 'path/to/locale/en.yml'
-    def load_path
-      @@load_path ||= []
-    end
-
-    # Sets the load path instance. Custom implementations are expected to
-    # behave like a Ruby Array.
-    def load_path=(load_path)
-      @@load_path = load_path
-    end
-
-    # Tells the backend to reload translations. Used in situations like the
-    # Rails development environment. Backends can implement whatever strategy
-    # is useful.
-    def reload!
-      backend.reload!
-    end
-
-    # Translates, pluralizes and interpolates a given key using a given locale,
-    # scope, and default, as well as interpolation values.
-    #
-    # *LOOKUP*
-    #
-    # Translation data is organized as a nested hash using the upper-level keys
-    # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
-    # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
-    #
-    # Translations can be looked up at any level of this hash using the key argument
-    # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
-    # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
-    #
-    # Key can be either a single key or a dot-separated key (both Strings and Symbols
-    # work). <em>E.g.</em>, the short format can be looked up using both:
-    #   I18n.t 'date.formats.short'
-    #   I18n.t :'date.formats.short'
-    #
-    # Scope can be either a single key, a dot-separated key or an array of keys
-    # or dot-separated keys. Keys and scopes can be combined freely. So these
-    # examples will all look up the same short date format:
-    #   I18n.t 'date.formats.short'
-    #   I18n.t 'formats.short', :scope => 'date'
-    #   I18n.t 'short', :scope => 'date.formats'
-    #   I18n.t 'short', :scope => %w(date formats)
-    #
-    # *INTERPOLATION*
-    #
-    # Translations can contain interpolation variables which will be replaced by
-    # values passed to #translate as part of the options hash, with the keys matching
-    # the interpolation variable names.
-    #
-    # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
-    # value for the key +bar+ will be interpolated into the translation:
-    #   I18n.t :foo, :bar => 'baz' # => 'foo baz'
-    #
-    # *PLURALIZATION*
-    #
-    # Translation data can contain pluralized translations. Pluralized translations
-    # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
-    #
-    # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
-    # pluralization rules. Other algorithms can be supported by custom backends.
-    #
-    # This returns the singular version of a pluralized translation:
-    #   I18n.t :foo, :count => 1 # => 'Foo'
-    #
-    # These both return the plural version of a pluralized translation:
-    #   I18n.t :foo, :count => 0 # => 'Foos'
-    #   I18n.t :foo, :count => 2 # => 'Foos'
-    #
-    # The <tt>:count</tt> option can be used both for pluralization and interpolation.
-    # <em>E.g.</em>, with the translation
-    # <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
-    # be interpolated to the pluralized translation:
-    #   I18n.t :foo, :count => 1 # => '1 foo'
-    #
-    # *DEFAULTS*
-    #
-    # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
-    #   I18n.t :foo, :default => 'default'
-    #
-    # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
-    # translation for <tt>:foo</tt> was found:
-    #   I18n.t :foo, :default => :bar
-    #
-    # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
-    # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
-    #   I18n.t :foo, :default => [:bar, 'default']
-    #
-    # <b>BULK LOOKUP</b>
-    #
-    # This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
-    #   I18n.t [:foo, :bar]
-    #
-    # Can be used with dot-separated nested keys:
-    #   I18n.t [:'baz.foo', :'baz.bar']
-    #
-    # Which is the same as using a scope option:
-    #   I18n.t [:foo, :bar], :scope => :baz
-    def translate(key, options = {})
-      locale = options.delete(:locale) || I18n.locale
-      backend.translate(locale, key, options)
-    rescue I18n::ArgumentError => e
-      raise e if options[:raise]
-      send(@@exception_handler, e, locale, key, options)
-    end
-    alias :t :translate
-
-    # Localizes certain objects, such as dates and numbers to local formatting.
-    def localize(object, options = {})
-      locale = options[:locale] || I18n.locale
-      format = options[:format] || :default
-      backend.localize(locale, object, format)
-    end
-    alias :l :localize
-
-  protected
-    # Handles exceptions raised in the backend. All exceptions except for
-    # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
-    # was caught and the option :raise is not set the handler returns an error
-    # message string containing the key/scope.
-    def default_exception_handler(exception, locale, key, options)
-      return exception.message if MissingTranslationData === exception
-      raise exception
-    end
-
-    # Merges the given locale, key and scope into a single array of keys.
-    # Splits keys that contain dots into multiple keys. Makes sure all
-    # keys are Symbols.
-    def normalize_translation_keys(locale, key, scope)
-      keys = [locale] + Array(scope) + [key]
-      keys = keys.map { |k| k.to_s.split(/\./) }
-      keys.flatten.map { |k| k.to_sym }
-    end
-  end
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
deleted file mode 100644
index c32cc76f34..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
+++ /dev/null
@@ -1,215 +0,0 @@
-require 'i18n/exceptions'
-
-module I18n
-  module Backend
-    class Simple
-      INTERPOLATION_RESERVED_KEYS = %w(scope default)
-      MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
-
-      # Accepts a list of paths to translation files. Loads translations from
-      # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
-      # for details.
-      def load_translations(*filenames)
-        filenames.each { |filename| load_file(filename) }
-      end
-
-      # Stores translations for the given locale in memory.
-      # This uses a deep merge for the translations hash, so existing
-      # translations will be overwritten by new ones only at the deepest
-      # level of the hash.
-      def store_translations(locale, data)
-        merge_translations(locale, data)
-      end
-
-      def translate(locale, key, options = {})
-        raise InvalidLocale.new(locale) if locale.nil?
-        return key.map { |k| translate(locale, k, options) } if key.is_a? Array
-
-        reserved = :scope, :default
-        count, scope, default = options.values_at(:count, *reserved)
-        options.delete(:default)
-        values = options.reject { |name, value| reserved.include?(name) }
-
-        entry = lookup(locale, key, scope)
-        if entry.nil?
-          entry = default(locale, default, options)
-          if entry.nil?
-            raise(I18n::MissingTranslationData.new(locale, key, options))
-          end
-        end
-        entry = pluralize(locale, entry, count)
-        entry = interpolate(locale, entry, values)
-        entry
-      end
-
-      # Acts the same as +strftime+, but returns a localized version of the
-      # formatted date string. Takes a key from the date/time formats
-      # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
-      def localize(locale, object, format = :default)
-        raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
-
-        type = object.respond_to?(:sec) ? 'time' : 'date'
-        # TODO only translate these if format is a String?
-        formats = translate(locale, :"#{type}.formats")
-        format = formats[format.to_sym] if formats && formats[format.to_sym]
-        # TODO raise exception unless format found?
-        format = format.to_s.dup
-
-        # TODO only translate these if the format string is actually present
-        # TODO check which format strings are present, then bulk translate then, then replace them
-        format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
-        format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
-        format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
-        format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
-        format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
-        object.strftime(format)
-      end
-
-      def initialized?
-        @initialized ||= false
-      end
-
-      # Returns an array of locales for which translations are available
-      def available_locales
-        init_translations unless initialized?
-        translations.keys
-      end
-
-      def reload!
-        @initialized = false
-        @translations = nil
-      end
-
-      protected
-        def init_translations
-          load_translations(*I18n.load_path.flatten)
-          @initialized = true
-        end
-
-        def translations
-          @translations ||= {}
-        end
-
-        # Looks up a translation from the translations hash. Returns nil if
-        # eiher key is nil, or locale, scope or key do not exist as a key in the
-        # nested translations hash. Splits keys or scopes containing dots
-        # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
-        # <tt>%w(currency format)</tt>.
-        def lookup(locale, key, scope = [])
-          return unless key
-          init_translations unless initialized?
-          keys = I18n.send(:normalize_translation_keys, locale, key, scope)
-          keys.inject(translations) do |result, k|
-            if (x = result[k.to_sym]).nil?
-              return nil
-            else
-              x
-            end
-          end
-        end
-
-        # Evaluates a default translation.
-        # If the given default is a String it is used literally. If it is a Symbol
-        # it will be translated with the given options. If it is an Array the first
-        # translation yielded will be returned.
-        #
-        # <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
-        # <tt>translate(locale, :foo)</tt> does not yield a result.
-        def default(locale, default, options = {})
-          case default
-            when String then default
-            when Symbol then translate locale, default, options
-            when Array  then default.each do |obj|
-              result = default(locale, obj, options.dup) and return result
-            end and nil
-          end
-        rescue MissingTranslationData
-          nil
-        end
-
-        # Picks a translation from an array according to English pluralization
-        # rules. It will pick the first translation if count is not equal to 1
-        # and the second translation if it is equal to 1. Other backends can
-        # implement more flexible or complex pluralization rules.
-        def pluralize(locale, entry, count)
-          return entry unless entry.is_a?(Hash) and count
-          # raise InvalidPluralizationData.new(entry, count) unless entry.is_a?(Hash)
-          key = :zero if count == 0 && entry.has_key?(:zero)
-          key ||= count == 1 ? :one : :other
-          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
-          entry[key]
-        end
-
-        # Interpolates values into a given string.
-        #
-        #   interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
-        #   # => "file test.txt opened by {{user}}"
-        #
-        # Note that you have to double escape the <tt>\\</tt> when you want to escape
-        # the <tt>{{...}}</tt> key in a string (once for the string and once for the
-        # interpolation).
-        def interpolate(locale, string, values = {})
-          return string unless string.is_a?(String)
-
-          string.gsub(MATCH) do
-            escaped, pattern, key = $1, $2, $2.to_sym
-
-            if escaped
-              pattern
-            elsif INTERPOLATION_RESERVED_KEYS.include?(pattern)
-              raise ReservedInterpolationKey.new(pattern, string)
-            elsif !values.include?(key)
-              raise MissingInterpolationArgument.new(pattern, string)
-            else
-              values[key].to_s
-            end
-          end
-        end
-
-        # Loads a single translations file by delegating to #load_rb or
-        # #load_yml depending on the file extension and directly merges the
-        # data to the existing translations. Raises I18n::UnknownFileType
-        # for all other file extensions.
-        def load_file(filename)
-          type = File.extname(filename).tr('.', '').downcase
-          raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}")
-          data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
-          data.each { |locale, d| merge_translations(locale, d) }
-        end
-
-        # Loads a plain Ruby translations file. eval'ing the file must yield
-        # a Hash containing translation data with locales as toplevel keys.
-        def load_rb(filename)
-          eval(IO.read(filename), binding, filename)
-        end
-
-        # Loads a YAML translations file. The data must have locales as
-        # toplevel keys.
-        def load_yml(filename)
-          require 'yaml' unless defined? :YAML
-          YAML::load(IO.read(filename))
-        end
-
-        # Deep merges the given translations hash with the existing translations
-        # for the given locale
-        def merge_translations(locale, data)
-          locale = locale.to_sym
-          translations[locale] ||= {}
-          data = deep_symbolize_keys(data)
-
-          # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
-          merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
-          translations[locale].merge!(data, &merger)
-        end
-
-        # Return a new hash with all keys and nested keys converted to symbols.
-        def deep_symbolize_keys(hash)
-          hash.inject({}) { |result, (key, value)|
-            value = deep_symbolize_keys(value) if value.is_a? Hash
-            result[(key.to_sym rescue key) || key] = value
-            result
-          }
-        end
-    end
-  end
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
deleted file mode 100644
index 6897055d6d..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-module I18n
-  class ArgumentError < ::ArgumentError; end
-
-  class InvalidLocale < ArgumentError
-    attr_reader :locale
-    def initialize(locale)
-      @locale = locale
-      super "#{locale.inspect} is not a valid locale"
-    end
-  end
-
-  class MissingTranslationData < ArgumentError
-    attr_reader :locale, :key, :options
-    def initialize(locale, key, options)
-      @key, @locale, @options = key, locale, options
-      keys = I18n.send(:normalize_translation_keys, locale, key, options[:scope])
-      keys << 'no key' if keys.size < 2
-      super "translation missing: #{keys.join(', ')}"
-    end
-  end
-
-  class InvalidPluralizationData < ArgumentError
-    attr_reader :entry, :count
-    def initialize(entry, count)
-      @entry, @count = entry, count
-      super "translation data #{entry.inspect} can not be used with :count => #{count}"
-    end
-  end
-
-  class MissingInterpolationArgument < ArgumentError
-    attr_reader :key, :string
-    def initialize(key, string)
-      @key, @string = key, string
-      super "interpolation argument #{key} missing in #{string.inspect}"
-    end
-  end
-
-  class ReservedInterpolationKey < ArgumentError
-    attr_reader :key, :string
-    def initialize(key, string)
-      @key, @string = key, string
-      super "reserved key #{key.inspect} used in #{string.inspect}"
-    end
-  end
-
-  class UnknownFileType < ArgumentError
-    attr_reader :type, :filename
-    def initialize(type, filename)
-      @type, @filename = type, filename
-      super "can not load translations from #{filename}, the file type #{type} is not known"
-    end
-  end
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
deleted file mode 100644
index 353712da49..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-dir = File.dirname(__FILE__)
-require dir + '/i18n_test.rb'
-require dir + '/simple_backend_test.rb'
-require dir + '/i18n_exceptions_test.rb'
-# *require* dir + '/custom_backend_test.rb'
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
deleted file mode 100644
index 4e78e71b34..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-$:.unshift "lib"
-
-require 'rubygems'
-require 'test/unit'
-require 'i18n'
-require 'active_support'
-
-class I18nExceptionsTest < Test::Unit::TestCase
-  def test_invalid_locale_stores_locale
-    force_invalid_locale
-  rescue I18n::ArgumentError => e
-    assert_nil e.locale
-  end
-
-  def test_invalid_locale_message
-    force_invalid_locale
-  rescue I18n::ArgumentError => e
-    assert_equal 'nil is not a valid locale', e.message
-  end
-
-  def test_missing_translation_data_stores_locale_key_and_options
-    force_missing_translation_data
-  rescue I18n::ArgumentError => e
-    options = {:scope => :bar}
-    assert_equal 'de', e.locale
-    assert_equal :foo, e.key
-    assert_equal options, e.options
-  end
-
-  def test_missing_translation_data_message
-    force_missing_translation_data
-  rescue I18n::ArgumentError => e
-    assert_equal 'translation missing: de, bar, foo', e.message
-  end
-
-  def test_invalid_pluralization_data_stores_entry_and_count
-    force_invalid_pluralization_data
-  rescue I18n::ArgumentError => e
-    assert_equal [:bar], e.entry
-    assert_equal 1, e.count
-  end
-
-  def test_invalid_pluralization_data_message
-    force_invalid_pluralization_data
-  rescue I18n::ArgumentError => e
-    assert_equal 'translation data [:bar] can not be used with :count => 1', e.message
-  end
-
-  def test_missing_interpolation_argument_stores_key_and_string
-    force_missing_interpolation_argument
-  rescue I18n::ArgumentError => e
-    assert_equal 'bar', e.key
-    assert_equal "{{bar}}", e.string
-  end
-
-  def test_missing_interpolation_argument_message
-    force_missing_interpolation_argument
-  rescue I18n::ArgumentError => e
-    assert_equal 'interpolation argument bar missing in "{{bar}}"', e.message
-  end
-
-  def test_reserved_interpolation_key_stores_key_and_string
-    force_reserved_interpolation_key
-  rescue I18n::ArgumentError => e
-    assert_equal 'scope', e.key
-    assert_equal "{{scope}}", e.string
-  end
-
-  def test_reserved_interpolation_key_message
-    force_reserved_interpolation_key
-  rescue I18n::ArgumentError => e
-    assert_equal 'reserved key "scope" used in "{{scope}}"', e.message
-  end
-
-  private
-    def force_invalid_locale
-      I18n.backend.translate nil, :foo
-    end
-
-    def force_missing_translation_data
-      I18n.backend.store_translations 'de', :bar => nil
-      I18n.backend.translate 'de', :foo, :scope => :bar
-    end
-
-    def force_invalid_pluralization_data
-      I18n.backend.store_translations 'de', :foo => [:bar]
-      I18n.backend.translate 'de', :foo, :count => 1
-    end
-
-    def force_missing_interpolation_argument
-      I18n.backend.store_translations 'de', :foo => "{{bar}}"
-      I18n.backend.translate 'de', :foo, :baz => 'baz'
-    end
-
-    def force_reserved_interpolation_key
-      I18n.backend.store_translations 'de', :foo => "{{scope}}"
-      I18n.backend.translate 'de', :foo, :baz => 'baz'
-    end
-end
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
deleted file mode 100644
index 2835ec4eab..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-$:.unshift "lib"
-
-require 'rubygems'
-require 'test/unit'
-require 'i18n'
-require 'active_support'
-
-class I18nTest < Test::Unit::TestCase
-  def setup
-    I18n.backend.store_translations :'en', {
-      :currency => {
-        :format => {
-          :separator => '.',
-          :delimiter => ',',
-        }
-      }
-    }
-  end
-
-  def test_uses_simple_backend_set_by_default
-    assert I18n.backend.is_a?(I18n::Backend::Simple)
-  end
-
-  def test_can_set_backend
-    assert_nothing_raised{ I18n.backend = self }
-    assert_equal self, I18n.backend
-    I18n.backend = I18n::Backend::Simple.new
-  end
-
-  def test_uses_en_us_as_default_locale_by_default
-    assert_equal 'en', I18n.default_locale
-  end
-
-  def test_can_set_default_locale
-    assert_nothing_raised{ I18n.default_locale = 'de' }
-    assert_equal 'de', I18n.default_locale
-    I18n.default_locale = 'en'
-  end
-
-  def test_uses_default_locale_as_locale_by_default
-    assert_equal I18n.default_locale, I18n.locale
-  end
-
-  def test_can_set_locale_to_thread_current
-    assert_nothing_raised{ I18n.locale = 'de' }
-    assert_equal 'de', I18n.locale
-    assert_equal 'de', Thread.current[:locale]
-    I18n.locale = 'en'
-  end
-
-  def test_can_set_exception_handler
-    assert_nothing_raised{ I18n.exception_handler = :custom_exception_handler }
-    I18n.exception_handler = :default_exception_handler # revert it
-  end
-
-  def test_uses_custom_exception_handler
-    I18n.exception_handler = :custom_exception_handler
-    I18n.expects(:custom_exception_handler)
-    I18n.translate :bogus
-    I18n.exception_handler = :default_exception_handler # revert it
-  end
-
-  def test_delegates_translate_to_backend
-    I18n.backend.expects(:translate).with 'de', :foo, {}
-    I18n.translate :foo, :locale => 'de'
-  end
-
-  def test_delegates_localize_to_backend
-    I18n.backend.expects(:localize).with 'de', :whatever, :default
-    I18n.localize :whatever, :locale => 'de'
-  end
-
-  def test_translate_given_no_locale_uses_i18n_locale
-    I18n.backend.expects(:translate).with 'en', :foo, {}
-    I18n.translate :foo
-  end
-
-  def test_translate_on_nested_symbol_keys_works
-    assert_equal ".", I18n.t(:'currency.format.separator')
-  end
-
-  def test_translate_with_nested_string_keys_works
-    assert_equal ".", I18n.t('currency.format.separator')
-  end
-
-  def test_translate_with_array_as_scope_works
-    assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
-  end
-
-  def test_translate_with_array_containing_dot_separated_strings_as_scope_works
-    assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
-  end
-
-  def test_translate_with_key_array_and_dot_separated_scope_works
-    assert_equal [".", ","], I18n.t(%w(separator delimiter), :scope => 'currency.format')
-  end
-
-  def test_translate_with_dot_separated_key_array_and_scope_works
-    assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency')
-  end
-
-  def test_translate_with_options_using_scope_works
-    I18n.backend.expects(:translate).with('de', :precision, :scope => :"currency.format")
-    I18n.with_options :locale => 'de', :scope => :'currency.format' do |locale|
-      locale.t :precision
-    end
-  end
-
-  # def test_translate_given_no_args_raises_missing_translation_data
-  #   assert_equal "translation missing: en, no key", I18n.t
-  # end
-
-  def test_translate_given_a_bogus_key_raises_missing_translation_data
-    assert_equal "translation missing: en, bogus", I18n.t(:bogus)
-  end
-
-  def test_localize_nil_raises_argument_error
-    assert_raise(I18n::ArgumentError) { I18n.l nil }
-  end
-
-  def test_localize_object_raises_argument_error
-    assert_raise(I18n::ArgumentError) { I18n.l Object.new }
-  end
-end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
deleted file mode 100644
index 6044ce10d9..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
+++ /dev/null
@@ -1 +0,0 @@
-{:'en-Ruby' => {:foo => {:bar => "baz"}}}
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
deleted file mode 100644
index 0b298c9c0e..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-en-Yaml:
-  foo:
-    bar: baz
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
deleted file mode 100644
index a1696c77f6..0000000000
--- a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
+++ /dev/null
@@ -1,567 +0,0 @@
-# encoding: utf-8
-$:.unshift "lib"
-
-require 'rubygems'
-require 'test/unit'
-require 'i18n'
-require 'time'
-require 'yaml'
-
-module I18nSimpleBackendTestSetup
-  def setup_backend
-    # backend_reset_translations!
-    @backend = I18n::Backend::Simple.new
-    @backend.store_translations 'en', :foo => {:bar => 'bar', :baz => 'baz'}
-    @locale_dir = File.dirname(__FILE__) + '/locale'
-  end
-  alias :setup :setup_backend
-
-  # def backend_reset_translations!
-  #   I18n::Backend::Simple::ClassMethods.send :class_variable_set, :@@translations, {}
-  # end
-
-  def backend_get_translations
-    # I18n::Backend::Simple::ClassMethods.send :class_variable_get, :@@translations
-    @backend.instance_variable_get :@translations
-  end
-
-  def add_datetime_translations
-    @backend.store_translations :'de', {
-      :date => {
-        :formats => {
-          :default => "%d.%m.%Y",
-          :short => "%d. %b",
-          :long => "%d. %B %Y",
-        },
-        :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
-        :abbr_day_names => %w(So Mo Di Mi Do Fr  Sa),
-        :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
-        :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil),
-        :order => [:day, :month, :year]
-      },
-      :time => {
-        :formats => {
-          :default => "%a, %d. %b %Y %H:%M:%S %z",
-          :short => "%d. %b %H:%M",
-          :long => "%d. %B %Y %H:%M",
-        },
-        :am => 'am',
-        :pm => 'pm'
-      },
-      :datetime => {
-        :distance_in_words => {
-          :half_a_minute => 'half a minute',
-          :less_than_x_seconds => {
-            :one => 'less than 1 second',
-            :other => 'less than {{count}} seconds'
-          },
-          :x_seconds => {
-            :one => '1 second',
-            :other => '{{count}} seconds'
-          },
-          :less_than_x_minutes => {
-            :one => 'less than a minute',
-            :other => 'less than {{count}} minutes'
-          },
-          :x_minutes => {
-            :one => '1 minute',
-            :other => '{{count}} minutes'
-          },
-          :about_x_hours => {
-            :one => 'about 1 hour',
-            :other => 'about {{count}} hours'
-          },
-          :x_days => {
-            :one => '1 day',
-            :other => '{{count}} days'
-          },
-          :about_x_months => {
-            :one => 'about 1 month',
-            :other => 'about {{count}} months'
-          },
-          :x_months => {
-            :one => '1 month',
-            :other => '{{count}} months'
-          },
-          :about_x_years => {
-            :one => 'about 1 year',
-            :other => 'about {{count}} year'
-          },
-          :over_x_years => {
-            :one => 'over 1 year',
-            :other => 'over {{count}} years'
-          }
-        }
-      }
-    }
-  end
-end
-
-class I18nSimpleBackendTranslationsTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def test_store_translations_adds_translations # no, really :-)
-    @backend.store_translations :'en', :foo => 'bar'
-    assert_equal Hash[:'en', {:foo => 'bar'}], backend_get_translations
-  end
-
-  def test_store_translations_deep_merges_translations
-    @backend.store_translations :'en', :foo => {:bar => 'bar'}
-    @backend.store_translations :'en', :foo => {:baz => 'baz'}
-    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
-  end
-
-  def test_store_translations_forces_locale_to_sym
-    @backend.store_translations 'en', :foo => 'bar'
-    assert_equal Hash[:'en', {:foo => 'bar'}], backend_get_translations
-  end
-
-  def test_store_translations_converts_keys_to_symbols
-    # backend_reset_translations!
-    @backend.store_translations 'en', 'foo' => {'bar' => 'bar', 'baz' => 'baz'}
-    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
-  end
-end
-
-class I18nSimpleBackendAvailableLocalesTest < Test::Unit::TestCase
-  def test_available_locales
-    @backend = I18n::Backend::Simple.new
-    @backend.store_translations 'de', :foo => 'bar'
-    @backend.store_translations 'en', :foo => 'foo'
-
-    assert_equal ['de', 'en'], @backend.available_locales.map{|locale| locale.to_s }.sort
-  end
-end
-
-class I18nSimpleBackendTranslateTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def test_translate_calls_lookup_with_locale_given
-    @backend.expects(:lookup).with('de', :bar, [:foo]).returns 'bar'
-    @backend.translate 'de', :bar, :scope => [:foo]
-  end
-
-  def test_given_no_keys_it_returns_the_default
-    assert_equal 'default', @backend.translate('en', nil, :default => 'default')
-  end
-
-  def test_translate_given_a_symbol_as_a_default_translates_the_symbol
-    assert_equal 'bar', @backend.translate('en', nil, :scope => [:foo], :default => :bar)
-  end
-
-  def test_translate_given_an_array_as_default_uses_the_first_match
-    assert_equal 'bar', @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :bar])
-  end
-
-  def test_translate_given_an_array_of_inexistent_keys_it_raises_missing_translation_data
-    assert_raise I18n::MissingTranslationData do
-      @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :does_not_exist_3])
-    end
-  end
-
-  def test_translate_an_array_of_keys_translates_all_of_them
-    assert_equal %w(bar baz), @backend.translate('en', [:bar, :baz], :scope => [:foo])
-  end
-
-  def test_translate_calls_pluralize
-    @backend.expects(:pluralize).with 'en', 'bar', 1
-    @backend.translate 'en', :bar, :scope => [:foo], :count => 1
-  end
-
-  def test_translate_calls_interpolate
-    @backend.expects(:interpolate).with 'en', 'bar', {}
-    @backend.translate 'en', :bar, :scope => [:foo]
-  end
-
-  def test_translate_calls_interpolate_including_count_as_a_value
-    @backend.expects(:interpolate).with 'en', 'bar', {:count => 1}
-    @backend.translate 'en', :bar, :scope => [:foo], :count => 1
-  end
-
-  def test_translate_given_nil_as_a_locale_raises_an_argument_error
-    assert_raise(I18n::InvalidLocale){ @backend.translate nil, :bar }
-  end
-
-  def test_translate_with_a_bogus_key_and_no_default_raises_missing_translation_data
-    assert_raise(I18n::MissingTranslationData){ @backend.translate 'de', :bogus }
-  end
-end
-
-class I18nSimpleBackendLookupTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  # useful because this way we can use the backend with no key for interpolation/pluralization
-  def test_lookup_given_nil_as_a_key_returns_nil
-    assert_nil @backend.send(:lookup, 'en', nil)
-  end
-
-  def test_lookup_given_nested_keys_looks_up_a_nested_hash_value
-    assert_equal 'bar', @backend.send(:lookup, 'en', :bar, [:foo])
-  end
-end
-
-class I18nSimpleBackendPluralizeTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def test_pluralize_given_nil_returns_the_given_entry
-    entry = {:one => 'bar', :other => 'bars'}
-    assert_equal entry, @backend.send(:pluralize, nil, entry, nil)
-  end
-
-  def test_pluralize_given_0_returns_zero_string_if_zero_key_given
-    assert_equal 'zero', @backend.send(:pluralize, nil, {:zero => 'zero', :one => 'bar', :other => 'bars'}, 0)
-  end
-
-  def test_pluralize_given_0_returns_plural_string_if_no_zero_key_given
-    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 0)
-  end
-
-  def test_pluralize_given_1_returns_singular_string
-    assert_equal 'bar', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 1)
-  end
-
-  def test_pluralize_given_2_returns_plural_string
-    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 2)
-  end
-
-  def test_pluralize_given_3_returns_plural_string
-    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 3)
-  end
-
-  def test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluralization_data
-    assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, {:one => 'bar'}, 2) }
-  end
-
-  # def test_interpolate_given_a_string_raises_invalid_pluralization_data
-  #   assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, 'bar', 2) }
-  # end
-  #
-  # def test_interpolate_given_an_array_raises_invalid_pluralization_data
-  #   assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, ['bar'], 2) }
-  # end
-end
-
-class I18nSimpleBackendInterpolateTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def test_interpolate_given_a_value_hash_interpolates_the_values_to_the_string
-    assert_equal 'Hi David!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'David')
-  end
-
-  def test_interpolate_given_a_value_hash_interpolates_into_unicode_string
-    assert_equal 'Häi David!', @backend.send(:interpolate, nil, 'Häi {{name}}!', :name => 'David')
-  end
-
-  def test_interpolate_given_an_unicode_value_hash_interpolates_to_the_string
-    assert_equal 'Hi ゆきひろ!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'ゆきひろ')
-  end
-
-  def test_interpolate_given_an_unicode_value_hash_interpolates_into_unicode_string
-    assert_equal 'こんにちは、ゆきひろさん!', @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
-  end
-
-  if Kernel.const_defined?(:Encoding)
-    def test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding
-      assert_equal euc_jp('Hi ゆきひろ!'), @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
-    end
-
-    def test_interpolate_given_an_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error
-      assert_raise(Encoding::CompatibilityError) do
-        @backend.send(:interpolate, nil, euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
-      end
-    end
-
-    def test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error
-      assert_raise(Encoding::CompatibilityError) do
-        @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
-      end
-    end
-  end
-
-  def test_interpolate_given_nil_as_a_string_returns_nil
-    assert_nil @backend.send(:interpolate, nil, nil, :name => 'David')
-  end
-
-  def test_interpolate_given_an_non_string_as_a_string_returns_nil
-    assert_equal [], @backend.send(:interpolate, nil, [], :name => 'David')
-  end
-
-  def test_interpolate_given_a_values_hash_with_nil_values_interpolates_the_string
-    assert_equal 'Hi !', @backend.send(:interpolate, nil, 'Hi {{name}}!', {:name => nil})
-  end
-
-  def test_interpolate_given_an_empty_values_hash_raises_missing_interpolation_argument
-    assert_raise(I18n::MissingInterpolationArgument) { @backend.send(:interpolate, nil, 'Hi {{name}}!', {}) }
-  end
-
-  def test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key
-    assert_raise(I18n::ReservedInterpolationKey) { @backend.send(:interpolate, nil, '{{default}}', {:default => nil}) }
-  end
-  
-  private
-  
-  def euc_jp(string)
-    string.encode!(Encoding::EUC_JP)
-  end
-end
-
-class I18nSimpleBackendLocalizeDateTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def setup
-    @backend = I18n::Backend::Simple.new
-    add_datetime_translations
-    @date = Date.new 2008, 1, 1
-  end
-
-  def test_translate_given_the_short_format_it_uses_it
-    assert_equal '01. Jan', @backend.localize('de', @date, :short)
-  end
-
-  def test_translate_given_the_long_format_it_uses_it
-    assert_equal '01. Januar 2008', @backend.localize('de', @date, :long)
-  end
-
-  def test_translate_given_the_default_format_it_uses_it
-    assert_equal '01.01.2008', @backend.localize('de', @date, :default)
-  end
-
-  def test_translate_given_a_day_name_format_it_returns_a_day_name
-    assert_equal 'Dienstag', @backend.localize('de', @date, '%A')
-  end
-
-  def test_translate_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name
-    assert_equal 'Di', @backend.localize('de', @date, '%a')
-  end
-
-  def test_translate_given_a_month_name_format_it_returns_a_month_name
-    assert_equal 'Januar', @backend.localize('de', @date, '%B')
-  end
-
-  def test_translate_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name
-    assert_equal 'Jan', @backend.localize('de', @date, '%b')
-  end
-
-  def test_translate_given_no_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @date }
-  end
-
-  def test_translate_given_an_unknown_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @date, '%x' }
-  end
-
-  def test_localize_nil_raises_argument_error
-    assert_raise(I18n::ArgumentError) { @backend.localize 'de', nil }
-  end
-
-  def test_localize_object_raises_argument_error
-    assert_raise(I18n::ArgumentError) { @backend.localize 'de', Object.new }
-  end
-end
-
-class I18nSimpleBackendLocalizeDateTimeTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def setup
-    @backend = I18n::Backend::Simple.new
-    add_datetime_translations
-    @morning = DateTime.new 2008, 1, 1, 6
-    @evening = DateTime.new 2008, 1, 1, 18
-  end
-
-  def test_translate_given_the_short_format_it_uses_it
-    assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
-  end
-
-  def test_translate_given_the_long_format_it_uses_it
-    assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
-  end
-
-  def test_translate_given_the_default_format_it_uses_it
-    assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)
-  end
-
-  def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
-    assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
-  end
-
-  def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
-    assert_equal 'Di', @backend.localize('de', @morning, '%a')
-  end
-
-  def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
-    assert_equal 'Januar', @backend.localize('de', @morning, '%B')
-  end
-
-  def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
-    assert_equal 'Jan', @backend.localize('de', @morning, '%b')
-  end
-
-  def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
-    assert_equal 'am', @backend.localize('de', @morning, '%p')
-    assert_equal 'pm', @backend.localize('de', @evening, '%p')
-  end
-
-  def test_translate_given_no_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @morning }
-  end
-
-  def test_translate_given_an_unknown_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
-  end
-end
-
-class I18nSimpleBackendLocalizeTimeTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def setup
-    @old_timezone, ENV['TZ'] = ENV['TZ'], 'UTC'
-    @backend = I18n::Backend::Simple.new
-    add_datetime_translations
-    @morning = Time.parse '2008-01-01 6:00 UTC'
-    @evening = Time.parse '2008-01-01 18:00 UTC'
-  end
-
-  def teardown
-    @old_timezone ? ENV['TZ'] = @old_timezone : ENV.delete('TZ')
-  end
-
-  def test_translate_given_the_short_format_it_uses_it
-    assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
-  end
-
-  def test_translate_given_the_long_format_it_uses_it
-    assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
-  end
-
-  # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this?
-  # def test_translate_given_the_default_format_it_uses_it
-  #   assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)
-  # end
-
-  def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
-    assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
-  end
-
-  def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
-    assert_equal 'Di', @backend.localize('de', @morning, '%a')
-  end
-
-  def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
-    assert_equal 'Januar', @backend.localize('de', @morning, '%B')
-  end
-
-  def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
-    assert_equal 'Jan', @backend.localize('de', @morning, '%b')
-  end
-
-  def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
-    assert_equal 'am', @backend.localize('de', @morning, '%p')
-    assert_equal 'pm', @backend.localize('de', @evening, '%p')
-  end
-
-  def test_translate_given_no_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @morning }
-  end
-
-  def test_translate_given_an_unknown_format_it_does_not_fail
-    assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
-  end
-end
-
-class I18nSimpleBackendHelperMethodsTest < Test::Unit::TestCase
-  def setup
-    @backend = I18n::Backend::Simple.new
-  end
-
-  def test_deep_symbolize_keys_works
-    result = @backend.send :deep_symbolize_keys, 'foo' => {'bar' => {'baz' => 'bar'}}
-    expected = {:foo => {:bar => {:baz => 'bar'}}}
-    assert_equal expected, result
-  end
-end
-
-class I18nSimpleBackendLoadTranslationsTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def test_load_translations_with_unknown_file_type_raises_exception
-    assert_raise(I18n::UnknownFileType) { @backend.load_translations "#{@locale_dir}/en.xml" }
-  end
-
-  def test_load_translations_with_ruby_file_type_does_not_raise_exception
-    assert_nothing_raised { @backend.load_translations "#{@locale_dir}/en.rb" }
-  end
-
-  def test_load_rb_loads_data_from_ruby_file
-    data = @backend.send :load_rb, "#{@locale_dir}/en.rb"
-    assert_equal({:'en-Ruby' => {:foo => {:bar => "baz"}}}, data)
-  end
-
-  def test_load_rb_loads_data_from_yaml_file
-    data = @backend.send :load_yml, "#{@locale_dir}/en.yml"
-    assert_equal({'en-Yaml' => {'foo' => {'bar' => 'baz'}}}, data)
-  end
-
-  def test_load_translations_loads_from_different_file_formats
-    @backend = I18n::Backend::Simple.new
-    @backend.load_translations "#{@locale_dir}/en.rb", "#{@locale_dir}/en.yml"
-    expected = {
-      :'en-Ruby' => {:foo => {:bar => "baz"}},
-      :'en-Yaml' => {:foo => {:bar => "baz"}}
-    }
-    assert_equal expected, backend_get_translations
-  end
-end
-
-class I18nSimpleBackendLoadPathTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-
-  def teardown
-    I18n.load_path = []
-  end
-
-  def test_nested_load_paths_do_not_break_locale_loading
-    @backend = I18n::Backend::Simple.new
-    I18n.load_path = [[File.dirname(__FILE__) + '/locale/en.yml']]
-    assert_nil backend_get_translations
-    assert_nothing_raised { @backend.send :init_translations }
-    assert_not_nil backend_get_translations
-  end
-
-  def test_adding_arrays_of_filenames_to_load_path_do_not_break_locale_loading
-    @backend = I18n::Backend::Simple.new
-    I18n.load_path << Dir[File.dirname(__FILE__) + '/locale/*.{rb,yml}']
-    assert_nil backend_get_translations
-    assert_nothing_raised { @backend.send :init_translations }
-    assert_not_nil backend_get_translations
-  end
-end
-
-class I18nSimpleBackendReloadTranslationsTest < Test::Unit::TestCase
-  include I18nSimpleBackendTestSetup
-  
-  def setup
-    @backend = I18n::Backend::Simple.new
-    I18n.load_path = [File.dirname(__FILE__) + '/locale/en.yml']
-    assert_nil backend_get_translations
-    @backend.send :init_translations
-  end
-  
-  def teardown
-    I18n.load_path = []
-  end
-  
-  def test_setup
-    assert_not_nil backend_get_translations
-  end
-  
-  def test_reload_translations_unloads_translations
-    @backend.reload!
-    assert_nil backend_get_translations
-  end
-  
-  def test_reload_translations_uninitializes_translations
-    @backend.reload!
-    assert_equal @backend.initialized?, false
-  end
-end
-- 
cgit v1.2.3


From 0f1da1cb5cfac1343958daef4c5e7c37a9ce0da3 Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@Yehuda-Katz.local>
Date: Mon, 9 Nov 2009 11:33:47 -0800
Subject: Revert "Bundle I18n 0.2.0."

This reverts commit 83f329f5f30567a10bc96410da230bf986db8ad4.
---
 .../core_ext/string/interpolation.rb               |   2 +-
 activesupport/lib/active_support/vendor.rb         |   2 +-
 .../active_support/vendor/i18n-0.1.3/MIT-LICENSE   |  20 +
 .../vendor/i18n-0.1.3/README.textile               |  20 +
 .../lib/active_support/vendor/i18n-0.1.3/Rakefile  |   5 +
 .../active_support/vendor/i18n-0.1.3/i18n.gemspec  |  27 +
 .../active_support/vendor/i18n-0.1.3/lib/i18n.rb   | 204 ++++++++
 .../vendor/i18n-0.1.3/lib/i18n/backend/simple.rb   | 215 ++++++++
 .../vendor/i18n-0.1.3/lib/i18n/exceptions.rb       |  53 ++
 .../active_support/vendor/i18n-0.1.3/test/all.rb   |   5 +
 .../vendor/i18n-0.1.3/test/i18n_exceptions_test.rb |  99 ++++
 .../vendor/i18n-0.1.3/test/i18n_test.rb            | 124 +++++
 .../vendor/i18n-0.1.3/test/locale/en.rb            |   1 +
 .../vendor/i18n-0.1.3/test/locale/en.yml           |   3 +
 .../vendor/i18n-0.1.3/test/simple_backend_test.rb  | 567 +++++++++++++++++++++
 15 files changed, 1345 insertions(+), 2 deletions(-)
 create mode 100755 activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
 create mode 100755 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
 create mode 100644 activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
index c4a5c0ca35..d9159b690a 100644
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ b/activesupport/lib/active_support/core_ext/string/interpolation.rb
@@ -5,7 +5,7 @@
   You may redistribute it and/or modify it under the same license terms as Ruby.
 =end
 
-if RUBY_VERSION < '1.9' && !"".respond_to?(:interpolate_without_ruby_19_syntax)
+if RUBY_VERSION < '1.9'
   require 'active_support/core_ext/string/bytesize'
 
   # KeyError is raised by String#% when the string contains a named placeholder
diff --git a/activesupport/lib/active_support/vendor.rb b/activesupport/lib/active_support/vendor.rb
index 15898d153c..4a711b7e25 100644
--- a/activesupport/lib/active_support/vendor.rb
+++ b/activesupport/lib/active_support/vendor.rb
@@ -4,7 +4,7 @@ def ActiveSupport.requirable?(file)
   $LOAD_PATH.any? { |p| Dir.glob("#{p}/#{file}.*").any? }
 end
 
-[%w(builder 2.1.2), %w(memcache-client 1.7.5), %w(tzinfo 0.3.15)].each do |lib, version|
+[%w(builder 2.1.2), %w(i18n 0.1.3), %w(memcache-client 1.7.5), %w(tzinfo 0.3.15)].each do |lib, version|
   # If the lib is not already requirable
   unless ActiveSupport.requirable? lib
     # Try to activate a gem ~> satisfying the requested version first.
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE b/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
new file mode 100755
index 0000000000..ed8e9ee66d
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008 The Ruby I18n team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile b/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
new file mode 100644
index 0000000000..a07fc8426d
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
@@ -0,0 +1,20 @@
+h1. Ruby I18n gem
+
+I18n and localization solution for Ruby.
+
+For information please refer to http://rails-i18n.org
+
+h2. Authors
+
+* "Matt Aimonetti":http://railsontherun.com
+* "Sven Fuchs":http://www.artweb-design.de
+* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
+* "Saimon Moore":http://saimonmoore.net
+* "Stephan Soller":http://www.arkanis-development.de
+
+h2. License
+
+MIT License. See the included MIT-LICENCE file.
+
+
+
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile b/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
new file mode 100644
index 0000000000..2164e13e69
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/Rakefile
@@ -0,0 +1,5 @@
+task :default => [:test]
+
+task :test do
+  ruby "test/all.rb"
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec b/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
new file mode 100644
index 0000000000..f102689a6f
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec
@@ -0,0 +1,27 @@
+Gem::Specification.new do |s|
+  s.name = "i18n"
+  s.version = "0.1.3"
+  s.date = "2009-01-09"
+  s.summary = "Internationalization support for Ruby"
+  s.email = "rails-i18n@googlegroups.com"
+  s.homepage = "http://rails-i18n.org"
+  s.description = "Add Internationalization support to your Ruby application."
+  s.has_rdoc = false
+  s.authors = ['Sven Fuchs', 'Joshua Harvey', 'Matt Aimonetti', 'Stephan Soller', 'Saimon Moore']
+  s.files = [
+    'i18n.gemspec',
+    'lib/i18n/backend/simple.rb',
+    'lib/i18n/exceptions.rb',
+    'lib/i18n.rb',
+    'MIT-LICENSE',
+    'README.textile'
+  ]
+  s.test_files = [
+    'test/all.rb',
+    'test/i18n_exceptions_test.rb',
+    'test/i18n_test.rb',
+    'test/locale/en.rb',
+    'test/locale/en.yml',
+    'test/simple_backend_test.rb'
+  ]
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
new file mode 100755
index 0000000000..1b49debc05
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb
@@ -0,0 +1,204 @@
+#--
+# Authors::   Matt Aimonetti (http://railsontherun.com/),
+#             Sven Fuchs (http://www.artweb-design.de),
+#             Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
+#             Saimon Moore (http://saimonmoore.net),
+#             Stephan Soller (http://www.arkanis-development.de/)
+# Copyright:: Copyright (c) 2008 The Ruby i18n Team
+# License::   MIT
+#++
+
+module I18n
+  autoload :ArgumentError, 'i18n/exceptions'
+  module Backend
+    autoload :Simple, 'i18n/backend/simple'
+  end
+
+  @@backend = nil
+  @@load_path = nil
+  @@default_locale = :'en'
+  @@exception_handler = :default_exception_handler
+
+  class << self
+    # Returns the current backend. Defaults to +Backend::Simple+.
+    def backend
+      @@backend ||= Backend::Simple.new
+    end
+
+    # Sets the current backend. Used to set a custom backend.
+    def backend=(backend)
+      @@backend = backend
+    end
+
+    # Returns the current default locale. Defaults to :'en'
+    def default_locale
+      @@default_locale
+    end
+
+    # Sets the current default locale. Used to set a custom default locale.
+    def default_locale=(locale)
+      @@default_locale = locale
+    end
+
+    # Returns the current locale. Defaults to I18n.default_locale.
+    def locale
+      Thread.current[:locale] ||= default_locale
+    end
+
+    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
+    def locale=(locale)
+      Thread.current[:locale] = locale
+    end
+
+    # Returns an array of locales for which translations are available
+    def available_locales
+      backend.available_locales
+    end
+
+    # Sets the exception handler.
+    def exception_handler=(exception_handler)
+      @@exception_handler = exception_handler
+    end
+
+    # Allow clients to register paths providing translation data sources. The
+    # backend defines acceptable sources.
+    #
+    # E.g. the provided SimpleBackend accepts a list of paths to translation
+    # files which are either named *.rb and contain plain Ruby Hashes or are
+    # named *.yml and contain YAML data. So for the SimpleBackend clients may
+    # register translation files like this:
+    #   I18n.load_path << 'path/to/locale/en.yml'
+    def load_path
+      @@load_path ||= []
+    end
+
+    # Sets the load path instance. Custom implementations are expected to
+    # behave like a Ruby Array.
+    def load_path=(load_path)
+      @@load_path = load_path
+    end
+
+    # Tells the backend to reload translations. Used in situations like the
+    # Rails development environment. Backends can implement whatever strategy
+    # is useful.
+    def reload!
+      backend.reload!
+    end
+
+    # Translates, pluralizes and interpolates a given key using a given locale,
+    # scope, and default, as well as interpolation values.
+    #
+    # *LOOKUP*
+    #
+    # Translation data is organized as a nested hash using the upper-level keys
+    # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
+    # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Translations can be looked up at any level of this hash using the key argument
+    # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
+    # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
+    #
+    # Key can be either a single key or a dot-separated key (both Strings and Symbols
+    # work). <em>E.g.</em>, the short format can be looked up using both:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t :'date.formats.short'
+    #
+    # Scope can be either a single key, a dot-separated key or an array of keys
+    # or dot-separated keys. Keys and scopes can be combined freely. So these
+    # examples will all look up the same short date format:
+    #   I18n.t 'date.formats.short'
+    #   I18n.t 'formats.short', :scope => 'date'
+    #   I18n.t 'short', :scope => 'date.formats'
+    #   I18n.t 'short', :scope => %w(date formats)
+    #
+    # *INTERPOLATION*
+    #
+    # Translations can contain interpolation variables which will be replaced by
+    # values passed to #translate as part of the options hash, with the keys matching
+    # the interpolation variable names.
+    #
+    # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
+    # value for the key +bar+ will be interpolated into the translation:
+    #   I18n.t :foo, :bar => 'baz' # => 'foo baz'
+    #
+    # *PLURALIZATION*
+    #
+    # Translation data can contain pluralized translations. Pluralized translations
+    # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
+    #
+    # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
+    # pluralization rules. Other algorithms can be supported by custom backends.
+    #
+    # This returns the singular version of a pluralized translation:
+    #   I18n.t :foo, :count => 1 # => 'Foo'
+    #
+    # These both return the plural version of a pluralized translation:
+    #   I18n.t :foo, :count => 0 # => 'Foos'
+    #   I18n.t :foo, :count => 2 # => 'Foos'
+    #
+    # The <tt>:count</tt> option can be used both for pluralization and interpolation.
+    # <em>E.g.</em>, with the translation
+    # <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
+    # be interpolated to the pluralized translation:
+    #   I18n.t :foo, :count => 1 # => '1 foo'
+    #
+    # *DEFAULTS*
+    #
+    # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
+    #   I18n.t :foo, :default => 'default'
+    #
+    # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
+    # translation for <tt>:foo</tt> was found:
+    #   I18n.t :foo, :default => :bar
+    #
+    # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
+    # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
+    #   I18n.t :foo, :default => [:bar, 'default']
+    #
+    # <b>BULK LOOKUP</b>
+    #
+    # This returns an array with the translations for <tt>:foo</tt> and <tt>:bar</tt>.
+    #   I18n.t [:foo, :bar]
+    #
+    # Can be used with dot-separated nested keys:
+    #   I18n.t [:'baz.foo', :'baz.bar']
+    #
+    # Which is the same as using a scope option:
+    #   I18n.t [:foo, :bar], :scope => :baz
+    def translate(key, options = {})
+      locale = options.delete(:locale) || I18n.locale
+      backend.translate(locale, key, options)
+    rescue I18n::ArgumentError => e
+      raise e if options[:raise]
+      send(@@exception_handler, e, locale, key, options)
+    end
+    alias :t :translate
+
+    # Localizes certain objects, such as dates and numbers to local formatting.
+    def localize(object, options = {})
+      locale = options[:locale] || I18n.locale
+      format = options[:format] || :default
+      backend.localize(locale, object, format)
+    end
+    alias :l :localize
+
+  protected
+    # Handles exceptions raised in the backend. All exceptions except for
+    # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
+    # was caught and the option :raise is not set the handler returns an error
+    # message string containing the key/scope.
+    def default_exception_handler(exception, locale, key, options)
+      return exception.message if MissingTranslationData === exception
+      raise exception
+    end
+
+    # Merges the given locale, key and scope into a single array of keys.
+    # Splits keys that contain dots into multiple keys. Makes sure all
+    # keys are Symbols.
+    def normalize_translation_keys(locale, key, scope)
+      keys = [locale] + Array(scope) + [key]
+      keys = keys.map { |k| k.to_s.split(/\./) }
+      keys.flatten.map { |k| k.to_sym }
+    end
+  end
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
new file mode 100644
index 0000000000..c32cc76f34
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb
@@ -0,0 +1,215 @@
+require 'i18n/exceptions'
+
+module I18n
+  module Backend
+    class Simple
+      INTERPOLATION_RESERVED_KEYS = %w(scope default)
+      MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
+
+      # Accepts a list of paths to translation files. Loads translations from
+      # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
+      # for details.
+      def load_translations(*filenames)
+        filenames.each { |filename| load_file(filename) }
+      end
+
+      # Stores translations for the given locale in memory.
+      # This uses a deep merge for the translations hash, so existing
+      # translations will be overwritten by new ones only at the deepest
+      # level of the hash.
+      def store_translations(locale, data)
+        merge_translations(locale, data)
+      end
+
+      def translate(locale, key, options = {})
+        raise InvalidLocale.new(locale) if locale.nil?
+        return key.map { |k| translate(locale, k, options) } if key.is_a? Array
+
+        reserved = :scope, :default
+        count, scope, default = options.values_at(:count, *reserved)
+        options.delete(:default)
+        values = options.reject { |name, value| reserved.include?(name) }
+
+        entry = lookup(locale, key, scope)
+        if entry.nil?
+          entry = default(locale, default, options)
+          if entry.nil?
+            raise(I18n::MissingTranslationData.new(locale, key, options))
+          end
+        end
+        entry = pluralize(locale, entry, count)
+        entry = interpolate(locale, entry, values)
+        entry
+      end
+
+      # Acts the same as +strftime+, but returns a localized version of the
+      # formatted date string. Takes a key from the date/time formats
+      # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
+      def localize(locale, object, format = :default)
+        raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
+
+        type = object.respond_to?(:sec) ? 'time' : 'date'
+        # TODO only translate these if format is a String?
+        formats = translate(locale, :"#{type}.formats")
+        format = formats[format.to_sym] if formats && formats[format.to_sym]
+        # TODO raise exception unless format found?
+        format = format.to_s.dup
+
+        # TODO only translate these if the format string is actually present
+        # TODO check which format strings are present, then bulk translate then, then replace them
+        format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
+        format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
+        format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
+        format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
+        format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
+        object.strftime(format)
+      end
+
+      def initialized?
+        @initialized ||= false
+      end
+
+      # Returns an array of locales for which translations are available
+      def available_locales
+        init_translations unless initialized?
+        translations.keys
+      end
+
+      def reload!
+        @initialized = false
+        @translations = nil
+      end
+
+      protected
+        def init_translations
+          load_translations(*I18n.load_path.flatten)
+          @initialized = true
+        end
+
+        def translations
+          @translations ||= {}
+        end
+
+        # Looks up a translation from the translations hash. Returns nil if
+        # eiher key is nil, or locale, scope or key do not exist as a key in the
+        # nested translations hash. Splits keys or scopes containing dots
+        # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
+        # <tt>%w(currency format)</tt>.
+        def lookup(locale, key, scope = [])
+          return unless key
+          init_translations unless initialized?
+          keys = I18n.send(:normalize_translation_keys, locale, key, scope)
+          keys.inject(translations) do |result, k|
+            if (x = result[k.to_sym]).nil?
+              return nil
+            else
+              x
+            end
+          end
+        end
+
+        # Evaluates a default translation.
+        # If the given default is a String it is used literally. If it is a Symbol
+        # it will be translated with the given options. If it is an Array the first
+        # translation yielded will be returned.
+        #
+        # <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
+        # <tt>translate(locale, :foo)</tt> does not yield a result.
+        def default(locale, default, options = {})
+          case default
+            when String then default
+            when Symbol then translate locale, default, options
+            when Array  then default.each do |obj|
+              result = default(locale, obj, options.dup) and return result
+            end and nil
+          end
+        rescue MissingTranslationData
+          nil
+        end
+
+        # Picks a translation from an array according to English pluralization
+        # rules. It will pick the first translation if count is not equal to 1
+        # and the second translation if it is equal to 1. Other backends can
+        # implement more flexible or complex pluralization rules.
+        def pluralize(locale, entry, count)
+          return entry unless entry.is_a?(Hash) and count
+          # raise InvalidPluralizationData.new(entry, count) unless entry.is_a?(Hash)
+          key = :zero if count == 0 && entry.has_key?(:zero)
+          key ||= count == 1 ? :one : :other
+          raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
+          entry[key]
+        end
+
+        # Interpolates values into a given string.
+        #
+        #   interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
+        #   # => "file test.txt opened by {{user}}"
+        #
+        # Note that you have to double escape the <tt>\\</tt> when you want to escape
+        # the <tt>{{...}}</tt> key in a string (once for the string and once for the
+        # interpolation).
+        def interpolate(locale, string, values = {})
+          return string unless string.is_a?(String)
+
+          string.gsub(MATCH) do
+            escaped, pattern, key = $1, $2, $2.to_sym
+
+            if escaped
+              pattern
+            elsif INTERPOLATION_RESERVED_KEYS.include?(pattern)
+              raise ReservedInterpolationKey.new(pattern, string)
+            elsif !values.include?(key)
+              raise MissingInterpolationArgument.new(pattern, string)
+            else
+              values[key].to_s
+            end
+          end
+        end
+
+        # Loads a single translations file by delegating to #load_rb or
+        # #load_yml depending on the file extension and directly merges the
+        # data to the existing translations. Raises I18n::UnknownFileType
+        # for all other file extensions.
+        def load_file(filename)
+          type = File.extname(filename).tr('.', '').downcase
+          raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}")
+          data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
+          data.each { |locale, d| merge_translations(locale, d) }
+        end
+
+        # Loads a plain Ruby translations file. eval'ing the file must yield
+        # a Hash containing translation data with locales as toplevel keys.
+        def load_rb(filename)
+          eval(IO.read(filename), binding, filename)
+        end
+
+        # Loads a YAML translations file. The data must have locales as
+        # toplevel keys.
+        def load_yml(filename)
+          require 'yaml' unless defined? :YAML
+          YAML::load(IO.read(filename))
+        end
+
+        # Deep merges the given translations hash with the existing translations
+        # for the given locale
+        def merge_translations(locale, data)
+          locale = locale.to_sym
+          translations[locale] ||= {}
+          data = deep_symbolize_keys(data)
+
+          # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
+          merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
+          translations[locale].merge!(data, &merger)
+        end
+
+        # Return a new hash with all keys and nested keys converted to symbols.
+        def deep_symbolize_keys(hash)
+          hash.inject({}) { |result, (key, value)|
+            value = deep_symbolize_keys(value) if value.is_a? Hash
+            result[(key.to_sym rescue key) || key] = value
+            result
+          }
+        end
+    end
+  end
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
new file mode 100644
index 0000000000..6897055d6d
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb
@@ -0,0 +1,53 @@
+module I18n
+  class ArgumentError < ::ArgumentError; end
+
+  class InvalidLocale < ArgumentError
+    attr_reader :locale
+    def initialize(locale)
+      @locale = locale
+      super "#{locale.inspect} is not a valid locale"
+    end
+  end
+
+  class MissingTranslationData < ArgumentError
+    attr_reader :locale, :key, :options
+    def initialize(locale, key, options)
+      @key, @locale, @options = key, locale, options
+      keys = I18n.send(:normalize_translation_keys, locale, key, options[:scope])
+      keys << 'no key' if keys.size < 2
+      super "translation missing: #{keys.join(', ')}"
+    end
+  end
+
+  class InvalidPluralizationData < ArgumentError
+    attr_reader :entry, :count
+    def initialize(entry, count)
+      @entry, @count = entry, count
+      super "translation data #{entry.inspect} can not be used with :count => #{count}"
+    end
+  end
+
+  class MissingInterpolationArgument < ArgumentError
+    attr_reader :key, :string
+    def initialize(key, string)
+      @key, @string = key, string
+      super "interpolation argument #{key} missing in #{string.inspect}"
+    end
+  end
+
+  class ReservedInterpolationKey < ArgumentError
+    attr_reader :key, :string
+    def initialize(key, string)
+      @key, @string = key, string
+      super "reserved key #{key.inspect} used in #{string.inspect}"
+    end
+  end
+
+  class UnknownFileType < ArgumentError
+    attr_reader :type, :filename
+    def initialize(type, filename)
+      @type, @filename = type, filename
+      super "can not load translations from #{filename}, the file type #{type} is not known"
+    end
+  end
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
new file mode 100644
index 0000000000..353712da49
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/all.rb
@@ -0,0 +1,5 @@
+dir = File.dirname(__FILE__)
+require dir + '/i18n_test.rb'
+require dir + '/simple_backend_test.rb'
+require dir + '/i18n_exceptions_test.rb'
+# *require* dir + '/custom_backend_test.rb'
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
new file mode 100644
index 0000000000..4e78e71b34
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb
@@ -0,0 +1,99 @@
+$:.unshift "lib"
+
+require 'rubygems'
+require 'test/unit'
+require 'i18n'
+require 'active_support'
+
+class I18nExceptionsTest < Test::Unit::TestCase
+  def test_invalid_locale_stores_locale
+    force_invalid_locale
+  rescue I18n::ArgumentError => e
+    assert_nil e.locale
+  end
+
+  def test_invalid_locale_message
+    force_invalid_locale
+  rescue I18n::ArgumentError => e
+    assert_equal 'nil is not a valid locale', e.message
+  end
+
+  def test_missing_translation_data_stores_locale_key_and_options
+    force_missing_translation_data
+  rescue I18n::ArgumentError => e
+    options = {:scope => :bar}
+    assert_equal 'de', e.locale
+    assert_equal :foo, e.key
+    assert_equal options, e.options
+  end
+
+  def test_missing_translation_data_message
+    force_missing_translation_data
+  rescue I18n::ArgumentError => e
+    assert_equal 'translation missing: de, bar, foo', e.message
+  end
+
+  def test_invalid_pluralization_data_stores_entry_and_count
+    force_invalid_pluralization_data
+  rescue I18n::ArgumentError => e
+    assert_equal [:bar], e.entry
+    assert_equal 1, e.count
+  end
+
+  def test_invalid_pluralization_data_message
+    force_invalid_pluralization_data
+  rescue I18n::ArgumentError => e
+    assert_equal 'translation data [:bar] can not be used with :count => 1', e.message
+  end
+
+  def test_missing_interpolation_argument_stores_key_and_string
+    force_missing_interpolation_argument
+  rescue I18n::ArgumentError => e
+    assert_equal 'bar', e.key
+    assert_equal "{{bar}}", e.string
+  end
+
+  def test_missing_interpolation_argument_message
+    force_missing_interpolation_argument
+  rescue I18n::ArgumentError => e
+    assert_equal 'interpolation argument bar missing in "{{bar}}"', e.message
+  end
+
+  def test_reserved_interpolation_key_stores_key_and_string
+    force_reserved_interpolation_key
+  rescue I18n::ArgumentError => e
+    assert_equal 'scope', e.key
+    assert_equal "{{scope}}", e.string
+  end
+
+  def test_reserved_interpolation_key_message
+    force_reserved_interpolation_key
+  rescue I18n::ArgumentError => e
+    assert_equal 'reserved key "scope" used in "{{scope}}"', e.message
+  end
+
+  private
+    def force_invalid_locale
+      I18n.backend.translate nil, :foo
+    end
+
+    def force_missing_translation_data
+      I18n.backend.store_translations 'de', :bar => nil
+      I18n.backend.translate 'de', :foo, :scope => :bar
+    end
+
+    def force_invalid_pluralization_data
+      I18n.backend.store_translations 'de', :foo => [:bar]
+      I18n.backend.translate 'de', :foo, :count => 1
+    end
+
+    def force_missing_interpolation_argument
+      I18n.backend.store_translations 'de', :foo => "{{bar}}"
+      I18n.backend.translate 'de', :foo, :baz => 'baz'
+    end
+
+    def force_reserved_interpolation_key
+      I18n.backend.store_translations 'de', :foo => "{{scope}}"
+      I18n.backend.translate 'de', :foo, :baz => 'baz'
+    end
+end
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
new file mode 100644
index 0000000000..2835ec4eab
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb
@@ -0,0 +1,124 @@
+$:.unshift "lib"
+
+require 'rubygems'
+require 'test/unit'
+require 'i18n'
+require 'active_support'
+
+class I18nTest < Test::Unit::TestCase
+  def setup
+    I18n.backend.store_translations :'en', {
+      :currency => {
+        :format => {
+          :separator => '.',
+          :delimiter => ',',
+        }
+      }
+    }
+  end
+
+  def test_uses_simple_backend_set_by_default
+    assert I18n.backend.is_a?(I18n::Backend::Simple)
+  end
+
+  def test_can_set_backend
+    assert_nothing_raised{ I18n.backend = self }
+    assert_equal self, I18n.backend
+    I18n.backend = I18n::Backend::Simple.new
+  end
+
+  def test_uses_en_us_as_default_locale_by_default
+    assert_equal 'en', I18n.default_locale
+  end
+
+  def test_can_set_default_locale
+    assert_nothing_raised{ I18n.default_locale = 'de' }
+    assert_equal 'de', I18n.default_locale
+    I18n.default_locale = 'en'
+  end
+
+  def test_uses_default_locale_as_locale_by_default
+    assert_equal I18n.default_locale, I18n.locale
+  end
+
+  def test_can_set_locale_to_thread_current
+    assert_nothing_raised{ I18n.locale = 'de' }
+    assert_equal 'de', I18n.locale
+    assert_equal 'de', Thread.current[:locale]
+    I18n.locale = 'en'
+  end
+
+  def test_can_set_exception_handler
+    assert_nothing_raised{ I18n.exception_handler = :custom_exception_handler }
+    I18n.exception_handler = :default_exception_handler # revert it
+  end
+
+  def test_uses_custom_exception_handler
+    I18n.exception_handler = :custom_exception_handler
+    I18n.expects(:custom_exception_handler)
+    I18n.translate :bogus
+    I18n.exception_handler = :default_exception_handler # revert it
+  end
+
+  def test_delegates_translate_to_backend
+    I18n.backend.expects(:translate).with 'de', :foo, {}
+    I18n.translate :foo, :locale => 'de'
+  end
+
+  def test_delegates_localize_to_backend
+    I18n.backend.expects(:localize).with 'de', :whatever, :default
+    I18n.localize :whatever, :locale => 'de'
+  end
+
+  def test_translate_given_no_locale_uses_i18n_locale
+    I18n.backend.expects(:translate).with 'en', :foo, {}
+    I18n.translate :foo
+  end
+
+  def test_translate_on_nested_symbol_keys_works
+    assert_equal ".", I18n.t(:'currency.format.separator')
+  end
+
+  def test_translate_with_nested_string_keys_works
+    assert_equal ".", I18n.t('currency.format.separator')
+  end
+
+  def test_translate_with_array_as_scope_works
+    assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
+  end
+
+  def test_translate_with_array_containing_dot_separated_strings_as_scope_works
+    assert_equal ".", I18n.t(:separator, :scope => ['currency.format'])
+  end
+
+  def test_translate_with_key_array_and_dot_separated_scope_works
+    assert_equal [".", ","], I18n.t(%w(separator delimiter), :scope => 'currency.format')
+  end
+
+  def test_translate_with_dot_separated_key_array_and_scope_works
+    assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency')
+  end
+
+  def test_translate_with_options_using_scope_works
+    I18n.backend.expects(:translate).with('de', :precision, :scope => :"currency.format")
+    I18n.with_options :locale => 'de', :scope => :'currency.format' do |locale|
+      locale.t :precision
+    end
+  end
+
+  # def test_translate_given_no_args_raises_missing_translation_data
+  #   assert_equal "translation missing: en, no key", I18n.t
+  # end
+
+  def test_translate_given_a_bogus_key_raises_missing_translation_data
+    assert_equal "translation missing: en, bogus", I18n.t(:bogus)
+  end
+
+  def test_localize_nil_raises_argument_error
+    assert_raise(I18n::ArgumentError) { I18n.l nil }
+  end
+
+  def test_localize_object_raises_argument_error
+    assert_raise(I18n::ArgumentError) { I18n.l Object.new }
+  end
+end
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
new file mode 100644
index 0000000000..6044ce10d9
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb
@@ -0,0 +1 @@
+{:'en-Ruby' => {:foo => {:bar => "baz"}}}
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
new file mode 100644
index 0000000000..0b298c9c0e
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml
@@ -0,0 +1,3 @@
+en-Yaml:
+  foo:
+    bar: baz
\ No newline at end of file
diff --git a/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
new file mode 100644
index 0000000000..a1696c77f6
--- /dev/null
+++ b/activesupport/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb
@@ -0,0 +1,567 @@
+# encoding: utf-8
+$:.unshift "lib"
+
+require 'rubygems'
+require 'test/unit'
+require 'i18n'
+require 'time'
+require 'yaml'
+
+module I18nSimpleBackendTestSetup
+  def setup_backend
+    # backend_reset_translations!
+    @backend = I18n::Backend::Simple.new
+    @backend.store_translations 'en', :foo => {:bar => 'bar', :baz => 'baz'}
+    @locale_dir = File.dirname(__FILE__) + '/locale'
+  end
+  alias :setup :setup_backend
+
+  # def backend_reset_translations!
+  #   I18n::Backend::Simple::ClassMethods.send :class_variable_set, :@@translations, {}
+  # end
+
+  def backend_get_translations
+    # I18n::Backend::Simple::ClassMethods.send :class_variable_get, :@@translations
+    @backend.instance_variable_get :@translations
+  end
+
+  def add_datetime_translations
+    @backend.store_translations :'de', {
+      :date => {
+        :formats => {
+          :default => "%d.%m.%Y",
+          :short => "%d. %b",
+          :long => "%d. %B %Y",
+        },
+        :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
+        :abbr_day_names => %w(So Mo Di Mi Do Fr  Sa),
+        :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
+        :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil),
+        :order => [:day, :month, :year]
+      },
+      :time => {
+        :formats => {
+          :default => "%a, %d. %b %Y %H:%M:%S %z",
+          :short => "%d. %b %H:%M",
+          :long => "%d. %B %Y %H:%M",
+        },
+        :am => 'am',
+        :pm => 'pm'
+      },
+      :datetime => {
+        :distance_in_words => {
+          :half_a_minute => 'half a minute',
+          :less_than_x_seconds => {
+            :one => 'less than 1 second',
+            :other => 'less than {{count}} seconds'
+          },
+          :x_seconds => {
+            :one => '1 second',
+            :other => '{{count}} seconds'
+          },
+          :less_than_x_minutes => {
+            :one => 'less than a minute',
+            :other => 'less than {{count}} minutes'
+          },
+          :x_minutes => {
+            :one => '1 minute',
+            :other => '{{count}} minutes'
+          },
+          :about_x_hours => {
+            :one => 'about 1 hour',
+            :other => 'about {{count}} hours'
+          },
+          :x_days => {
+            :one => '1 day',
+            :other => '{{count}} days'
+          },
+          :about_x_months => {
+            :one => 'about 1 month',
+            :other => 'about {{count}} months'
+          },
+          :x_months => {
+            :one => '1 month',
+            :other => '{{count}} months'
+          },
+          :about_x_years => {
+            :one => 'about 1 year',
+            :other => 'about {{count}} year'
+          },
+          :over_x_years => {
+            :one => 'over 1 year',
+            :other => 'over {{count}} years'
+          }
+        }
+      }
+    }
+  end
+end
+
+class I18nSimpleBackendTranslationsTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def test_store_translations_adds_translations # no, really :-)
+    @backend.store_translations :'en', :foo => 'bar'
+    assert_equal Hash[:'en', {:foo => 'bar'}], backend_get_translations
+  end
+
+  def test_store_translations_deep_merges_translations
+    @backend.store_translations :'en', :foo => {:bar => 'bar'}
+    @backend.store_translations :'en', :foo => {:baz => 'baz'}
+    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
+  end
+
+  def test_store_translations_forces_locale_to_sym
+    @backend.store_translations 'en', :foo => 'bar'
+    assert_equal Hash[:'en', {:foo => 'bar'}], backend_get_translations
+  end
+
+  def test_store_translations_converts_keys_to_symbols
+    # backend_reset_translations!
+    @backend.store_translations 'en', 'foo' => {'bar' => 'bar', 'baz' => 'baz'}
+    assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], backend_get_translations
+  end
+end
+
+class I18nSimpleBackendAvailableLocalesTest < Test::Unit::TestCase
+  def test_available_locales
+    @backend = I18n::Backend::Simple.new
+    @backend.store_translations 'de', :foo => 'bar'
+    @backend.store_translations 'en', :foo => 'foo'
+
+    assert_equal ['de', 'en'], @backend.available_locales.map{|locale| locale.to_s }.sort
+  end
+end
+
+class I18nSimpleBackendTranslateTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def test_translate_calls_lookup_with_locale_given
+    @backend.expects(:lookup).with('de', :bar, [:foo]).returns 'bar'
+    @backend.translate 'de', :bar, :scope => [:foo]
+  end
+
+  def test_given_no_keys_it_returns_the_default
+    assert_equal 'default', @backend.translate('en', nil, :default => 'default')
+  end
+
+  def test_translate_given_a_symbol_as_a_default_translates_the_symbol
+    assert_equal 'bar', @backend.translate('en', nil, :scope => [:foo], :default => :bar)
+  end
+
+  def test_translate_given_an_array_as_default_uses_the_first_match
+    assert_equal 'bar', @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :bar])
+  end
+
+  def test_translate_given_an_array_of_inexistent_keys_it_raises_missing_translation_data
+    assert_raise I18n::MissingTranslationData do
+      @backend.translate('en', :does_not_exist, :scope => [:foo], :default => [:does_not_exist_2, :does_not_exist_3])
+    end
+  end
+
+  def test_translate_an_array_of_keys_translates_all_of_them
+    assert_equal %w(bar baz), @backend.translate('en', [:bar, :baz], :scope => [:foo])
+  end
+
+  def test_translate_calls_pluralize
+    @backend.expects(:pluralize).with 'en', 'bar', 1
+    @backend.translate 'en', :bar, :scope => [:foo], :count => 1
+  end
+
+  def test_translate_calls_interpolate
+    @backend.expects(:interpolate).with 'en', 'bar', {}
+    @backend.translate 'en', :bar, :scope => [:foo]
+  end
+
+  def test_translate_calls_interpolate_including_count_as_a_value
+    @backend.expects(:interpolate).with 'en', 'bar', {:count => 1}
+    @backend.translate 'en', :bar, :scope => [:foo], :count => 1
+  end
+
+  def test_translate_given_nil_as_a_locale_raises_an_argument_error
+    assert_raise(I18n::InvalidLocale){ @backend.translate nil, :bar }
+  end
+
+  def test_translate_with_a_bogus_key_and_no_default_raises_missing_translation_data
+    assert_raise(I18n::MissingTranslationData){ @backend.translate 'de', :bogus }
+  end
+end
+
+class I18nSimpleBackendLookupTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  # useful because this way we can use the backend with no key for interpolation/pluralization
+  def test_lookup_given_nil_as_a_key_returns_nil
+    assert_nil @backend.send(:lookup, 'en', nil)
+  end
+
+  def test_lookup_given_nested_keys_looks_up_a_nested_hash_value
+    assert_equal 'bar', @backend.send(:lookup, 'en', :bar, [:foo])
+  end
+end
+
+class I18nSimpleBackendPluralizeTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def test_pluralize_given_nil_returns_the_given_entry
+    entry = {:one => 'bar', :other => 'bars'}
+    assert_equal entry, @backend.send(:pluralize, nil, entry, nil)
+  end
+
+  def test_pluralize_given_0_returns_zero_string_if_zero_key_given
+    assert_equal 'zero', @backend.send(:pluralize, nil, {:zero => 'zero', :one => 'bar', :other => 'bars'}, 0)
+  end
+
+  def test_pluralize_given_0_returns_plural_string_if_no_zero_key_given
+    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 0)
+  end
+
+  def test_pluralize_given_1_returns_singular_string
+    assert_equal 'bar', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 1)
+  end
+
+  def test_pluralize_given_2_returns_plural_string
+    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 2)
+  end
+
+  def test_pluralize_given_3_returns_plural_string
+    assert_equal 'bars', @backend.send(:pluralize, nil, {:one => 'bar', :other => 'bars'}, 3)
+  end
+
+  def test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluralization_data
+    assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, {:one => 'bar'}, 2) }
+  end
+
+  # def test_interpolate_given_a_string_raises_invalid_pluralization_data
+  #   assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, 'bar', 2) }
+  # end
+  #
+  # def test_interpolate_given_an_array_raises_invalid_pluralization_data
+  #   assert_raise(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, ['bar'], 2) }
+  # end
+end
+
+class I18nSimpleBackendInterpolateTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def test_interpolate_given_a_value_hash_interpolates_the_values_to_the_string
+    assert_equal 'Hi David!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'David')
+  end
+
+  def test_interpolate_given_a_value_hash_interpolates_into_unicode_string
+    assert_equal 'Häi David!', @backend.send(:interpolate, nil, 'Häi {{name}}!', :name => 'David')
+  end
+
+  def test_interpolate_given_an_unicode_value_hash_interpolates_to_the_string
+    assert_equal 'Hi ゆきひろ!', @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => 'ゆきひろ')
+  end
+
+  def test_interpolate_given_an_unicode_value_hash_interpolates_into_unicode_string
+    assert_equal 'こんにちは、ゆきひろさん!', @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => 'ゆきひろ')
+  end
+
+  if Kernel.const_defined?(:Encoding)
+    def test_interpolate_given_a_non_unicode_multibyte_value_hash_interpolates_into_a_string_with_the_same_encoding
+      assert_equal euc_jp('Hi ゆきひろ!'), @backend.send(:interpolate, nil, 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
+    end
+
+    def test_interpolate_given_an_unicode_value_hash_into_a_non_unicode_multibyte_string_raises_encoding_compatibility_error
+      assert_raise(Encoding::CompatibilityError) do
+        @backend.send(:interpolate, nil, euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
+      end
+    end
+
+    def test_interpolate_given_a_non_unicode_multibyte_value_hash_into_an_unicode_string_raises_encoding_compatibility_error
+      assert_raise(Encoding::CompatibilityError) do
+        @backend.send(:interpolate, nil, 'こんにちは、{{name}}さん!', :name => euc_jp('ゆきひろ'))
+      end
+    end
+  end
+
+  def test_interpolate_given_nil_as_a_string_returns_nil
+    assert_nil @backend.send(:interpolate, nil, nil, :name => 'David')
+  end
+
+  def test_interpolate_given_an_non_string_as_a_string_returns_nil
+    assert_equal [], @backend.send(:interpolate, nil, [], :name => 'David')
+  end
+
+  def test_interpolate_given_a_values_hash_with_nil_values_interpolates_the_string
+    assert_equal 'Hi !', @backend.send(:interpolate, nil, 'Hi {{name}}!', {:name => nil})
+  end
+
+  def test_interpolate_given_an_empty_values_hash_raises_missing_interpolation_argument
+    assert_raise(I18n::MissingInterpolationArgument) { @backend.send(:interpolate, nil, 'Hi {{name}}!', {}) }
+  end
+
+  def test_interpolate_given_a_string_containing_a_reserved_key_raises_reserved_interpolation_key
+    assert_raise(I18n::ReservedInterpolationKey) { @backend.send(:interpolate, nil, '{{default}}', {:default => nil}) }
+  end
+  
+  private
+  
+  def euc_jp(string)
+    string.encode!(Encoding::EUC_JP)
+  end
+end
+
+class I18nSimpleBackendLocalizeDateTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def setup
+    @backend = I18n::Backend::Simple.new
+    add_datetime_translations
+    @date = Date.new 2008, 1, 1
+  end
+
+  def test_translate_given_the_short_format_it_uses_it
+    assert_equal '01. Jan', @backend.localize('de', @date, :short)
+  end
+
+  def test_translate_given_the_long_format_it_uses_it
+    assert_equal '01. Januar 2008', @backend.localize('de', @date, :long)
+  end
+
+  def test_translate_given_the_default_format_it_uses_it
+    assert_equal '01.01.2008', @backend.localize('de', @date, :default)
+  end
+
+  def test_translate_given_a_day_name_format_it_returns_a_day_name
+    assert_equal 'Dienstag', @backend.localize('de', @date, '%A')
+  end
+
+  def test_translate_given_an_abbr_day_name_format_it_returns_an_abbrevated_day_name
+    assert_equal 'Di', @backend.localize('de', @date, '%a')
+  end
+
+  def test_translate_given_a_month_name_format_it_returns_a_month_name
+    assert_equal 'Januar', @backend.localize('de', @date, '%B')
+  end
+
+  def test_translate_given_an_abbr_month_name_format_it_returns_an_abbrevated_month_name
+    assert_equal 'Jan', @backend.localize('de', @date, '%b')
+  end
+
+  def test_translate_given_no_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @date }
+  end
+
+  def test_translate_given_an_unknown_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @date, '%x' }
+  end
+
+  def test_localize_nil_raises_argument_error
+    assert_raise(I18n::ArgumentError) { @backend.localize 'de', nil }
+  end
+
+  def test_localize_object_raises_argument_error
+    assert_raise(I18n::ArgumentError) { @backend.localize 'de', Object.new }
+  end
+end
+
+class I18nSimpleBackendLocalizeDateTimeTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def setup
+    @backend = I18n::Backend::Simple.new
+    add_datetime_translations
+    @morning = DateTime.new 2008, 1, 1, 6
+    @evening = DateTime.new 2008, 1, 1, 18
+  end
+
+  def test_translate_given_the_short_format_it_uses_it
+    assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
+  end
+
+  def test_translate_given_the_long_format_it_uses_it
+    assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
+  end
+
+  def test_translate_given_the_default_format_it_uses_it
+    assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)
+  end
+
+  def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
+    assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
+  end
+
+  def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
+    assert_equal 'Di', @backend.localize('de', @morning, '%a')
+  end
+
+  def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
+    assert_equal 'Januar', @backend.localize('de', @morning, '%B')
+  end
+
+  def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
+    assert_equal 'Jan', @backend.localize('de', @morning, '%b')
+  end
+
+  def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
+    assert_equal 'am', @backend.localize('de', @morning, '%p')
+    assert_equal 'pm', @backend.localize('de', @evening, '%p')
+  end
+
+  def test_translate_given_no_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @morning }
+  end
+
+  def test_translate_given_an_unknown_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
+  end
+end
+
+class I18nSimpleBackendLocalizeTimeTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def setup
+    @old_timezone, ENV['TZ'] = ENV['TZ'], 'UTC'
+    @backend = I18n::Backend::Simple.new
+    add_datetime_translations
+    @morning = Time.parse '2008-01-01 6:00 UTC'
+    @evening = Time.parse '2008-01-01 18:00 UTC'
+  end
+
+  def teardown
+    @old_timezone ? ENV['TZ'] = @old_timezone : ENV.delete('TZ')
+  end
+
+  def test_translate_given_the_short_format_it_uses_it
+    assert_equal '01. Jan 06:00', @backend.localize('de', @morning, :short)
+  end
+
+  def test_translate_given_the_long_format_it_uses_it
+    assert_equal '01. Januar 2008 06:00', @backend.localize('de', @morning, :long)
+  end
+
+  # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this?
+  # def test_translate_given_the_default_format_it_uses_it
+  #   assert_equal 'Di, 01. Jan 2008 06:00:00 +0000', @backend.localize('de', @morning, :default)
+  # end
+
+  def test_translate_given_a_day_name_format_it_returns_the_correct_day_name
+    assert_equal 'Dienstag', @backend.localize('de', @morning, '%A')
+  end
+
+  def test_translate_given_an_abbr_day_name_format_it_returns_the_correct_abbrevated_day_name
+    assert_equal 'Di', @backend.localize('de', @morning, '%a')
+  end
+
+  def test_translate_given_a_month_name_format_it_returns_the_correct_month_name
+    assert_equal 'Januar', @backend.localize('de', @morning, '%B')
+  end
+
+  def test_translate_given_an_abbr_month_name_format_it_returns_the_correct_abbrevated_month_name
+    assert_equal 'Jan', @backend.localize('de', @morning, '%b')
+  end
+
+  def test_translate_given_a_meridian_indicator_format_it_returns_the_correct_meridian_indicator
+    assert_equal 'am', @backend.localize('de', @morning, '%p')
+    assert_equal 'pm', @backend.localize('de', @evening, '%p')
+  end
+
+  def test_translate_given_no_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @morning }
+  end
+
+  def test_translate_given_an_unknown_format_it_does_not_fail
+    assert_nothing_raised{ @backend.localize 'de', @morning, '%x' }
+  end
+end
+
+class I18nSimpleBackendHelperMethodsTest < Test::Unit::TestCase
+  def setup
+    @backend = I18n::Backend::Simple.new
+  end
+
+  def test_deep_symbolize_keys_works
+    result = @backend.send :deep_symbolize_keys, 'foo' => {'bar' => {'baz' => 'bar'}}
+    expected = {:foo => {:bar => {:baz => 'bar'}}}
+    assert_equal expected, result
+  end
+end
+
+class I18nSimpleBackendLoadTranslationsTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def test_load_translations_with_unknown_file_type_raises_exception
+    assert_raise(I18n::UnknownFileType) { @backend.load_translations "#{@locale_dir}/en.xml" }
+  end
+
+  def test_load_translations_with_ruby_file_type_does_not_raise_exception
+    assert_nothing_raised { @backend.load_translations "#{@locale_dir}/en.rb" }
+  end
+
+  def test_load_rb_loads_data_from_ruby_file
+    data = @backend.send :load_rb, "#{@locale_dir}/en.rb"
+    assert_equal({:'en-Ruby' => {:foo => {:bar => "baz"}}}, data)
+  end
+
+  def test_load_rb_loads_data_from_yaml_file
+    data = @backend.send :load_yml, "#{@locale_dir}/en.yml"
+    assert_equal({'en-Yaml' => {'foo' => {'bar' => 'baz'}}}, data)
+  end
+
+  def test_load_translations_loads_from_different_file_formats
+    @backend = I18n::Backend::Simple.new
+    @backend.load_translations "#{@locale_dir}/en.rb", "#{@locale_dir}/en.yml"
+    expected = {
+      :'en-Ruby' => {:foo => {:bar => "baz"}},
+      :'en-Yaml' => {:foo => {:bar => "baz"}}
+    }
+    assert_equal expected, backend_get_translations
+  end
+end
+
+class I18nSimpleBackendLoadPathTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+
+  def teardown
+    I18n.load_path = []
+  end
+
+  def test_nested_load_paths_do_not_break_locale_loading
+    @backend = I18n::Backend::Simple.new
+    I18n.load_path = [[File.dirname(__FILE__) + '/locale/en.yml']]
+    assert_nil backend_get_translations
+    assert_nothing_raised { @backend.send :init_translations }
+    assert_not_nil backend_get_translations
+  end
+
+  def test_adding_arrays_of_filenames_to_load_path_do_not_break_locale_loading
+    @backend = I18n::Backend::Simple.new
+    I18n.load_path << Dir[File.dirname(__FILE__) + '/locale/*.{rb,yml}']
+    assert_nil backend_get_translations
+    assert_nothing_raised { @backend.send :init_translations }
+    assert_not_nil backend_get_translations
+  end
+end
+
+class I18nSimpleBackendReloadTranslationsTest < Test::Unit::TestCase
+  include I18nSimpleBackendTestSetup
+  
+  def setup
+    @backend = I18n::Backend::Simple.new
+    I18n.load_path = [File.dirname(__FILE__) + '/locale/en.yml']
+    assert_nil backend_get_translations
+    @backend.send :init_translations
+  end
+  
+  def teardown
+    I18n.load_path = []
+  end
+  
+  def test_setup
+    assert_not_nil backend_get_translations
+  end
+  
+  def test_reload_translations_unloads_translations
+    @backend.reload!
+    assert_nil backend_get_translations
+  end
+  
+  def test_reload_translations_uninitializes_translations
+    @backend.reload!
+    assert_equal @backend.initialized?, false
+  end
+end
-- 
cgit v1.2.3


From 17dee01b6f2186888629859fe2e99232225ae5ea Mon Sep 17 00:00:00 2001
From: Bryan Helmkamp <bryan@brynary.com>
Date: Thu, 29 Oct 2009 14:43:25 -0400
Subject: Fix Ruby warning: method redefined; discarding old breakpoint

---
 activesupport/lib/active_support/core_ext/kernel/debugger.rb | 1 +
 1 file changed, 1 insertion(+)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
index 0813a51383..59e03e3df7 100644
--- a/activesupport/lib/active_support/core_ext/kernel/debugger.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
@@ -7,6 +7,7 @@ module Kernel
     end
   end
 
+  undef :breakpoint if respond_to?(:breakpoint)
   def breakpoint
     message = "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
     defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
-- 
cgit v1.2.3


From d4513ac69958063de3cad9aa655fe9d63e82ec76 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 20:26:46 +0100
Subject: Object#instance_variable_defined? is not needed for Ruby >= 1.8.7

---
 .../lib/active_support/core_ext/object/instance_variables.rb       | 7 -------
 activesupport/test/core_ext/object_and_class_ext_test.rb           | 7 -------
 2 files changed, 14 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
index 4ecaab3bbb..866317b17a 100644
--- a/activesupport/lib/active_support/core_ext/object/instance_variables.rb
+++ b/activesupport/lib/active_support/core_ext/object/instance_variables.rb
@@ -1,11 +1,4 @@
 class Object
-  # Available in 1.8.6 and later.
-  unless respond_to?(:instance_variable_defined?)
-    def instance_variable_defined?(variable)
-      instance_variables.include?(variable.to_s)
-    end
-  end
-
   # Returns a hash that maps instance variable names without "@" to their
   # corresponding values. Keys are strings both in Ruby 1.8 and 1.9.
   #
diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb
index f0121b862d..e6fbdb637b 100644
--- a/activesupport/test/core_ext/object_and_class_ext_test.rb
+++ b/activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -182,13 +182,6 @@ class ObjectInstanceVariableTest < Test::Unit::TestCase
     assert_equal %w(@bar @baz), @source.instance_variable_names.sort
   end
 
-  def test_instance_variable_defined
-    assert @source.instance_variable_defined?('@bar')
-    assert @source.instance_variable_defined?(:@bar)
-    assert !@source.instance_variable_defined?(:@foo)
-    assert !@source.instance_variable_defined?('@foo')
-  end
-
   def test_copy_instance_variables_from_without_explicit_excludes
     assert_equal [], @dest.instance_variables
     @dest.copy_instance_variables_from(@source)
-- 
cgit v1.2.3


From 1979e9c8553f4d7905822fdcc99e52d179e78c3c Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:11:26 +0100
Subject: Symbol#to_proc is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/symbol.rb        |  1 -
 .../lib/active_support/core_ext/symbol/to_proc.rb          | 14 --------------
 activesupport/lib/active_support/ruby/shim.rb              |  2 --
 activesupport/test/core_ext/enumerable_test.rb             |  1 -
 activesupport/test/core_ext/symbol_test.rb                 |  9 ---------
 activesupport/test/dependencies_test.rb                    |  1 -
 6 files changed, 28 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/symbol.rb
 delete mode 100644 activesupport/lib/active_support/core_ext/symbol/to_proc.rb
 delete mode 100644 activesupport/test/core_ext/symbol_test.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/symbol.rb b/activesupport/lib/active_support/core_ext/symbol.rb
deleted file mode 100644
index c103cd9dcf..0000000000
--- a/activesupport/lib/active_support/core_ext/symbol.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'active_support/core_ext/symbol/to_proc'
diff --git a/activesupport/lib/active_support/core_ext/symbol/to_proc.rb b/activesupport/lib/active_support/core_ext/symbol/to_proc.rb
deleted file mode 100644
index 520369452b..0000000000
--- a/activesupport/lib/active_support/core_ext/symbol/to_proc.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class Symbol
-  # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
-  #
-  #   # The same as people.collect { |p| p.name }
-  #   people.collect(&:name)
-  #
-  #   # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
-  #   people.select(&:manager?).collect(&:salary)
-  #
-  # This is a builtin method in Ruby 1.8.7 and later.
-  def to_proc
-    Proc.new { |*args| args.shift.__send__(self, *args) }
-  end unless :to_proc.respond_to?(:to_proc)
-end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index 37c57c485a..43e7ffc938 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -9,7 +9,6 @@
 # Process     Process.daemon
 # REXML       security fix
 # String      ord
-# Symbol      to_proc
 # Time        to_date, to_time, to_datetime
 require 'active_support'
 require 'active_support/core_ext/date/calculations'
@@ -20,5 +19,4 @@ require 'active_support/core_ext/object/tap'
 require 'active_support/core_ext/process/daemon'
 require 'active_support/core_ext/string/conversions'
 require 'active_support/core_ext/rexml'
-require 'active_support/core_ext/symbol/to_proc'
 require 'active_support/core_ext/time/conversions'
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index 4170de3dce..a8e98891d3 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -1,6 +1,5 @@
 require 'abstract_unit'
 require 'active_support/core_ext/array'
-require 'active_support/core_ext/symbol'
 require 'active_support/core_ext/enumerable'
 
 Payment = Struct.new(:price)
diff --git a/activesupport/test/core_ext/symbol_test.rb b/activesupport/test/core_ext/symbol_test.rb
deleted file mode 100644
index 1eaccb9965..0000000000
--- a/activesupport/test/core_ext/symbol_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'abstract_unit'
-
-class SymbolTests < Test::Unit::TestCase
-  def test_to_proc
-    assert_equal %w(one two three), [:one, :two, :three].map(&:to_s)
-    assert_equal(%w(one two three),
-      {1 => "one", 2 => "two", 3 => "three"}.sort_by(&:first).map(&:last))
-  end
-end
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 97d70cf8c4..0fcf1eaf00 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -3,7 +3,6 @@ require 'pp'
 require 'active_support/dependencies'
 require 'active_support/core_ext/module/loading'
 require 'active_support/core_ext/kernel/reporting'
-require 'active_support/core_ext/symbol/to_proc'
 
 module ModuleWithMissing
   mattr_accessor :missing_count
-- 
cgit v1.2.3


From f8e713f488bba264ba73251b56ad56385b8ed824 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:23:19 +0100
Subject: Object#tap is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/object/misc.rb |  1 -
 activesupport/lib/active_support/core_ext/object/tap.rb  | 16 ----------------
 activesupport/lib/active_support/ruby/shim.rb            |  2 --
 activesupport/test/core_ext/object_ext_test.rb           |  9 ---------
 4 files changed, 28 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/object/tap.rb
 delete mode 100644 activesupport/test/core_ext/object_ext_test.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/object/misc.rb b/activesupport/lib/active_support/core_ext/object/misc.rb
index 80011dfbed..3e3af03cc5 100644
--- a/activesupport/lib/active_support/core_ext/object/misc.rb
+++ b/activesupport/lib/active_support/core_ext/object/misc.rb
@@ -1,3 +1,2 @@
 require 'active_support/core_ext/object/returning'
-require 'active_support/core_ext/object/tap'
 require 'active_support/core_ext/object/with_options'
diff --git a/activesupport/lib/active_support/core_ext/object/tap.rb b/activesupport/lib/active_support/core_ext/object/tap.rb
deleted file mode 100644
index db7e715e2d..0000000000
--- a/activesupport/lib/active_support/core_ext/object/tap.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Object
-  # Yields <code>x</code> to the block, and then returns <code>x</code>.
-  # The primary purpose of this method is to "tap into" a method chain,
-  # in order to perform operations on intermediate results within the chain.
-  #
-  #   (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
-  #     tap    { |x| puts "array: #{x.inspect}" }.
-  #     select { |x| x%2 == 0 }.
-  #     tap    { |x| puts "evens: #{x.inspect}" }.
-  #     map    { |x| x*x }.
-  #     tap    { |x| puts "squares: #{x.inspect}" }
-  def tap
-    yield self
-    self
-  end unless Object.respond_to?(:tap)
-end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index 43e7ffc938..1f47c04826 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -5,7 +5,6 @@
 # DateTime    to_date, to_datetime, xmlschema
 # Enumerable  group_by, each_with_object, none?
 # Integer     even?, odd?
-# Object      tap
 # Process     Process.daemon
 # REXML       security fix
 # String      ord
@@ -15,7 +14,6 @@ require 'active_support/core_ext/date/calculations'
 require 'active_support/core_ext/date_time/conversions'
 require 'active_support/core_ext/enumerable'
 require 'active_support/core_ext/integer/even_odd'
-require 'active_support/core_ext/object/tap'
 require 'active_support/core_ext/process/daemon'
 require 'active_support/core_ext/string/conversions'
 require 'active_support/core_ext/rexml'
diff --git a/activesupport/test/core_ext/object_ext_test.rb b/activesupport/test/core_ext/object_ext_test.rb
deleted file mode 100644
index 04c19ed2aa..0000000000
--- a/activesupport/test/core_ext/object_ext_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'abstract_unit'
-require 'active_support/core_ext/object/metaclass'
-
-class ObjectExtTest < Test::Unit::TestCase
-  def test_tap_yields_and_returns_self
-    foo = Object.new
-    assert_equal foo, foo.tap { |x| assert_equal foo, x; :bar }
-  end
-end
-- 
cgit v1.2.3


From 004db18cb0f690486336f0fa141ad383c79f9558 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:27:58 +0100
Subject: String#bytesize is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/string/bytesize.rb      | 5 -----
 activesupport/lib/active_support/core_ext/string/interpolation.rb | 1 -
 activesupport/lib/active_support/message_verifier.rb              | 2 --
 activesupport/test/core_ext/string_ext_test.rb                    | 7 -------
 4 files changed, 15 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/string/bytesize.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/bytesize.rb b/activesupport/lib/active_support/core_ext/string/bytesize.rb
deleted file mode 100644
index ed051b921e..0000000000
--- a/activesupport/lib/active_support/core_ext/string/bytesize.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-unless '1.9'.respond_to?(:bytesize)
-  class String
-    alias :bytesize :size
-  end
-end
diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
index d9159b690a..41a061c1a4 100644
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ b/activesupport/lib/active_support/core_ext/string/interpolation.rb
@@ -6,7 +6,6 @@
 =end
 
 if RUBY_VERSION < '1.9'
-  require 'active_support/core_ext/string/bytesize'
 
   # KeyError is raised by String#% when the string contains a named placeholder
   # that is not contained in the given arguments hash. Ruby 1.9 includes and
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
index 282346b1a6..87e4b1ad33 100644
--- a/activesupport/lib/active_support/message_verifier.rb
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/string/bytesize'
-
 module ActiveSupport
   # MessageVerifier makes it easy to generate and verify messages which are signed
   # to prevent tampering.
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 584a41b631..0f988e78a4 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -350,13 +350,6 @@ class TestGetTextString < Test::Unit::TestCase
   end
 end
 
-class StringBytesizeTest < Test::Unit::TestCase
-  def test_bytesize
-    assert_respond_to 'foo', :bytesize
-    assert_equal 3, 'foo'.bytesize
-  end
-end
-
 class OutputSafetyTest < ActiveSupport::TestCase
   def setup
     @string = "hello"
-- 
cgit v1.2.3


From c0bb4c6ed2f5a5676569746e7bfd70405346ef8f Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:35:43 +0100
Subject: String#start_with? and String#end_with? are not needed for Ruby >=
 1.8.7, leaves their plural aliases though

---
 .../lib/active_support/core_ext/string/starts_ends_with.rb | 14 --------------
 activesupport/test/core_ext/string_ext_test.rb             |  8 --------
 2 files changed, 22 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb b/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
index f65bb8f75b..641acf62d0 100644
--- a/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
+++ b/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb
@@ -1,18 +1,4 @@
 class String
-  unless '1.8.7 and up'.respond_to?(:start_with?)
-    # Does the string start with the specified +prefix+?
-    def start_with?(prefix)
-      prefix = prefix.to_s
-      self[0, prefix.length] == prefix
-    end
-
-    # Does the string end with the specified +suffix+?
-    def end_with?(suffix)
-      suffix = suffix.to_s
-      self[-suffix.length, suffix.length] == suffix
-    end
-  end
-
   alias_method :starts_with?, :start_with?
   alias_method :ends_with?, :end_with?
 end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 0f988e78a4..dd9e9e0ebb 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -185,17 +185,9 @@ class StringInflectionsTest < Test::Unit::TestCase
     assert s.starts_with?('hel')
     assert !s.starts_with?('el')
 
-    assert s.start_with?('h')
-    assert s.start_with?('hel')
-    assert !s.start_with?('el')
-
     assert s.ends_with?('o')
     assert s.ends_with?('lo')
     assert !s.ends_with?('el')
-
-    assert s.end_with?('o')
-    assert s.end_with?('lo')
-    assert !s.end_with?('el')
   end
 
   def test_string_squish
-- 
cgit v1.2.3


From b6598c683bb8f8ef484f54755cced77a5d6200bb Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:39:32 +0100
Subject: String#each_char is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/string.rb         |  1 -
 .../lib/active_support/core_ext/string/iterators.rb         | 13 -------------
 activesupport/test/core_ext/string_ext_test.rb              | 11 -----------
 3 files changed, 25 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/string/iterators.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb
index 6c52f12712..0365b6af1c 100644
--- a/activesupport/lib/active_support/core_ext/string.rb
+++ b/activesupport/lib/active_support/core_ext/string.rb
@@ -4,7 +4,6 @@ require 'active_support/core_ext/string/multibyte'
 require 'active_support/core_ext/string/starts_ends_with'
 require 'active_support/core_ext/string/inflections'
 require 'active_support/core_ext/string/access'
-require 'active_support/core_ext/string/iterators'
 require 'active_support/core_ext/string/xchar'
 require 'active_support/core_ext/string/behavior'
 require 'active_support/core_ext/string/interpolation'
diff --git a/activesupport/lib/active_support/core_ext/string/iterators.rb b/activesupport/lib/active_support/core_ext/string/iterators.rb
deleted file mode 100644
index 2f8aa84024..0000000000
--- a/activesupport/lib/active_support/core_ext/string/iterators.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-unless '1.9'.respond_to?(:each_char)
-  class String
-    # Yields a single-character string for each character in the string.
-    # When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
-    def each_char
-      require 'strscan' unless defined? ::StringScanner
-      scanner, char = ::StringScanner.new(self), /./mu
-      while c = scanner.scan(char)
-        yield c
-      end
-    end
-  end
-end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index dd9e9e0ebb..ffcd086716 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -206,17 +206,6 @@ class StringInflectionsTest < Test::Unit::TestCase
     # And changes the original string:
     assert_equal original, expected
   end
-
-  if RUBY_VERSION < '1.9'
-    def test_each_char_with_utf8_string_when_kcode_is_utf8
-      with_kcode('UTF8') do
-        '€2.99'.each_char do |char|
-          assert_not_equal 1, char.length
-          break
-        end
-      end
-    end
-  end
 end
 
 class StringBehaviourTest < Test::Unit::TestCase
-- 
cgit v1.2.3


From 329e7f44417c00a8d6fee337c288a463e9d64346 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 21:46:16 +0100
Subject: Integer#even? and Integer#odd? are not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/integer.rb     |  2 +-
 .../lib/active_support/core_ext/integer/even_odd.rb      | 16 ----------------
 .../lib/active_support/core_ext/integer/multiple.rb      |  6 ++++++
 activesupport/lib/active_support/ruby/shim.rb            |  2 --
 activesupport/test/core_ext/integer_ext_test.rb          | 16 ----------------
 5 files changed, 7 insertions(+), 35 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/integer/even_odd.rb
 create mode 100644 activesupport/lib/active_support/core_ext/integer/multiple.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/integer.rb b/activesupport/lib/active_support/core_ext/integer.rb
index 7ba018ed7f..a44a1b4c74 100644
--- a/activesupport/lib/active_support/core_ext/integer.rb
+++ b/activesupport/lib/active_support/core_ext/integer.rb
@@ -1,3 +1,3 @@
-require 'active_support/core_ext/integer/even_odd'
+require 'active_support/core_ext/integer/multiple'
 require 'active_support/core_ext/integer/inflections'
 require 'active_support/core_ext/integer/time'
diff --git a/activesupport/lib/active_support/core_ext/integer/even_odd.rb b/activesupport/lib/active_support/core_ext/integer/even_odd.rb
deleted file mode 100644
index 8f9a97b44c..0000000000
--- a/activesupport/lib/active_support/core_ext/integer/even_odd.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Integer
-  # Check whether the integer is evenly divisible by the argument.
-  def multiple_of?(number)
-    self % number == 0
-  end
-
-  # Is the integer a multiple of 2?
-  def even?
-    multiple_of? 2
-  end unless method_defined?(:even?)
-
-  # Is the integer not a multiple of 2?
-  def odd?
-    !even?
-  end unless method_defined?(:odd?)
-end
diff --git a/activesupport/lib/active_support/core_ext/integer/multiple.rb b/activesupport/lib/active_support/core_ext/integer/multiple.rb
new file mode 100644
index 0000000000..40bea54c67
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/integer/multiple.rb
@@ -0,0 +1,6 @@
+class Integer
+  # Check whether the integer is evenly divisible by the argument.
+  def multiple_of?(number)
+    self % number == 0
+  end
+end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index 1f47c04826..f811239077 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -4,7 +4,6 @@
 # Date        next_year, next_month
 # DateTime    to_date, to_datetime, xmlschema
 # Enumerable  group_by, each_with_object, none?
-# Integer     even?, odd?
 # Process     Process.daemon
 # REXML       security fix
 # String      ord
@@ -13,7 +12,6 @@ require 'active_support'
 require 'active_support/core_ext/date/calculations'
 require 'active_support/core_ext/date_time/conversions'
 require 'active_support/core_ext/enumerable'
-require 'active_support/core_ext/integer/even_odd'
 require 'active_support/core_ext/process/daemon'
 require 'active_support/core_ext/string/conversions'
 require 'active_support/core_ext/rexml'
diff --git a/activesupport/test/core_ext/integer_ext_test.rb b/activesupport/test/core_ext/integer_ext_test.rb
index 956ae5189d..e1591089f5 100644
--- a/activesupport/test/core_ext/integer_ext_test.rb
+++ b/activesupport/test/core_ext/integer_ext_test.rb
@@ -2,22 +2,6 @@ require 'abstract_unit'
 require 'active_support/core_ext/integer'
 
 class IntegerExtTest < Test::Unit::TestCase
-  def test_even
-    assert [ -2, 0, 2, 4 ].all? { |i| i.even? }
-    assert ![ -1, 1, 3 ].all? { |i| i.even? }
-
-    assert 22953686867719691230002707821868552601124472329079.odd?
-    assert !22953686867719691230002707821868552601124472329079.even?
-    assert 22953686867719691230002707821868552601124472329080.even?
-    assert !22953686867719691230002707821868552601124472329080.odd?
-  end
-
-  def test_odd
-    assert ![ -2, 0, 2, 4 ].all? { |i| i.odd? }
-    assert [ -1, 1, 3 ].all? { |i| i.odd? }
-    assert 1000000000000000000000000000000000000000000000000000000001.odd?
-  end
-
   def test_multiple_of
     [ -7, 0, 7, 14 ].each { |i| assert i.multiple_of?(7) }
     [ -7, 7, 14 ].each { |i| assert ! i.multiple_of?(6) }
-- 
cgit v1.2.3


From db2c0d79e3f9ba4fa921b7a122e9e7849729de64 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 22:05:31 +0100
Subject: Enumerable#none? is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/enumerable.rb |  9 ---------
 activesupport/test/core_ext/enumerable_test.rb          | 11 -----------
 2 files changed, 20 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index 15a303cf04..b11c916f61 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -101,15 +101,6 @@ module Enumerable
     size = block_given? ? select(&block).size : self.size
     size > 1
   end
-
-  # Returns true if none of the elements match the given block.
-  #
-  #   success = responses.none? {|r| r.status / 100 == 5 }
-  #
-  # This is a builtin method in Ruby 1.8.7 and later.
-  def none?(&block)
-    !any?(&block)
-  end unless [].respond_to?(:none?)
 end
 
 class Range #:nodoc:
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index a8e98891d3..66f5f9fbde 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -89,15 +89,4 @@ class EnumerableTests < Test::Unit::TestCase
     assert ![ 1, 2 ].many? {|x| x > 1 }
     assert [ 1, 2, 2 ].many? {|x| x > 1 }
   end
-
-  def test_none
-    assert [].none?
-    assert [nil, false].none?
-    assert ![1].none?
-
-    assert [].none? {|x| x > 1 }
-    assert ![ 2 ].none? {|x| x > 1 }
-    assert ![ 1, 2 ].none? {|x| x > 1 }
-    assert [ 1, 1 ].none? {|x| x > 1 }
-  end
 end
-- 
cgit v1.2.3


From a48f49e56bf53e0a2386da898576ef12d5258358 Mon Sep 17 00:00:00 2001
From: Xavier Noria <fxn@hashref.com>
Date: Mon, 9 Nov 2009 22:14:21 +0100
Subject: the REXML security fix is not needed for Ruby >= 1.8.7

---
 activesupport/lib/active_support/core_ext/rexml.rb | 43 ----------------------
 activesupport/lib/active_support/ruby/shim.rb      |  2 -
 2 files changed, 45 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/rexml.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/rexml.rb b/activesupport/lib/active_support/core_ext/rexml.rb
deleted file mode 100644
index 5288b639a6..0000000000
--- a/activesupport/lib/active_support/core_ext/rexml.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require 'active_support/core_ext/kernel/reporting'
-
-# Fixes the rexml vulnerability disclosed at:
-# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
-# This fix is identical to rexml-expansion-fix version 1.0.1
-require 'rexml/rexml'
-
-# Earlier versions of rexml defined REXML::Version, newer ones REXML::VERSION
-unless (defined?(REXML::VERSION) ? REXML::VERSION : REXML::Version) > "3.1.7.2"
-  silence_warnings { require 'rexml/document' }
-
-  # REXML in 1.8.7 has the patch but early patchlevels didn't update Version from 3.1.7.2.
-  unless REXML::Document.respond_to?(:entity_expansion_limit=)
-    silence_warnings { require 'rexml/entity' }
-
-    module REXML #:nodoc:
-      class Entity < Child #:nodoc:
-        undef_method :unnormalized
-        def unnormalized
-          document.record_entity_expansion! if document
-          v = value()
-          return nil if v.nil?
-          @unnormalized = Text::unnormalize(v, parent)
-          @unnormalized
-        end
-      end
-      class Document < Element #:nodoc:
-        @@entity_expansion_limit = 10_000
-        def self.entity_expansion_limit= val
-          @@entity_expansion_limit = val
-        end
-
-        def record_entity_expansion!
-          @number_of_expansions ||= 0
-          @number_of_expansions += 1
-          if @number_of_expansions > @@entity_expansion_limit
-            raise "Number of entity expansions exceeded, processing aborted."
-          end
-        end
-      end
-    end
-  end
-end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index f811239077..af6e8aa91e 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -5,7 +5,6 @@
 # DateTime    to_date, to_datetime, xmlschema
 # Enumerable  group_by, each_with_object, none?
 # Process     Process.daemon
-# REXML       security fix
 # String      ord
 # Time        to_date, to_time, to_datetime
 require 'active_support'
@@ -14,5 +13,4 @@ require 'active_support/core_ext/date_time/conversions'
 require 'active_support/core_ext/enumerable'
 require 'active_support/core_ext/process/daemon'
 require 'active_support/core_ext/string/conversions'
-require 'active_support/core_ext/rexml'
 require 'active_support/core_ext/time/conversions'
-- 
cgit v1.2.3


From eeac054d59dd9373313596dc3ef9db30c4b227d5 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 16:57:10 -0800
Subject: Fix missing dependency

---
 activesupport/test/core_ext/string_ext_test.rb | 1 +
 1 file changed, 1 insertion(+)

(limited to 'activesupport')

diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index ffcd086716..1e8a1c4f08 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -5,6 +5,7 @@ require 'inflector_test_cases'
 
 require 'active_support/core_ext/string'
 require 'active_support/core_ext/time'
+require 'active_support/core_ext/kernel/reporting'
 
 class StringInflectionsTest < Test::Unit::TestCase
   include InflectorTestCases
-- 
cgit v1.2.3


From feaa762e40e7ca7fd9b43172dea92b14ed6b3584 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 16:59:38 -0800
Subject: Ditto

---
 activesupport/test/multibyte_utils_test.rb | 1 +
 1 file changed, 1 insertion(+)

(limited to 'activesupport')

diff --git a/activesupport/test/multibyte_utils_test.rb b/activesupport/test/multibyte_utils_test.rb
index 0a2f20d282..1dff944922 100644
--- a/activesupport/test/multibyte_utils_test.rb
+++ b/activesupport/test/multibyte_utils_test.rb
@@ -2,6 +2,7 @@
 
 require 'abstract_unit'
 require 'multibyte_test_helpers'
+require 'active_support/core_ext/kernel/reporting'
 
 class MultibyteUtilsTest < ActiveSupport::TestCase
   include MultibyteTestHelpers
-- 
cgit v1.2.3


From 08f7c4dd8951053c443371f786be59d04448c225 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Mon, 9 Nov 2009 19:30:02 -0800
Subject: Revert "the REXML security fix is not needed for Ruby >= 1.8.7"

Still required on older 1.8.7 patchlevels.

This reverts commit a48f49e56bf53e0a2386da898576ef12d5258358.
---
 activesupport/lib/active_support/core_ext/rexml.rb | 43 ++++++++++++++++++++++
 activesupport/lib/active_support/ruby/shim.rb      |  2 +
 2 files changed, 45 insertions(+)
 create mode 100644 activesupport/lib/active_support/core_ext/rexml.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/rexml.rb b/activesupport/lib/active_support/core_ext/rexml.rb
new file mode 100644
index 0000000000..5288b639a6
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/rexml.rb
@@ -0,0 +1,43 @@
+require 'active_support/core_ext/kernel/reporting'
+
+# Fixes the rexml vulnerability disclosed at:
+# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
+# This fix is identical to rexml-expansion-fix version 1.0.1
+require 'rexml/rexml'
+
+# Earlier versions of rexml defined REXML::Version, newer ones REXML::VERSION
+unless (defined?(REXML::VERSION) ? REXML::VERSION : REXML::Version) > "3.1.7.2"
+  silence_warnings { require 'rexml/document' }
+
+  # REXML in 1.8.7 has the patch but early patchlevels didn't update Version from 3.1.7.2.
+  unless REXML::Document.respond_to?(:entity_expansion_limit=)
+    silence_warnings { require 'rexml/entity' }
+
+    module REXML #:nodoc:
+      class Entity < Child #:nodoc:
+        undef_method :unnormalized
+        def unnormalized
+          document.record_entity_expansion! if document
+          v = value()
+          return nil if v.nil?
+          @unnormalized = Text::unnormalize(v, parent)
+          @unnormalized
+        end
+      end
+      class Document < Element #:nodoc:
+        @@entity_expansion_limit = 10_000
+        def self.entity_expansion_limit= val
+          @@entity_expansion_limit = val
+        end
+
+        def record_entity_expansion!
+          @number_of_expansions ||= 0
+          @number_of_expansions += 1
+          if @number_of_expansions > @@entity_expansion_limit
+            raise "Number of entity expansions exceeded, processing aborted."
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/activesupport/lib/active_support/ruby/shim.rb b/activesupport/lib/active_support/ruby/shim.rb
index af6e8aa91e..f811239077 100644
--- a/activesupport/lib/active_support/ruby/shim.rb
+++ b/activesupport/lib/active_support/ruby/shim.rb
@@ -5,6 +5,7 @@
 # DateTime    to_date, to_datetime, xmlschema
 # Enumerable  group_by, each_with_object, none?
 # Process     Process.daemon
+# REXML       security fix
 # String      ord
 # Time        to_date, to_time, to_datetime
 require 'active_support'
@@ -13,4 +14,5 @@ require 'active_support/core_ext/date_time/conversions'
 require 'active_support/core_ext/enumerable'
 require 'active_support/core_ext/process/daemon'
 require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/rexml'
 require 'active_support/core_ext/time/conversions'
-- 
cgit v1.2.3


From 94058c689a1ad74ccc6df2732c360fcdea267cae Mon Sep 17 00:00:00 2001
From: Joshua Peek <josh@joshpeek.com>
Date: Mon, 9 Nov 2009 22:44:28 -0600
Subject: Remove automatic rubygems loading from AS test runner

---
 activesupport/test/abstract_unit.rb | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index f390c66838..8967b54537 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -7,16 +7,8 @@ rescue LoadError
   $:.unshift("#{root}/activerecord/lib")
 end
 
-
 require 'test/unit'
-
-begin
-  require 'mocha'
-rescue LoadError
-  $stderr.puts 'Loading rubygems'
-  require 'rubygems'
-  require 'mocha'
-end
+require 'mocha'
 
 ENV['NO_RELOAD'] = '1'
 require 'active_support'
-- 
cgit v1.2.3


From 22b581e04cb13a1a80768c0487490eec3dd85879 Mon Sep 17 00:00:00 2001
From: Joshua Peek <josh@joshpeek.com>
Date: Mon, 9 Nov 2009 22:56:49 -0600
Subject: Always add AS lib/ to path when running its test suite

---
 activesupport/test/abstract_unit.rb | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index 8967b54537..d640c9bc63 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -1,12 +1,12 @@
 ORIG_ARGV = ARGV.dup
-root = File.expand_path('../../..', __FILE__)
+
 begin
-  require "#{root}/vendor/gems/environment"
+  require File.expand_path('../../../vendor/gems/environment', __FILE__)
 rescue LoadError
-  $:.unshift("#{root}/activesupport/lib")
-  $:.unshift("#{root}/activerecord/lib")
 end
 
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+
 require 'test/unit'
 require 'mocha'
 
-- 
cgit v1.2.3


From 11e798ae0f2f46498811282756c9d21df3d4b523 Mon Sep 17 00:00:00 2001
From: Joshua Peek <josh@joshpeek.com>
Date: Mon, 9 Nov 2009 23:28:36 -0600
Subject: Avoid adding component lib/ to load path multiple times

---
 activesupport/test/abstract_unit.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index d640c9bc63..dda139372e 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -5,7 +5,8 @@ begin
 rescue LoadError
 end
 
-$:.unshift(File.dirname(__FILE__) + '/../lib')
+lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
+$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
 
 require 'test/unit'
 require 'mocha'
-- 
cgit v1.2.3


From af44b0764965a9ae1f77290056473b35eac79562 Mon Sep 17 00:00:00 2001
From: David Vrensk <david@vrensk.com>
Date: Sun, 1 Nov 2009 16:46:12 +0100
Subject: Rdoc for changes introduced in e2ed1a1ca, 36058f450.

[#3451 state:committed]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
---
 activesupport/lib/active_support/cache/mem_cache_store.rb | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/cache/mem_cache_store.rb b/activesupport/lib/active_support/cache/mem_cache_store.rb
index bec9de86ed..1b6b820ca4 100644
--- a/activesupport/lib/active_support/cache/mem_cache_store.rb
+++ b/activesupport/lib/active_support/cache/mem_cache_store.rb
@@ -38,6 +38,11 @@ module ActiveSupport
       #
       # If no addresses are specified, then MemCacheStore will connect to
       # localhost port 11211 (the default memcached port).
+      #
+      # Instead of addresses one can pass in a MemCache-like object. For example:
+      #
+      #   require 'memcached' # gem install memcached; uses C bindings to libmemcached
+      #   ActiveSupport::Cache::MemCacheStore.new(Memcached::Rails.new("localhost:11211"))
       def initialize(*addresses)
         if addresses.first.respond_to?(:get)
           @data = addresses.first
-- 
cgit v1.2.3


From c0ebc2149380a59371553765053f55671c737533 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Thu, 12 Nov 2009 16:19:33 -0800
Subject: Test that Array.wrap works with proxy objects and structs

---
 activesupport/test/core_ext/array_ext_test.rb | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

(limited to 'activesupport')

diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb
index 8198b9bd2c..f5f91ddd80 100644
--- a/activesupport/test/core_ext/array_ext_test.rb
+++ b/activesupport/test/core_ext/array_ext_test.rb
@@ -339,6 +339,11 @@ class ArrayWrapperTests < Test::Unit::TestCase
     end
   end
 
+  class Proxy
+    def initialize(target) @target = target end
+    def method_missing(*a) @target.send(*a) end
+  end
+
   def test_array
     ary = %w(foo bar)
     assert_same ary, Array.wrap(ary)
@@ -364,4 +369,19 @@ class ArrayWrapperTests < Test::Unit::TestCase
   def test_object_with_to_ary
     assert_equal ["foo", "bar"], Array.wrap(FakeCollection.new)
   end
+
+  def test_proxy_object
+    p = Proxy.new(Object.new)
+    assert_equal [p], Array.wrap(p)
+  end
+
+  def test_proxy_to_object_with_to_ary
+    p = Proxy.new(FakeCollection.new)
+    assert_equal [p], Array.wrap(p)
+  end
+
+  def test_struct
+    o = Struct.new(:foo).new(123)
+    assert_equal [o], Array.wrap(o)
+  end
 end
-- 
cgit v1.2.3


From f07bcf015e35c400f12bf8274dc9cc4ec38be986 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Thu, 12 Nov 2009 16:31:23 -0800
Subject: Ruby 1.9.2: work around Array allowing method_missing for to_ary

---
 activesupport/lib/active_support/core_ext/array/wrap.rb | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/array/wrap.rb b/activesupport/lib/active_support/core_ext/array/wrap.rb
index 38bb68c1ec..f48d5ce500 100644
--- a/activesupport/lib/active_support/core_ext/array/wrap.rb
+++ b/activesupport/lib/active_support/core_ext/array/wrap.rb
@@ -4,11 +4,10 @@ class Array
   def self.wrap(object)
     if object.nil?
       []
-    # to_a doesn't work correctly with Array() but to_ary always does
-    elsif object.respond_to?(:to_a) && !object.respond_to?(:to_ary)
-      [object]
+    elsif object.respond_to?(:to_ary)
+      object.to_ary
     else
-      Array(object)
+      [object]
     end
   end
 end
-- 
cgit v1.2.3


From 18d497651628c73287f3e808c3807121ad36e278 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Thu, 12 Nov 2009 16:50:55 -0800
Subject: Prefer Array.wrap to Array()

---
 activesupport/lib/active_support/rescuable.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb
index 879662c16c..dd0752b09d 100644
--- a/activesupport/lib/active_support/rescuable.rb
+++ b/activesupport/lib/active_support/rescuable.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
 require 'active_support/core_ext/class/inheritable_attributes'
 require 'active_support/core_ext/proc'
 
@@ -81,7 +82,7 @@ module ActiveSupport
     def handler_for_rescue(exception)
       # We go from right to left because pairs are pushed onto rescue_handlers
       # as rescue_from declarations are found.
-      _, rescuer = Array(rescue_handlers).reverse.detect do |klass_name, handler|
+      _, rescuer = Array.wrap(rescue_handlers).reverse.detect do |klass_name, handler|
         # The purpose of allowing strings in rescue_from is to support the
         # declaration of handler associations for exception classes whose
         # definition is yet unknown.
-- 
cgit v1.2.3


From 0214d337b3b3301f4e1478248b386d43ca6c15e0 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 11:00:18 -0800
Subject: Rescue handlers should never need array wrapping. Bug if so.

---
 activesupport/lib/active_support/rescuable.rb | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/rescuable.rb b/activesupport/lib/active_support/rescuable.rb
index dd0752b09d..f0119f5994 100644
--- a/activesupport/lib/active_support/rescuable.rb
+++ b/activesupport/lib/active_support/rescuable.rb
@@ -1,4 +1,3 @@
-require 'active_support/core_ext/array/wrap'
 require 'active_support/core_ext/class/inheritable_attributes'
 require 'active_support/core_ext/proc'
 
@@ -82,7 +81,7 @@ module ActiveSupport
     def handler_for_rescue(exception)
       # We go from right to left because pairs are pushed onto rescue_handlers
       # as rescue_from declarations are found.
-      _, rescuer = Array.wrap(rescue_handlers).reverse.detect do |klass_name, handler|
+      _, rescuer = rescue_handlers.reverse.detect do |klass_name, handler|
         # The purpose of allowing strings in rescue_from is to support the
         # declaration of handler associations for exception classes whose
         # definition is yet unknown.
-- 
cgit v1.2.3


From 9acc824d96db039486fc493c6f904035fe386967 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 12:15:49 -0800
Subject: Ruby 1.9.2: disallow explicit coercion via method_missing. Only give
 friendly nil errors for Array and Active Record methods.

---
 .../lib/active_support/core_ext/name_error.rb      |  4 +++-
 activesupport/lib/active_support/whiny_nil.rb      | 10 +++++++--
 activesupport/test/core_ext/name_error_test.rb     | 26 +++++++++-------------
 activesupport/test/whiny_nil_test.rb               | 14 +++++++++++-
 4 files changed, 35 insertions(+), 19 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/name_error.rb b/activesupport/lib/active_support/core_ext/name_error.rb
index cd165626c8..e1ebd4f91c 100644
--- a/activesupport/lib/active_support/core_ext/name_error.rb
+++ b/activesupport/lib/active_support/core_ext/name_error.rb
@@ -1,7 +1,9 @@
 class NameError
   # Extract the name of the missing constant from the exception message.
   def missing_name
-    $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
+    if /undefined local variable or method/ !~ message
+      $1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
+    end
   end
 
   # Was this exception raised because the given name was missing?
diff --git a/activesupport/lib/active_support/whiny_nil.rb b/activesupport/lib/active_support/whiny_nil.rb
index 36fe9510ba..c4aaba7ab3 100644
--- a/activesupport/lib/active_support/whiny_nil.rb
+++ b/activesupport/lib/active_support/whiny_nil.rb
@@ -43,7 +43,14 @@ class NilClass
 
   private
     def method_missing(method, *args, &block)
-      raise_nil_warning_for METHOD_CLASS_MAP[method], method, caller
+      # Ruby 1.9.2: disallow explicit coercion via method_missing.
+      if method == :to_ary || method == :to_str
+        super
+      elsif klass = METHOD_CLASS_MAP[method]
+        raise_nil_warning_for klass, method, caller
+      else
+        super
+      end
     end
 
     # Raises a NoMethodError when you attempt to call a method on +nil+.
@@ -55,4 +62,3 @@ class NilClass
       raise NoMethodError, message, with_caller || caller
     end
 end
-
diff --git a/activesupport/test/core_ext/name_error_test.rb b/activesupport/test/core_ext/name_error_test.rb
index 10913e2ade..6352484d04 100644
--- a/activesupport/test/core_ext/name_error_test.rb
+++ b/activesupport/test/core_ext/name_error_test.rb
@@ -3,23 +3,19 @@ require 'active_support/core_ext/name_error'
 
 class NameErrorTest < Test::Unit::TestCase
   def test_name_error_should_set_missing_name
-    begin
-      SomeNameThatNobodyWillUse____Really ? 1 : 0
-      flunk "?!?!"
-    rescue NameError => exc
-      assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
-      assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
-      assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
-    end
+    SomeNameThatNobodyWillUse____Really ? 1 : 0
+    flunk "?!?!"
+  rescue NameError => exc
+    assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
+    assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
+    assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
   end
 
   def test_missing_method_should_ignore_missing_name
-    begin
-      some_method_that_does_not_exist
-      flunk "?!?!"
-    rescue NameError => exc
-      assert_equal nil, exc.missing_name
-      assert ! exc.missing_name?(:Foo)
-    end
+    some_method_that_does_not_exist
+    flunk "?!?!"
+  rescue NameError => exc
+    assert !exc.missing_name?(:Foo)
+    assert_nil exc.missing_name
   end
 end
diff --git a/activesupport/test/whiny_nil_test.rb b/activesupport/test/whiny_nil_test.rb
index 4cb22c41b2..009d97940f 100644
--- a/activesupport/test/whiny_nil_test.rb
+++ b/activesupport/test/whiny_nil_test.rb
@@ -13,7 +13,7 @@ class WhinyNilTest < Test::Unit::TestCase
   def test_unchanged
     nil.method_thats_not_in_whiners
   rescue NoMethodError => nme
-    assert_match(/nil.method_thats_not_in_whiners/, nme.message)
+    assert(nme.message =~ /nil:NilClass/)
   end
 
   def test_active_record
@@ -35,4 +35,16 @@ class WhinyNilTest < Test::Unit::TestCase
   rescue RuntimeError => nme
     assert(!(nme.message =~ /nil:NilClass/))
   end
+
+  def test_no_to_ary_coercion
+    nil.to_ary
+  rescue NoMethodError => nme
+    assert(nme.message =~ /nil:NilClass/)
+  end
+
+  def test_no_to_str_coercion
+    nil.to_str
+  rescue NoMethodError => nme
+    assert(nme.message =~ /nil:NilClass/)
+  end
 end
-- 
cgit v1.2.3


From 2841a14f4b26e093e88cdb6d84c82d120f53ca46 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 12:42:40 -0800
Subject: Ruby 1.9.2: fix broken to_ary expectation

---
 activesupport/test/caching_test.rb | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 6a51ce9402..00e05f76fe 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -30,7 +30,9 @@ class CacheStoreSettingTest < ActiveSupport::TestCase
 
   def test_mem_cache_fragment_cache_store_with_given_mem_cache_like_object
     MemCache.expects(:new).never
-    store = ActiveSupport::Cache.lookup_store :mem_cache_store, stub("memcache", :get => true)
+    memcache = Object.new
+    def memcache.get() true end
+    store = ActiveSupport::Cache.lookup_store :mem_cache_store, memcache
     assert_kind_of(ActiveSupport::Cache::MemCacheStore, store)
   end
 
-- 
cgit v1.2.3


From 7ab78b9ccd1f760960a77b5be9aac0c27212abe2 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 18:57:10 -0800
Subject: CI: slow down brittle notifications tests

---
 activesupport/test/notifications_test.rb | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 9175c8f26e..334496374b 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -75,7 +75,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       1 + 1
     end
 
-    sleep(0.1)
+    sleep 1
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -88,14 +88,14 @@ class NotificationsMainTest < Test::Unit::TestCase
         1 + 1
       end
 
-      sleep(0.1)
+      sleep 1
 
       assert_equal 1, @events.size
       assert_equal :wot, @events.first.name
       assert_equal Hash[:payload => "child"], @events.first.payload
     end
 
-    sleep(0.1)
+    sleep 1
 
     assert_equal 2, @events.size
     assert_equal :awesome, @events.last.name
@@ -108,7 +108,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       raise "OMG"
     end rescue RuntimeError
 
-    sleep(0.1)
+    sleep 1
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -117,7 +117,7 @@ class NotificationsMainTest < Test::Unit::TestCase
 
   def test_event_is_pushed_even_without_block
     ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications")
-    sleep(0.1)
+    sleep 1
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -137,8 +137,9 @@ class NotificationsMainTest < Test::Unit::TestCase
     end
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep 0.1
+    sleep 1
 
+    assert_equal 3, @another.size
     before, during, after = @another.map {|e| e.transaction_id }
     assert_equal before, after
     assert_not_equal before, during
@@ -153,7 +154,7 @@ class NotificationsMainTest < Test::Unit::TestCase
 
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep(0.1)
+    sleep 1
 
     assert_equal 1, @another.size
     assert_equal :cache, @another.first.name
@@ -169,7 +170,7 @@ class NotificationsMainTest < Test::Unit::TestCase
     ActiveSupport::Notifications.instrument(:something){ 0 }
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep(0.1)
+    sleep 1
 
     assert_equal 1, @another.size
     assert_equal :cache, @another.first.name
@@ -186,7 +187,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       ActiveSupport::Notifications.instrument(:value){ i }
     end
 
-    sleep 0.1
+    sleep 1
 
     assert_equal 100, @events.size
     assert_equal :value, @events.first.name
-- 
cgit v1.2.3


From 66fda6b8949cde07966ab098125e1da7969e9468 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 19:28:59 -0800
Subject: Fix duration check for longer sleep

---
 activesupport/test/notifications_test.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 334496374b..466af49931 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -100,7 +100,7 @@ class NotificationsMainTest < Test::Unit::TestCase
     assert_equal 2, @events.size
     assert_equal :awesome, @events.last.name
     assert_equal Hash[:payload => "notifications"], @events.last.payload
-    assert_in_delta 100, @events.last.duration, 70
+    assert_in_delta 1000, @events.last.duration, 70
   end
 
   def test_event_is_pushed_even_if_block_fails
-- 
cgit v1.2.3


From 58c0d31487d158286576b0745a55a0941ed076ad Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Fri, 13 Nov 2009 20:58:38 -0800
Subject: Notifications: queue.drained? for testability in place of brittle
 sleeps

---
 activesupport/lib/active_support/notifications.rb | 16 +++++++--------
 activesupport/test/notifications_test.rb          | 24 +++++++++++++----------
 2 files changed, 21 insertions(+), 19 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 6304f496f5..7a9f76b26a 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -144,27 +144,21 @@ module ActiveSupport
     class LittleFanout
       def initialize
         @listeners = []
-        @stream    = Queue.new
-        Thread.new { consume }
       end
 
       def publish(*args)
-        @stream.push(args)
+        @listeners.each { |l| l.publish(*args) }
       end
 
       def subscribe(pattern=nil, &block)
         @listeners << Listener.new(pattern, &block)
       end
 
-      def consume
-        while args = @stream.shift
-          @listeners.each { |l| l.publish(*args) }
-        end
+      def drained?
+        @listeners.all? &:drained?
       end
 
       class Listener
-        # attr_reader :thread
-
         def initialize(pattern, &block)
           @pattern = pattern
           @subscriber = block
@@ -183,6 +177,10 @@ module ActiveSupport
             @subscriber.call(*args)
           end
         end
+
+        def drained?
+          @queue.size.zero?
+        end
       end
     end
   end
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 466af49931..01106e83e9 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -75,7 +75,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       1 + 1
     end
 
-    sleep 1
+    drain
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -88,19 +88,18 @@ class NotificationsMainTest < Test::Unit::TestCase
         1 + 1
       end
 
-      sleep 1
+      drain
 
       assert_equal 1, @events.size
       assert_equal :wot, @events.first.name
       assert_equal Hash[:payload => "child"], @events.first.payload
     end
 
-    sleep 1
+    drain
 
     assert_equal 2, @events.size
     assert_equal :awesome, @events.last.name
     assert_equal Hash[:payload => "notifications"], @events.last.payload
-    assert_in_delta 1000, @events.last.duration, 70
   end
 
   def test_event_is_pushed_even_if_block_fails
@@ -108,7 +107,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       raise "OMG"
     end rescue RuntimeError
 
-    sleep 1
+    drain
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -117,7 +116,7 @@ class NotificationsMainTest < Test::Unit::TestCase
 
   def test_event_is_pushed_even_without_block
     ActiveSupport::Notifications.instrument(:awesome, :payload => "notifications")
-    sleep 1
+    drain
 
     assert_equal 1, @events.size
     assert_equal :awesome, @events.last.name
@@ -137,7 +136,7 @@ class NotificationsMainTest < Test::Unit::TestCase
     end
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep 1
+    drain
 
     assert_equal 3, @another.size
     before, during, after = @another.map {|e| e.transaction_id }
@@ -154,7 +153,7 @@ class NotificationsMainTest < Test::Unit::TestCase
 
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep 1
+    drain
 
     assert_equal 1, @another.size
     assert_equal :cache, @another.first.name
@@ -170,7 +169,7 @@ class NotificationsMainTest < Test::Unit::TestCase
     ActiveSupport::Notifications.instrument(:something){ 0 }
     ActiveSupport::Notifications.instrument(:cache){ 1 }
 
-    sleep 1
+    drain
 
     assert_equal 1, @another.size
     assert_equal :cache, @another.first.name
@@ -187,7 +186,7 @@ class NotificationsMainTest < Test::Unit::TestCase
       ActiveSupport::Notifications.instrument(:value){ i }
     end
 
-    sleep 1
+    drain
 
     assert_equal 100, @events.size
     assert_equal :value, @events.first.name
@@ -199,4 +198,9 @@ class NotificationsMainTest < Test::Unit::TestCase
     assert_equal 1, @another.first.result
     assert_equal 100, @another.last.result
   end
+
+  private
+    def drain
+      sleep(0.1) until ActiveSupport::Notifications.queue.drained?
+    end
 end
-- 
cgit v1.2.3


From 7eb4f2ecc53831d850682d88634ccf41676e40a2 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 14 Nov 2009 01:13:54 -0800
Subject: Consolidate date & time landscape: require 'active_support/time'

---
 activesupport/lib/active_support/core_ext/date.rb  |  7 -------
 .../lib/active_support/core_ext/date_time.rb       |  5 -----
 activesupport/lib/active_support/core_ext/time.rb  | 10 ----------
 activesupport/lib/active_support/time.rb           | 23 +++++++++++++++++++---
 .../lib/active_support/values/time_zone.rb         |  3 ---
 activesupport/test/core_ext/date_ext_test.rb       |  2 +-
 activesupport/test/core_ext/date_time_ext_test.rb  |  2 +-
 activesupport/test/core_ext/string_ext_test.rb     |  2 +-
 8 files changed, 23 insertions(+), 31 deletions(-)
 delete mode 100644 activesupport/lib/active_support/core_ext/date.rb
 delete mode 100644 activesupport/lib/active_support/core_ext/date_time.rb
 delete mode 100644 activesupport/lib/active_support/core_ext/time.rb

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/date.rb b/activesupport/lib/active_support/core_ext/date.rb
deleted file mode 100644
index 6672129076..0000000000
--- a/activesupport/lib/active_support/core_ext/date.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-require 'date'
-
-require 'active_support/core_ext/date/acts_like'
-require 'active_support/core_ext/date/freeze'
-
-require 'active_support/core_ext/date/calculations'
-require 'active_support/core_ext/date/conversions'
diff --git a/activesupport/lib/active_support/core_ext/date_time.rb b/activesupport/lib/active_support/core_ext/date_time.rb
deleted file mode 100644
index 004fd0ad29..0000000000
--- a/activesupport/lib/active_support/core_ext/date_time.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require 'active_support/core_ext/time'
-require 'active_support/core_ext/date_time/acts_like'
-require 'active_support/core_ext/date_time/calculations'
-require 'active_support/core_ext/date_time/conversions'
-require 'active_support/core_ext/date_time/zones'
diff --git a/activesupport/lib/active_support/core_ext/time.rb b/activesupport/lib/active_support/core_ext/time.rb
deleted file mode 100644
index b28f7f1a32..0000000000
--- a/activesupport/lib/active_support/core_ext/time.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'date'
-require 'time'
-
-require 'active_support/core_ext/time/publicize_conversion_methods'
-require 'active_support/core_ext/time/marshal_with_utc_flag'
-
-require 'active_support/core_ext/time/acts_like'
-require 'active_support/core_ext/time/calculations'
-require 'active_support/core_ext/time/conversions'
-require 'active_support/core_ext/time/zones'
diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb
index d36a683601..1362f6997c 100644
--- a/activesupport/lib/active_support/time.rb
+++ b/activesupport/lib/active_support/time.rb
@@ -1,7 +1,4 @@
 require 'active_support'
-require 'active_support/core_ext/time'
-require 'active_support/core_ext/date'
-require 'active_support/core_ext/date_time'
 
 module ActiveSupport
   autoload :Duration, 'active_support/duration'
@@ -12,3 +9,23 @@ module ActiveSupport
     [Duration, TimeWithZone, TimeZone]
   end
 end
+
+require 'date'
+require 'time'
+
+require 'active_support/core_ext/time/publicize_conversion_methods'
+require 'active_support/core_ext/time/marshal_with_utc_flag'
+require 'active_support/core_ext/time/acts_like'
+require 'active_support/core_ext/time/calculations'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/time/zones'
+
+require 'active_support/core_ext/date/acts_like'
+require 'active_support/core_ext/date/freeze'
+require 'active_support/core_ext/date/calculations'
+require 'active_support/core_ext/date/conversions'
+
+require 'active_support/core_ext/date_time/acts_like'
+require 'active_support/core_ext/date_time/calculations'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/date_time/zones'
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index e7583bef1b..cbb8e890ae 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -1,7 +1,4 @@
 require 'active_support/core_ext/object/blank'
-require 'active_support/core_ext/time'
-require 'active_support/core_ext/date'
-require 'active_support/core_ext/date_time'
 
 # The TimeZone class serves as a wrapper around TZInfo::Timezone instances. It allows us to do the following:
 #
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index 18422d68bc..23c9bc7fb1 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -1,5 +1,5 @@
 require 'abstract_unit'
-require 'active_support/core_ext/date'
+require 'active_support/time'
 
 class DateExtCalculationsTest < Test::Unit::TestCase
   def test_to_s
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index a7b179b2be..4341ead488 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -1,5 +1,5 @@
 require 'abstract_unit'
-require 'active_support/core_ext/date_time'
+require 'active_support/time'
 
 class DateTimeExtCalculationsTest < Test::Unit::TestCase
   def test_to_s
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index 1e8a1c4f08..56ed296dac 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -4,7 +4,7 @@ require 'abstract_unit'
 require 'inflector_test_cases'
 
 require 'active_support/core_ext/string'
-require 'active_support/core_ext/time'
+require 'active_support/time'
 require 'active_support/core_ext/kernel/reporting'
 
 class StringInflectionsTest < Test::Unit::TestCase
-- 
cgit v1.2.3


From 61843595eaa58fc3c7f30043f2e9d84e2ef2b401 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 14 Nov 2009 02:14:43 -0800
Subject: No need for test stub

---
 activesupport/test/i18n_test.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/test/i18n_test.rb b/activesupport/test/i18n_test.rb
index 9868f1e87d..dfcd4f822d 100644
--- a/activesupport/test/i18n_test.rb
+++ b/activesupport/test/i18n_test.rb
@@ -9,8 +9,8 @@ class I18nTest < Test::Unit::TestCase
   end
   
   def test_time_zone_localization_with_default_format
-    Time.zone.stubs(:now).returns Time.local(2000)
-    assert_equal Time.zone.now.strftime("%a, %d %b %Y %H:%M:%S %z"), I18n.localize(Time.zone.now)
+    now = Time.local(2000)
+    assert_equal now.strftime("%a, %d %b %Y %H:%M:%S %z"), I18n.localize(now)
   end
   
   def test_date_localization_should_use_default_format
-- 
cgit v1.2.3


From 74e1ff9dc2ebd86c783a274710e2f762059e818b Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 14 Nov 2009 03:32:35 -0800
Subject: Loosen optional gem deps from ~> to >=

---
 activesupport/lib/active_support/vendor.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/vendor.rb b/activesupport/lib/active_support/vendor.rb
index 4a711b7e25..eb5080888c 100644
--- a/activesupport/lib/active_support/vendor.rb
+++ b/activesupport/lib/active_support/vendor.rb
@@ -9,7 +9,7 @@ end
   unless ActiveSupport.requirable? lib
     # Try to activate a gem ~> satisfying the requested version first.
     begin
-      gem lib, "~> #{version}"
+      gem lib, ">= #{version}"
       # Use the vendored lib if the gem's missing or we aren't using RubyGems.
     rescue LoadError, NoMethodError
       # There could be symlinks
-- 
cgit v1.2.3


From bc1538e9951847dd4d1d7e37816d91b791862a0c Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 14 Nov 2009 11:37:06 -0800
Subject: Repair time dependencies

---
 activesupport/lib/active_support/core_ext/date/conversions.rb | 3 ---
 activesupport/lib/active_support/json/encoding.rb             | 2 +-
 activesupport/lib/active_support/time.rb                      | 3 +++
 activesupport/lib/active_support/time_with_zone.rb            | 8 --------
 activesupport/test/core_ext/range_ext_test.rb                 | 2 +-
 activesupport/test/json/decoding_test.rb                      | 1 +
 activesupport/test/message_encryptor_test.rb                  | 1 +
 activesupport/test/message_verifier_test.rb                   | 2 ++
 8 files changed, 9 insertions(+), 13 deletions(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index b41ad5b686..f6c870035b 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -1,7 +1,4 @@
 require 'active_support/inflector'
-require 'active_support/core_ext/time/conversions'
-require 'active_support/core_ext/date_time/conversions'
-require 'active_support/values/time_zone'
 
 class Date
   DATE_FORMATS = {
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 8e8f9022c1..3c15056c41 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -6,7 +6,7 @@ require 'active_support/core_ext/module/delegation'
 require 'active_support/core_ext/object/instance_variables'
 require 'active_support/deprecation'
 
-require 'active_support/time_with_zone'
+require 'active_support/time'
 
 # Hack to load json gem first so we can overwrite its to_json.
 begin
diff --git a/activesupport/lib/active_support/time.rb b/activesupport/lib/active_support/time.rb
index 1362f6997c..0f421421d0 100644
--- a/activesupport/lib/active_support/time.rb
+++ b/activesupport/lib/active_support/time.rb
@@ -29,3 +29,6 @@ require 'active_support/core_ext/date_time/acts_like'
 require 'active_support/core_ext/date_time/calculations'
 require 'active_support/core_ext/date_time/conversions'
 require 'active_support/core_ext/date_time/zones'
+
+require 'active_support/core_ext/integer/time'
+require 'active_support/core_ext/numeric/time'
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index a64128e49e..8cd5c1de63 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -1,11 +1,3 @@
-require 'active_support/duration'
-require 'active_support/values/time_zone'
-require 'active_support/core_ext/numeric/time'
-require 'active_support/core_ext/integer/time'
-require 'active_support/core_ext/time/conversions'
-require 'active_support/core_ext/date/conversions'
-require 'active_support/core_ext/date_time/conversions'
-
 module ActiveSupport
   # A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are
   # limited to UTC and the system's <tt>ENV['TZ']</tt> zone.
diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb
index 2565c56b8a..5701eeef28 100644
--- a/activesupport/test/core_ext/range_ext_test.rb
+++ b/activesupport/test/core_ext/range_ext_test.rb
@@ -1,6 +1,6 @@
 require 'abstract_unit'
+require 'active_support/time'
 require 'active_support/core_ext/range'
-require 'active_support/core_ext/date/conversions'
 
 class RangeTest < Test::Unit::TestCase
   def test_to_s_from_dates
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index 7b5a4d0416..8fcb16abfb 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -1,6 +1,7 @@
 # encoding: UTF-8
 require 'abstract_unit'
 require 'active_support/json'
+require 'active_support/time'
 require 'active_support/core_ext/kernel/reporting'
 
 class TestJSONDecoding < ActiveSupport::TestCase
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index ed3461571a..5c2b44f188 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -1,4 +1,5 @@
 require 'abstract_unit'
+require 'active_support/time'
 
 class MessageEncryptorTest < Test::Unit::TestCase
   def setup
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index ef300e4e26..714a3b3a39 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -7,6 +7,8 @@ rescue LoadError, NameError
   $stderr.puts "Skipping MessageVerifier test: broken OpenSSL install"
 else
 
+require 'active_support/time'
+
 class MessageVerifierTest < Test::Unit::TestCase
   def setup
     @verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
-- 
cgit v1.2.3


From cc011bc2bef98bf8b1dc78351f243af7ad641269 Mon Sep 17 00:00:00 2001
From: Yehuda Katz <wycats@Yehuda-Katz.local>
Date: Sat, 14 Nov 2009 19:33:58 -0800
Subject: Add TimeZone dependency

---
 activesupport/lib/active_support/time_with_zone.rb | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 8cd5c1de63..8304f6c434 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -1,3 +1,5 @@
+require "active_support/values/time_zone"
+
 module ActiveSupport
   # A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are
   # limited to UTC and the system's <tt>ENV['TZ']</tt> zone.
-- 
cgit v1.2.3


From 4403dfac6ce876c7ffb7a450b2249864c7a17cb7 Mon Sep 17 00:00:00 2001
From: Jeremy Kemper <jeremy@bitsweat.net>
Date: Sat, 14 Nov 2009 02:00:04 -0800
Subject: Check whether another lib has implemented ruby 1.9 string interp
 syntax

---
 activesupport/lib/active_support/core_ext/string/interpolation.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'activesupport')

diff --git a/activesupport/lib/active_support/core_ext/string/interpolation.rb b/activesupport/lib/active_support/core_ext/string/interpolation.rb
index 41a061c1a4..2048d35091 100644
--- a/activesupport/lib/active_support/core_ext/string/interpolation.rb
+++ b/activesupport/lib/active_support/core_ext/string/interpolation.rb
@@ -5,7 +5,7 @@
   You may redistribute it and/or modify it under the same license terms as Ruby.
 =end
 
-if RUBY_VERSION < '1.9'
+if RUBY_VERSION < '1.9' && !"".respond_to?(:interpolate_without_ruby_19_syntax)
 
   # KeyError is raised by String#% when the string contains a named placeholder
   # that is not contained in the given arguments hash. Ruby 1.9 includes and
-- 
cgit v1.2.3