require 'mail'
require 'action_mailer/collector'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/anonymous'
require 'action_mailer/log_subscriber'

module ActionMailer
  # Action Mailer allows you to send email from your application using a mailer model and views.
  #
  # = Mailer Models
  #
  # To use Action Mailer, you need to create a mailer model.
  #
  #   $ rails generate mailer Notifier
  #
  # The generated model inherits from <tt>ActionMailer::Base</tt>. A mailer model defines methods
  # used to generate an email message. In these methods, you can setup variables to be used in
  # the mailer views, options on the mail itself such as the <tt>:from</tt> address, and attachments.
  #
  #   class Notifier < ActionMailer::Base
  #     default from: 'no-reply@example.com',
  #             return_path: 'system@example.com'
  #
  #     def welcome(recipient)
  #       @account = recipient
  #       mail(to: recipient.email_address_with_name,
  #            bcc: ["bcc@example.com", "Order Watcher <watcher@example.com>"])
  #     end
  #   end
  #
  # Within the mailer method, you have access to the following methods:
  #
  # * <tt>attachments[]=</tt> - Allows you to add attachments to your email in an intuitive
  #   manner; <tt>attachments['filename.png'] = File.read('path/to/filename.png')</tt>
  #
  # * <tt>attachments.inline[]=</tt> - Allows you to add an inline attachment to your email
  #   in the same manner as <tt>attachments[]=</tt>
  #
  # * <tt>headers[]=</tt> - Allows you to specify any header field in your email such
  #   as <tt>headers['X-No-Spam'] = 'True'</tt>. Note, while most fields like <tt>To:</tt>
  #   <tt>From:</tt> can only appear once in an email header, other fields like <tt>X-Anything</tt>
  #   can appear multiple times. If you want to change a field that can appear multiple times,
  #   you need to set it to nil first so that Mail knows you are replacing it and not adding
  #   another field of the same name.
  #
  # * <tt>headers(hash)</tt> - Allows you to specify multiple headers in your email such
  #   as <tt>headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})</tt>
  #
  # * <tt>mail</tt> - Allows you to specify email to be sent.
  #
  # The hash passed to the mail method allows you to specify any header that a Mail::Message
  # will accept (any valid Email header including optional fields).
  #
  # The mail method, if not passed a block, will inspect your views and send all the views with
  # the same name as the method, so the above action would send the +welcome.text.erb+ view
  # file as well as the +welcome.text.html.erb+ view file in a +multipart/alternative+ email.
  #
  # If you want to explicitly render only certain templates, pass a block:
  #
  #   mail(to: user.email) do |format|
  #     format.text
  #     format.html
  #   end
  #
  # The block syntax is also useful in providing information specific to a part:
  #
  #   mail(to: user.email) do |format|
  #     format.text(content_transfer_encoding: "base64")
  #     format.html
  #   end
  #
  # Or even to render a special view:
  #
  #   mail(to: user.email) do |format|
  #     format.text
  #     format.html { render "some_other_template" }
  #   end
  #
  # = Mailer views
  #
  # Like Action Controller, each mailer class has a corresponding view directory in which each
  # method of the class looks for a template with its name.
  #
  # To define a template to be used with a mailing, create an <tt>.erb</tt> file with the same
  # name as the method in your mailer model. For example, in the mailer defined above, the template at
  # <tt>app/views/notifier/welcome.text.erb</tt> would be used to generate the email.
  #
  # Variables defined in the model are accessible as instance variables in the view.
  #
  # Emails by default are sent in plain text, so a sample view for our model example might look like this:
  #
  #   Hi <%= @account.name %>,
  #   Thanks for joining our service! Please check back often.
  #
  # You can even use Action Pack helpers in these views. For example:
  #
  #   You got a new note!
  #   <%= truncate(@note.body, length: 25) %>
  #
  # If you need to access the subject, from or the recipients in the view, you can do that through message object:
  #
  #   You got a new note from <%= message.from %>!
  #   <%= truncate(@note.body, length: 25) %>
  #
  #
  # = Generating URLs
  #
  # URLs can be generated in mailer views using <tt>url_for</tt> or named routes. Unlike controllers from
  # Action Pack, the mailer instance doesn't have any context about the incoming request, so you'll need
  # to provide all of the details needed to generate a URL.
  #
  # When using <tt>url_for</tt> you'll need to provide the <tt>:host</tt>, <tt>:controller</tt>, and <tt>:action</tt>:
  #
  #   <%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>
  #
  # When using named routes you only need to supply the <tt>:host</tt>:
  #
  #   <%= users_url(host: "example.com") %>
  #
  # You should use the <tt>named_route_url</tt> style (which generates absolute URLs) and avoid using the
  # <tt>named_route_path</tt> style (which generates relative URLs), since clients reading the mail will
  # have no concept of a current URL from which to determine a relative path.
  #
  # It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt>
  # option as a configuration option in <tt>config/application.rb</tt>:
  #
  #   config.action_mailer.default_url_options = { host: "example.com" }
  #
  # When you decide to set a default <tt>:host</tt> for your mailers, then you need to make sure to use the
  # <tt>only_path: false</tt> option when using <tt>url_for</tt>. Since the <tt>url_for</tt> view helper
  # will generate relative URLs by default when a <tt>:host</tt> option isn't explicitly provided, passing
  # <tt>only_path: false</tt> will ensure that absolute URLs are generated.
  #
  # = Sending mail
  #
  # Once a mailer action and template are defined, you can deliver your message or create it and save it
  # for delivery later:
  #
  #   Notifier.welcome(david).deliver # sends the email
  #   mail = Notifier.welcome(david)  # => a Mail::Message object
  #   mail.deliver                    # sends the email
  #
  # You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
  #
  # = Multipart Emails
  #
  # Multipart messages can also be used implicitly because Action Mailer will automatically detect and use
  # multipart templates, where each template is named after the name of the action, followed by the content
  # type. Each such detected template will be added as a separate part to the message.
  #
  # For example, if the following templates exist:
  # * signup_notification.text.erb
  # * signup_notification.text.html.erb
  # * signup_notification.text.xml.builder
  # * signup_notification.text.yaml.erb
  #
  # Each would be rendered and added as a separate part to the message, with the corresponding content
  # type. The content type for the entire message is automatically set to <tt>multipart/alternative</tt>,
  # which indicates that the email contains multiple different representations of the same email
  # body. The same instance variables defined in the action are passed to all email templates.
  #
  # Implicit template rendering is not performed if any attachments or parts have been added to the email.
  # This means that you'll have to manually add each part to the email and set the content type of the email
  # to <tt>multipart/alternative</tt>.
  #
  # = Attachments
  #
  # Sending attachment in emails is easy:
  #
  #   class ApplicationMailer < ActionMailer::Base
  #     def welcome(recipient)
  #       attachments['free_book.pdf'] = File.read('path/to/file.pdf')
  #       mail(to: recipient, subject: "New account information")
  #     end
  #   end
  #
  # Which will (if it had both a <tt>welcome.text.erb</tt> and <tt>welcome.text.html.erb</tt>
  # template in the view directory), send a complete <tt>multipart/mixed</tt> email with two parts,
  # the first part being a <tt>multipart/alternative</tt> with the text and HTML email parts inside,
  # and the second being a <tt>application/pdf</tt> with a Base64 encoded copy of the file.pdf book
  # with the filename +free_book.pdf+.
  #
  # If you need to send attachments with no content, you need to create an empty view for it,
  # or add an empty body parameter like this:
  #
  #     class ApplicationMailer < ActionMailer::Base
  #       def welcome(recipient)
  #         attachments['free_book.pdf'] = File.read('path/to/file.pdf')
  #         mail(to: recipient, subject: "New account information", body: "")
  #       end
  #     end
  #
  # = Inline Attachments
  #
  # You can also specify that a file should be displayed inline with other HTML. This is useful
  # if you want to display a corporate logo or a photo.
  #
  #   class ApplicationMailer < ActionMailer::Base
  #     def welcome(recipient)
  #       attachments.inline['photo.png'] = File.read('path/to/photo.png')
  #       mail(to: recipient, subject: "Here is what we look like")
  #     end
  #   end
  #
  # And then to reference the image in the view, you create a <tt>welcome.html.erb</tt> file and
  # make a call to +image_tag+ passing in the attachment you want to display and then call
  # +url+ on the attachment to get the relative content id path for the image source:
  #
  #   <h1>Please Don't Cringe</h1>
  #
  #   <%= image_tag attachments['photo.png'].url -%>
  #
  # As we are using Action View's +image_tag+ method, you can pass in any other options you want:
  #
  #   <h1>Please Don't Cringe</h1>
  #
  #   <%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
  #
  # = Observing and Intercepting Mails
  #
  # Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to
  # register classes that are called during the mail delivery life cycle.
  #
  # An observer class must implement the <tt>:delivered_email(message)</tt> method which will be
  # called once for every email sent after the email has been sent.
  #
  # An interceptor class must implement the <tt>:delivering_email(message)</tt> method which will be
  # called before the email is sent, allowing you to make modifications to the email before it hits
  # the delivery agents. Your class should make any needed modifications directly to the passed
  # in Mail::Message instance.
  #
  # = Default Hash
  #
  # Action Mailer provides some intelligent defaults for your emails, these are usually specified in a
  # default method inside the class definition:
  #
  #   class Notifier < ActionMailer::Base
  #     default sender: 'system@example.com'
  #   end
  #
  # You can pass in any header value that a <tt>Mail::Message</tt> accepts. Out of the box,
  # <tt>ActionMailer::Base</tt> sets the following:
  #
  # * <tt>mime_version: "1.0"</tt>
  # * <tt>charset:      "UTF-8",</tt>
  # * <tt>content_type: "text/plain",</tt>
  # * <tt>parts_order:  [ "text/plain", "text/enriched", "text/html" ]</tt>
  #
  # <tt>parts_order</tt> and <tt>charset</tt> are not actually valid <tt>Mail::Message</tt> header fields,
  # but Action Mailer translates them appropriately and sets the correct values.
  #
  # As you can pass in any header, you need to either quote the header as a string, or pass it in as
  # an underscored symbol, so the following will work:
  #
  #   class Notifier < ActionMailer::Base
  #     default 'Content-Transfer-Encoding' => '7bit',
  #             content_description: 'This is a description'
  #   end
  #
  # Finally, Action Mailer also supports passing <tt>Proc</tt> objects into the default hash, so you
  # can define methods that evaluate as the message is being generated:
  #
  #   class Notifier < ActionMailer::Base
  #     default 'X-Special-Header' => Proc.new { my_method }
  #
  #     private
  #
  #       def my_method
  #         'some complex call'
  #       end
  #   end
  #
  # Note that the proc is evaluated right at the start of the mail message generation, so if you
  # set something in the defaults using a proc, and then set the same thing inside of your
  # mailer method, it will get over written by the mailer method.
  #
  # It is also possible to set these default options that will be used in all mailers through
  # the <tt>default_options=</tt> configuration in <tt>config/application.rb</tt>:
  #
  #    config.action_mailer.default_options = { from: "no-reply@example.org" }
  #
  # = Callbacks
  #
  # You can specify callbacks using before_action and after_action for configuring your messages.
  # This may be useful, for example, when you want to add default inline attachments for all
  # messages sent out by a certain mailer class:
  #
  #   class Notifier < ActionMailer::Base
  #     before_action :add_inline_attachment!
  #
  #     def welcome
  #       mail
  #     end
  #
  #     private
  #
  #       def add_inline_attachment!
  #         attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
  #       end
  #   end
  #
  # Callbacks in ActionMailer are implemented using AbstractController::Callbacks, so you
  # can define and configure callbacks in the same manner that you would use callbacks in
  # classes that inherit from ActionController::Base.
  #
  # Note that unless you have a specific reason to do so, you should prefer using before_action
  # rather than after_action in your ActionMailer classes so that headers are parsed properly.
  #
  # = Configuration options
  #
  # These options are specified on the class level, like
  # <tt>ActionMailer::Base.raise_delivery_errors = true</tt>
  #
  # * <tt>default_options</tt> - You can pass this in at a class level as well as within the class itself as
  #   per the above section.
  #
  # * <tt>logger</tt> - the logger is used for generating information on the mailing run if available.
  #   Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
  #
  # * <tt>smtp_settings</tt> - Allows detailed configuration for <tt>:smtp</tt> delivery method:
  #   * <tt>:address</tt> - Allows you to use a remote mail server. Just change it from its default
  #     "localhost" setting.
  #   * <tt>:port</tt> - On the off chance that your mail server doesn't run on port 25, you can change it.
  #   * <tt>:domain</tt> - If you need to specify a HELO domain, you can do it here.
  #   * <tt>:user_name</tt> - If your mail server requires authentication, set the username in this setting.
  #   * <tt>:password</tt> - If your mail server requires authentication, set the password in this setting.
  #   * <tt>:authentication</tt> - If your mail server requires authentication, you need to specify the
  #     authentication type here.
  #     This is a symbol and one of <tt>:plain</tt> (will send the password in the clear), <tt>:login</tt> (will
  #     send password Base64 encoded) or <tt>:cram_md5</tt> (combines a Challenge/Response mechanism to exchange
  #     information and a cryptographic Message Digest 5 algorithm to hash important information)
  #   * <tt>:enable_starttls_auto</tt> - When set to true, detects if STARTTLS is enabled in your SMTP server
  #     and starts to use it.
  #   * <tt>:openssl_verify_mode</tt> - When using TLS, you can set how OpenSSL checks the certificate. This is
  #     really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
  #     of an OpenSSL verify constant ('none', 'peer', 'client_once','fail_if_no_peer_cert') or directly the
  #     constant  (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER,...).
  #
  # * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
  #   * <tt>:location</tt> - The location of the sendmail executable. Defaults to <tt>/usr/sbin/sendmail</tt>.
  #   * <tt>:arguments</tt> - The command line arguments. Defaults to <tt>-i -t</tt> with <tt>-f sender@address</tt>
  #     added automatically before the message is sent.
  #
  # * <tt>file_settings</tt> - Allows you to override options for the <tt>:file</tt> delivery method.
  #   * <tt>:location</tt> - The directory into which emails will be written. Defaults to the application
  #     <tt>tmp/mails</tt>.
  #
  # * <tt>raise_delivery_errors</tt> - Whether or not errors should be raised if the email fails to be delivered.
  #
  # * <tt>delivery_method</tt> - Defines a delivery method. Possible values are <tt>:smtp</tt> (default),
  #   <tt>:sendmail</tt>, <tt>:test</tt>, and <tt>:file</tt>. Or you may provide a custom delivery method
  #   object e.g. MyOwnDeliveryMethodClass. See the Mail gem documentation on the interface you need to
  #   implement for a custom delivery agent.
  #
  # * <tt>perform_deliveries</tt> - Determines whether emails are actually sent from Action Mailer when you
  #   call <tt>.deliver</tt> on an mail message or on an Action Mailer method. This is on by default but can
  #   be turned off to aid in functional testing.
  #
  # * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with
  #   <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
  class Base < AbstractController::Base
    include DeliveryMethods
    abstract!

    include AbstractController::Logger
    include AbstractController::Rendering
    include AbstractController::Layouts
    include AbstractController::Helpers
    include AbstractController::Translation
    include AbstractController::AssetPaths
    include AbstractController::Callbacks

    self.protected_instance_variables = [:@_action_has_layout]

    helper ActionMailer::MailHelper

    private_class_method :new #:nodoc:

    class_attribute :default_params
    self.default_params = {
      mime_version: "1.0",
      charset:      "UTF-8",
      content_type: "text/plain",
      parts_order:  [ "text/plain", "text/enriched", "text/html" ]
    }.freeze

    class << self
      # Register one or more Observers which will be notified when mail is delivered.
      def register_observers(*observers)
        observers.flatten.compact.each { |observer| register_observer(observer) }
      end

      # Register one or more Interceptors which will be called before mail is sent.
      def register_interceptors(*interceptors)
        interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
      end

      # Register an Observer which will be notified when mail is delivered.
      # Either a class or a string can be passed in as the Observer. If a string is passed in
      # it will be <tt>constantize</tt>d.
      def register_observer(observer)
        delivery_observer = (observer.is_a?(String) ? observer.constantize : observer)
        Mail.register_observer(delivery_observer)
      end

      # Register an Interceptor which will be called before mail is sent.
      # Either a class or a string can be passed in as the Interceptor. If a string is passed in
      # it will be <tt>constantize</tt>d.
      def register_interceptor(interceptor)
        delivery_interceptor = (interceptor.is_a?(String) ? interceptor.constantize : interceptor)
        Mail.register_interceptor(delivery_interceptor)
      end

      def mailer_name
        @mailer_name ||= anonymous? ? "anonymous" : name.underscore
      end
      attr_writer :mailer_name
      alias :controller_path :mailer_name

      def default(value = nil)
        self.default_params = default_params.merge(value).freeze if value
        default_params
      end
      # Allows to set defaults through app configuration:
      #
      #    config.action_mailer.default_options = { from: "no-reply@example.org" }
      alias :default_options= :default

      # Receives a raw email, parses it into an email object, decodes it,
      # instantiates a new mailer, and passes the email object to the mailer
      # object's +receive+ method. If you want your mailer to be able to
      # process incoming messages, you'll need to implement a +receive+
      # method that accepts the raw email string as a parameter:
      #
      #   class MyMailer < ActionMailer::Base
      #     def receive(mail)
      #       ...
      #     end
      #   end
      def receive(raw_mail)
        ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
          mail = Mail.new(raw_mail)
          set_payload_for_mail(payload, mail)
          new.receive(mail)
        end
      end

      # Wraps an email delivery inside of Active Support Notifications instrumentation. This
      # method is actually called by the <tt>Mail::Message</tt> object itself through a callback
      # when you call <tt>:deliver</tt> on the Mail::Message, calling +deliver_mail+ directly
      # and passing a Mail::Message will do nothing except tell the logger you sent the email.
      def deliver_mail(mail) #:nodoc:
        ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload|
          set_payload_for_mail(payload, mail)
          yield # Let Mail do the delivery actions
        end
      end

      def respond_to?(method, include_private = false) #:nodoc:
        super || action_methods.include?(method.to_s)
      end

    protected

      def set_payload_for_mail(payload, mail) #:nodoc:
        payload[:mailer]     = name
        payload[:message_id] = mail.message_id
        payload[:subject]    = mail.subject
        payload[:to]         = mail.to
        payload[:from]       = mail.from
        payload[:bcc]        = mail.bcc if mail.bcc.present?
        payload[:cc]         = mail.cc  if mail.cc.present?
        payload[:date]       = mail.date
        payload[:mail]       = mail.encoded
      end

      def method_missing(method_name, *args)
        if respond_to?(method_name)
          new(method_name, *args).message
        else
          super
        end
      end
    end

    attr_internal :message

    # Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
    # will be initialized according to the named method. If not, the mailer will
    # remain uninitialized (useful when you only need to invoke the "receive"
    # method, for instance).
    def initialize(method_name=nil, *args)
      super()
      @_mail_was_called = false
      @_message = Mail.new
      process(method_name, *args) if method_name
    end

    def process(*args) #:nodoc:
      lookup_context.skip_default_locale!

      super
      @_message = NullMail.new unless @_mail_was_called
    end

    class NullMail #:nodoc:
      def body; '' end

      def method_missing(*args)
        nil
      end
    end

    def mailer_name
      self.class.mailer_name
    end

    # Allows you to pass random and unusual headers to the new <tt>Mail::Message</tt> object
    # which will add them to itself.
    #
    #   headers['X-Special-Domain-Specific-Header'] = "SecretValue"
    #
    # You can also pass a hash into headers of header field names and values, which
    # will then be set on the Mail::Message object:
    #
    #   headers 'X-Special-Domain-Specific-Header' => "SecretValue",
    #           'In-Reply-To' => incoming.message_id
    #
    # The resulting Mail::Message will have the following in its header:
    #
    #   X-Special-Domain-Specific-Header: SecretValue
    def headers(args = nil)
      if args
        @_message.headers(args)
      else
        @_message
      end
    end

    # Allows you to add attachments to an email, like so:
    #
    #  mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
    #
    # If you do this, then Mail will take the file name and work out the mime type
    # set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
    # base64 encode the contents of the attachment all for you.
    #
    # You can also specify overrides if you want by passing a hash instead of a string:
    #
    #  mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip',
    #                                      content: File.read('/path/to/filename.jpg')}
    #
    # If you want to use a different encoding than Base64, you can pass an encoding in,
    # but then it is up to you to pass in the content pre-encoded, and don't expect
    # Mail to know how to decode this data:
    #
    #  file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
    #  mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip',
    #                                      encoding: 'SpecialEncoding',
    #                                      content: file_content }
    #
    # You can also search for specific attachments:
    #
    #  # By Filename
    #  mail.attachments['filename.jpg']   # => Mail::Part object or nil
    #
    #  # or by index
    #  mail.attachments[0]                # => Mail::Part (first attachment)
    #
    def attachments
      @_message.attachments
    end

    # The main method that creates the message and renders the email templates. There are
    # two ways to call this method, with a block, or without a block.
    #
    # Both methods accept a headers hash. This hash allows you to specify the most used headers
    # in an email message, these are:
    #
    # * <tt>:subject</tt> - The subject of the message, if this is omitted, Action Mailer will
    #   ask the Rails I18n class for a translated <tt>:subject</tt> in the scope of
    #   <tt>[mailer_scope, action_name]</tt> or if this is missing, will translate the
    #   humanized version of the <tt>action_name</tt>
    # * <tt>:to</tt> - Who the message is destined for, can be a string of addresses, or an array
    #   of addresses.
    # * <tt>:from</tt> - Who the message is from
    # * <tt>:cc</tt> - Who you would like to Carbon-Copy on this email, can be a string of addresses,
    #   or an array of addresses.
    # * <tt>:bcc</tt> - Who you would like to Blind-Carbon-Copy on this email, can be a string of
    #   addresses, or an array of addresses.
    # * <tt>:reply_to</tt> - Who to set the Reply-To header of the email to.
    # * <tt>:date</tt> - The date to say the email was sent on.
    #
    # You can set default values for any of the above headers (except :date) by using the <tt>default</tt>
    # class method:
    #
    #  class Notifier < ActionMailer::Base
    #    self.default from: 'no-reply@test.lindsaar.net',
    #                 bcc: 'email_logger@test.lindsaar.net',
    #                 reply_to: 'bounces@test.lindsaar.net'
    #  end
    #
    # If you need other headers not listed above, you can either pass them in
    # as part of the headers hash or use the <tt>headers['name'] = value</tt>
    # method.
    #
    # When a <tt>:return_path</tt> is specified as header, that value will be used as the 'envelope from'
    # address for the Mail message. Setting this is useful when you want delivery notifications
    # sent to a different address than the one in <tt>:from</tt>. Mail will actually use the
    # <tt>:return_path</tt> in preference to the <tt>:sender</tt> in preference to the <tt>:from</tt>
    # field for the 'envelope from' value.
    #
    # If you do not pass a block to the +mail+ method, it will find all templates in the
    # view paths using by default the mailer name and the method name that it is being
    # called from, it will then create parts for each of these templates intelligently,
    # making educated guesses on correct content type and sequence, and return a fully
    # prepared Mail::Message ready to call <tt>:deliver</tt> on to send.
    #
    # For example:
    #
    #   class Notifier < ActionMailer::Base
    #     default from: 'no-reply@test.lindsaar.net',
    #
    #     def welcome
    #       mail(to: 'mikel@test.lindsaar.net')
    #     end
    #   end
    #
    # Will look for all templates at "app/views/notifier" with name "welcome".
    # If no welcome template exists, it will raise an ActionView::MissingTemplate error.
    #
    # However, those can be customized:
    #
    #   mail(template_path: 'notifications', template_name: 'another')
    #
    # And now it will look for all templates at "app/views/notifications" with name "another".
    #
    # If you do pass a block, you can render specific templates of your choice:
    #
    #   mail(to: 'mikel@test.lindsaar.net') do |format|
    #     format.text
    #     format.html
    #   end
    #
    # You can even render text directly without using a template:
    #
    #   mail(to: 'mikel@test.lindsaar.net') do |format|
    #     format.text { render text: "Hello Mikel!" }
    #     format.html { render text: "<h1>Hello Mikel!</h1>" }
    #   end
    #
    # Which will render a <tt>multipart/alternative</tt> email with <tt>text/plain</tt> and
    # <tt>text/html</tt> parts.
    #
    # The block syntax also allows you to customize the part headers if desired:
    #
    #   mail(to: 'mikel@test.lindsaar.net') do |format|
    #     format.text(content_transfer_encoding: "base64")
    #     format.html
    #   end
    #
    def mail(headers = {}, &block)
      @_mail_was_called = true
      m = @_message

      # At the beginning, do not consider class default for content_type
      content_type = headers[:content_type]

      # Call all the procs (if any)
      class_default = self.class.default
      default_values = class_default.merge(class_default) do |k,v|
        v.respond_to?(:to_proc) ? instance_eval(&v) : v
      end

      # Handle defaults
      headers = headers.reverse_merge(default_values)
      headers[:subject] ||= default_i18n_subject

      # Apply charset at the beginning so all fields are properly quoted
      m.charset = charset = headers[:charset]

      # Set configure delivery behavior
      wrap_delivery_behavior!(headers.delete(:delivery_method),headers.delete(:delivery_method_options))

      # Assign all headers except parts_order, content_type and body
      assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
      assignable.each { |k, v| m[k] = v }

      # Render the templates and blocks
      responses = collect_responses(headers, &block)
      create_parts_from_responses(m, responses)

      # Setup content type, reapply charset and handle parts order
      m.content_type = set_content_type(m, content_type, headers[:content_type])
      m.charset      = charset

      if m.multipart?
        m.body.set_sort_order(headers[:parts_order])
        m.body.sort_parts!
      end

      m
    end

  protected

    def set_content_type(m, user_content_type, class_default)
      params = m.content_type_parameters || {}
      case
      when user_content_type.present?
        user_content_type
      when m.has_attachments?
        if m.attachments.detect { |a| a.inline? }
          ["multipart", "related", params]
        else
          ["multipart", "mixed", params]
        end
      when m.multipart?
        ["multipart", "alternative", params]
      else
        m.content_type || class_default
      end
    end

    # Translates the +subject+ using Rails I18n class under <tt>[mailer_scope, action_name]</tt> scope.
    # If it does not find a translation for the +subject+ under the specified scope it will default to a
    # humanized version of the <tt>action_name</tt>.
    # If the subject has interpolations, you can pass them through the +interpolations+ parameter.
    def default_i18n_subject(interpolations = {})
      mailer_scope = self.class.mailer_name.tr('/', '.')
      I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
    end

    def collect_responses(headers) #:nodoc:
      responses = []

      if block_given?
        collector = ActionMailer::Collector.new(lookup_context) { render(action_name) }
        yield(collector)
        responses = collector.responses
      elsif headers[:body]
        responses << {
          body: headers.delete(:body),
          content_type: self.class.default[:content_type] || "text/plain"
        }
      else
        templates_path = headers.delete(:template_path) || self.class.mailer_name
        templates_name = headers.delete(:template_name) || action_name

        each_template(Array(templates_path), templates_name) do |template|
          self.formats = template.formats

          responses << {
            body: render(template: template),
            content_type: template.type.to_s
          }
        end
      end

      responses
    end

    def each_template(paths, name, &block) #:nodoc:
      templates = lookup_context.find_all(name, paths)
      if templates.empty?
        raise ActionView::MissingTemplate.new(paths, name, paths, false, 'mailer')
      else
        templates.uniq { |t| t.formats }.each(&block)
      end
    end

    def create_parts_from_responses(m, responses) #:nodoc:
      if responses.size == 1 && !m.has_attachments?
        responses[0].each { |k,v| m[k] = v }
      elsif responses.size > 1 && m.has_attachments?
        container = Mail::Part.new
        container.content_type = "multipart/alternative"
        responses.each { |r| insert_part(container, r, m.charset) }
        m.add_part(container)
      else
        responses.each { |r| insert_part(m, r, m.charset) }
      end
    end

    def insert_part(container, response, charset) #:nodoc:
      response[:charset] ||= charset
      part = Mail::Part.new(response)
      container.add_part(part)
    end

    ActiveSupport.run_load_hooks(:action_mailer, self)
  end
end
require 'abstract_controller/collector'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/array/extract_options'

module ActionMailer
  class Collector
    include AbstractController::Collector
    attr_reader :responses

    def initialize(context, &block)
      @context = context
      @responses = []
      @default_render = block
    end

    def any(*args, &block)
      options = args.extract_options!
      raise ArgumentError, "You have to supply at least one format" if args.empty?
      args.each { |type| send(type, options.dup, &block) }
    end
    alias :all :any

    def custom(mime, options = {})
      options.reverse_merge!(content_type: mime.to_s)
      @context.formats = [mime.to_sym]
      options[:body] = block_given? ? yield : @default_render.call
      @responses << options
    end
  end
end
require 'tmpdir'

module ActionMailer
  # This module handles everything related to mail delivery, from registering
  # new delivery methods to configuring the mail object to be sent.
  module DeliveryMethods
    extend ActiveSupport::Concern

    included do
      class_attribute :delivery_methods, :delivery_method

      # Do not make this inheritable, because we always want it to propagate
      cattr_accessor :raise_delivery_errors
      self.raise_delivery_errors = true

      cattr_accessor :perform_deliveries
      self.perform_deliveries = true

      self.delivery_methods = {}.freeze
      self.delivery_method  = :smtp

      add_delivery_method :smtp, Mail::SMTP,
        address:              "localhost",
        port:                 25,
        domain:               'localhost.localdomain',
        user_name:            nil,
        password:             nil,
        authentication:       nil,
        enable_starttls_auto: true

      add_delivery_method :file, Mail::FileDelivery,
        location: defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"

      add_delivery_method :sendmail, Mail::Sendmail,
        location:  '/usr/sbin/sendmail',
        arguments: '-i -t'

      add_delivery_method :test, Mail::TestMailer
    end

    module ClassMethods
      # Provides a list of emails that have been delivered by Mail::TestMailer
      delegate :deliveries, :deliveries=, to: Mail::TestMailer

      # Adds a new delivery method through the given class using the given
      # symbol as alias and the default options supplied.
      #
      #   add_delivery_method :sendmail, Mail::Sendmail,
      #     location:  '/usr/sbin/sendmail',
      #     arguments: '-i -t'
      def add_delivery_method(symbol, klass, default_options={})
        class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
        send(:"#{symbol}_settings=", default_options)
        self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
      end

      def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc:
        method ||= self.delivery_method
        mail.delivery_handler = self

        case method
        when NilClass
          raise "Delivery method cannot be nil"
        when Symbol
          if klass = delivery_methods[method]
            mail.delivery_method(klass,(send(:"#{method}_settings") || {}).merge!(options || {}))
          else
            raise "Invalid delivery method #{method.inspect}"
          end
        else
          mail.delivery_method(method)
        end

        mail.perform_deliveries    = perform_deliveries
        mail.raise_delivery_errors = raise_delivery_errors
      end
    end

    def wrap_delivery_behavior!(*args) # :nodoc:
      self.class.wrap_delivery_behavior(message, *args)
    end
  end
end
module ActionMailer
  class LogSubscriber < ActiveSupport::LogSubscriber
    def deliver(event)
      return unless logger.info?
      recipients = Array(event.payload[:to]).join(', ')
      info("\nSent mail to #{recipients} (#{event.duration.round(1)}ms)")
      debug(event.payload[:mail])
    end

    def receive(event)
      return unless logger.info?
      info("\nReceived mail (#{event.duration.round(1)}ms)")
      debug(event.payload[:mail])
    end

    def logger
      ActionMailer::Base.logger
    end
  end
end

ActionMailer::LogSubscriber.attach_to :action_mailer
module ActionMailer
  module MailHelper
    # Take the text and format it, indented two spaces for each line, and
    # wrapped at 72 columns.
    def block_format(text)
      formatted = text.split(/\n\r?\n/).collect { |paragraph|
        format_paragraph(paragraph)
      }.join("\n\n")

      # Make list points stand on their own line
      formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| "  #{$1} #{$2.strip}\n" }
      formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| "  #{$1} #{$2.strip}\n" }

      formatted
    end

    # Access the mailer instance.
    def mailer
      @_controller
    end

    # Access the message instance.
    def message
      @_message
    end

    # Access the message attachments list.
    def attachments
      @_message.attachments
    end

    # Returns +text+ wrapped at +len+ columns and indented +indent+ spaces.
    #
    #   my_text = 'Here is a sample text with more than 40 characters'
    #
    #   format_paragraph(my_text, 25, 4)
    #   # => "    Here is a sample text with\n    more than 40 characters"
    def format_paragraph(text, len = 72, indent = 2)
      sentences = [[]]

      text.split.each do |word|
        if sentences.first.present? && (sentences.last + [word]).join(' ').length > len
          sentences << [word]
        else
          sentences.last << word
        end
      end

      sentences.map { |sentence|
        "#{" " * indent}#{sentence.join(' ')}"
      }.join "\n"
    end
  end
end
require "action_mailer"
require "rails"
require "abstract_controller/railties/routes_helpers"

module ActionMailer
  class Railtie < Rails::Railtie # :nodoc:
    config.action_mailer = ActiveSupport::OrderedOptions.new
    config.eager_load_namespaces << ActionMailer

    initializer "action_mailer.logger" do
      ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
    end

    initializer "action_mailer.set_configs" do |app|
      paths   = app.config.paths
      options = app.config.action_mailer

      options.assets_dir      ||= paths["public"].first
      options.javascripts_dir ||= paths["public/javascripts"].first
      options.stylesheets_dir ||= paths["public/stylesheets"].first

      # make sure readers methods get compiled
      options.asset_host          ||= app.config.asset_host
      options.relative_url_root   ||= app.config.relative_url_root

      ActiveSupport.on_load(:action_mailer) do
        include AbstractController::UrlFor
        extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
        include app.routes.mounted_helpers

        register_interceptors(options.delete(:interceptors))
        register_observers(options.delete(:observers))

        options.each { |k,v| send("#{k}=", v) }
      end
    end

    initializer "action_mailer.compile_config_methods" do
      ActiveSupport.on_load(:action_mailer) do
        config.compile_methods! if config.respond_to?(:compile_methods!)
      end
    end
  end
end
require 'active_support/test_case'

module ActionMailer
  class NonInferrableMailerError < ::StandardError
    def initialize(name)
      super "Unable to determine the mailer to test from #{name}. " +
        "You'll need to specify it using tests YourMailer in your " +
        "test case definition"
    end
  end

  class TestCase < ActiveSupport::TestCase
    module Behavior
      extend ActiveSupport::Concern

      include ActiveSupport::Testing::ConstantLookup
      include TestHelper

      included do
        class_attribute :_mailer_class
        setup :initialize_test_deliveries
        setup :set_expected_mail
      end

      module ClassMethods
        def tests(mailer)
          case mailer
          when String, Symbol
            self._mailer_class = mailer.to_s.camelize.constantize
          when Module
            self._mailer_class = mailer
          else
            raise NonInferrableMailerError.new(mailer)
          end
        end

        def mailer_class
          if mailer = self._mailer_class
            mailer
          else
            tests determine_default_mailer(name)
          end
        end

        def determine_default_mailer(name)
          mailer = determine_constant_from_test_name(name) do |constant|
            Class === constant && constant < ActionMailer::Base
          end
          raise NonInferrableMailerError.new(name) if mailer.nil?
          mailer
        end
      end

      protected

        def initialize_test_deliveries
          ActionMailer::Base.delivery_method = :test
          ActionMailer::Base.perform_deliveries = true
          ActionMailer::Base.deliveries.clear
        end

        def set_expected_mail
          @expected = Mail.new
          @expected.content_type ["text", "plain", { "charset" => charset }]
          @expected.mime_version = '1.0'
        end

      private

        def charset
          "UTF-8"
        end

        def encode(subject)
          Mail::Encodings.q_value_encode(subject, charset)
        end

        def read_fixture(action)
          IO.readlines(File.join(Rails.root, 'test', 'fixtures', self.class.mailer_class.name.underscore, action))
        end
    end

    include Behavior
  end
end
module ActionMailer
  module TestHelper
    # Asserts that the number of emails sent matches the given number.
    #
    #   def test_emails
    #     assert_emails 0
    #     ContactMailer.welcome.deliver
    #     assert_emails 1
    #     ContactMailer.welcome.deliver
    #     assert_emails 2
    #   end
    #
    # If a block is passed, that block should cause the specified number of
    # emails to be sent.
    #
    #   def test_emails_again
    #     assert_emails 1 do
    #       ContactMailer.welcome.deliver
    #     end
    #
    #     assert_emails 2 do
    #       ContactMailer.welcome.deliver
    #       ContactMailer.welcome.deliver
    #     end
    #   end
    def assert_emails(number)
      if block_given?
        original_count = ActionMailer::Base.deliveries.size
        yield
        new_count = ActionMailer::Base.deliveries.size
        assert_equal original_count + number, new_count, "#{number} emails expected, but #{new_count - original_count} were sent"
      else
        assert_equal number, ActionMailer::Base.deliveries.size
      end
    end

    # Assert that no emails have been sent.
    #
    #   def test_emails
    #     assert_no_emails
    #     ContactMailer.welcome.deliver
    #     assert_emails 1
    #   end
    #
    # If a block is passed, that block should not cause any emails to be sent.
    #
    #   def test_emails_again
    #     assert_no_emails do
    #       # No emails should be sent from this block
    #     end
    #   end
    #
    # Note: This assertion is simply a shortcut for:
    #
    #   assert_emails 0
    def assert_no_emails(&block)
      assert_emails 0, &block
    end
  end
end
module ActionMailer
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'abstract_controller'
require 'action_view'
require 'action_mailer/version'

# Common Active Support usage in Action Mailer
require 'active_support/rails'
require 'active_support/core_ext/class'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/string/inflections'
require 'active_support/lazy_load_hooks'

module ActionMailer
  extend ::ActiveSupport::Autoload

  eager_autoload do
    autoload :Collector
  end

  autoload :Base
  autoload :DeliveryMethods
  autoload :MailHelper
  autoload :TestCase
  autoload :TestHelper
end
module Rails
  module Generators
    class MailerGenerator < NamedBase
      source_root File.expand_path("../templates", __FILE__)

      argument :actions, type: :array, default: [], banner: "method method"
      check_class_collision

      def create_mailer_file
        template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb")
      end

      hook_for :template_engine, :test_framework
    end
  end
end
<% module_namespacing do -%>
class <%= class_name %> < ActionMailer::Base
  default from: "from@example.com"
<% actions.each do |action| -%>

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.<%= file_path.tr("/",".") %>.<%= action %>.subject
  #
  def <%= action %>
    @greeting = "Hi"

    mail to: "to@example.org"
  end
<% end -%>
end
<% end -%>
module AbstractController
  module AssetPaths #:nodoc:
    extend ActiveSupport::Concern

    included do
      config_accessor :asset_host, :assets_dir, :javascripts_dir,
        :stylesheets_dir, :default_asset_host_protocol, :relative_url_root
    end
  end
end
require 'erubis'
require 'set'
require 'active_support/configurable'
require 'active_support/descendants_tracker'
require 'active_support/core_ext/module/anonymous'

module AbstractController
  class Error < StandardError #:nodoc:
  end

  class ActionNotFound < StandardError #:nodoc:
  end

  # <tt>AbstractController::Base</tt> is a low-level API. Nobody should be
  # using it directly, and subclasses (like ActionController::Base) are
  # expected to provide their own +render+ method, since rendering means
  # different things depending on the context.
  class Base
    attr_internal :response_body
    attr_internal :action_name
    attr_internal :formats

    include ActiveSupport::Configurable
    extend ActiveSupport::DescendantsTracker

    undef_method :not_implemented
    class << self
      attr_reader :abstract
      alias_method :abstract?, :abstract

      # Define a controller as abstract. See internal_methods for more
      # details.
      def abstract!
        @abstract = true
      end

      def inherited(klass) # :nodoc:
        # define the abstract ivar on subclasses so that we don't get
        # uninitialized ivar warnings
        unless klass.instance_variable_defined?(:@abstract)
          klass.instance_variable_set(:@abstract, false)
        end
        super
      end

      # A list of all internal methods for a controller. This finds the first
      # abstract superclass of a controller, and gets a list of all public
      # instance methods on that abstract class. Public instance methods of
      # a controller would normally be considered action methods, so methods
      # declared on abstract classes are being removed.
      # (ActionController::Metal and ActionController::Base are defined as abstract)
      def internal_methods
        controller = self

        controller = controller.superclass until controller.abstract?
        controller.public_instance_methods(true)
      end

      # The list of hidden actions. Defaults to an empty array.
      # This can be modified by other modules or subclasses
      # to specify particular actions as hidden.
      #
      # ==== Returns
      # * <tt>Array</tt> - An array of method names that should not be considered actions.
      def hidden_actions
        []
      end

      # A list of method names that should be considered actions. This
      # includes all public instance methods on a controller, less
      # any internal methods (see #internal_methods), adding back in
      # any methods that are internal, but still exist on the class
      # itself. Finally, #hidden_actions are removed.
      #
      # ==== Returns
      # * <tt>Set</tt> - A set of all methods that should be considered actions.
      def action_methods
        @action_methods ||= begin
          # All public instance methods of this class, including ancestors
          methods = (public_instance_methods(true) -
            # Except for public instance methods of Base and its ancestors
            internal_methods +
            # Be sure to include shadowed public instance methods of this class
            public_instance_methods(false)).uniq.map { |x| x.to_s } -
            # And always exclude explicitly hidden actions
            hidden_actions.to_a

          # Clear out AS callback method pollution
          Set.new(methods.reject { |method| method =~ /_one_time_conditions/ })
        end
      end

      # action_methods are cached and there is sometimes need to refresh
      # them. clear_action_methods! allows you to do that, so next time
      # you run action_methods, they will be recalculated
      def clear_action_methods!
        @action_methods = nil
      end

      # Returns the full controller name, underscored, without the ending Controller.
      # For instance, MyApp::MyPostsController would return "my_app/my_posts" for
      # controller_path.
      #
      # ==== Returns
      # * <tt>String</tt>
      def controller_path
        @controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
      end

      # Refresh the cached action_methods when a new action_method is added.
      def method_added(name)
        super
        clear_action_methods!
      end
    end

    abstract!

    # Calls the action going through the entire action dispatch stack.
    #
    # The actual method that is called is determined by calling
    # #method_for_action. If no method can handle the action, then an
    # ActionNotFound error is raised.
    #
    # ==== Returns
    # * <tt>self</tt>
    def process(action, *args)
      @_action_name = action_name = action.to_s

      unless action_name = method_for_action(action_name)
        raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
      end

      @_response_body = nil

      process_action(action_name, *args)
    end

    # Delegates to the class' #controller_path
    def controller_path
      self.class.controller_path
    end

    # Delegates to the class' #action_methods
    def action_methods
      self.class.action_methods
    end

    # Returns true if a method for the action is available and
    # can be dispatched, false otherwise.
    #
    # Notice that <tt>action_methods.include?("foo")</tt> may return
    # false and <tt>available_action?("foo")</tt> returns true because
    # this method considers actions that are also available
    # through other means, for example, implicit render ones.
    #
    # ==== Parameters
    # * <tt>action_name</tt> - The name of an action to be tested
    #
    # ==== Returns
    # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
    def available_action?(action_name)
      method_for_action(action_name).present?
    end

    private

      # Returns true if the name can be considered an action because
      # it has a method defined in the controller.
      #
      # ==== Parameters
      # * <tt>name</tt> - The name of an action to be tested
      #
      # ==== Returns
      # * <tt>TrueClass</tt>, <tt>FalseClass</tt>
      #
      # :api: private
      def action_method?(name)
        self.class.action_methods.include?(name)
      end

      # Call the action. Override this in a subclass to modify the
      # behavior around processing an action. This, and not #process,
      # is the intended way to override action dispatching.
      #
      # Notice that the first argument is the method to be dispatched
      # which is *not* necessarily the same as the action name.
      def process_action(method_name, *args)
        send_action(method_name, *args)
      end

      # Actually call the method associated with the action. Override
      # this method if you wish to change how action methods are called,
      # not to add additional behavior around it. For example, you would
      # override #send_action if you want to inject arguments into the
      # method.
      alias send_action send

      # If the action name was not found, but a method called "action_missing"
      # was found, #method_for_action will return "_handle_action_missing".
      # This method calls #action_missing with the current action name.
      def _handle_action_missing(*args)
        action_missing(@_action_name, *args)
      end

      # Takes an action name and returns the name of the method that will
      # handle the action. In normal cases, this method returns the same
      # name as it receives. By default, if #method_for_action receives
      # a name that is not an action, it will look for an #action_missing
      # method and return "_handle_action_missing" if one is found.
      #
      # Subclasses may override this method to add additional conditions
      # that should be considered an action. For instance, an HTTP controller
      # with a template matching the action name is considered to exist.
      #
      # If you override this method to handle additional cases, you may
      # also provide a method (like _handle_method_missing) to handle
      # the case.
      #
      # If none of these conditions are true, and method_for_action
      # returns nil, an ActionNotFound exception will be raised.
      #
      # ==== Parameters
      # * <tt>action_name</tt> - An action name to find a method name for
      #
      # ==== Returns
      # * <tt>string</tt> - The name of the method that handles the action
      # * <tt>nil</tt>    - No method name could be found. Raise ActionNotFound.
      def method_for_action(action_name)
        if action_method?(action_name)
          action_name
        elsif respond_to?(:action_missing, true)
          "_handle_action_missing"
        end
      end
  end
end
module AbstractController
  module Callbacks
    extend ActiveSupport::Concern

    # Uses ActiveSupport::Callbacks as the base functionality. For
    # more details on the whole callback system, read the documentation
    # for ActiveSupport::Callbacks.
    include ActiveSupport::Callbacks

    included do
      define_callbacks :process_action, :terminator => "response_body", :skip_after_callbacks_if_terminated => true
    end

    # Override AbstractController::Base's process_action to run the
    # process_action callbacks around the normal behavior.
    def process_action(*args)
      run_callbacks(:process_action) do
        super
      end
    end

    module ClassMethods
      # If :only or :except are used, convert the options into the
      # :unless and :if options of ActiveSupport::Callbacks.
      # The basic idea is that :only => :index gets converted to
      # :if => proc {|c| c.action_name == "index" }.
      #
      # ==== Options
      # * <tt>only</tt>   - The callback should be run only for this action
      # * <tt>except</tt>  - The callback should be run for all actions except this action
      def _normalize_callback_options(options)
        _normalize_callback_option(options, :only, :if)
        _normalize_callback_option(options, :except, :unless)
      end

      def _normalize_callback_option(options, from, to) # :nodoc:
        if from = options[from]
          from = Array(from).map {|o| "action_name == '#{o}'"}.join(" || ")
          options[to] = Array(options[to]) << from
        end
      end

      # Skip before, after, and around action callbacks matching any of the names
      # Aliased as skip_filter.
      #
      # ==== Parameters
      # * <tt>names</tt> - A list of valid names that could be used for
      #   callbacks. Note that skipping uses Ruby equality, so it's
      #   impossible to skip a callback defined using an anonymous proc
      #   using #skip_filter
      def skip_action_callback(*names)
        skip_before_action(*names)
        skip_after_action(*names)
        skip_around_action(*names)
      end

      alias_method :skip_filter, :skip_action_callback

      # Take callback names and an optional callback proc, normalize them,
      # then call the block with each callback. This allows us to abstract
      # the normalization across several methods that use it.
      #
      # ==== Parameters
      # * <tt>callbacks</tt> - An array of callbacks, with an optional
      #   options hash as the last parameter.
      # * <tt>block</tt>    - A proc that should be added to the callbacks.
      #
      # ==== Block Parameters
      # * <tt>name</tt>     - The callback to be added
      # * <tt>options</tt>  - A hash of options to be used when adding the callback
      def _insert_callbacks(callbacks, block = nil)
        options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
        _normalize_callback_options(options)
        callbacks.push(block) if block
        callbacks.each do |callback|
          yield callback, options
        end
      end

      ##
      # :method: before_action
      #
      # :call-seq: before_action(names, block)
      #
      # Append a callback before actions. See _insert_callbacks for parameter details.
      # Aliased as before_filter.

      ##
      # :method: prepend_before_action
      #
      # :call-seq: prepend_before_action(names, block)
      #
      # Prepend a callback before actions. See _insert_callbacks for parameter details.
      # Aliased as prepend_before_filter.

      ##
      # :method: skip_before_action
      #
      # :call-seq: skip_before_action(names)
      #
      # Skip a callback before actions. See _insert_callbacks for parameter details.
      # Aliased as skip_before_filter.

      ##
      # :method: append_before_action
      #
      # :call-seq: append_before_action(names, block)
      #
      # Append a callback before actions. See _insert_callbacks for parameter details.
      # Aliased as append_before_filter.

      ##
      # :method: after_action
      #
      # :call-seq: after_action(names, block)
      #
      # Append a callback after actions. See _insert_callbacks for parameter details.
      # Aliased as after_filter.

      ##
      # :method: prepend_after_action
      #
      # :call-seq: prepend_after_action(names, block)
      #
      # Prepend a callback after actions. See _insert_callbacks for parameter details.
      # Aliased as prepend_after_filter.

      ##
      # :method: skip_after_action
      #
      # :call-seq: skip_after_action(names)
      #
      # Skip a callback after actions. See _insert_callbacks for parameter details.
      # Aliased as skip_after_filter.

      ##
      # :method: append_after_action
      #
      # :call-seq: append_after_action(names, block)
      #
      # Append a callback after actions. See _insert_callbacks for parameter details.
      # Aliased as append_after_filter.

      ##
      # :method: around_action
      #
      # :call-seq: around_action(names, block)
      #
      # Append a callback around actions. See _insert_callbacks for parameter details.
      # Aliased as around_filter.

      ##
      # :method: prepend_around_action
      #
      # :call-seq: prepend_around_action(names, block)
      #
      # Prepend a callback around actions. See _insert_callbacks for parameter details.
      # Aliased as prepend_around_filter.

      ##
      # :method: skip_around_action
      #
      # :call-seq: skip_around_action(names)
      #
      # Skip a callback around actions. See _insert_callbacks for parameter details.
      # Aliased as skip_around_filter.

      ##
      # :method: append_around_action
      #
      # :call-seq: append_around_action(names, block)
      #
      # Append a callback around actions. See _insert_callbacks for parameter details.
      # Aliased as append_around_filter.

      # set up before_action, prepend_before_action, skip_before_action, etc.
      # for each of before, after, and around.
      [:before, :after, :around].each do |callback|
        class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
          # Append a before, after or around callback. See _insert_callbacks
          # for details on the allowed parameters.
          def #{callback}_action(*names, &blk)                                                    # def before_action(*names, &blk)
            _insert_callbacks(names, blk) do |name, options|                                      #   _insert_callbacks(names, blk) do |name, options|
              set_callback(:process_action, :#{callback}, name, options)                          #     set_callback(:process_action, :before, name, options)
            end                                                                                   #   end
          end                                                                                     # end

          alias_method :#{callback}_filter, :#{callback}_action

          # Prepend a before, after or around callback. See _insert_callbacks
          # for details on the allowed parameters.
          def prepend_#{callback}_action(*names, &blk)                                            # def prepend_before_action(*names, &blk)
            _insert_callbacks(names, blk) do |name, options|                                      #   _insert_callbacks(names, blk) do |name, options|
              set_callback(:process_action, :#{callback}, name, options.merge(:prepend => true))  #     set_callback(:process_action, :before, name, options.merge(:prepend => true))
            end                                                                                   #   end
          end                                                                                     # end

          alias_method :prepend_#{callback}_filter, :prepend_#{callback}_action

          # Skip a before, after or around callback. See _insert_callbacks
          # for details on the allowed parameters.
          def skip_#{callback}_action(*names)                                                     # def skip_before_action(*names)
            _insert_callbacks(names) do |name, options|                                           #   _insert_callbacks(names) do |name, options|
              skip_callback(:process_action, :#{callback}, name, options)                         #     skip_callback(:process_action, :before, name, options)
            end                                                                                   #   end
          end                                                                                     # end

          alias_method :skip_#{callback}_filter, :skip_#{callback}_action

          # *_action is the same as append_*_action
          alias_method :append_#{callback}_action, :#{callback}_action  # alias_method :append_before_action, :before_action
          alias_method :append_#{callback}_filter, :#{callback}_action  # alias_method :append_before_filter, :before_action
        RUBY_EVAL
      end
    end
  end
end
require "action_dispatch/http/mime_type"

module AbstractController
  module Collector
    def self.generate_method_for_mime(mime)
      sym = mime.is_a?(Symbol) ? mime : mime.to_sym
      const = sym.upcase
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{sym}(*args, &block)                # def html(*args, &block)
          custom(Mime::#{const}, *args, &block)  #   custom(Mime::HTML, *args, &block)
        end                                      # end
      RUBY
    end

    Mime::SET.each do |mime|
      generate_method_for_mime(mime)
    end

    Mime::Type.register_callback do |mime|
      generate_method_for_mime(mime) unless self.instance_methods.include?(mime.to_sym)
    end

  protected

    def method_missing(symbol, &block)
      mime_constant = Mime.const_get(symbol.upcase)

      if Mime::SET.include?(mime_constant)
        AbstractController::Collector.generate_method_for_mime(mime_constant)
        send(symbol, &block)
      else
        super
      end
    end
  end
end
require 'active_support/dependencies'

module AbstractController
  module Helpers
    extend ActiveSupport::Concern

    included do
      class_attribute :_helpers
      self._helpers = Module.new

      class_attribute :_helper_methods
      self._helper_methods = Array.new
    end

    module ClassMethods
      # When a class is inherited, wrap its helper module in a new module.
      # This ensures that the parent class's module can be changed
      # independently of the child class's.
      def inherited(klass)
        helpers = _helpers
        klass._helpers = Module.new { include helpers }
        klass.class_eval { default_helper_module! } unless klass.anonymous?
        super
      end

      # Declare a controller method as a helper. For example, the following
      # makes the +current_user+ controller method available to the view:
      #   class ApplicationController < ActionController::Base
      #     helper_method :current_user, :logged_in?
      #
      #     def current_user
      #       @current_user ||= User.find_by_id(session[:user])
      #     end
      #
      #     def logged_in?
      #       current_user != nil
      #     end
      #   end
      #
      # In a view:
      #  <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
      #
      # ==== Parameters
      # * <tt>method[, method]</tt> - A name or names of a method on the controller
      #   to be made available on the view.
      def helper_method(*meths)
        meths.flatten!
        self._helper_methods += meths

        meths.each do |meth|
          _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
            def #{meth}(*args, &blk)                               # def current_user(*args, &blk)
              controller.send(%(#{meth}), *args, &blk)             #   controller.send(:current_user, *args, &blk)
            end                                                    # end
          ruby_eval
        end
      end

      # The +helper+ class method can take a series of helper module names, a block, or both.
      #
      # ==== Options
      # * <tt>*args</tt> - Module, Symbol, String, :all
      # * <tt>block</tt> - A block defining helper methods
      #
      # When the argument is a module it will be included directly in the template class.
      #   helper FooHelper # => includes FooHelper
      #
      # When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
      # and include the module in the template class. The second form illustrates how to include custom helpers
      # when working with namespaced controllers, or other cases where the file containing the helper definition is not
      # in one of Rails' standard load paths:
      #   helper :foo             # => requires 'foo_helper' and includes FooHelper
      #   helper 'resources/foo'  # => requires 'resources/foo_helper' and includes Resources::FooHelper
      #
      # Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
      # to the template.
      #
      #   # One line
      #   helper { def hello() "Hello, world!" end }
      #
      #   # Multi-line
      #   helper do
      #     def foo(bar)
      #       "#{bar} is the very best"
      #     end
      #   end
      #
      # Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
      # +symbols+, +strings+, +modules+ and blocks.
      #
      #   helper(:three, BlindHelper) { def mice() 'mice' end }
      #
      def helper(*args, &block)
        modules_for_helpers(args).each do |mod|
          add_template_helper(mod)
        end

        _helpers.module_eval(&block) if block_given?
      end

      # Clears up all existing helpers in this class, only keeping the helper
      # with the same name as this class.
      def clear_helpers
        inherited_helper_methods = _helper_methods
        self._helpers = Module.new
        self._helper_methods = Array.new

        inherited_helper_methods.each { |meth| helper_method meth }
        default_helper_module! unless anonymous?
      end

      # Returns a list of modules, normalized from the acceptable kinds of
      # helpers with the following behavior:
      #
      # String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper",
      # and "foo_bar_helper.rb" is loaded using require_dependency.
      #
      # Module:: No further processing
      #
      # After loading the appropriate files, the corresponding modules
      # are returned.
      #
      # ==== Parameters
      # * <tt>args</tt> - An array of helpers
      #
      # ==== Returns
      # * <tt>Array</tt> - A normalized list of modules for the list of
      #   helpers provided.
      def modules_for_helpers(args)
        args.flatten.map! do |arg|
          case arg
          when String, Symbol
            file_name = "#{arg.to_s.underscore}_helper"
            begin
              require_dependency(file_name)
            rescue LoadError => e
              raise MissingHelperError.new(e, file_name)
            end
            file_name.camelize.constantize
          when Module
            arg
          else
            raise ArgumentError, "helper must be a String, Symbol, or Module"
          end
        end
      end

      class MissingHelperError < LoadError
        def initialize(error, path)
          @error = error
          @path  = "helpers/#{path}.rb"
          set_backtrace error.backtrace
          super("Missing helper file helpers/%s.rb" % path)
        end
      end

      private
      # Makes all the (instance) methods in the helper module available to templates
      # rendered through this controller.
      #
      # ==== Parameters
      # * <tt>module</tt> - The module to include into the current helper module
      #   for the class
      def add_template_helper(mod)
        _helpers.module_eval { include mod }
      end

      def default_helper_module!
        module_name = name.sub(/Controller$/, '')
        module_path = module_name.underscore
        helper module_path
      rescue MissingSourceFile => e
        raise e unless e.is_missing? "helpers/#{module_path}_helper"
      rescue NameError => e
        raise e unless e.missing_name? "#{module_name}Helper"
      end
    end
  end
end
require "active_support/core_ext/module/remove_method"

module AbstractController
  # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
  # repeated setups. The inclusion pattern has pages that look like this:
  #
  #   <%= render "shared/header" %>
  #   Hello World
  #   <%= render "shared/footer" %>
  #
  # This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose
  # and if you ever want to change the structure of these two includes, you'll have to change all the templates.
  #
  # With layouts, you can flip it around and have the common structure know where to insert changing content. This means
  # that the header and footer are only mentioned in one place, like this:
  #
  #   // The header part of this layout
  #   <%= yield %>
  #   // The footer part of this layout
  #
  # And then you have content pages that look like this:
  #
  #    hello world
  #
  # At rendering time, the content page is computed and then inserted in the layout, like this:
  #
  #   // The header part of this layout
  #   hello world
  #   // The footer part of this layout
  #
  # == Accessing shared variables
  #
  # Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
  # references that won't materialize before rendering time:
  #
  #   <h1><%= @page_title %></h1>
  #   <%= yield %>
  #
  # ...and content pages that fulfill these references _at_ rendering time:
  #
  #    <% @page_title = "Welcome" %>
  #    Off-world colonies offers you a chance to start a new life
  #
  # The result after rendering is:
  #
  #   <h1>Welcome</h1>
  #   Off-world colonies offers you a chance to start a new life
  #
  # == Layout assignment
  #
  # You can either specify a layout declaratively (using the #layout class method) or give
  # it the same name as your controller, and place it in <tt>app/views/layouts</tt>.
  # If a subclass does not have a layout specified, it inherits its layout using normal Ruby inheritance.
  #
  # For instance, if you have PostsController and a template named <tt>app/views/layouts/posts.html.erb</tt>,
  # that template will be used for all actions in PostsController and controllers inheriting
  # from PostsController.
  #
  # If you use a module, for instance Weblog::PostsController, you will need a template named
  # <tt>app/views/layouts/weblog/posts.html.erb</tt>.
  #
  # Since all your controllers inherit from ApplicationController, they will use
  # <tt>app/views/layouts/application.html.erb</tt> if no other layout is specified
  # or provided.
  #
  # == Inheritance Examples
  #
  #   class BankController < ActionController::Base
  #     # bank.html.erb exists
  #
  #   class ExchangeController < BankController
  #     # exchange.html.erb exists
  #
  #   class CurrencyController < BankController
  #
  #   class InformationController < BankController
  #     layout "information"
  #
  #   class TellerController < InformationController
  #     # teller.html.erb exists
  #
  #   class EmployeeController < InformationController
  #     # employee.html.erb exists
  #     layout nil
  #
  #   class VaultController < BankController
  #     layout :access_level_layout
  #
  #   class TillController < BankController
  #     layout false
  #
  # In these examples, we have three implicit lookup scenarios:
  # * The BankController uses the "bank" layout.
  # * The ExchangeController uses the "exchange" layout.
  # * The CurrencyController inherits the layout from BankController.
  #
  # However, when a layout is explicitly set, the explicitly set layout wins:
  # * The InformationController uses the "information" layout, explicitly set.
  # * The TellerController also uses the "information" layout, because the parent explicitly set it.
  # * The EmployeeController uses the "employee" layout, because it set the layout to nil, resetting the parent configuration.
  # * The VaultController chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
  # * The TillController does not use a layout at all.
  #
  # == Types of layouts
  #
  # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes
  # you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can
  # be done either by specifying a method reference as a symbol or using an inline method (as a proc).
  #
  # The method reference is the preferred approach to variable layouts and is used like this:
  #
  #   class WeblogController < ActionController::Base
  #     layout :writers_and_readers
  #
  #     def index
  #       # fetching posts
  #     end
  #
  #     private
  #       def writers_and_readers
  #         logged_in? ? "writer_layout" : "reader_layout"
  #       end
  #   end
  #
  # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing
  # is logged in or not.
  #
  # If you want to use an inline method, such as a proc, do something like this:
  #
  #   class WeblogController < ActionController::Base
  #     layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
  #   end
  #
  # If an argument isn't given to the proc, it's evaluated in the context of
  # the current controller anyway.
  #
  #   class WeblogController < ActionController::Base
  #     layout proc { logged_in? ? "writer_layout" : "reader_layout" }
  #   end
  #
  # Of course, the most common way of specifying a layout is still just as a plain template name:
  #
  #   class WeblogController < ActionController::Base
  #     layout "weblog_standard"
  #   end
  #
  # The template will be looked always in <tt>app/views/layouts/</tt> folder. But you can point
  # <tt>layouts</tt> folder direct also. <tt>layout "layouts/demo"</tt> is the same as <tt>layout "demo"</tt>.
  #
  # Setting the layout to nil forces it to be looked up in the filesystem and fallbacks to the parent behavior if none exists.
  # Setting it to nil is useful to re-enable template lookup overriding a previous configuration set in the parent:
  #
  #     class ApplicationController < ActionController::Base
  #       layout "application"
  #     end
  #
  #     class PostsController < ApplicationController
  #       # Will use "application" layout
  #     end
  #
  #     class CommentsController < ApplicationController
  #       # Will search for "comments" layout and fallback "application" layout
  #       layout nil
  #     end
  #
  # == Conditional layouts
  #
  # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering
  # a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The
  # <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
  #
  #   class WeblogController < ActionController::Base
  #     layout "weblog_standard", except: :rss
  #
  #     # ...
  #
  #   end
  #
  # This will assign "weblog_standard" as the WeblogController's layout for all actions except for the +rss+ action, which will
  # be rendered directly, without wrapping a layout around the rendered view.
  #
  # Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
  # #<tt>except: [ :rss, :text_only ]</tt> is valid, as is <tt>except: :rss</tt>.
  #
  # == Using a different layout in the action render call
  #
  # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above.
  # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller.
  # You can do this by passing a <tt>:layout</tt> option to the <tt>render</tt> call. For example:
  #
  #   class WeblogController < ActionController::Base
  #     layout "weblog_standard"
  #
  #     def help
  #       render action: "help", layout: "help"
  #     end
  #   end
  #
  # This will override the controller-wide "weblog_standard" layout, and will render the help action with the "help" layout instead.
  module Layouts
    extend ActiveSupport::Concern

    include Rendering

    included do
      class_attribute :_layout, :_layout_conditions, :instance_accessor => false
      self._layout = nil
      self._layout_conditions = {}
      _write_layout_method
    end

    delegate :_layout_conditions, to: :class

    module ClassMethods
      def inherited(klass) # :nodoc:
        super
        klass._write_layout_method
      end

      # This module is mixed in if layout conditions are provided. This means
      # that if no layout conditions are used, this method is not used
      module LayoutConditions # :nodoc:
      private

        # Determines whether the current action has a layout definition by
        # checking the action name against the :only and :except conditions
        # set by the <tt>layout</tt> method.
        #
        # ==== Returns
        # * <tt> Boolean</tt> - True if the action has a layout definition, false otherwise.
        def _conditional_layout?
          return unless super

          conditions = _layout_conditions

          if only = conditions[:only]
            only.include?(action_name)
          elsif except = conditions[:except]
            !except.include?(action_name)
          else
            true
          end
        end
      end

      # Specify the layout to use for this class.
      #
      # If the specified layout is a:
      # String:: the String is the template name
      # Symbol:: call the method specified by the symbol, which will return the template name
      # false::  There is no layout
      # true::   raise an ArgumentError
      # nil::    Force default layout behavior with inheritance
      #
      # ==== Parameters
      # * <tt>layout</tt> - The layout to use.
      #
      # ==== Options (conditions)
      # * :only   - A list of actions to apply this layout to.
      # * :except - Apply this layout to all actions but this one.
      def layout(layout, conditions = {})
        include LayoutConditions unless conditions.empty?

        conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
        self._layout_conditions = conditions

        self._layout = layout
        _write_layout_method
      end

      # If no layout is supplied, look for a template named the return
      # value of this method.
      #
      # ==== Returns
      # * <tt>String</tt> - A template name
      def _implied_layout_name # :nodoc:
        controller_path
      end

      # Creates a _layout method to be called by _default_layout .
      #
      # If a layout is not explicitly mentioned then look for a layout with the controller's name.
      # if nothing is found then try same procedure to find super class's layout.
      def _write_layout_method # :nodoc:
        remove_possible_method(:_layout)

        prefixes    = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
        name_clause = if name
          <<-RUBY
            lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super
          RUBY
        else
          <<-RUBY
            super
          RUBY
        end

        layout_definition = case _layout
          when String
            _layout.inspect
          when Symbol
            <<-RUBY
              #{_layout}.tap do |layout|
                unless layout.is_a?(String) || !layout
                  raise ArgumentError, "Your layout method :#{_layout} returned \#{layout}. It " \
                    "should have returned a String, false, or nil"
                end
              end
            RUBY
          when Proc
              define_method :_layout_from_proc, &_layout
              _layout.arity == 0 ? "_layout_from_proc" : "_layout_from_proc(self)"
          when false
            nil
          when true
            raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil"
          when nil
            name_clause
        end

        self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
          def _layout
            if _conditional_layout?
              #{layout_definition}
            else
              #{name_clause}
            end
          end
          private :_layout
        RUBY
      end
    end

    def _normalize_options(options) # :nodoc:
      super

      if _include_layout?(options)
        layout = options.delete(:layout) { :default }
        options[:layout] = _layout_for_option(layout)
      end
    end

    attr_internal_writer :action_has_layout

    def initialize(*) # :nodoc:
      @_action_has_layout = true
      super
    end

    # Controls whether an action should be rendered using a layout.
    # If you want to disable any <tt>layout</tt> settings for the
    # current action so that it is rendered without a layout then
    # either override this method in your controller to return false
    # for that action or set the <tt>action_has_layout</tt> attribute
    # to false before rendering.
    def action_has_layout?
      @_action_has_layout
    end

  private

    def _conditional_layout?
      true
    end

    # This will be overwritten by _write_layout_method
    def _layout; end

    # Determine the layout for a given name, taking into account the name type.
    #
    # ==== Parameters
    # * <tt>name</tt> - The name of the template
    def _layout_for_option(name)
      case name
      when String     then _normalize_layout(name)
      when Proc       then name
      when true       then Proc.new { _default_layout(true)  }
      when :default   then Proc.new { _default_layout(false) }
      when false, nil then nil
      else
        raise ArgumentError,
          "String, Proc, :default, true, or false, expected for `layout'; you passed #{name.inspect}"
      end
    end

    def _normalize_layout(value)
      value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value
    end

    # Returns the default layout for this controller.
    # Optionally raises an exception if the layout could not be found.
    #
    # ==== Parameters
    # * <tt>require_layout</tt> - If set to true and layout is not found,
    #   an ArgumentError exception is raised (defaults to false)
    #
    # ==== Returns
    # * <tt>template</tt> - The template object for the default layout (or nil)
    def _default_layout(require_layout = false)
      begin
        value = _layout if action_has_layout?
      rescue NameError => e
        raise e, "Could not render layout: #{e.message}"
      end

      if require_layout && action_has_layout? && !value
        raise ArgumentError,
          "There was no default layout for #{self.class} in #{view_paths.inspect}"
      end

      _normalize_layout(value)
    end

    def _include_layout?(options)
      (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout)
    end
  end
end
require "active_support/benchmarkable"

module AbstractController
  module Logger #:nodoc:
    extend ActiveSupport::Concern

    included do
      config_accessor :logger
      include ActiveSupport::Benchmarkable
    end
  end
end
module AbstractController
  module Railties
    module RoutesHelpers
      def self.with(routes)
        Module.new do
          define_method(:inherited) do |klass|
            super(klass)
            if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
              klass.send(:include, namespace.railtie_routes_url_helpers)
            else
              klass.send(:include, routes.url_helpers)
            end
          end
        end
      end
    end
  end
end
require "abstract_controller/base"
require "action_view"

module AbstractController
  class DoubleRenderError < Error
    DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."

    def initialize(message = nil)
      super(message || DEFAULT_MESSAGE)
    end
  end

  # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
  # it will trigger the lookup_context and consequently expire the cache.
  class I18nProxy < ::I18n::Config #:nodoc:
    attr_reader :original_config, :lookup_context

    def initialize(original_config, lookup_context)
      original_config = original_config.original_config if original_config.respond_to?(:original_config)
      @original_config, @lookup_context = original_config, lookup_context
    end

    def locale
      @original_config.locale
    end

    def locale=(value)
      @lookup_context.locale = value
    end
  end

  module Rendering
    extend ActiveSupport::Concern
    include AbstractController::ViewPaths

    included do
      class_attribute :protected_instance_variables
      self.protected_instance_variables = []
    end

    # Overwrite process to setup I18n proxy.
    def process(*) #:nodoc:
      old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
      super
    ensure
      I18n.config = old_config
    end

    module ClassMethods
      def view_context_class
        @view_context_class ||= begin
          routes = respond_to?(:_routes) && _routes
          helpers = respond_to?(:_helpers) && _helpers

          Class.new(ActionView::Base) do
            if routes
              include routes.url_helpers
              include routes.mounted_helpers
            end

            if helpers
              include helpers
            end
          end
        end
      end
    end

    attr_internal_writer :view_context_class

    def view_context_class
      @_view_context_class ||= self.class.view_context_class
    end

    # An instance of a view class. The default view class is ActionView::Base
    #
    # The view class must have the following methods:
    # View.new[lookup_context, assigns, controller]
    #   Create a new ActionView instance for a controller
    # View#render[options]
    #   Returns String with the rendered template
    #
    # Override this method in a module to change the default behavior.
    def view_context
      view_context_class.new(view_renderer, view_assigns, self)
    end

    # Returns an object that is able to render templates.
    def view_renderer
      @_view_renderer ||= ActionView::Renderer.new(lookup_context)
    end

    # Normalize arguments, options and then delegates render_to_body and
    # sticks the result in self.response_body.
    def render(*args, &block)
      options = _normalize_render(*args, &block)
      self.response_body = render_to_body(options)
    end

    # Raw rendering of a template to a string. Just convert the results of
    # render_response into a String.
    # :api: plugin
    def render_to_string(*args, &block)
      options = _normalize_render(*args, &block)
      render_to_body(options)
    end

    # Raw rendering of a template to a Rack-compatible body.
    # :api: plugin
    def render_to_body(options = {})
      _process_options(options)
      _render_template(options)
    end

    # Find and renders a template based on the options given.
    # :api: private
    def _render_template(options) #:nodoc:
      lookup_context.rendered_format = nil if options[:formats]
      view_renderer.render(view_context, options)
    end

    DEFAULT_PROTECTED_INSTANCE_VARIABLES = [
      :@_action_name, :@_response_body, :@_formats, :@_prefixes, :@_config,
      :@_view_context_class, :@_view_renderer, :@_lookup_context
    ]

    # This method should return a hash with assigns.
    # You can overwrite this configuration per controller.
    # :api: public
    def view_assigns
      hash = {}
      variables  = instance_variables
      variables -= protected_instance_variables
      variables -= DEFAULT_PROTECTED_INSTANCE_VARIABLES
      variables.each { |name| hash[name[1..-1]] = instance_variable_get(name) }
      hash
    end

    private

    # Normalize args and options.
    # :api: private
    def _normalize_render(*args, &block)
      options = _normalize_args(*args, &block)
      _normalize_options(options)
      options
    end

    # Normalize args by converting render "foo" to render :action => "foo" and
    # render "foo/bar" to render :file => "foo/bar".
    # :api: plugin
    def _normalize_args(action=nil, options={})
      case action
      when NilClass
      when Hash
        options = action
      when String, Symbol
        action = action.to_s
        key = action.include?(?/) ? :file : :action
        options[key] = action
      else
        options[:partial] = action
      end

      options
    end

    # Normalize options.
    # :api: plugin
    def _normalize_options(options)
      if options[:partial] == true
        options[:partial] = action_name
      end

      if (options.keys & [:partial, :file, :template]).empty?
        options[:prefixes] ||= _prefixes
      end

      options[:template] ||= (options[:action] || action_name).to_s
      options
    end

    # Process extra options.
    # :api: plugin
    def _process_options(options)
    end
  end
end
module AbstractController
  module Translation
    # Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
    #
    # When the given key starts with a period, it will be scoped by the current
    # controller and action. So if you call <tt>translate(".foo")</tt> from
    # <tt>PeopleController#index</tt>, it will convert the call to
    # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
    # to translate many keys within the same controller / action and gives you a
    # simple framework for scoping them consistently.
    def translate(*args)
      key = args.first
      if key.is_a?(String) && (key[0] == '.')
        key = "#{ controller_path.gsub('/', '.') }.#{ action_name }#{ key }"
        args[0] = key
      end

      I18n.translate(*args)
    end
    alias :t :translate

    # Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
    def localize(*args)
      I18n.localize(*args)
    end
    alias :l :localize
  end
end
module AbstractController
  # Includes +url_for+ into the host class (e.g. an abstract controller or mailer). The class
  # has to provide a +RouteSet+ by implementing the <tt>_routes</tt> methods. Otherwise, an
  # exception will be raised.
  #
  # Note that this module is completely decoupled from HTTP - the only requirement is a valid
  # <tt>_routes</tt> implementation.
  module UrlFor
    extend ActiveSupport::Concern
    include ActionDispatch::Routing::UrlFor

    def _routes
      raise "In order to use #url_for, you must include routing helpers explicitly. " \
            "For instance, `include Rails.application.routes.url_helpers"
    end

    module ClassMethods
      def _routes
        nil
      end

      def action_methods
        @action_methods ||= begin
          if _routes
            super - _routes.named_routes.helper_names
          else
            super
          end
        end
      end
    end
  end
end
require 'action_view/base'

module AbstractController
  module ViewPaths
    extend ActiveSupport::Concern

    included do
      class_attribute :_view_paths
      self._view_paths = ActionView::PathSet.new
      self._view_paths.freeze
    end

    delegate :template_exists?, :view_paths, :formats, :formats=,
             :locale, :locale=, :to => :lookup_context

    module ClassMethods
      def parent_prefixes
        @parent_prefixes ||= begin
          parent_controller = superclass
          prefixes = []

          until parent_controller.abstract?
            prefixes << parent_controller.controller_path
            parent_controller = parent_controller.superclass
          end

          prefixes
        end
      end
    end

    # The prefixes used in render "foo" shortcuts.
    def _prefixes
      @_prefixes ||= begin
        parent_prefixes = self.class.parent_prefixes
        parent_prefixes.dup.unshift(controller_path)
      end
    end

    # LookupContext is the object responsible to hold all information required to lookup
    # templates, i.e. view paths and details. Check ActionView::LookupContext for more
    # information.
    def lookup_context
      @_lookup_context ||=
        ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
    end

    def details_for_lookup
      { }
    end

    def append_view_path(path)
      lookup_context.view_paths.push(*path)
    end

    def prepend_view_path(path)
      lookup_context.view_paths.unshift(*path)
    end

    module ClassMethods
      # Append a path to the list of view paths for this controller.
      #
      # ==== Parameters
      # * <tt>path</tt> - If a String is provided, it gets converted into
      #   the default view path. You may also provide a custom view path
      #   (see ActionView::PathSet for more information)
      def append_view_path(path)
        self._view_paths = view_paths + Array(path)
      end

      # Prepend a path to the list of view paths for this controller.
      #
      # ==== Parameters
      # * <tt>path</tt> - If a String is provided, it gets converted into
      #   the default view path. You may also provide a custom view path
      #   (see ActionView::PathSet for more information)
      def prepend_view_path(path)
        self._view_paths = ActionView::PathSet.new(Array(path) + view_paths)
      end

      # A list of all of the default view paths for this controller.
      def view_paths
        _view_paths
      end

      # Set the view paths.
      #
      # ==== Parameters
      # * <tt>paths</tt> - If a PathSet is provided, use that;
      #   otherwise, process the parameter into a PathSet.
      def view_paths=(paths)
        self._view_paths = ActionView::PathSet.new(Array(paths))
      end
    end
  end
end
require 'action_pack'
require 'active_support/rails'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/anonymous'
require 'active_support/i18n'

module AbstractController
  extend ActiveSupport::Autoload

  autoload :Base
  autoload :Callbacks
  autoload :Collector
  autoload :Helpers
  autoload :Layouts
  autoload :Logger
  autoload :Rendering
  autoload :Translation
  autoload :AssetPaths
  autoload :ViewPaths
  autoload :UrlFor
end
require "action_controller/log_subscriber"
require "action_controller/metal/params_wrapper"

module ActionController
  # Action Controllers are the core of a web request in \Rails. They are made up of one or more actions that are executed
  # on request and then either render a template or redirect to another action. An action is defined as a public method
  # on the controller, which will automatically be made accessible to the web-server through \Rails Routes.
  #
  # By default, only the ApplicationController in a \Rails application inherits from <tt>ActionController::Base</tt>. All other
  # controllers in turn inherit from ApplicationController. This gives you one class to configure things such as
  # request forgery protection and filtering of sensitive request parameters.
  #
  # A sample controller could look like this:
  #
  #   class PostsController < ApplicationController
  #     def index
  #       @posts = Post.all
  #     end
  #
  #     def create
  #       @post = Post.create params[:post]
  #       redirect_to posts_path
  #     end
  #   end
  #
  # Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
  # after executing code in the action. For example, the +index+ action of the PostsController would render the
  # template <tt>app/views/posts/index.html.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
  #
  # Unlike index, the create action will not render a template. After performing its main purpose (creating a
  # new post), it initiates a redirect instead. This redirect works by returning an external
  # "302 Moved" HTTP response that takes the user to the index action.
  #
  # These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
  # Most actions are variations on these themes.
  #
  # == Requests
  #
  # For every request, the router determines the value of the +controller+ and +action+ keys. These determine which controller
  # and action are called. The remaining request parameters, the session (if one is available), and the full request with
  # all the HTTP headers are made available to the action through accessor methods. Then the action is performed.
  #
  # The full request object is available via the request accessor and is primarily used to query for HTTP headers:
  #
  #   def server_ip
  #     location = request.env["SERVER_ADDR"]
  #     render text: "This server hosted at #{location}"
  #   end
  #
  # == Parameters
  #
  # All request parameters, whether they come from a GET or POST request, or from the URL, are available through the params method
  # which returns a hash. For example, an action that was performed through <tt>/posts?category=All&limit=5</tt> will include
  # <tt>{ "category" => "All", "limit" => "5" }</tt> in params.
  #
  # It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
  #
  #   <input type="text" name="post[name]" value="david">
  #   <input type="text" name="post[address]" value="hyacintvej">
  #
  # A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
  # If the address input had been named "post[address][street]", the params would have included
  # <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
  #
  # == Sessions
  #
  # Sessions allow you to store objects in between requests. This is useful for objects that are not yet ready to be persisted,
  # such as a Signup object constructed in a multi-paged process, or objects that don't change much and are needed all the time, such
  # as a User object for a system that requires login. The session should not be used, however, as a cache for objects where it's likely
  # they could be changed unknowingly. It's usually too much work to keep it all synchronized -- something databases already excel at.
  #
  # You can place objects in the session by using the <tt>session</tt> method, which accesses a hash:
  #
  #   session[:person] = Person.authenticate(user_name, password)
  #
  # And retrieved again through the same hash:
  #
  #   Hello #{session[:person]}
  #
  # For removing objects from the session, you can either assign a single key to +nil+:
  #
  #   # removes :person from session
  #   session[:person] = nil
  #
  # or you can remove the entire session with +reset_session+.
  #
  # Sessions are stored by default in a browser cookie that's cryptographically signed, but unencrypted.
  # This prevents the user from tampering with the session but also allows him to see its contents.
  #
  # Do not put secret information in cookie-based sessions!
  #
  # == Responses
  #
  # Each action results in a response, which holds the headers and document to be sent to the user's browser. The actual response
  # object is generated automatically through the use of renders and redirects and requires no user intervention.
  #
  # == Renders
  #
  # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering
  # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured.
  # The controller passes objects to the view by assigning instance variables:
  #
  #   def show
  #     @post = Post.find(params[:id])
  #   end
  #
  # Which are then automatically available to the view:
  #
  #   Title: <%= @post.title %>
  #
  # You don't have to rely on the automated rendering. For example, actions that could result in the rendering of different templates
  # will use the manual rendering methods:
  #
  #   def search
  #     @results = Search.find(params[:query])
  #     case @results.count
  #       when 0 then render action: "no_results"
  #       when 1 then render action: "show"
  #       when 2..10 then render action: "show_many"
  #     end
  #   end
  #
  # Read more about writing ERB and Builder templates in ActionView::Base.
  #
  # == Redirects
  #
  # Redirects are used to move from one action to another. For example, after a <tt>create</tt> action, which stores a blog entry to the
  # database, we might like to show the user the new entry. Because we're following good DRY principles (Don't Repeat Yourself), we're
  # going to reuse (and redirect to) a <tt>show</tt> action that we'll assume has already been created. The code might look like this:
  #
  #   def create
  #     @entry = Entry.new(params[:entry])
  #     if @entry.save
  #       # The entry was saved correctly, redirect to show
  #       redirect_to action: 'show', id: @entry.id
  #     else
  #       # things didn't go so well, do something else
  #     end
  #   end
  #
  # In this case, after saving our new entry to the database, the user is redirected to the <tt>show</tt> method, which is then executed.
  # Note that this is an external HTTP-level redirection which will cause the browser to make a second request (a GET to the show action),
  # and not some internal re-routing which calls both "create" and then "show" within one request.
  #
  # Learn more about <tt>redirect_to</tt> and what options you have in ActionController::Redirecting.
  #
  # == Calling multiple redirects or renders
  #
  # An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
  #
  #   def do_something
  #     redirect_to action: "elsewhere"
  #     render action: "overthere" # raises DoubleRenderError
  #   end
  #
  # If you need to redirect on the condition of something, then be sure to add "and return" to halt execution.
  #
  #   def do_something
  #     redirect_to(action: "elsewhere") and return if monkeys.nil?
  #     render action: "overthere" # won't be called if monkeys is nil
  #   end
  #
  class Base < Metal
    abstract!

    # We document the request and response methods here because albeit they are
    # implemented in ActionController::Metal, the type of the returned objects
    # is unknown at that level.

    ##
    # :method: request
    #
    # Returns an ActionDispatch::Request instance that represents the
    # current request.

    ##
    # :method: response
    #
    # Returns an ActionDispatch::Response that represents the current
    # response.

    # Shortcut helper that returns all the modules included in
    # ActionController::Base except the ones passed as arguments:
    #
    #   class MetalController
    #     ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left|
    #       include left
    #     end
    #   end
    #
    # This gives better control over what you want to exclude and makes it
    # easier to create a bare controller class, instead of listing the modules
    # required manually.
    def self.without_modules(*modules)
      modules = modules.map do |m|
        m.is_a?(Symbol) ? ActionController.const_get(m) : m
      end

      MODULES - modules
    end

    MODULES = [
      AbstractController::Layouts,
      AbstractController::Translation,
      AbstractController::AssetPaths,

      Helpers,
      HideActions,
      UrlFor,
      Redirecting,
      Rendering,
      Renderers::All,
      ConditionalGet,
      RackDelegation,
      Caching,
      MimeResponds,
      ImplicitRender,
      StrongParameters,

      Cookies,
      Flash,
      RequestForgeryProtection,
      ForceSSL,
      Streaming,
      DataStreaming,
      RecordIdentifier,
      HttpAuthentication::Basic::ControllerMethods,
      HttpAuthentication::Digest::ControllerMethods,
      HttpAuthentication::Token::ControllerMethods,

      # Before callbacks should also be executed the earliest as possible, so
      # also include them at the bottom.
      AbstractController::Callbacks,

      # Append rescue at the bottom to wrap as much as possible.
      Rescue,

      # Add instrumentations hooks at the bottom, to ensure they instrument
      # all the methods properly.
      Instrumentation,

      # Params wrapper should come before instrumentation so they are
      # properly showed in logs
      ParamsWrapper
    ]

    MODULES.each do |mod|
      include mod
    end

    # Define some internal variables that should not be propagated to the view.
    self.protected_instance_variables = [
      :@_status, :@_headers, :@_params, :@_env, :@_response, :@_request,
      :@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout
    ]

    ActiveSupport.run_load_hooks(:action_controller, self)
  end
end
module ActionController
  module Caching
    # Fragment caching is used for caching various blocks within
    # views without caching the entire action as a whole. This is
    # useful when certain elements of an action change frequently or
    # depend on complicated state while other parts rarely change or
    # can be shared amongst multiple parties. The caching is done using
    # the +cache+ helper available in the Action View. See
    # ActionView::Helpers::CacheHelper for more information.
    #
    # While it's strongly recommended that you use key-based cache
    # expiration (see links in CacheHelper for more information),
    # it is also possible to manually expire caches. For example:
    #
    #   expire_fragment('name_of_cache')
    module Fragments
      # Given a key (as described in +expire_fragment+), returns
      # a key suitable for use in reading, writing, or expiring a
      # cached fragment. All keys are prefixed with <tt>views/</tt> and uses
      # ActiveSupport::Cache.expand_cache_key for the expansion.
      def fragment_cache_key(key)
        ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
      end

      # Writes +content+ to the location signified by
      # +key+ (see +expire_fragment+ for acceptable formats).
      def write_fragment(key, content, options = nil)
        return content unless cache_configured?

        key = fragment_cache_key(key)
        instrument_fragment_cache :write_fragment, key do
          content = content.to_str
          cache_store.write(key, content, options)
        end
        content
      end

      # Reads a cached fragment from the location signified by +key+
      # (see +expire_fragment+ for acceptable formats).
      def read_fragment(key, options = nil)
        return unless cache_configured?

        key = fragment_cache_key(key)
        instrument_fragment_cache :read_fragment, key do
          result = cache_store.read(key, options)
          result.respond_to?(:html_safe) ? result.html_safe : result
        end
      end

      # Check if a cached fragment from the location signified by
      # +key+ exists (see +expire_fragment+ for acceptable formats).
      def fragment_exist?(key, options = nil)
        return unless cache_configured?
        key = fragment_cache_key(key)

        instrument_fragment_cache :exist_fragment?, key do
          cache_store.exist?(key, options)
        end
      end

      # Removes fragments from the cache.
      #
      # +key+ can take one of three forms:
      #
      # * String - This would normally take the form of a path, like
      #   <tt>pages/45/notes</tt>.
      # * Hash - Treated as an implicit call to +url_for+, like
      #   <tt>{ controller: 'pages', action: 'notes', id: 45}</tt>
      # * Regexp - Will remove any fragment that matches, so
      #   <tt>%r{pages/\d*/notes}</tt> might remove all notes. Make sure you
      #   don't use anchors in the regex (<tt>^</tt> or <tt>$</tt>) because
      #   the actual filename matched looks like
      #   <tt>./cache/filename/path.cache</tt>. Note: Regexp expiration is
      #   only supported on caches that can iterate over all keys (unlike
      #   memcached).
      #
      # +options+ is passed through to the cache store's +delete+
      # method (or <tt>delete_matched</tt>, for Regexp keys).
      def expire_fragment(key, options = nil)
        return unless cache_configured?
        key = fragment_cache_key(key) unless key.is_a?(Regexp)

        instrument_fragment_cache :expire_fragment, key do
          if key.is_a?(Regexp)
            cache_store.delete_matched(key, options)
          else
            cache_store.delete(key, options)
          end
        end
      end

      def instrument_fragment_cache(name, key) # :nodoc:
        ActiveSupport::Notifications.instrument("#{name}.action_controller", :key => key){ yield }
      end
    end
  end
end
require 'fileutils'
require 'uri'
require 'set'

module ActionController
  # \Caching is a cheap way of speeding up slow applications by keeping the result of
  # calculations, renderings, and database calls around for subsequent requests.
  #
  # You can read more about each approach by clicking the modules below.
  #
  # Note: To turn off all caching, set
  #   config.action_controller.perform_caching = false.
  #
  # == \Caching stores
  #
  # All the caching stores from ActiveSupport::Cache are available to be used as backends
  # for Action Controller caching.
  #
  # Configuration examples (MemoryStore is the default):
  #
  #   config.action_controller.cache_store = :memory_store
  #   config.action_controller.cache_store = :file_store, '/path/to/cache/directory'
  #   config.action_controller.cache_store = :mem_cache_store, 'localhost'
  #   config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211')
  #   config.action_controller.cache_store = MyOwnStore.new('parameter')
  module Caching
    extend ActiveSupport::Concern
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :Fragments
    end

    module ConfigMethods
      def cache_store
        config.cache_store
      end

      def cache_store=(store)
        config.cache_store = ActiveSupport::Cache.lookup_store(store)
      end

      private
        def cache_configured?
          perform_caching && cache_store
        end
    end

    include RackDelegation
    include AbstractController::Callbacks

    include ConfigMethods
    include Fragments

    included do
      extend ConfigMethods

      config_accessor :default_static_extension
      self.default_static_extension ||= '.html'

      def self.page_cache_extension=(extension)
        ActiveSupport::Deprecation.deprecation_warning(:page_cache_extension, :default_static_extension)
        self.default_static_extension = extension
      end

      def self.page_cache_extension
        ActiveSupport::Deprecation.deprecation_warning(:page_cache_extension, :default_static_extension)
        default_static_extension
      end

      config_accessor :perform_caching
      self.perform_caching = true if perform_caching.nil?

      class_attribute :_view_cache_dependencies
      self._view_cache_dependencies = []
      helper_method :view_cache_dependencies if respond_to?(:helper_method)
    end

    module ClassMethods
      def view_cache_dependency(&dependency)
        self._view_cache_dependencies += [dependency]
      end
    end

    def view_cache_dependencies
      self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
    end

    protected
      # Convenience accessor.
      def cache(key, options = {}, &block)
        if cache_configured?
          cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
        else
          yield
        end
      end
  end
end
ActionController::Integration = ActionDispatch::Integration
ActionController::IntegrationTest = ActionDispatch::IntegrationTest

ActiveSupport::Deprecation.warn 'ActionController::Integration is deprecated and will be removed, use ActionDispatch::Integration instead.'
ActiveSupport::Deprecation.warn 'ActionController::IntegrationTest is deprecated and will be removed, use ActionDispatch::IntegrationTest instead.'
ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request
ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response
ActionController::Routing = ActionDispatch::Routing

ActiveSupport::Deprecation.warn 'ActionController::AbstractRequest and ActionController::Request are deprecated and will be removed, use ActionDispatch::Request instead.'
ActiveSupport::Deprecation.warn 'ActionController::AbstractResponse and ActionController::Response are deprecated and will be removed, use ActionDispatch::Response instead.'
ActiveSupport::Deprecation.warn 'ActionController::Routing is deprecated and will be removed, use ActionDispatch::Routing instead.'
module ActionController
  class LogSubscriber < ActiveSupport::LogSubscriber
    INTERNAL_PARAMS = %w(controller action format _method only_path)

    def start_processing(event)
      return unless logger.info?

      payload = event.payload
      params  = payload[:params].except(*INTERNAL_PARAMS)
      format  = payload[:format]
      format  = format.to_s.upcase if format.is_a?(Symbol)

      info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
      info "  Parameters: #{params.inspect}" unless params.empty?
    end

    def process_action(event)
      return unless logger.info?

      payload   = event.payload
      additions = ActionController::Base.log_process_action(payload)

      status = payload[:status]
      if status.nil? && payload[:exception].present?
        exception_class_name = payload[:exception].first
        status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
      end
      message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
      message << " (#{additions.join(" | ")})" unless additions.blank?

      info(message)
    end

    def halted_callback(event)
      info("Filter chain halted as #{event.payload[:filter]} rendered or redirected")
    end

    def send_file(event)
      info("Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)")
    end

    def redirect_to(event)
      info("Redirected to #{event.payload[:location]}")
    end

    def send_data(event)
      info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
    end

    %w(write_fragment read_fragment exist_fragment?
       expire_fragment expire_page write_page).each do |method|
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{method}(event)
          return unless logger.info?
          key_or_path = event.payload[:key] || event.payload[:path]
          human_name  = #{method.to_s.humanize.inspect}
          info("\#{human_name} \#{key_or_path} (\#{event.duration.round(1)}ms)")
        end
      METHOD
    end

    def logger
      ActionController::Base.logger
    end
  end
end

ActionController::LogSubscriber.attach_to :action_controller
require 'active_support/core_ext/hash/keys'

module ActionController
  module ConditionalGet
    extend ActiveSupport::Concern

    include RackDelegation
    include Head

    included do
      class_attribute :etaggers
      self.etaggers = []
    end

    module ClassMethods
      # Allows you to consider additional controller-wide information when generating an etag.
      # For example, if you serve pages tailored depending on who's logged in at the moment, you
      # may want to add the current user id to be part of the etag to prevent authorized displaying
      # of cached pages.
      #
      #   class InvoicesController < ApplicationController
      #     etag { current_user.try :id }
      #
      #     def show
      #       # Etag will differ even for the same invoice when it's viewed by a different current_user
      #       @invoice = Invoice.find(params[:id])
      #       fresh_when(@invoice)
      #     end
      #   end
      def etag(&etagger)
        self.etaggers += [etagger]
      end
    end

    # Sets the etag, +last_modified+, or both on the response and renders a
    # <tt>304 Not Modified</tt> response if the request is already fresh.
    #
    # === Parameters:
    #
    # * <tt>:etag</tt>.
    # * <tt>:last_modified</tt>.
    # * <tt>:public</tt> By default the Cache-Control header is private, set this to
    #   +true+ if you want your application to be cachable by other devices (proxy caches).
    #
    # === Example:
    #
    #   def show
    #     @article = Article.find(params[:id])
    #     fresh_when(etag: @article, last_modified: @article.created_at, public: true)
    #   end
    #
    # This will render the show template if the request isn't sending a matching etag or
    # If-Modified-Since header and just a <tt>304 Not Modified</tt> response if there's a match.
    #
    # You can also just pass a record where +last_modified+ will be set by calling
    # +updated_at+ and the etag by passing the object itself.
    #
    #   def show
    #     @article = Article.find(params[:id])
    #     fresh_when(@article)
    #   end
    #
    # When passing a record, you can still set whether the public header:
    #
    #   def show
    #     @article = Article.find(params[:id])
    #     fresh_when(@article, public: true)
    #   end
    def fresh_when(record_or_options, additional_options = {})
      if record_or_options.is_a? Hash
        options = record_or_options
        options.assert_valid_keys(:etag, :last_modified, :public)
      else
        record  = record_or_options
        options = { etag: record, last_modified: record.try(:updated_at) }.merge!(additional_options)
      end

      response.etag          = combine_etags(options[:etag]) if options[:etag]
      response.last_modified = options[:last_modified]       if options[:last_modified]
      response.cache_control[:public] = true                 if options[:public]

      head :not_modified if request.fresh?(response)
    end

    # Sets the +etag+ and/or +last_modified+ on the response and checks it against
    # the client request. If the request doesn't match the options provided, the
    # request is considered stale and should be generated from scratch. Otherwise,
    # it's fresh and we don't need to generate anything and a reply of <tt>304 Not Modified</tt> is sent.
    #
    # === Parameters:
    #
    # * <tt>:etag</tt>.
    # * <tt>:last_modified</tt>.
    # * <tt>:public</tt> By default the Cache-Control header is private, set this to
    #   +true+ if you want your application to be cachable by other devices (proxy caches).
    #
    # === Example:
    #
    #   def show
    #     @article = Article.find(params[:id])
    #
    #     if stale?(etag: @article, last_modified: @article.created_at)
    #       @statistics = @article.really_expensive_call
    #       respond_to do |format|
    #         # all the supported formats
    #       end
    #     end
    #   end
    #
    # You can also just pass a record where +last_modified+ will be set by calling
    # updated_at and the etag by passing the object itself.
    #
    #   def show
    #     @article = Article.find(params[:id])
    #
    #     if stale?(@article)
    #       @statistics = @article.really_expensive_call
    #       respond_to do |format|
    #         # all the supported formats
    #       end
    #     end
    #   end
    #
    # When passing a record, you can still set whether the public header:
    #
    #   def show
    #     @article = Article.find(params[:id])
    #
    #     if stale?(@article, public: true)
    #       @statistics = @article.really_expensive_call
    #       respond_to do |format|
    #         # all the supported formats
    #       end
    #     end
    #   end
    def stale?(record_or_options, additional_options = {})
      fresh_when(record_or_options, additional_options)
      !request.fresh?(response)
    end

    # Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a +private+
    # instruction, so that intermediate caches must not cache the response.
    #
    #   expires_in 20.minutes
    #   expires_in 3.hours, public: true
    #   expires_in 3.hours, public: true, must_revalidate: true
    #
    # This method will overwrite an existing Cache-Control header.
    # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
    #
    # The method will also ensure a HTTP Date header for client compatibility.
    def expires_in(seconds, options = {})
      response.cache_control.merge!(
        :max_age         => seconds,
        :public          => options.delete(:public),
        :must_revalidate => options.delete(:must_revalidate)
      )
      options.delete(:private)

      response.cache_control[:extras] = options.map {|k,v| "#{k}=#{v}"}
      response.date = Time.now unless response.date?
    end

    # Sets a HTTP 1.1 Cache-Control header of <tt>no-cache</tt> so no caching should
    # occur by the browser or intermediate caches (like caching proxy servers).
    def expires_now
      response.cache_control.replace(:no_cache => true)
    end

    private
      def combine_etags(etag)
        [ etag, *etaggers.map { |etagger| instance_exec(&etagger) }.compact ]
      end
  end
end
module ActionController #:nodoc:
  module Cookies
    extend ActiveSupport::Concern

    include RackDelegation

    included do
      helper_method :cookies
    end

    private
      def cookies
        request.cookie_jar
      end
  end
end
require 'action_controller/metal/exceptions'

module ActionController #:nodoc:
  # Methods for sending arbitrary data and for streaming files to the browser,
  # instead of rendering.
  module DataStreaming
    extend ActiveSupport::Concern

    include ActionController::Rendering

    DEFAULT_SEND_FILE_TYPE        = 'application/octet-stream'.freeze #:nodoc:
    DEFAULT_SEND_FILE_DISPOSITION = 'attachment'.freeze #:nodoc:

    protected
      # Sends the file. This uses a server-appropriate method (such as X-Sendfile)
      # via the Rack::Sendfile middleware. The header to use is set via
      # +config.action_dispatch.x_sendfile_header+.
      # Your server can also configure this for you by setting the X-Sendfile-Type header.
      #
      # Be careful to sanitize the path parameter if it is coming from a web
      # page. <tt>send_file(params[:path])</tt> allows a malicious user to
      # download any file on your server.
      #
      # Options:
      # * <tt>:filename</tt> - suggests a filename for the browser to use.
      #   Defaults to <tt>File.basename(path)</tt>.
      # * <tt>:type</tt> - specifies an HTTP content type.
      #   You can specify either a string or a symbol for a registered type register with
      #   <tt>Mime::Type.register</tt>, for example :json
      #   If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
      #   If no content type is registered for the extension, default type 'application/octet-stream' will be used.
      # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
      #   Valid values are 'inline' and 'attachment' (default).
      # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
      # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
      #   the URL, which is necessary for i18n filenames on certain browsers
      #   (setting <tt>:filename</tt> overrides this option).
      #
      # The default Content-Type and Content-Disposition headers are
      # set to download arbitrary binary files in as many browsers as
      # possible. IE versions 4, 5, 5.5, and 6 are all known to have
      # a variety of quirks (especially when downloading over SSL).
      #
      # Simple download:
      #
      #   send_file '/path/to.zip'
      #
      # Show a JPEG in the browser:
      #
      #   send_file '/path/to.jpeg', type: 'image/jpeg', disposition: 'inline'
      #
      # Show a 404 page in the browser:
      #
      #   send_file '/path/to/404.html', type: 'text/html; charset=utf-8', status: 404
      #
      # Read about the other Content-* HTTP headers if you'd like to
      # provide the user with more information (such as Content-Description) in
      # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
      #
      # Also be aware that the document may be cached by proxies and browsers.
      # The Pragma and Cache-Control headers declare how the file may be cached
      # by intermediaries. They default to require clients to validate with
      # the server before releasing cached responses. See
      # http://www.mnot.net/cache_docs/ for an overview of web caching and
      # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
      # for the Cache-Control header spec.
      def send_file(path, options = {}) #:doc:
        raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)

        options[:filename] ||= File.basename(path) unless options[:url_based_filename]
        send_file_headers! options

        self.status = options[:status] || 200
        self.content_type = options[:content_type] if options.key?(:content_type)
        self.response_body = FileBody.new(path)
      end

      # Avoid having to pass an open file handle as the response body.
      # Rack::Sendfile will usually intercept the response and uses
      # the path directly, so there is no reason to open the file.
      class FileBody #:nodoc:
        attr_reader :to_path

        def initialize(path)
          @to_path = path
        end

        # Stream the file's contents if Rack::Sendfile isn't present.
        def each
          File.open(to_path, 'rb') do |file|
            while chunk = file.read(16384)
              yield chunk
            end
          end
        end
      end

      # Sends the given binary data to the browser. This method is similar to
      # <tt>render text: data</tt>, but also allows you to specify whether
      # the browser should display the response as a file attachment (i.e. in a
      # download dialog) or as inline data. You may also set the content type,
      # the apparent file name, and other things.
      #
      # Options:
      # * <tt>:filename</tt> - suggests a filename for the browser to use.
      # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
      #   either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
      #   If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
      #   If no content type is registered for the extension, default type 'application/octet-stream' will be used.
      # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
      #   Valid values are 'inline' and 'attachment' (default).
      # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
      #
      # Generic data download:
      #
      #   send_data buffer
      #
      # Download a dynamically-generated tarball:
      #
      #   send_data generate_tgz('dir'), filename: 'dir.tgz'
      #
      # Display an image Active Record in the browser:
      #
      #   send_data image.data, type: image.content_type, disposition: 'inline'
      #
      # See +send_file+ for more information on HTTP Content-* headers and caching.
      def send_data(data, options = {}) #:doc:
        send_file_headers! options
        render options.slice(:status, :content_type).merge(:text => data)
      end

    private
      def send_file_headers!(options)
        type_provided = options.has_key?(:type)

        content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
        raise ArgumentError, ":type option required" if content_type.nil?

        if content_type.is_a?(Symbol)
          extension = Mime[content_type]
          raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension
          self.content_type = extension
        else
          if !type_provided && options[:filename]
            # If type wasn't provided, try guessing from file extension.
            content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete('.')) || content_type
          end
          self.content_type = content_type
        end

        disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION)
        unless disposition.nil?
          disposition  = disposition.to_s
          disposition += %(; filename="#{options[:filename]}") if options[:filename]
          headers['Content-Disposition'] = disposition
        end

        headers['Content-Transfer-Encoding'] = 'binary'

        response.sending_file = true

        # Fix a problem with IE 6.0 on opening downloaded files:
        # If Cache-Control: no-cache is set (which Rails does by default),
        # IE removes the file it just downloaded from its cache immediately
        # after it displays the "open/save" dialog, which means that if you
        # hit "open" the file isn't there anymore when the application that
        # is called for handling the download is run, so let's workaround that
        response.cache_control[:public] ||= false
      end
  end
end
module ActionController
  class ActionControllerError < StandardError #:nodoc:
  end

  class BadRequest < ActionControllerError #:nodoc:
    attr_reader :original_exception

    def initialize(type = nil, e = nil)
      return super() unless type && e

      super("Invalid #{type} parameters: #{e.message}")
      @original_exception = e
      set_backtrace e.backtrace
    end
  end

  class RenderError < ActionControllerError #:nodoc:
  end

  class RoutingError < ActionControllerError #:nodoc:
    attr_reader :failures
    def initialize(message, failures=[])
      super(message)
      @failures = failures
    end
  end

  class ActionController::UrlGenerationError < RoutingError #:nodoc:
  end

  class MethodNotAllowed < ActionControllerError #:nodoc:
    def initialize(*allowed_methods)
      super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
    end
  end

  class NotImplemented < MethodNotAllowed #:nodoc:
  end

  class UnknownController < ActionControllerError #:nodoc:
  end

  class MissingFile < ActionControllerError #:nodoc:
  end

  class SessionOverflowError < ActionControllerError #:nodoc:
    DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.'

    def initialize(message = nil)
      super(message || DEFAULT_MESSAGE)
    end
  end

  class UnknownHttpMethod < ActionControllerError #:nodoc:
  end

  class UnknownFormat < ActionControllerError #:nodoc:
  end
end
module ActionController #:nodoc:
  module Flash
    extend ActiveSupport::Concern

    included do
      class_attribute :_flash_types, instance_accessor: false
      self._flash_types = []

      delegate :flash, to: :request
      add_flash_types(:alert, :notice)
    end

    module ClassMethods
      def add_flash_types(*types)
        types.each do |type|
          next if _flash_types.include?(type)

          define_method(type) do
            request.flash[type]
          end
          helper_method type

          _flash_types << type
        end
      end
    end

    protected
      def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
        self.class._flash_types.each do |flash_type|
          if type = response_status_and_flash.delete(flash_type)
            flash[flash_type] = type
          end
        end

        if other_flashes = response_status_and_flash.delete(:flash)
          flash.update(other_flashes)
        end

        super(options, response_status_and_flash)
      end
  end
end
module ActionController
  # This module provides a method which will redirect browser to use HTTPS
  # protocol. This will ensure that user's sensitive information will be
  # transferred safely over the internet. You _should_ always force browser
  # to use HTTPS when you're transferring sensitive information such as
  # user authentication, account information, or credit card information.
  #
  # Note that if you are really concerned about your application security,
  # you might consider using +config.force_ssl+ in your config file instead.
  # That will ensure all the data transferred via HTTPS protocol and prevent
  # user from getting session hijacked when accessing the site under unsecured
  # HTTP protocol.
  module ForceSSL
    extend ActiveSupport::Concern
    include AbstractController::Callbacks

    module ClassMethods
      # Force the request to this particular controller or specified actions to be
      # under HTTPS protocol.
      #
      # If you need to disable this for any reason (e.g. development) then you can use
      # an +:if+ or +:unless+ condition.
      #
      #     class AccountsController < ApplicationController
      #       force_ssl if: :ssl_configured?
      #
      #       def ssl_configured?
      #         !Rails.env.development?
      #       end
      #     end
      #
      # ==== Options
      # * <tt>host</tt>   - Redirect to a different host name
      # * <tt>only</tt>   - The callback should be run only for this action
      # * <tt>except</tt> - The callback should be run for all actions except this action
      # * <tt>if</tt>     - A symbol naming an instance method or a proc; the callback
      #                     will be called only when it returns a true value.
      # * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
      #                     will be called only when it returns a false value.
      def force_ssl(options = {})
        host = options.delete(:host)
        before_action(options) do
          force_ssl_redirect(host)
        end
      end
    end

    # Redirect the existing request to use the HTTPS protocol.
    #
    # ==== Parameters
    # * <tt>host</tt> - Redirect to a different host name
    def force_ssl_redirect(host = nil)
      unless request.ssl?
        redirect_options = {:protocol => 'https://', :status => :moved_permanently}
        redirect_options.merge!(:host => host) if host
        redirect_options.merge!(:params => request.query_parameters)
        flash.keep if respond_to?(:flash)
        redirect_to redirect_options
      end
    end
  end
end
module ActionController
  module Head
    extend ActiveSupport::Concern

    # Return a response that has no content (merely headers). The options
    # argument is interpreted to be a hash of header names and values.
    # This allows you to easily return a response that consists only of
    # significant headers:
    #
    #   head :created, location: person_path(@person)
    #
    #   head :created, location: @person
    #
    # It can also be used to return exceptional conditions:
    #
    #   return head(:method_not_allowed) unless request.post?
    #   return head(:bad_request) unless valid_request?
    #   render
    def head(status, options = {})
      options, status = status, nil if status.is_a?(Hash)
      status ||= options.delete(:status) || :ok
      location = options.delete(:location)
      content_type = options.delete(:content_type)

      options.each do |key, value|
        headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s
      end

      self.status = status
      self.location = url_for(location) if location

      if include_content?(self.status)
        self.content_type = content_type || (Mime[formats.first] if formats)
        self.response.charset = false if self.response
        self.response_body = " "
      else
        headers.delete('Content-Type')
        headers.delete('Content-Length')
        self.response_body = ""
      end
    end

    private
    # :nodoc:
    def include_content?(status)
      case status
      when 100..199
        false
      when 204, 205, 304
        false
      else
        true
      end
    end
  end
end
module ActionController
  # The \Rails framework provides a large number of helpers for working with assets, dates, forms,
  # numbers and model objects, to name a few. These helpers are available to all templates
  # by default.
  #
  # In addition to using the standard template helpers provided, creating custom helpers to
  # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller
  # will include all helpers.
  #
  # In previous versions of \Rails the controller will include a helper whose
  # name matches that of the controller, e.g., <tt>MyController</tt> will automatically
  # include <tt>MyHelper</tt>. To return old behavior set +config.action_controller.include_all_helpers+ to +false+.
  #
  # Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
  # controller which inherits from it.
  #
  # The +to_s+ method from the \Time class can be wrapped in a helper method to display a custom message if
  # a \Time object is blank:
  #
  #   module FormattedTimeHelper
  #     def format_time(time, format=:long, blank_message="&nbsp;")
  #       time.blank? ? blank_message : time.to_s(format)
  #     end
  #   end
  #
  # FormattedTimeHelper can now be included in a controller, using the +helper+ class method:
  #
  #   class EventsController < ActionController::Base
  #     helper FormattedTimeHelper
  #     def index
  #       @events = Event.all
  #     end
  #   end
  #
  # Then, in any view rendered by <tt>EventController</tt>, the <tt>format_time</tt> method can be called:
  #
  #   <% @events.each do |event| -%>
  #     <p>
  #       <%= format_time(event.time, :short, "N/A") %> | <%= event.name %>
  #     </p>
  #   <% end -%>
  #
  # Finally, assuming we have two event instances, one which has a time and one which does not,
  # the output might look like this:
  #
  #   23 Aug 11:30 | Carolina Railhawks Soccer Match
  #   N/A | Carolina Railhaws Training Workshop
  #
  module Helpers
    extend ActiveSupport::Concern

    class << self; attr_accessor :helpers_path; end
    include AbstractController::Helpers

    included do
      class_attribute :helpers_path, :include_all_helpers
      self.helpers_path ||= []
      self.include_all_helpers = true
    end

    module ClassMethods
      # Declares helper accessors for controller attributes. For example, the
      # following adds new +name+ and <tt>name=</tt> instance methods to a
      # controller and makes them available to the view:
      #   attr_accessor :name
      #   helper_attr :name
      #
      # ==== Parameters
      # * <tt>attrs</tt> - Names of attributes to be converted into helpers.
      def helper_attr(*attrs)
        attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
      end

      # Provides a proxy to access helpers methods from outside the view.
      def helpers
        @helper_proxy ||= ActionView::Base.new.extend(_helpers)
      end

      # Overwrite modules_for_helpers to accept :all as argument, which loads
      # all helpers in helpers_path.
      #
      # ==== Parameters
      # * <tt>args</tt> - A list of helpers
      #
      # ==== Returns
      # * <tt>array</tt> - A normalized list of modules for the list of helpers provided.
      def modules_for_helpers(args)
        args += all_application_helpers if args.delete(:all)
        super(args)
      end

      def all_helpers_from_path(path)
        helpers = Array(path).flat_map do |_path|
          extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
          names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
          names.sort!
          names
        end
        helpers.uniq!
        helpers
      end

      private
      # Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
      def all_application_helpers
        all_helpers_from_path(helpers_path)
      end
    end
  end
end

module ActionController
  # Adds the ability to prevent public methods on a controller to be called as actions.
  module HideActions
    extend ActiveSupport::Concern

    included do
      class_attribute :hidden_actions
      self.hidden_actions = Set.new.freeze
    end

  private

    # Overrides AbstractController::Base#action_method? to return false if the
    # action name is in the list of hidden actions.
    def method_for_action(action_name)
      self.class.visible_action?(action_name) && super
    end

    module ClassMethods
      # Sets all of the actions passed in as hidden actions.
      #
      # ==== Parameters
      # * <tt>args</tt> - A list of actions
      def hide_action(*args)
        self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s)).freeze
      end

      def visible_action?(action_name)
        action_methods.include?(action_name)
      end

      # Overrides AbstractController::Base#action_methods to remove any methods
      # that are listed as hidden methods.
      def action_methods
        @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) }).freeze
      end
    end
  end
end
require 'base64'

module ActionController
  # Makes it dead easy to do HTTP Basic, Digest and Token authentication.
  module HttpAuthentication
    # Makes it dead easy to do HTTP \Basic authentication.
    #
    # === Simple \Basic example
    #
    #   class PostsController < ApplicationController
    #     http_basic_authenticate_with name: "dhh", password: "secret", except: :index
    #
    #     def index
    #       render text: "Everyone can see me!"
    #     end
    #
    #     def edit
    #       render text: "I'm only accessible if you know the password"
    #     end
    #  end
    #
    # === Advanced \Basic example
    #
    # Here is a more advanced \Basic example where only Atom feeds and the XML API is protected by HTTP authentication,
    # the regular HTML interface is protected by a session approach:
    #
    #   class ApplicationController < ActionController::Base
    #     before_action :set_account, :authenticate
    #
    #     protected
    #       def set_account
    #         @account = Account.find_by_url_name(request.subdomains.first)
    #       end
    #
    #       def authenticate
    #         case request.format
    #         when Mime::XML, Mime::ATOM
    #           if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
    #             @current_user = user
    #           else
    #             request_http_basic_authentication
    #           end
    #         else
    #           if session_authenticated?
    #             @current_user = @account.users.find(session[:authenticated][:user_id])
    #           else
    #             redirect_to(login_url) and return false
    #           end
    #         end
    #       end
    #   end
    #
    # In your integration tests, you can do something like this:
    #
    #   def test_access_granted_from_xml
    #     get(
    #       "/notes/1.xml", nil,
    #       'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
    #     )
    #
    #     assert_equal 200, status
    #   end
    module Basic
      extend self

      module ControllerMethods
        extend ActiveSupport::Concern

        module ClassMethods
          def http_basic_authenticate_with(options = {})
            before_action(options.except(:name, :password, :realm)) do
              authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
                name == options[:name] && password == options[:password]
              end
            end
          end
        end

        def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
          authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
        end

        def authenticate_with_http_basic(&login_procedure)
          HttpAuthentication::Basic.authenticate(request, &login_procedure)
        end

        def request_http_basic_authentication(realm = "Application")
          HttpAuthentication::Basic.authentication_request(self, realm)
        end
      end

      def authenticate(request, &login_procedure)
        unless request.authorization.blank?
          login_procedure.call(*user_name_and_password(request))
        end
      end

      def user_name_and_password(request)
        decode_credentials(request).split(/:/, 2)
      end

      def decode_credentials(request)
        ::Base64.decode64(request.authorization.split(' ', 2).last || '')
      end

      def encode_credentials(user_name, password)
        "Basic #{::Base64.strict_encode64("#{user_name}:#{password}")}"
      end

      def authentication_request(controller, realm)
        controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
        controller.response_body = "HTTP Basic: Access denied.\n"
        controller.status = 401
      end
    end

    # Makes it dead easy to do HTTP \Digest authentication.
    #
    # === Simple \Digest example
    #
    #   require 'digest/md5'
    #   class PostsController < ApplicationController
    #     REALM = "SuperSecret"
    #     USERS = {"dhh" => "secret", #plain text password
    #              "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))}  #ha1 digest password
    #
    #     before_action :authenticate, except: [:index]
    #
    #     def index
    #       render text: "Everyone can see me!"
    #     end
    #
    #     def edit
    #       render text: "I'm only accessible if you know the password"
    #     end
    #
    #     private
    #       def authenticate
    #         authenticate_or_request_with_http_digest(REALM) do |username|
    #           USERS[username]
    #         end
    #       end
    #   end
    #
    # === Notes
    #
    # The +authenticate_or_request_with_http_digest+ block must return the user's password
    # or the ha1 digest hash so the framework can appropriately hash to check the user's
    # credentials. Returning +nil+ will cause authentication to fail.
    #
    # Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
    # the password file or database is compromised, the attacker would be able to use the ha1 hash to
    # authenticate as the user at this +realm+, but would not have the user's password to try using at
    # other sites.
    #
    # In rare instances, web servers or front proxies strip authorization headers before
    # they reach your application. You can debug this situation by logging all environment
    # variables, and check for HTTP_AUTHORIZATION, amongst others.
    module Digest
      extend self

      module ControllerMethods
        def authenticate_or_request_with_http_digest(realm = "Application", &password_procedure)
          authenticate_with_http_digest(realm, &password_procedure) || request_http_digest_authentication(realm)
        end

        # Authenticate with HTTP Digest, returns true or false
        def authenticate_with_http_digest(realm = "Application", &password_procedure)
          HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
        end

        # Render output including the HTTP Digest authentication header
        def request_http_digest_authentication(realm = "Application", message = nil)
          HttpAuthentication::Digest.authentication_request(self, realm, message)
        end
      end

      # Returns false on a valid response, true otherwise
      def authenticate(request, realm, &password_procedure)
        request.authorization && validate_digest_response(request, realm, &password_procedure)
      end

      # Returns false unless the request credentials response value matches the expected value.
      # First try the password as a ha1 digest password. If this fails, then try it as a plain
      # text password.
      def validate_digest_response(request, realm, &password_procedure)
        secret_key  = secret_token(request)
        credentials = decode_credentials_header(request)
        valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])

        if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque]
          password = password_procedure.call(credentials[:username])
          return false unless password

          method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
          uri    = credentials[:uri]

          [true, false].any? do |trailing_question_mark|
            [true, false].any? do |password_is_ha1|
              _uri = trailing_question_mark ? uri + "?" : uri
              expected = expected_response(method, _uri, credentials, password, password_is_ha1)
              expected == credentials[:response]
            end
          end
        end
      end

      # Returns the expected response for a request of +http_method+ to +uri+ with the decoded +credentials+ and the expected +password+
      # Optional parameter +password_is_ha1+ is set to +true+ by default, since best practice is to store ha1 digest instead
      # of a plain-text password.
      def expected_response(http_method, uri, credentials, password, password_is_ha1=true)
        ha1 = password_is_ha1 ? password : ha1(credentials, password)
        ha2 = ::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(':'))
        ::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(':'))
      end

      def ha1(credentials, password)
        ::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(':'))
      end

      def encode_credentials(http_method, credentials, password, password_is_ha1)
        credentials[:response] = expected_response(http_method, credentials[:uri], credentials, password, password_is_ha1)
        "Digest " + credentials.sort_by {|x| x[0].to_s }.map {|v| "#{v[0]}='#{v[1]}'" }.join(', ')
      end

      def decode_credentials_header(request)
        decode_credentials(request.authorization)
      end

      def decode_credentials(header)
        ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, '').split(',').map do |pair|
          key, value = pair.split('=', 2)
          [key.strip, value.to_s.gsub(/^"|"$/,'').delete('\'')]
        end]
      end

      def authentication_header(controller, realm)
        secret_key = secret_token(controller.request)
        nonce = self.nonce(secret_key)
        opaque = opaque(secret_key)
        controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
      end

      def authentication_request(controller, realm, message = nil)
        message ||= "HTTP Digest: Access denied.\n"
        authentication_header(controller, realm)
        controller.response_body = message
        controller.status = 401
      end

      def secret_token(request)
        key_generator  = request.env["action_dispatch.key_generator"]
        http_auth_salt = request.env["action_dispatch.http_auth_salt"]
        key_generator.generate_key(http_auth_salt)
      end

      # Uses an MD5 digest based on time to generate a value to be used only once.
      #
      # A server-specified data string which should be uniquely generated each time a 401 response is made.
      # It is recommended that this string be base64 or hexadecimal data.
      # Specifically, since the string is passed in the header lines as a quoted string, the double-quote character is not allowed.
      #
      # The contents of the nonce are implementation dependent.
      # The quality of the implementation depends on a good choice.
      # A nonce might, for example, be constructed as the base 64 encoding of
      #
      #   time-stamp H(time-stamp ":" ETag ":" private-key)
      #
      # where time-stamp is a server-generated time or other non-repeating value,
      # ETag is the value of the HTTP ETag header associated with the requested entity,
      # and private-key is data known only to the server.
      # With a nonce of this form a server would recalculate the hash portion after receiving the client authentication header and
      # reject the request if it did not match the nonce from that header or
      # if the time-stamp value is not recent enough. In this way the server can limit the time of the nonce's validity.
      # The inclusion of the ETag prevents a replay request for an updated version of the resource.
      # (Note: including the IP address of the client in the nonce would appear to offer the server the ability
      # to limit the reuse of the nonce to the same client that originally got it.
      # However, that would break proxy farms, where requests from a single user often go through different proxies in the farm.
      # Also, IP address spoofing is not that hard.)
      #
      # An implementation might choose not to accept a previously used nonce or a previously used digest, in order to
      # protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for
      # POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
      # of this document.
      #
      # The nonce is opaque to the client. Composed of Time, and hash of Time with secret
      # key from the Rails session secret generated upon creation of project. Ensures
      # the time cannot be modified by client.
      def nonce(secret_key, time = Time.now)
        t = time.to_i
        hashed = [t, secret_key]
        digest = ::Digest::MD5.hexdigest(hashed.join(":"))
        ::Base64.strict_encode64("#{t}:#{digest}")
      end

      # Might want a shorter timeout depending on whether the request
      # is a PATCH, PUT, or POST, and if client is browser or web service.
      # Can be much shorter if the Stale directive is implemented. This would
      # allow a user to use new nonce without prompting user again for their
      # username and password.
      def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60)
        t = ::Base64.decode64(value).split(":").first.to_i
        nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
      end

      # Opaque based on random generation - but changing each request?
      def opaque(secret_key)
        ::Digest::MD5.hexdigest(secret_key)
      end

    end

    # Makes it dead easy to do HTTP Token authentication.
    #
    # Simple Token example:
    #
    #   class PostsController < ApplicationController
    #     TOKEN = "secret"
    #
    #     before_action :authenticate, except: [ :index ]
    #
    #     def index
    #       render text: "Everyone can see me!"
    #     end
    #
    #     def edit
    #       render text: "I'm only accessible if you know the password"
    #     end
    #
    #     private
    #       def authenticate
    #         authenticate_or_request_with_http_token do |token, options|
    #           token == TOKEN
    #         end
    #       end
    #   end
    #
    #
    # Here is a more advanced Token example where only Atom feeds and the XML API is protected by HTTP token authentication,
    # the regular HTML interface is protected by a session approach:
    #
    #   class ApplicationController < ActionController::Base
    #     before_action :set_account, :authenticate
    #
    #     protected
    #       def set_account
    #         @account = Account.find_by_url_name(request.subdomains.first)
    #       end
    #
    #       def authenticate
    #         case request.format
    #         when Mime::XML, Mime::ATOM
    #           if user = authenticate_with_http_token { |t, o| @account.users.authenticate(t, o) }
    #             @current_user = user
    #           else
    #             request_http_token_authentication
    #           end
    #         else
    #           if session_authenticated?
    #             @current_user = @account.users.find(session[:authenticated][:user_id])
    #           else
    #             redirect_to(login_url) and return false
    #           end
    #         end
    #       end
    #   end
    #
    #
    # In your integration tests, you can do something like this:
    #
    #   def test_access_granted_from_xml
    #     get(
    #       "/notes/1.xml", nil,
    #       'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Token.encode_credentials(users(:dhh).token)
    #     )
    #
    #     assert_equal 200, status
    #   end
    #
    #
    # On shared hosts, Apache sometimes doesn't pass authentication headers to
    # FCGI instances. If your environment matches this description and you cannot
    # authenticate, try this rule in your Apache setup:
    #
    #   RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
    module Token
      TOKEN_REGEX = /^Token /
      AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
      extend self

      module ControllerMethods
        def authenticate_or_request_with_http_token(realm = "Application", &login_procedure)
          authenticate_with_http_token(&login_procedure) || request_http_token_authentication(realm)
        end

        def authenticate_with_http_token(&login_procedure)
          Token.authenticate(self, &login_procedure)
        end

        def request_http_token_authentication(realm = "Application")
          Token.authentication_request(self, realm)
        end
      end

      # If token Authorization header is present, call the login
      # procedure with the present token and options.
      #
      # [controller]
      #   ActionController::Base instance for the current request.
      #
      # [login_procedure]
      #   Proc to call if a token is present. The Proc should take two arguments:
      #
      #     authenticate(controller) { |token, options| ... }
      #
      # Returns the return value of <tt>login_procedure</tt> if a
      # token is found. Returns <tt>nil</tt> if no token is found.

      def authenticate(controller, &login_procedure)
        token, options = token_and_options(controller.request)
        unless token.blank?
          login_procedure.call(token, options)
        end
      end

      # Parses the token and options out of the token authorization header. If
      # the header looks like this:
      #   Authorization: Token token="abc", nonce="def"
      # Then the returned token is "abc", and the options is {nonce: "def"}
      #
      # request - ActionDispatch::Request instance with the current headers.
      #
      # Returns an Array of [String, Hash] if a token is present.
      # Returns nil if no token is found.
      def token_and_options(request)
        authorization_request = request.authorization.to_s
        if authorization_request[TOKEN_REGEX]
          params = token_params_from authorization_request
          [params.shift.last, Hash[params].with_indifferent_access]
        end
      end

      def token_params_from(auth)
        rewrite_param_values params_array_from raw_params auth
      end

      # Takes raw_params and turns it into an array of parameters
      def params_array_from(raw_params)
        raw_params.map { |param| param.split %r/=(.+)?/ }
      end

      # This removes the `"` characters wrapping the value.
      def rewrite_param_values(array_params)
        array_params.each { |param| param.last.gsub! %r/^"|"$/, '' }
      end

      # This method takes an authorization body and splits up the key-value
      # pairs by the standardized `:`, `;`, or `\t` delimiters defined in
      # `AUTHN_PAIR_DELIMITERS`.
      def raw_params(auth)
        auth.sub(TOKEN_REGEX, '').split(/"\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
      end

      # Encodes the given token and options into an Authorization header value.
      #
      # token   - String token.
      # options - optional Hash of the options.
      #
      # Returns String.
      def encode_credentials(token, options = {})
        values = ["token=#{token.to_s.inspect}"] + options.map do |key, value|
          "#{key}=#{value.to_s.inspect}"
        end
        "Token #{values * ", "}"
      end

      # Sets a WWW-Authenticate to let the client know a token is desired.
      #
      # controller - ActionController::Base instance for the outgoing response.
      # realm      - String realm to use in the header.
      #
      # Returns nothing.
      def authentication_request(controller, realm)
        controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.gsub(/"/, "")}")
        controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized
      end
    end
  end
end
module ActionController
  module ImplicitRender
    def send_action(method, *args)
      ret = super
      default_render unless performed?
      ret
    end

    def default_render(*args)
      render(*args)
    end

    def method_for_action(action_name)
      super || if template_exists?(action_name.to_s, _prefixes)
        "default_render"
      end
    end
  end
end
require 'benchmark'
require 'abstract_controller/logger'

module ActionController
  # Adds instrumentation to several ends in ActionController::Base. It also provides
  # some hooks related with process_action, this allows an ORM like Active Record
  # and/or DataMapper to plug in ActionController and show related information.
  #
  # Check ActiveRecord::Railties::ControllerRuntime for an example.
  module Instrumentation
    extend ActiveSupport::Concern

    include AbstractController::Logger
    include ActionController::RackDelegation

    attr_internal :view_runtime

    def process_action(*args)
      raw_payload = {
        :controller => self.class.name,
        :action     => self.action_name,
        :params     => request.filtered_parameters,
        :format     => request.format.try(:ref),
        :method     => request.method,
        :path       => (request.fullpath rescue "unknown")
      }

      ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)

      ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
        result = super
        payload[:status] = response.status
        append_info_to_payload(payload)
        result
      end
    end

    def render(*args)
      render_output = nil
      self.view_runtime = cleanup_view_runtime do
        Benchmark.ms { render_output = super }
      end
      render_output
    end

    def send_file(path, options={})
      ActiveSupport::Notifications.instrument("send_file.action_controller",
        options.merge(:path => path)) do
        super
      end
    end

    def send_data(data, options = {})
      ActiveSupport::Notifications.instrument("send_data.action_controller", options) do
        super
      end
    end

    def redirect_to(*args)
      ActiveSupport::Notifications.instrument("redirect_to.action_controller") do |payload|
        result = super
        payload[:status]   = response.status
        payload[:location] = response.filtered_location
        result
      end
    end

  private

    # A hook invoked everytime a before callback is halted.
    def halted_callback_hook(filter)
      ActiveSupport::Notifications.instrument("halted_callback.action_controller", :filter => filter)
    end

    # A hook which allows you to clean up any time taken into account in
    # views wrongly, like database querying time.
    #
    #   def cleanup_view_runtime
    #     super - time_taken_in_something_expensive
    #   end
    #
    # :api: plugin
    def cleanup_view_runtime #:nodoc:
      yield
    end

    # Every time after an action is processed, this method is invoked
    # with the payload, so you can add more information.
    # :api: plugin
    def append_info_to_payload(payload) #:nodoc:
      payload[:view_runtime] = view_runtime
    end

    module ClassMethods
      # A hook which allows other frameworks to log what happened during
      # controller process action. This method should return an array
      # with the messages to be added.
      # :api: plugin
      def log_process_action(payload) #:nodoc:
        messages, view_runtime = [], payload[:view_runtime]
        messages << ("Views: %.1fms" % view_runtime.to_f) if view_runtime
        messages
      end
    end
  end
end
require 'action_dispatch/http/response'
require 'delegate'

module ActionController
  # Mix this module in to your controller, and all actions in that controller
  # will be able to stream data to the client as it's written.
  #
  #   class MyController < ActionController::Base
  #     include ActionController::Live
  #
  #     def stream
  #       response.headers['Content-Type'] = 'text/event-stream'
  #       100.times {
  #         response.stream.write "hello world\n"
  #         sleep 1
  #       }
  #       response.stream.close
  #     end
  #   end
  #
  # There are a few caveats with this use. You *cannot* write headers after the
  # response has been committed (Response#committed? will return truthy).
  # Calling +write+ or +close+ on the response stream will cause the response
  # object to be committed. Make sure all headers are set before calling write
  # or close on your stream.
  #
  # You *must* call close on your stream when you're finished, otherwise the
  # socket may be left open forever.
  #
  # The final caveat is that your actions are executed in a separate thread than
  # the main thread. Make sure your actions are thread safe, and this shouldn't
  # be a problem (don't share state across threads, etc).
  module Live
    class Buffer < ActionDispatch::Response::Buffer #:nodoc:
      def initialize(response)
        super(response, SizedQueue.new(10))
      end

      def write(string)
        unless @response.committed?
          @response.headers["Cache-Control"] = "no-cache"
          @response.headers.delete "Content-Length"
        end

        super
      end

      def each
        while str = @buf.pop
          yield str
        end
      end

      def close
        super
        @buf.push nil
      end
    end

    class Response < ActionDispatch::Response #:nodoc: all
      class Header < DelegateClass(Hash)
        def initialize(response, header)
          @response = response
          super(header)
        end

        def []=(k,v)
          if @response.committed?
            raise ActionDispatch::IllegalStateError, 'header already sent'
          end

          super
        end

        def merge(other)
          self.class.new @response, __getobj__.merge(other)
        end

        def to_hash
          __getobj__.dup
        end
      end

      def commit!
        headers.freeze
        super
      end

      private

      def build_buffer(response, body)
        buf = Live::Buffer.new response
        body.each { |part| buf.write part }
        buf
      end

      def merge_default_headers(original, default)
        Header.new self, super
      end
    end

    def process(name)
      t1 = Thread.current
      locals = t1.keys.map { |key| [key, t1[key]] }

      # This processes the action in a child thread. It lets us return the
      # response code and headers back up the rack stack, and still process
      # the body in parallel with sending data to the client
      Thread.new {
        t2 = Thread.current
        t2.abort_on_exception = true

        # Since we're processing the view in a different thread, copy the
        # thread locals from the main thread to the child thread. :'(
        locals.each { |k,v| t2[k] = v }

        begin
          super(name)
        ensure
          @_response.commit!
        end
      }

      @_response.await_commit
    end

    def response_body=(body)
      super
      response.stream.close if response
    end

    def set_response!(request)
      if request.env["HTTP_VERSION"] == "HTTP/1.0"
        super
      else
        @_response         = Live::Response.new
        @_response.request = request
      end
    end
  end
end
require 'active_support/core_ext/array/extract_options'
require 'abstract_controller/collector'

module ActionController #:nodoc:
  module MimeResponds
    extend ActiveSupport::Concern

    included do
      class_attribute :responder, :mimes_for_respond_to
      self.responder = ActionController::Responder
      clear_respond_to
    end

    module ClassMethods
      # Defines mime types that are rendered by default when invoking
      # <tt>respond_with</tt>.
      #
      #   respond_to :html, :xml, :json
      #
      # Specifies that all actions in the controller respond to requests
      # for <tt>:html</tt>, <tt>:xml</tt> and <tt>:json</tt>.
      #
      # To specify on per-action basis, use <tt>:only</tt> and
      # <tt>:except</tt> with an array of actions or a single action:
      #
      #   respond_to :html
      #   respond_to :xml, :json, except: [ :edit ]
      #
      # This specifies that all actions respond to <tt>:html</tt>
      # and all actions except <tt>:edit</tt> respond to <tt>:xml</tt> and
      # <tt>:json</tt>.
      #
      #   respond_to :json, only: :create
      #
      # This specifies that the <tt>:create</tt> action and no other responds
      # to <tt>:json</tt>.
      def respond_to(*mimes)
        options = mimes.extract_options!

        only_actions   = Array(options.delete(:only)).map(&:to_s)
        except_actions = Array(options.delete(:except)).map(&:to_s)

        new = mimes_for_respond_to.dup
        mimes.each do |mime|
          mime = mime.to_sym
          new[mime]          = {}
          new[mime][:only]   = only_actions   unless only_actions.empty?
          new[mime][:except] = except_actions unless except_actions.empty?
        end
        self.mimes_for_respond_to = new.freeze
      end

      # Clear all mime types in <tt>respond_to</tt>.
      #
      def clear_respond_to
        self.mimes_for_respond_to = Hash.new.freeze
      end
    end

    # Without web-service support, an action which collects the data for displaying a list of people
    # might look something like this:
    #
    #   def index
    #     @people = Person.all
    #   end
    #
    # Here's the same action, with web-service support baked in:
    #
    #   def index
    #     @people = Person.all
    #
    #     respond_to do |format|
    #       format.html
    #       format.xml { render xml: @people }
    #     end
    #   end
    #
    # What that says is, "if the client wants HTML in response to this action, just respond as we
    # would have before, but if the client wants XML, return them the list of people in XML format."
    # (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
    #
    # Supposing you have an action that adds a new person, optionally creating their company
    # (by name) if it does not already exist, without web-services, it might look like this:
    #
    #   def create
    #     @company = Company.find_or_create_by(name: params[:company][:name])
    #     @person  = @company.people.create(params[:person])
    #
    #     redirect_to(person_list_url)
    #   end
    #
    # Here's the same action, with web-service support baked in:
    #
    #   def create
    #     company  = params[:person].delete(:company)
    #     @company = Company.find_or_create_by(name: company[:name])
    #     @person  = @company.people.create(params[:person])
    #
    #     respond_to do |format|
    #       format.html { redirect_to(person_list_url) }
    #       format.js
    #       format.xml  { render xml: @person.to_xml(include: @company) }
    #     end
    #   end
    #
    # If the client wants HTML, we just redirect them back to the person list. If they want JavaScript,
    # then it is an Ajax request and we render the JavaScript template associated with this action.
    # Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also
    # include the person's company in the rendered XML, so you get something like this:
    #
    #   <person>
    #     <id>...</id>
    #     ...
    #     <company>
    #       <id>...</id>
    #       <name>...</name>
    #       ...
    #     </company>
    #   </person>
    #
    # Note, however, the extra bit at the top of that action:
    #
    #   company  = params[:person].delete(:company)
    #   @company = Company.find_or_create_by(name: company[:name])
    #
    # This is because the incoming XML document (if a web-service request is in process) can only contain a
    # single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):
    #
    #   person[name]=...&person[company][name]=...&...
    #
    # And, like this (xml-encoded):
    #
    #   <person>
    #     <name>...</name>
    #     <company>
    #       <name>...</name>
    #     </company>
    #   </person>
    #
    # In other words, we make the request so that it operates on a single entity's person. Then, in the action,
    # we extract the company data from the request, find or create the company, and then create the new person
    # with the remaining data.
    #
    # Note that you can define your own XML parameter parser which would allow you to describe multiple entities
    # in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow
    # and accept Rails' defaults, life will be much easier.
    #
    # If you need to use a MIME type which isn't supported by default, you can register your own handlers in
    # config/initializers/mime_types.rb as follows.
    #
    #   Mime::Type.register "image/jpg", :jpg
    #
    # Respond to also allows you to specify a common block for different formats by using any:
    #
    #   def index
    #     @people = Person.all
    #
    #     respond_to do |format|
    #       format.html
    #       format.any(:xml, :json) { render request.format.to_sym => @people }
    #     end
    #   end
    #
    # In the example above, if the format is xml, it will render:
    #
    #   render xml: @people
    #
    # Or if the format is json:
    #
    #   render json: @people
    #
    # Since this is a common pattern, you can use the class method respond_to
    # with the respond_with method to have the same results:
    #
    #   class PeopleController < ApplicationController
    #     respond_to :html, :xml, :json
    #
    #     def index
    #       @people = Person.all
    #       respond_with(@people)
    #     end
    #   end
    #
    # Be sure to check the documentation of +respond_with+ and
    # <tt>ActionController::MimeResponds.respond_to</tt> for more examples.
    def respond_to(*mimes, &block)
      raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?

      if collector = retrieve_collector_from_mimes(mimes, &block)
        response = collector.response
        response ? response.call : render({})
      end
    end

    # For a given controller action, respond_with generates an appropriate
    # response based on the mime-type requested by the client.
    #
    # If the method is called with just a resource, as in this example -
    #
    #   class PeopleController < ApplicationController
    #     respond_to :html, :xml, :json
    #
    #     def index
    #       @people = Person.all
    #       respond_with @people
    #     end
    #   end
    #
    # then the mime-type of the response is typically selected based on the
    # request's Accept header and the set of available formats declared
    # by previous calls to the controller's class method +respond_to+. Alternatively
    # the mime-type can be selected by explicitly setting <tt>request.format</tt> in
    # the controller.
    #
    # If an acceptable format is not identified, the application returns a
    # '406 - not acceptable' status. Otherwise, the default response is to render
    # a template named after the current action and the selected format,
    # e.g. <tt>index.html.erb</tt>. If no template is available, the behavior
    # depends on the selected format:
    #
    # * for an html response - if the request method is +get+, an exception
    #   is raised but for other requests such as +post+ the response
    #   depends on whether the resource has any validation errors (i.e.
    #   assuming that an attempt has been made to save the resource,
    #   e.g. by a +create+ action) -
    #   1. If there are no errors, i.e. the resource
    #      was saved successfully, the response +redirect+'s to the resource
    #      i.e. its +show+ action.
    #   2. If there are validation errors, the response
    #      renders a default action, which is <tt>:new</tt> for a
    #      +post+ request or <tt>:edit</tt> for +patch+ or +put+.
    #   Thus an example like this -
    #
    #     respond_to :html, :xml
    #
    #     def create
    #       @user = User.new(params[:user])
    #       flash[:notice] = 'User was successfully created.' if @user.save
    #       respond_with(@user)
    #     end
    #
    #   is equivalent, in the absence of <tt>create.html.erb</tt>, to -
    #
    #     def create
    #       @user = User.new(params[:user])
    #       respond_to do |format|
    #         if @user.save
    #           flash[:notice] = 'User was successfully created.'
    #           format.html { redirect_to(@user) }
    #           format.xml { render xml: @user }
    #         else
    #           format.html { render action: "new" }
    #           format.xml { render xml: @user }
    #         end
    #       end
    #     end
    #
    # * for a javascript request - if the template isn't found, an exception is
    #   raised.
    # * for other requests - i.e. data formats such as xml, json, csv etc, if
    #   the resource passed to +respond_with+ responds to <code>to_<format></code>,
    #   the method attempts to render the resource in the requested format
    #   directly, e.g. for an xml request, the response is equivalent to calling 
    #   <code>render xml: resource</code>.
    #
    # === Nested resources
    #
    # As outlined above, the +resources+ argument passed to +respond_with+
    # can play two roles. It can be used to generate the redirect url
    # for successful html requests (e.g. for +create+ actions when
    # no template exists), while for formats other than html and javascript
    # it is the object that gets rendered, by being converted directly to the
    # required format (again assuming no template exists).
    #
    # For redirecting successful html requests, +respond_with+ also supports
    # the use of nested resources, which are supplied in the same way as
    # in <code>form_for</code> and <code>polymorphic_url</code>. For example -
    #
    #   def create
    #     @project = Project.find(params[:project_id])
    #     @task = @project.comments.build(params[:task])
    #     flash[:notice] = 'Task was successfully created.' if @task.save
    #     respond_with(@project, @task)
    #   end
    #
    # This would cause +respond_with+ to redirect to <code>project_task_url</code>
    # instead of <code>task_url</code>. For request formats other than html or
    # javascript, if multiple resources are passed in this way, it is the last
    # one specified that is rendered.
    #
    # === Customizing response behavior
    #
    # Like +respond_to+, +respond_with+ may also be called with a block that
    # can be used to overwrite any of the default responses, e.g. -
    #
    #   def create
    #     @user = User.new(params[:user])
    #     flash[:notice] = "User was successfully created." if @user.save
    #
    #     respond_with(@user) do |format|
    #       format.html { render }
    #     end
    #   end
    #
    # The argument passed to the block is an ActionController::MimeResponds::Collector
    # object which stores the responses for the formats defined within the
    # block. Note that formats with responses defined explicitly in this way
    # do not have to first be declared using the class method +respond_to+.
    #
    # Also, a hash passed to +respond_with+ immediately after the specified
    # resource(s) is interpreted as a set of options relevant to all
    # formats. Any option accepted by +render+ can be used, e.g.
    #   respond_with @people, status: 200
    # However, note that these options are ignored after an unsuccessful attempt
    # to save a resource, e.g. when automatically rendering <tt>:new</tt>
    # after a post request.
    #
    # Two additional options are relevant specifically to +respond_with+ -
    # 1. <tt>:location</tt> - overwrites the default redirect location used after
    #    a successful html +post+ request.
    # 2. <tt>:action</tt> - overwrites the default render action used after an
    #    unsuccessful html +post+ request.
    def respond_with(*resources, &block)
      raise "In order to use respond_with, first you need to declare the formats your " \
            "controller responds to in the class level" if self.class.mimes_for_respond_to.empty?

      if collector = retrieve_collector_from_mimes(&block)
        options = resources.size == 1 ? {} : resources.extract_options!
        options[:default_response] = collector.response
        (options.delete(:responder) || self.class.responder).call(self, resources, options)
      end
    end

  protected

    # Collect mimes declared in the class method respond_to valid for the
    # current action.
    def collect_mimes_from_class_level #:nodoc:
      action = action_name.to_s

      self.class.mimes_for_respond_to.keys.select do |mime|
        config = self.class.mimes_for_respond_to[mime]

        if config[:except]
          !config[:except].include?(action)
        elsif config[:only]
          config[:only].include?(action)
        else
          true
        end
      end
    end

    # Returns a Collector object containing the appropriate mime-type response
    # for the current request, based on the available responses defined by a block.
    # In typical usage this is the block passed to +respond_with+ or +respond_to+.
    #
    # Sends :not_acceptable to the client and returns nil if no suitable format
    # is available.
    def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
      mimes ||= collect_mimes_from_class_level
      collector = Collector.new(mimes)
      block.call(collector) if block_given?
      format = collector.negotiate_format(request)

      if format
        self.content_type ||= format.to_s
        lookup_context.formats = [format.to_sym]
        lookup_context.rendered_format = lookup_context.formats.first
        collector
      else
        raise ActionController::UnknownFormat
      end
    end

    # A container for responses available from the current controller for
    # requests for different mime-types sent to a particular action.
    #
    # The public controller methods +respond_with+ and +respond_to+ may be called
    # with a block that is used to define responses to different mime-types, e.g.
    # for +respond_to+ :
    #
    #   respond_to do |format|
    #     format.html
    #     format.xml { render xml: @people }
    #   end
    #
    # In this usage, the argument passed to the block (+format+ above) is an
    # instance of the ActionController::MimeResponds::Collector class. This
    # object serves as a container in which available responses can be stored by
    # calling any of the dynamically generated, mime-type-specific methods such
    # as +html+, +xml+ etc on the Collector. Each response is represented by a
    # corresponding block if present.
    #
    # A subsequent call to #negotiate_format(request) will enable the Collector
    # to determine which specific mime-type it should respond with for the current
    # request, with this response then being accessible by calling #response.
    class Collector
      include AbstractController::Collector
      attr_accessor :order, :format

      def initialize(mimes)
        @order, @responses = [], {}
        mimes.each { |mime| send(mime) }
      end

      def any(*args, &block)
        if args.any?
          args.each { |type| send(type, &block) }
        else
          custom(Mime::ALL, &block)
        end
      end
      alias :all :any

      def custom(mime_type, &block)
        mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
        @order << mime_type
        @responses[mime_type] ||= block
      end

      def response
        @responses[format] || @responses[Mime::ALL]
      end

      def negotiate_format(request)
        @format = request.negotiate_mime(order)
      end
    end
  end
end
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/struct'
require 'action_dispatch/http/mime_type'

module ActionController
  # Wraps the parameters hash into a nested hash. This will allow clients to submit
  # POST requests without having to specify any root elements.
  #
  # This functionality is enabled in +config/initializers/wrap_parameters.rb+
  # and can be customized. If you are upgrading to \Rails 3.1, this file will
  # need to be created for the functionality to be enabled.
  #
  # You could also turn it on per controller by setting the format array to
  # a non-empty array:
  #
  #     class UsersController < ApplicationController
  #       wrap_parameters format: [:json, :xml]
  #     end
  #
  # If you enable +ParamsWrapper+ for +:json+ format, instead of having to
  # send JSON parameters like this:
  #
  #     {"user": {"name": "Konata"}}
  #
  # You can send parameters like this:
  #
  #     {"name": "Konata"}
  #
  # And it will be wrapped into a nested hash with the key name matching the
  # controller's name. For example, if you're posting to +UsersController+,
  # your new +params+ hash will look like this:
  #
  #     {"name" => "Konata", "user" => {"name" => "Konata"}}
  #
  # You can also specify the key in which the parameters should be wrapped to,
  # and also the list of attributes it should wrap by using either +:include+ or
  # +:exclude+ options like this:
  #
  #     class UsersController < ApplicationController
  #       wrap_parameters :person, include: [:username, :password]
  #     end
  #
  # On ActiveRecord models with no +:include+ or +:exclude+ option set,
  # it will only wrap the parameters returned by the class method
  # <tt>attribute_names</tt>.
  #
  # If you're going to pass the parameters to an +ActiveModel+ object (such as
  # <tt>User.new(params[:user])</tt>), you might consider passing the model class to
  # the method instead. The +ParamsWrapper+ will actually try to determine the
  # list of attribute names from the model and only wrap those attributes:
  #
  #     class UsersController < ApplicationController
  #       wrap_parameters Person
  #     end
  #
  # You still could pass +:include+ and +:exclude+ to set the list of attributes
  # you want to wrap.
  #
  # By default, if you don't specify the key in which the parameters would be
  # wrapped to, +ParamsWrapper+ will actually try to determine if there's
  # a model related to it or not. This controller, for example:
  #
  #     class Admin::UsersController < ApplicationController
  #     end
  #
  # will try to check if <tt>Admin::User</tt> or +User+ model exists, and use it to
  # determine the wrapper key respectively. If both models don't exist,
  # it will then fallback to use +user+ as the key.
  module ParamsWrapper
    extend ActiveSupport::Concern

    EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)

    require 'mutex_m'

    class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc:
      include Mutex_m

      def self.from_hash(hash)
        name    = hash[:name]
        format  = Array(hash[:format])
        include = hash[:include] && Array(hash[:include]).collect(&:to_s)
        exclude = hash[:exclude] && Array(hash[:exclude]).collect(&:to_s)
        new name, format, include, exclude, nil, nil
      end

      def initialize(name, format, include, exclude, klass, model) # nodoc
        super
        @include_set = include
        @name_set    = name
      end

      def model
        super || synchronize { super || self.model = _default_wrap_model }
      end

      def include
        return super if @include_set

        m = model
        synchronize do
          return super if @include_set

          @include_set = true

          unless super || exclude
            if m.respond_to?(:attribute_names) && m.attribute_names.any?
              self.include = m.attribute_names
            end
          end
        end
      end

      def name
        return super if @name_set

        m = model
        synchronize do
          return super if @name_set

          @name_set = true

          unless super || klass.anonymous?
            self.name = m ? m.to_s.demodulize.underscore :
              klass.controller_name.singularize
          end
        end
      end

      private
      # Determine the wrapper model from the controller's name. By convention,
      # this could be done by trying to find the defined model that has the
      # same singularize name as the controller. For example, +UsersController+
      # will try to find if the +User+ model exists.
      #
      # This method also does namespace lookup. Foo::Bar::UsersController will
      # try to find Foo::Bar::User, Foo::User and finally User.
      def _default_wrap_model #:nodoc:
        return nil if klass.anonymous?
        model_name = klass.name.sub(/Controller$/, '').classify

        begin
          if model_klass = model_name.safe_constantize
            model_klass
          else
            namespaces = model_name.split("::")
            namespaces.delete_at(-2)
            break if namespaces.last == model_name
            model_name = namespaces.join("::")
          end
        end until model_klass

        model_klass
      end
    end

    included do
      class_attribute :_wrapper_options
      self._wrapper_options = Options.from_hash(format: [])
    end

    module ClassMethods
      def _set_wrapper_options(options)
        self._wrapper_options = Options.from_hash(options)
      end

      # Sets the name of the wrapper key, or the model which +ParamsWrapper+
      # would use to determine the attribute names from.
      #
      # ==== Examples
      #   wrap_parameters format: :xml
      #     # enables the parameter wrapper for XML format
      #
      #   wrap_parameters :person
      #     # wraps parameters into +params[:person]+ hash
      #
      #   wrap_parameters Person
      #     # wraps parameters by determining the wrapper key from Person class
      #     (+person+, in this case) and the list of attribute names
      #
      #   wrap_parameters include: [:username, :title]
      #     # wraps only +:username+ and +:title+ attributes from parameters.
      #
      #   wrap_parameters false
      #     # disables parameters wrapping for this controller altogether.
      #
      # ==== Options
      # * <tt>:format</tt> - The list of formats in which the parameters wrapper
      #   will be enabled.
      # * <tt>:include</tt> - The list of attribute names which parameters wrapper
      #   will wrap into a nested hash.
      # * <tt>:exclude</tt> - The list of attribute names which parameters wrapper
      #   will exclude from a nested hash.
      def wrap_parameters(name_or_model_or_options, options = {})
        model = nil

        case name_or_model_or_options
        when Hash
          options = name_or_model_or_options
        when false
          options = options.merge(:format => [])
        when Symbol, String
          options = options.merge(:name => name_or_model_or_options)
        else
          model = name_or_model_or_options
        end

        opts   = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options)
        opts.model = model
        opts.klass = self

        self._wrapper_options = opts
      end

      # Sets the default wrapper key or model which will be used to determine
      # wrapper key and attribute names. Will be called automatically when the
      # module is inherited.
      def inherited(klass)
        if klass._wrapper_options.format.any?
          params = klass._wrapper_options.dup
          params.klass = klass
          klass._wrapper_options = params
        end
        super
      end
    end

    # Performs parameters wrapping upon the request. Will be called automatically
    # by the metal call stack.
    def process_action(*args)
      if _wrapper_enabled?
        wrapped_hash = _wrap_parameters request.request_parameters
        wrapped_keys = request.request_parameters.keys
        wrapped_filtered_hash = _wrap_parameters request.filtered_parameters.slice(*wrapped_keys)

        # This will make the wrapped hash accessible from controller and view
        request.parameters.merge! wrapped_hash
        request.request_parameters.merge! wrapped_hash

        # This will make the wrapped hash displayed in the log file
        request.filtered_parameters.merge! wrapped_filtered_hash
      end
      super
    end

    private

      # Returns the wrapper key which will use to stored wrapped parameters.
      def _wrapper_key
        _wrapper_options.name
      end

      # Returns the list of enabled formats.
      def _wrapper_formats
        _wrapper_options.format
      end

      # Returns the list of parameters which will be selected for wrapped.
      def _wrap_parameters(parameters)
        value = if include_only = _wrapper_options.include
          parameters.slice(*include_only)
        else
          exclude = _wrapper_options.exclude || []
          parameters.except(*(exclude + EXCLUDE_PARAMETERS))
        end

        { _wrapper_key => value }
      end

      # Checks if we should perform parameters wrapping.
      def _wrapper_enabled?
        ref = request.content_mime_type.try(:ref)
        _wrapper_formats.include?(ref) && _wrapper_key && !request.request_parameters[_wrapper_key]
      end
  end
end
require 'action_dispatch/http/request'
require 'action_dispatch/http/response'

module ActionController
  module RackDelegation
    extend ActiveSupport::Concern

    delegate :headers, :status=, :location=, :content_type=,
             :status, :location, :content_type, :to => "@_response"

    def dispatch(action, request)
      set_response!(request)
      super(action, request)
    end

    def response_body=(body)
      response.body = body if response
      super
    end

    def reset_session
      @_request.reset_session
    end

    private

    def set_response!(request)
      @_response         = ActionDispatch::Response.new
      @_response.request = request
    end
  end
end
module ActionController
  class RedirectBackError < AbstractController::Error #:nodoc:
    DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].'

    def initialize(message = nil)
      super(message || DEFAULT_MESSAGE)
    end
  end

  module Redirecting
    extend ActiveSupport::Concern

    include AbstractController::Logger
    include ActionController::RackDelegation
    include ActionController::UrlFor

    # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
    #
    # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
    # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
    # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) or a protocol relative reference (like <tt>//</tt>) - Is passed straight through as the target for redirection.
    # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
    # * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
    # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
    #   Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
    #
    #   redirect_to action: "show", id: 5
    #   redirect_to post
    #   redirect_to "http://www.rubyonrails.org"
    #   redirect_to "/images/screenshot.jpg"
    #   redirect_to articles_url
    #   redirect_to :back
    #   redirect_to proc { edit_post_url(@post) }
    #
    # The redirection happens as a "302 Found" header unless otherwise specified.
    #
    #   redirect_to post_url(@post), status: :found
    #   redirect_to action: 'atom', status: :moved_permanently
    #   redirect_to post_url(@post), status: 301
    #   redirect_to action: 'atom', status: 302
    #
    # The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
    # integer, or a symbol representing the downcased, underscored and symbolized description.
    # Note that the status code must be a 3xx HTTP code, or redirection will not occur.
    #
    # If you are using XHR requests other than GET or POST and redirecting after the
    # request then some browsers will follow the redirect using the original request
    # method. This may lead to undesirable behavior such as a double DELETE. To work
    # around this  you can return a <tt>303 See Other</tt> status code which will be
    # followed using a GET request.
    #
    #   redirect_to posts_url, status: :see_other
    #   redirect_to action: 'index', status: 303
    #
    # It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names
    # +alert+ and +notice+ as well as a general purpose +flash+ bucket.
    #
    #   redirect_to post_url(@post), alert: "Watch it, mister!"
    #   redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
    #   redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
    #   redirect_to { action: 'atom' }, alert: "Something serious happened"
    #
    # When using <tt>redirect_to :back</tt>, if there is no referrer, ActionController::RedirectBackError will be raised. You may specify some fallback
    # behavior for this case by rescuing ActionController::RedirectBackError.
    def redirect_to(options = {}, response_status = {}) #:doc:
      raise ActionControllerError.new("Cannot redirect to nil!") unless options
      raise AbstractController::DoubleRenderError if response_body

      self.status        = _extract_redirect_to_status(options, response_status)
      self.location      = _compute_redirect_to_location(options)
      self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.h(location)}\">redirected</a>.</body></html>"
    end

    private
      def _extract_redirect_to_status(options, response_status)
        if options.is_a?(Hash) && options.key?(:status)
          Rack::Utils.status_code(options.delete(:status))
        elsif response_status.key?(:status)
          Rack::Utils.status_code(response_status[:status])
        else
          302
        end
      end

      def _compute_redirect_to_location(options)
        case options
        # The scheme name consist of a letter followed by any combination of
        # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
        # characters; and is terminated by a colon (":").
        # The protocol relative scheme starts with a double slash "//"
        when %r{\A(\w[\w+.-]*:|//).*}
          options
        when String
          request.protocol + request.host_with_port + options
        when :back
          request.headers["Referer"] or raise RedirectBackError
        when Proc
          _compute_redirect_to_location options.call
        else
          url_for(options)
        end.delete("\0\r\n")
      end
  end
end
require 'set'

module ActionController
  # See <tt>Renderers.add</tt>
  def self.add_renderer(key, &block)
    Renderers.add(key, &block)
  end

  module Renderers
    extend ActiveSupport::Concern

    included do
      class_attribute :_renderers
      self._renderers = Set.new.freeze
    end

    module ClassMethods
      def use_renderers(*args)
        renderers = _renderers + args
        self._renderers = renderers.freeze
      end
      alias use_renderer use_renderers
    end

    def render_to_body(options)
      _handle_render_options(options) || super
    end

    def _handle_render_options(options)
      _renderers.each do |name|
        if options.key?(name)
          _process_options(options)
          return send("_render_option_#{name}", options.delete(name), options)
        end
      end
      nil
    end

    # Hash of available renderers, mapping a renderer name to its proc.
    # Default keys are :json, :js, :xml.
    RENDERERS = Set.new

    # Adds a new renderer to call within controller actions.
    # A renderer is invoked by passing its name as an option to
    # <tt>AbstractController::Rendering#render</tt>. To create a renderer
    # pass it a name and a block. The block takes two arguments, the first
    # is the value paired with its key and the second is the remaining
    # hash of options passed to +render+.
    #
    # Create a csv renderer:
    #
    #   ActionController::Renderers.add :csv do |obj, options|
    #     filename = options[:filename] || 'data'
    #     str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
    #     send_data str, type: Mime::CSV,
    #       disposition: "attachment; filename=#{filename}.csv"
    #   end
    #
    # Note that we used Mime::CSV for the csv mime type as it comes with Rails.
    # For a custom renderer, you'll need to register a mime type with
    # <tt>Mime::Type.register</tt>.
    #
    # To use the csv renderer in a controller action:
    #
    #   def show
    #     @csvable = Csvable.find(params[:id])
    #     respond_to do |format|
    #       format.html
    #       format.csv { render csv: @csvable, filename: @csvable.name }
    #     }
    #   end
    # To use renderers and their mime types in more concise ways, see
    # <tt>ActionController::MimeResponds::ClassMethods.respond_to</tt> and
    # <tt>ActionController::MimeResponds#respond_with</tt>
    def self.add(key, &block)
      define_method("_render_option_#{key}", &block)
      RENDERERS << key.to_sym
    end

    module All
      extend ActiveSupport::Concern
      include Renderers

      included do
        self._renderers = RENDERERS
      end
    end

    add :json do |json, options|
      json = json.to_json(options) unless json.kind_of?(String)

      if options[:callback].present?
        self.content_type ||= Mime::JS
        "#{options[:callback]}(#{json})"
      else
        self.content_type ||= Mime::JSON
        json
      end
    end

    add :js do |js, options|
      self.content_type ||= Mime::JS
      js.respond_to?(:to_js) ? js.to_js(options) : js
    end

    add :xml do |xml, options|
      self.content_type ||= Mime::XML
      xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml
    end
  end
end
module ActionController
  module Rendering
    extend ActiveSupport::Concern

    include AbstractController::Rendering

    # Before processing, set the request formats in current controller formats.
    def process_action(*) #:nodoc:
      self.formats = request.formats.map { |x| x.ref }
      super
    end

    # Check for double render errors and set the content_type after rendering.
    def render(*args) #:nodoc:
      raise ::AbstractController::DoubleRenderError if response_body
      super
      self.content_type ||= Mime[lookup_context.rendered_format].to_s
      response_body
    end

    # Overwrite render_to_string because body can now be set to a rack body.
    def render_to_string(*)
      if self.response_body = super
        string = ""
        response_body.each { |r| string << r }
        string
      end
    ensure
      self.response_body = nil
    end

    def render_to_body(*)
      super || " "
    end

    private

    # Normalize arguments by catching blocks and setting them on :update.
    def _normalize_args(action=nil, options={}, &blk) #:nodoc:
      options = super
      options[:update] = blk if block_given?
      options
    end

    # Normalize both text and status options.
    def _normalize_options(options) #:nodoc:
      if options.key?(:text) && options[:text].respond_to?(:to_text)
        options[:text] = options[:text].to_text
      end

      if options.delete(:nothing) || (options.key?(:text) && options[:text].nil?)
        options[:text] = " "
      end

      if options[:status]
        options[:status] = Rack::Utils.status_code(options[:status])
      end

      super
    end

    # Process controller specific options, as status, content-type and location.
    def _process_options(options) #:nodoc:
      status, content_type, location = options.values_at(:status, :content_type, :location)

      self.status = status if status
      self.content_type = content_type if content_type
      self.headers["Location"] = url_for(location) if location

      super
    end
  end
end
require 'rack/session/abstract/id'
require 'action_controller/metal/exceptions'

module ActionController #:nodoc:
  class InvalidAuthenticityToken < ActionControllerError #:nodoc:
  end

  # Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks
  # by including a token in the rendered html for your application. This token is
  # stored as a random string in the session, to which an attacker does not have
  # access. When a request reaches your application, \Rails verifies the received
  # token with the token in the session. Only HTML and JavaScript requests are checked,
  # so this will not protect your XML API (presumably you'll have a different
  # authentication scheme there anyway). Also, GET requests are not protected as these
  # should be idempotent.
  #
  # It's important to remember that XML or JSON requests are also affected and if
  # you're building an API you'll need something like:
  #
  #   class ApplicationController < ActionController::Base
  #     protect_from_forgery
  #     skip_before_action :verify_authenticity_token, if: :json_request?
  #
  #     protected
  #
  #     def json_request?
  #       request.format.json?
  #     end
  #   end
  #
  # CSRF protection is turned on with the <tt>protect_from_forgery</tt> method,
  # which checks the token and resets the session if it doesn't match what was expected.
  # A call to this method is generated for new \Rails applications by default.
  #
  # The token parameter is named <tt>authenticity_token</tt> by default. The name and
  # value of this token must be added to every layout that renders forms by including
  # <tt>csrf_meta_tags</tt> in the html +head+.
  #
  # Learn more about CSRF attacks and securing your application in the
  # {Ruby on Rails Security Guide}[http://guides.rubyonrails.org/security.html].
  module RequestForgeryProtection
    extend ActiveSupport::Concern

    include AbstractController::Helpers
    include AbstractController::Callbacks

    included do
      # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
      # sets it to <tt>:authenticity_token</tt> by default.
      config_accessor :request_forgery_protection_token
      self.request_forgery_protection_token ||= :authenticity_token

      # Controls whether request forgery protection is turned on or not. Turned off by default only in test mode.
      config_accessor :allow_forgery_protection
      self.allow_forgery_protection = true if allow_forgery_protection.nil?

      helper_method :form_authenticity_token
      helper_method :protect_against_forgery?
    end

    module ClassMethods
      # Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
      #
      #   class FooController < ApplicationController
      #     protect_from_forgery except: :index
      #
      # You can disable csrf protection on controller-by-controller basis:
      #
      #   skip_before_action :verify_authenticity_token
      #
      # It can also be disabled for specific controller actions:
      #
      #   skip_before_action :verify_authenticity_token, except: [:create]
      #
      # Valid Options:
      #
      # * <tt>:only/:except</tt> - Passed to the <tt>before_action</tt> call. Set which actions are verified.
      # * <tt>:with</tt> - Set the method to handle unverified request.
      #
      # Valid unverified request handling methods are:
      # * <tt>:exception</tt> - Raises ActionController::InvalidAuthenticityToken exception.
      # * <tt>:reset_session</tt> - Resets the session.
      # * <tt>:null_session</tt> - Provides an empty session during request but doesn't reset it completely. Used as default if <tt>:with</tt> option is not specified.
      def protect_from_forgery(options = {})
        include protection_method_module(options[:with] || :null_session)
        self.request_forgery_protection_token ||= :authenticity_token
        prepend_before_action :verify_authenticity_token, options
      end

      private

      def protection_method_module(name)
        ActionController::RequestForgeryProtection::ProtectionMethods.const_get(name.to_s.classify)
      rescue NameError
        raise ArgumentError, 'Invalid request forgery protection method, use :null_session, :exception, or :reset_session'
      end
    end

    module ProtectionMethods
      module NullSession
        protected

        # This is the method that defines the application behavior when a request is found to be unverified.
        def handle_unverified_request
          request.session = NullSessionHash.new(request.env)
          request.env['action_dispatch.request.flash_hash'] = nil
          request.env['rack.session.options'] = { skip: true }
          request.env['action_dispatch.cookies'] = NullCookieJar.build(request)
        end

        class NullSessionHash < Rack::Session::Abstract::SessionHash #:nodoc:
          def initialize(env)
            super(nil, env)
            @data = {}
            @loaded = true
          end

          def exists?
            true
          end
        end

        class NullCookieJar < ActionDispatch::Cookies::CookieJar #:nodoc:
          def self.build(request)
            key_generator = request.env[ActionDispatch::Cookies::GENERATOR_KEY]
            host          = request.host
            secure        = request.ssl?

            new(key_generator, host, secure, options_for_env({}))
          end

          def write(*)
            # nothing
          end
        end
      end

      module ResetSession
        protected

        def handle_unverified_request
          reset_session
        end
      end

      module Exception
        protected

        def handle_unverified_request
          raise ActionController::InvalidAuthenticityToken
        end
      end
    end

    protected
      # The actual before_action that is used. Modify this to change how you handle unverified requests.
      def verify_authenticity_token
        unless verified_request?
          logger.warn "Can't verify CSRF token authenticity" if logger
          handle_unverified_request
        end
      end

      # Returns true or false if a request is verified. Checks:
      #
      # * is it a GET or HEAD request?  Gets should be safe and idempotent
      # * Does the form_authenticity_token match the given token value from the params?
      # * Does the X-CSRF-Token header match the form_authenticity_token
      def verified_request?
        !protect_against_forgery? || request.get? || request.head? ||
          form_authenticity_token == params[request_forgery_protection_token] ||
          form_authenticity_token == request.headers['X-CSRF-Token']
      end

      # Sets the token value for the current session.
      def form_authenticity_token
        session[:_csrf_token] ||= SecureRandom.base64(32)
      end

      # The form's authenticity parameter. Override to provide your own.
      def form_authenticity_param
        params[request_forgery_protection_token]
      end

      def protect_against_forgery?
        allow_forgery_protection
      end
  end
end
module ActionController #:nodoc:
  # This module is responsible to provide `rescue_from` helpers
  # to controllers and configure when detailed exceptions must be
  # shown.
  module Rescue
    extend ActiveSupport::Concern
    include ActiveSupport::Rescuable

    def rescue_with_handler(exception)
      if (exception.respond_to?(:original_exception) &&
          (orig_exception = exception.original_exception) &&
          handler_for_rescue(orig_exception))
        exception = orig_exception
      end
      super(exception)
    end

    # Override this method if you want to customize when detailed
    # exceptions must be shown. This method is only called when
    # consider_all_requests_local is false. By default, it returns
    # false, but someone may set it to `request.local?` so local
    # requests in production still shows the detailed exception pages.
    def show_detailed_exceptions?
      false
    end

    private
      def process_action(*args)
        super
      rescue Exception => exception
        request.env['action_dispatch.show_detailed_exceptions'] ||= show_detailed_exceptions?
        rescue_with_handler(exception) || raise(exception)
      end
  end
end
require 'active_support/json'

module ActionController #:nodoc:
  # Responsible for exposing a resource to different mime requests,
  # usually depending on the HTTP verb. The responder is triggered when
  # <code>respond_with</code> is called. The simplest case to study is a GET request:
  #
  #   class PeopleController < ApplicationController
  #     respond_to :html, :xml, :json
  #
  #     def index
  #       @people = Person.all
  #       respond_with(@people)
  #     end
  #   end
  #
  # When a request comes in, for example for an XML response, three steps happen:
  #
  #   1) the responder searches for a template at people/index.xml;
  #
  #   2) if the template is not available, it will invoke <code>#to_xml</code> on the given resource;
  #
  #   3) if the responder does not <code>respond_to :to_xml</code>, call <code>#to_format</code> on it.
  #
  # === Builtin HTTP verb semantics
  #
  # The default \Rails responder holds semantics for each HTTP verb. Depending on the
  # content type, verb and the resource status, it will behave differently.
  #
  # Using \Rails default responder, a POST request for creating an object could
  # be written as:
  #
  #   def create
  #     @user = User.new(params[:user])
  #     flash[:notice] = 'User was successfully created.' if @user.save
  #     respond_with(@user)
  #   end
  #
  # Which is exactly the same as:
  #
  #   def create
  #     @user = User.new(params[:user])
  #
  #     respond_to do |format|
  #       if @user.save
  #         flash[:notice] = 'User was successfully created.'
  #         format.html { redirect_to(@user) }
  #         format.xml { render xml: @user, status: :created, location: @user }
  #       else
  #         format.html { render action: "new" }
  #         format.xml { render xml: @user.errors, status: :unprocessable_entity }
  #       end
  #     end
  #   end
  #
  # The same happens for PATCH/PUT and DELETE requests.
  #
  # === Nested resources
  #
  # You can supply nested resources as you do in <code>form_for</code> and <code>polymorphic_url</code>.
  # Consider the project has many tasks example. The create action for
  # TasksController would be like:
  #
  #   def create
  #     @project = Project.find(params[:project_id])
  #     @task = @project.tasks.build(params[:task])
  #     flash[:notice] = 'Task was successfully created.' if @task.save
  #     respond_with(@project, @task)
  #   end
  #
  # Giving several resources ensures that the responder will redirect to
  # <code>project_task_url</code> instead of <code>task_url</code>.
  #
  # Namespaced and singleton resources require a symbol to be given, as in
  # polymorphic urls. If a project has one manager which has many tasks, it
  # should be invoked as:
  #
  #   respond_with(@project, :manager, @task)
  #
  # Note that if you give an array, it will be treated as a collection,
  # so the following is not equivalent:
  #
  #   respond_with [@project, :manager, @task]
  #
  # === Custom options
  #
  # <code>respond_with</code> also allows you to pass options that are forwarded
  # to the underlying render call. Those options are only applied for success
  # scenarios. For instance, you can do the following in the create method above:
  #
  #   def create
  #     @project = Project.find(params[:project_id])
  #     @task = @project.tasks.build(params[:task])
  #     flash[:notice] = 'Task was successfully created.' if @task.save
  #     respond_with(@project, @task, status: 201)
  #   end
  #
  # This will return status 201 if the task was saved successfully. If not,
  # it will simply ignore the given options and return status 422 and the
  # resource errors. To customize the failure scenario, you can pass a
  # a block to <code>respond_with</code>:
  #
  #   def create
  #     @project = Project.find(params[:project_id])
  #     @task = @project.tasks.build(params[:task])
  #     respond_with(@project, @task, status: 201) do |format|
  #       if @task.save
  #         flash[:notice] = 'Task was successfully created.'
  #       else
  #         format.html { render "some_special_template" }
  #       end
  #     end
  #   end
  #
  # Using <code>respond_with</code> with a block follows the same syntax as <code>respond_to</code>.
  class Responder
    attr_reader :controller, :request, :format, :resource, :resources, :options

    DEFAULT_ACTIONS_FOR_VERBS = {
      :post => :new,
      :patch => :edit,
      :put => :edit
    }

    def initialize(controller, resources, options={})
      @controller = controller
      @request = @controller.request
      @format = @controller.formats.first
      @resource = resources.last
      @resources = resources
      @options = options
      @action = options.delete(:action)
      @default_response = options.delete(:default_response)
    end

    delegate :head, :render, :redirect_to,   :to => :controller
    delegate :get?, :post?, :patch?, :put?, :delete?, :to => :request

    # Undefine :to_json and :to_yaml since it's defined on Object
    undef_method(:to_json) if method_defined?(:to_json)
    undef_method(:to_yaml) if method_defined?(:to_yaml)

    # Initializes a new responder an invoke the proper format. If the format is
    # not defined, call to_format.
    #
    def self.call(*args)
      new(*args).respond
    end

    # Main entry point for responder responsible to dispatch to the proper format.
    #
    def respond
      method = "to_#{format}"
      respond_to?(method) ? send(method) : to_format
    end

    # HTML format does not render the resource, it always attempt to render a
    # template.
    #
    def to_html
      default_render
    rescue ActionView::MissingTemplate => e
      navigation_behavior(e)
    end

    # to_js simply tries to render a template. If no template is found, raises the error.
    def to_js
      default_render
    end

    # All other formats follow the procedure below. First we try to render a
    # template, if the template is not available, we verify if the resource
    # responds to :to_format and display it.
    #
    def to_format
      if get? || !has_errors? || response_overridden?
        default_render
      else
        display_errors
      end
    rescue ActionView::MissingTemplate => e
      api_behavior(e)
    end

  protected

    # This is the common behavior for formats associated with browsing, like :html, :iphone and so forth.
    def navigation_behavior(error)
      if get?
        raise error
      elsif has_errors? && default_action
        render :action => default_action
      else
        redirect_to navigation_location
      end
    end

    # This is the common behavior for formats associated with APIs, such as :xml and :json.
    def api_behavior(error)
      raise error unless resourceful?

      if get?
        display resource
      elsif post?
        display resource, :status => :created, :location => api_location
      else
        head :no_content
      end
    end

    # Checks whether the resource responds to the current format or not.
    #
    def resourceful?
      resource.respond_to?("to_#{format}")
    end

    # Returns the resource location by retrieving it from the options or
    # returning the resources array.
    #
    def resource_location
      options[:location] || resources
    end
    alias :navigation_location :resource_location
    alias :api_location :resource_location

    # If a response block was given, use it, otherwise call render on
    # controller.
    #
    def default_render
      if @default_response
        @default_response.call(options)
      else
        controller.default_render(options)
      end
    end

    # Display is just a shortcut to render a resource with the current format.
    #
    #   display @user, status: :ok
    #
    # For XML requests it's equivalent to:
    #
    #   render xml: @user, status: :ok
    #
    # Options sent by the user are also used:
    #
    #   respond_with(@user, status: :created)
    #   display(@user, status: :ok)
    #
    # Results in:
    #
    #   render xml: @user, status: :created
    #
    def display(resource, given_options={})
      controller.render given_options.merge!(options).merge!(format => resource)
    end

    def display_errors
      controller.render format => resource_errors, :status => :unprocessable_entity
    end

    # Check whether the resource has errors.
    #
    def has_errors?
      resource.respond_to?(:errors) && !resource.errors.empty?
    end

    # By default, render the <code>:edit</code> action for HTML requests with errors, unless
    # the verb was POST.
    #
    def default_action
      @action ||= DEFAULT_ACTIONS_FOR_VERBS[request.request_method_symbol]
    end

    def resource_errors
      respond_to?("#{format}_resource_errors", true) ? send("#{format}_resource_errors") : resource.errors
    end

    def json_resource_errors
      {:errors => resource.errors}
    end

    def response_overridden?
      @default_response.present?
    end
  end
end
require 'rack/chunked'

module ActionController #:nodoc:
  # Allows views to be streamed back to the client as they are rendered.
  #
  # The default way Rails renders views is by first rendering the template
  # and then the layout. The response is sent to the client after the whole
  # template is rendered, all queries are made, and the layout is processed.
  #
  # Streaming inverts the rendering flow by rendering the layout first and
  # streaming each part of the layout as they are processed. This allows the
  # header of the HTML (which is usually in the layout) to be streamed back
  # to client very quickly, allowing JavaScripts and stylesheets to be loaded
  # earlier than usual.
  #
  # This approach was introduced in Rails 3.1 and is still improving. Several
  # Rack middlewares may not work and you need to be careful when streaming.
  # Those points are going to be addressed soon.
  #
  # In order to use streaming, you will need to use a Ruby version that
  # supports fibers (fibers are supported since version 1.9.2 of the main
  # Ruby implementation).
  #
  # Streaming can be added to a given template easily, all you need to do is
  # to pass the :stream option.
  #
  #   class PostsController
  #     def index
  #       @posts = Post.all
  #       render stream: true
  #     end
  #   end
  #
  # == When to use streaming
  #
  # Streaming may be considered to be overkill for lightweight actions like
  # +new+ or +edit+. The real benefit of streaming is on expensive actions
  # that, for example, do a lot of queries on the database.
  #
  # In such actions, you want to delay queries execution as much as you can.
  # For example, imagine the following +dashboard+ action:
  #
  #   def dashboard
  #     @posts = Post.all
  #     @pages = Page.all
  #     @articles = Article.all
  #   end
  #
  # Most of the queries here are happening in the controller. In order to benefit
  # from streaming you would want to rewrite it as:
  #
  #   def dashboard
  #     # Allow lazy execution of the queries
  #     @posts = Post.all
  #     @pages = Page.all
  #     @articles = Article.all
  #     render stream: true
  #   end
  #
  # Notice that :stream only works with templates. Rendering :json
  # or :xml with :stream won't work.
  #
  # == Communication between layout and template
  #
  # When streaming, rendering happens top-down instead of inside-out.
  # Rails starts with the layout, and the template is rendered later,
  # when its +yield+ is reached.
  #
  # This means that, if your application currently relies on instance
  # variables set in the template to be used in the layout, they won't
  # work once you move to streaming. The proper way to communicate
  # between layout and template, regardless of whether you use streaming
  # or not, is by using +content_for+, +provide+ and +yield+.
  #
  # Take a simple example where the layout expects the template to tell
  # which title to use:
  #
  #   <html>
  #     <head><title><%= yield :title %></title></head>
  #     <body><%= yield %></body>
  #   </html>
  #
  # You would use +content_for+ in your template to specify the title:
  #
  #   <%= content_for :title, "Main" %>
  #   Hello
  #
  # And the final result would be:
  #
  #   <html>
  #     <head><title>Main</title></head>
  #     <body>Hello</body>
  #   </html>
  #
  # However, if +content_for+ is called several times, the final result
  # would have all calls concatenated. For instance, if we have the following
  # template:
  #
  #   <%= content_for :title, "Main" %>
  #   Hello
  #   <%= content_for :title, " page" %>
  #
  # The final result would be:
  #
  #   <html>
  #     <head><title>Main page</title></head>
  #     <body>Hello</body>
  #   </html>
  #
  # This means that, if you have <code>yield :title</code> in your layout
  # and you want to use streaming, you would have to render the whole template
  # (and eventually trigger all queries) before streaming the title and all
  # assets, which kills the purpose of streaming. For this reason Rails 3.1
  # introduces a new helper called +provide+ that does the same as +content_for+
  # but tells the layout to stop searching for other entries and continue rendering.
  #
  # For instance, the template above using +provide+ would be:
  #
  #   <%= provide :title, "Main" %>
  #   Hello
  #   <%= content_for :title, " page" %>
  #
  # Giving:
  #
  #   <html>
  #     <head><title>Main</title></head>
  #     <body>Hello</body>
  #   </html>
  #
  # That said, when streaming, you need to properly check your templates
  # and choose when to use +provide+ and +content_for+.
  #
  # == Headers, cookies, session and flash
  #
  # When streaming, the HTTP headers are sent to the client right before
  # it renders the first line. This means that, modifying headers, cookies,
  # session or flash after the template starts rendering will not propagate
  # to the client.
  #
  # == Middlewares
  #
  # Middlewares that need to manipulate the body won't work with streaming.
  # You should disable those middlewares whenever streaming in development
  # or production. For instance, <tt>Rack::Bug</tt> won't work when streaming as it
  # needs to inject contents in the HTML body.
  #
  # Also <tt>Rack::Cache</tt> won't work with streaming as it does not support
  # streaming bodies yet. Whenever streaming Cache-Control is automatically
  # set to "no-cache".
  #
  # == Errors
  #
  # When it comes to streaming, exceptions get a bit more complicated. This
  # happens because part of the template was already rendered and streamed to
  # the client, making it impossible to render a whole exception page.
  #
  # Currently, when an exception happens in development or production, Rails
  # will automatically stream to the client:
  #
  #   "><script>window.location = "/500.html"</script></html>
  #
  # The first two characters (">) are required in case the exception happens
  # while rendering attributes for a given tag. You can check the real cause
  # for the exception in your logger.
  #
  # == Web server support
  #
  # Not all web servers support streaming out-of-the-box. You need to check
  # the instructions for each of them.
  #
  # ==== Unicorn
  #
  # Unicorn supports streaming but it needs to be configured. For this, you
  # need to create a config file as follow:
  #
  #   # unicorn.config.rb
  #   listen 3000, tcp_nopush: false
  #
  # And use it on initialization:
  #
  #   unicorn_rails --config-file unicorn.config.rb
  #
  # You may also want to configure other parameters like <tt>:tcp_nodelay</tt>.
  # Please check its documentation for more information: http://unicorn.bogomips.org/Unicorn/Configurator.html#method-i-listen
  #
  # If you are using Unicorn with Nginx, you may need to tweak Nginx.
  # Streaming should work out of the box on Rainbows.
  #
  # ==== Passenger
  #
  # To be described.
  #
  module Streaming
    extend ActiveSupport::Concern

    include AbstractController::Rendering

    protected

    # Set proper cache control and transfer encoding when streaming
    def _process_options(options) #:nodoc:
      super
      if options[:stream]
        if env["HTTP_VERSION"] == "HTTP/1.0"
          options.delete(:stream)
        else
          headers["Cache-Control"] ||= "no-cache"
          headers["Transfer-Encoding"] = "chunked"
          headers.delete("Content-Length")
        end
      end
    end

    # Call render_body if we are streaming instead of usual +render+.
    def _render_template(options) #:nodoc:
      if options.delete(:stream)
        Rack::Chunked::Body.new view_renderer.render_body(view_context, options)
      else
        super
      end
    end
  end
end
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/array/wrap'
require 'active_support/rescuable'
require 'action_dispatch/http/upload'

module ActionController
  # Raised when a required parameter is missing.
  #
  #   params = ActionController::Parameters.new(a: {})
  #   params.fetch(:b)
  #   # => ActionController::ParameterMissing: param not found: b
  #   params.require(:a)
  #   # => ActionController::ParameterMissing: param not found: a
  class ParameterMissing < KeyError
    attr_reader :param # :nodoc:

    def initialize(param) # :nodoc:
      @param = param
      super("param not found: #{param}")
    end
  end

  # Raised when a supplied parameter is not expected.
  #
  #   params = ActionController::Parameters.new(a: "123", b: "456")
  #   params.permit(:c)
  #   # => ActionController::UnpermittedParameters: found unexpected keys: a, b
  class UnpermittedParameters < IndexError
    attr_reader :params # :nodoc:

    def initialize(params) # :nodoc:
      @params = params
      super("found unpermitted parameters: #{params.join(", ")}")
    end
  end

  # == Action Controller \Parameters
  #
  # Allows to choose which attributes should be whitelisted for mass updating
  # and thus prevent accidentally exposing that which shouldn’t be exposed.
  # Provides two methods for this purpose: #require and #permit. The former is
  # used to mark parameters as required. The latter is used to set the parameter
  # as permitted and limit which attributes should be allowed for mass updating.
  #
  #   params = ActionController::Parameters.new({
  #     person: {
  #       name: 'Francesco',
  #       age:  22,
  #       role: 'admin'
  #     }
  #   })
  #
  #   permitted = params.require(:person).permit(:name, :age)
  #   permitted            # => {"name"=>"Francesco", "age"=>22}
  #   permitted.class      # => ActionController::Parameters
  #   permitted.permitted? # => true
  #
  #   Person.first.update!(permitted)
  #   # => #<Person id: 1, name: "Francesco", age: 22, role: "user">
  #
  # It provides two options that controls the top-level behavior of new instances:
  #
  # * +permit_all_parameters+ - If it's +true+, all the parameters will be
  #   permitted by default. The default is +false+.
  # * +action_on_unpermitted_parameters+ - Allow to control the behavior when parameters
  #   that are not explicitly permitted are found. The values can be <tt>:log</tt> to
  #   write a message on the logger or <tt>:raise</tt> to raise
  #   ActionController::UnpermittedParameters exception. The default value is <tt>:log</tt>
  #   in test and development environments, +false+ otherwise.
  #
  #   params = ActionController::Parameters.new
  #   params.permitted? # => false
  #
  #   ActionController::Parameters.permit_all_parameters = true
  #
  #   params = ActionController::Parameters.new
  #   params.permitted? # => true
  #
  #   params = ActionController::Parameters.new(a: "123", b: "456")
  #   params.permit(:c)
  #   # => {}
  #
  #   ActionController::Parameters.action_on_unpermitted_parameters = :raise
  #
  #   params = ActionController::Parameters.new(a: "123", b: "456")
  #   params.permit(:c)
  #   # => ActionController::UnpermittedParameters: found unpermitted keys: a, b
  #
  # <tt>ActionController::Parameters</tt> is inherited from
  # <tt>ActiveSupport::HashWithIndifferentAccess</tt>, this means
  # that you can fetch values using either <tt>:key</tt> or <tt>"key"</tt>.
  #
  #   params = ActionController::Parameters.new(key: 'value')
  #   params[:key]  # => "value"
  #   params["key"] # => "value"
  class Parameters < ActiveSupport::HashWithIndifferentAccess
    cattr_accessor :permit_all_parameters, instance_accessor: false
    cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false

    # Never raise an UnpermittedParameters exception because of these params
    # are present. They are added by Rails and it's of no concern.
    NEVER_UNPERMITTED_PARAMS = %w( controller action )

    # Returns a new instance of <tt>ActionController::Parameters</tt>.
    # Also, sets the +permitted+ attribute to the default value of
    # <tt>ActionController::Parameters.permit_all_parameters</tt>.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   params = ActionController::Parameters.new(name: 'Francesco')
    #   params.permitted?  # => false
    #   Person.new(params) # => ActiveModel::ForbiddenAttributesError
    #
    #   ActionController::Parameters.permit_all_parameters = true
    #
    #   params = ActionController::Parameters.new(name: 'Francesco')
    #   params.permitted?  # => true
    #   Person.new(params) # => #<Person id: nil, name: "Francesco">
    def initialize(attributes = nil)
      super(attributes)
      @permitted = self.class.permit_all_parameters
    end

    # Returns +true+ if the parameter is permitted, +false+ otherwise.
    #
    #   params = ActionController::Parameters.new
    #   params.permitted? # => false
    #   params.permit!
    #   params.permitted? # => true
    def permitted?
      @permitted
    end

    # Sets the +permitted+ attribute to +true+. This can be used to pass
    # mass assignment. Returns +self+.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   params = ActionController::Parameters.new(name: 'Francesco')
    #   params.permitted?  # => false
    #   Person.new(params) # => ActiveModel::ForbiddenAttributesError
    #   params.permit!
    #   params.permitted?  # => true
    #   Person.new(params) # => #<Person id: nil, name: "Francesco">
    def permit!
      each_pair do |key, value|
        convert_hashes_to_parameters(key, value)
        self[key].permit! if self[key].respond_to? :permit!
      end

      @permitted = true
      self
    end

    # Ensures that a parameter is present. If it's present, returns
    # the parameter at the given +key+, otherwise raises an
    # <tt>ActionController::ParameterMissing</tt> error.
    #
    #   ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)
    #   # => {"name"=>"Francesco"}
    #
    #   ActionController::Parameters.new(person: nil).require(:person)
    #   # => ActionController::ParameterMissing: param not found: person
    #
    #   ActionController::Parameters.new(person: {}).require(:person)
    #   # => ActionController::ParameterMissing: param not found: person
    def require(key)
      self[key].presence || raise(ParameterMissing.new(key))
    end

    # Alias of #require.
    alias :required :require

    # Returns a new <tt>ActionController::Parameters</tt> instance that
    # includes only the given +filters+ and sets the +permitted+ attribute
    # for the object to +true+. This is useful for limiting which attributes
    # should be allowed for mass updating.
    #
    #   params = ActionController::Parameters.new(user: { name: 'Francesco', age: 22, role: 'admin' })
    #   permitted = params.require(:user).permit(:name, :age)
    #   permitted.permitted?      # => true
    #   permitted.has_key?(:name) # => true
    #   permitted.has_key?(:age)  # => true
    #   permitted.has_key?(:role) # => false
    #
    # Only permitted scalars pass the filter. For example, given
    #
    #   params.permit(:name)
    #
    # +:name+ passes it is a key of +params+ whose associated value is of type
    # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
    # +Date+, +Time+, +DateTime+, +StringIO+, +IO+, or
    # +ActionDispatch::Http::UploadedFile+. Otherwise, the key +:name+ is
    # filtered out.
    #
    # You may declare that the parameter should be an array of permitted scalars
    # by mapping it to an empty array:
    #
    #   params.permit(tags: [])
    #
    # You can also use +permit+ on nested parameters, like:
    #
    #   params = ActionController::Parameters.new({
    #     person: {
    #       name: 'Francesco',
    #       age:  22,
    #       pets: [{
    #         name: 'Purplish',
    #         category: 'dogs'
    #       }]
    #     }
    #   })
    #
    #   permitted = params.permit(person: [ :name, { pets: :name } ])
    #   permitted.permitted?                    # => true
    #   permitted[:person][:name]               # => "Francesco"
    #   permitted[:person][:age]                # => nil
    #   permitted[:person][:pets][0][:name]     # => "Purplish"
    #   permitted[:person][:pets][0][:category] # => nil
    #
    # Note that if you use +permit+ in a key that points to a hash,
    # it won't allow all the hash. You also need to specify which
    # attributes inside the hash should be whitelisted.
    #
    #   params = ActionController::Parameters.new({
    #     person: {
    #       contact: {
    #         email: 'none@test.com'
    #         phone: '555-1234'
    #       }
    #     }
    #   })
    #
    #   params.require(:person).permit(:contact)
    #   # => {}
    #
    #   params.require(:person).permit(contact: :phone)
    #   # => {"contact"=>{"phone"=>"555-1234"}}
    #
    #   params.require(:person).permit(contact: [ :email, :phone ])
    #   # => {"contact"=>{"email"=>"none@test.com", "phone"=>"555-1234"}}
    def permit(*filters)
      params = self.class.new

      filters.flatten.each do |filter|
        case filter
        when Symbol, String
          permitted_scalar_filter(params, filter)
        when Hash then
          hash_filter(params, filter)
        end
      end

      unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters

      params.permit!
    end

    # Returns a parameter for the given +key+. If not found,
    # returns +nil+.
    #
    #   params = ActionController::Parameters.new(person: { name: 'Francesco' })
    #   params[:person] # => {"name"=>"Francesco"}
    #   params[:none]   # => nil
    def [](key)
      convert_hashes_to_parameters(key, super)
    end

    # Returns a parameter for the given +key+. If the +key+
    # can't be found, there are several options: With no other arguments,
    # it will raise an <tt>ActionController::ParameterMissing</tt> error;
    # if more arguments are given, then that will be returned; if a block
    # is given, then that will be run and its result returned.
    #
    #   params = ActionController::Parameters.new(person: { name: 'Francesco' })
    #   params.fetch(:person)               # => {"name"=>"Francesco"}
    #   params.fetch(:none)                 # => ActionController::ParameterMissing: param not found: none
    #   params.fetch(:none, 'Francesco')    # => "Francesco"
    #   params.fetch(:none) { 'Francesco' } # => "Francesco"
    def fetch(key, *args)
      convert_hashes_to_parameters(key, super)
    rescue KeyError
      raise ActionController::ParameterMissing.new(key)
    end

    # Returns a new <tt>ActionController::Parameters</tt> instance that
    # includes only the given +keys+. If the given +keys+
    # don't exist, returns an empty hash.
    #
    #   params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
    #   params.slice(:a, :b) # => {"a"=>1, "b"=>2}
    #   params.slice(:d)     # => {}
    def slice(*keys)
      self.class.new(super).tap do |new_instance|
        new_instance.instance_variable_set :@permitted, @permitted
      end
    end

    # Returns an exact copy of the <tt>ActionController::Parameters</tt>
    # instance. +permitted+ state is kept on the duped object.
    #
    #   params = ActionController::Parameters.new(a: 1)
    #   params.permit!
    #   params.permitted?        # => true
    #   copy_params = params.dup # => {"a"=>1}
    #   copy_params.permitted?   # => true
    def dup
      super.tap do |duplicate|
        duplicate.instance_variable_set :@permitted, @permitted
      end
    end

    private
      def convert_hashes_to_parameters(key, value)
        if value.is_a?(Parameters) || !value.is_a?(Hash)
          value
        else
          # Convert to Parameters on first access
          self[key] = self.class.new(value)
        end
      end

      def each_element(object)
        if object.is_a?(Array)
          object.map { |el| yield el }.compact
        elsif object.is_a?(Hash) && object.keys.all? { |k| k =~ /\A-?\d+\z/ }
          hash = object.class.new
          object.each { |k,v| hash[k] = yield v }
          hash
        else
          yield object
        end
      end

      def unpermitted_parameters!(params)
        unpermitted_keys = unpermitted_keys(params)
        if unpermitted_keys.any?
          case self.class.action_on_unpermitted_parameters
          when :log
            ActionController::Base.logger.debug "Unpermitted parameters: #{unpermitted_keys.join(", ")}"
          when :raise
            raise ActionController::UnpermittedParameters.new(unpermitted_keys)
          end
        end
      end

      def unpermitted_keys(params)
        self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
      end

      #
      # --- Filtering ----------------------------------------------------------
      #

      # This is a white list of permitted scalar types that includes the ones
      # supported in XML and JSON requests.
      #
      # This list is in particular used to filter ordinary requests, String goes
      # as first element to quickly short-circuit the common case.
      #
      # If you modify this collection please update the API of +permit+ above.
      PERMITTED_SCALAR_TYPES = [
        String,
        Symbol,
        NilClass,
        Numeric,
        TrueClass,
        FalseClass,
        Date,
        Time,
        # DateTimes are Dates, we document the type but avoid the redundant check.
        StringIO,
        IO,
        ActionDispatch::Http::UploadedFile,
      ]

      def permitted_scalar?(value)
        PERMITTED_SCALAR_TYPES.any? {|type| value.is_a?(type)}
      end

      def permitted_scalar_filter(params, key)
        if has_key?(key) && permitted_scalar?(self[key])
          params[key] = self[key]
        end

        keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k|
          if permitted_scalar?(self[k])
            params[k] = self[k]
          end
        end
      end

      def array_of_permitted_scalars?(value)
        if value.is_a?(Array)
          value.all? {|element| permitted_scalar?(element)}
        end
      end

      def array_of_permitted_scalars_filter(params, key)
        if has_key?(key) && array_of_permitted_scalars?(self[key])
          params[key] = self[key]
        end
      end

      EMPTY_ARRAY = []
      def hash_filter(params, filter)
        filter = filter.with_indifferent_access

        # Slicing filters out non-declared keys.
        slice(*filter.keys).each do |key, value|
          return unless value

          if filter[key] == EMPTY_ARRAY
            # Declaration { comment_ids: [] }.
            array_of_permitted_scalars_filter(params, key)
          else
            # Declaration { user: :name } or { user: [:name, :age, { adress: ... }] }.
            params[key] = each_element(value) do |element|
              if element.is_a?(Hash)
                element = self.class.new(element) unless element.respond_to?(:permit)
                element.permit(*Array.wrap(filter[key]))
              end
            end
          end
        end
      end
  end

  # == Strong \Parameters
  #
  # It provides an interface for protecting attributes from end-user
  # assignment. This makes Action Controller parameters forbidden
  # to be used in Active Model mass assignment until they have been
  # whitelisted.
  #
  # In addition, parameters can be marked as required and flow through a
  # predefined raise/rescue flow to end up as a 400 Bad Request with no
  # effort.
  #
  #   class PeopleController < ActionController::Base
  #     # Using "Person.create(params[:person])" would raise an
  #     # ActiveModel::ForbiddenAttributes exception because it'd
  #     # be using mass assignment without an explicit permit step.
  #     # This is the recommended form:
  #     def create
  #       Person.create(person_params)
  #     end
  #
  #     # This will pass with flying colors as long as there's a person key in the
  #     # parameters, otherwise it'll raise an ActionController::MissingParameter
  #     # exception, which will get caught by ActionController::Base and turned
  #     # into a 400 Bad Request reply.
  #     def update
  #       redirect_to current_account.people.find(params[:id]).tap { |person|
  #         person.update!(person_params)
  #       }
  #     end
  #
  #     private
  #       # Using a private method to encapsulate the permissible parameters is
  #       # just a good pattern since you'll be able to reuse the same permit
  #       # list between create and update. Also, you can specialize this method
  #       # with per-user checking of permissible attributes.
  #       def person_params
  #         params.require(:person).permit(:name, :age)
  #       end
  #   end
  #
  # In order to use <tt>accepts_nested_attribute_for</tt> with Strong \Parameters, you
  # will need to specify which nested attributes should be whitelisted.
  #
  #   class Person
  #     has_many :pets
  #     accepts_nested_attributes_for :pets
  #   end
  #
  #   class PeopleController < ActionController::Base
  #     def create
  #       Person.create(person_params)
  #     end
  #
  #     ...
  #
  #     private
  #
  #       def person_params
  #         # It's mandatory to specify the nested attributes that should be whitelisted.
  #         # If you use `permit` with just the key that points to the nested attributes hash,
  #         # it will return an empty hash.
  #         params.require(:person).permit(:name, :age, pets_attributes: [ :name, :category ])
  #       end
  #   end
  #
  # See ActionController::Parameters.require and ActionController::Parameters.permit
  # for more information.
  module StrongParameters
    extend ActiveSupport::Concern
    include ActiveSupport::Rescuable

    # Returns a new ActionController::Parameters object that
    # has been instantiated with the <tt>request.parameters</tt>.
    def params
      @_params ||= Parameters.new(request.parameters)
    end

    # Assigns the given +value+ to the +params+ hash. If +value+
    # is a Hash, this will create an ActionController::Parameters
    # object that has been instantiated with the given +value+ hash.
    def params=(value)
      @_params = value.is_a?(Hash) ? Parameters.new(value) : value
    end
  end
end
module ActionController
  module Testing
    extend ActiveSupport::Concern

    include RackDelegation

    # TODO : Rewrite tests using controller.headers= to use Rack env
    def headers=(new_headers)
      @_response ||= ActionDispatch::Response.new
      @_response.headers.replace(new_headers)
    end

    # Behavior specific to functional tests
    module Functional # :nodoc:
      def set_response!(request)
      end

      def recycle!
        @_url_options = nil
        self.response_body = nil
        self.formats = nil
        self.params = nil
      end
    end

    module ClassMethods
      def before_filters
        _process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
      end
    end
  end
end
module ActionController
  # Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
  # the <tt>_routes</tt> method. Otherwise, an exception will be raised.
  #
  # In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
  # url options like the +host+. In order to do so, this module requires the host class
  # to implement +env+ and +request+, which need to be a Rack-compatible.
  #
  #   class RootUrl
  #     include ActionController::UrlFor
  #     include Rails.application.routes.url_helpers
  #
  #     delegate :env, :request, to: :controller
  #
  #     def initialize(controller)
  #       @controller = controller
  #       @url        = root_path # named route from the application.
  #     end
  #   end
  module UrlFor
    extend ActiveSupport::Concern

    include AbstractController::UrlFor

    def url_options
      @_url_options ||= super.reverse_merge(
        :host => request.host,
        :port => request.optional_port,
        :protocol => request.protocol,
        :_recall => request.symbolized_path_parameters
      ).freeze

      if (same_origin = _routes.equal?(env["action_dispatch.routes"])) ||
         (script_name = env["ROUTES_#{_routes.object_id}_SCRIPT_NAME"]) ||
         (original_script_name = env['SCRIPT_NAME'])
        @_url_options.dup.tap do |options|
          if original_script_name
            options[:original_script_name] = original_script_name
          else
            options[:script_name] = same_origin ? request.script_name.dup : script_name
          end
          options.freeze
        end
      else
        @_url_options
      end
    end
  end
end
require 'active_support/core_ext/array/extract_options'
require 'action_dispatch/middleware/stack'

module ActionController
  # Extend ActionDispatch middleware stack to make it aware of options
  # allowing the following syntax in controllers:
  #
  #   class PostsController < ApplicationController
  #     use AuthenticationMiddleware, except: [:index, :show]
  #   end
  #
  class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
    class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
      def initialize(klass, *args, &block)
        options = args.extract_options!
        @only   = Array(options.delete(:only)).map(&:to_s)
        @except = Array(options.delete(:except)).map(&:to_s)
        args << options unless options.empty?
        super
      end

      def valid?(action)
        if @only.present?
          @only.include?(action)
        elsif @except.present?
          !@except.include?(action)
        else
          true
        end
      end
    end

    def build(action, app=nil, &block)
      app  ||= block
      action = action.to_s
      raise "MiddlewareStack#build requires an app" unless app

      middlewares.reverse.inject(app) do |a, middleware|
        middleware.valid?(action) ?
          middleware.build(a) : a
      end
    end
  end

  # <tt>ActionController::Metal</tt> is the simplest possible controller, providing a
  # valid Rack interface without the additional niceties provided by
  # <tt>ActionController::Base</tt>.
  #
  # A sample metal controller might look like this:
  #
  #   class HelloController < ActionController::Metal
  #     def index
  #       self.response_body = "Hello World!"
  #     end
  #   end
  #
  # And then to route requests to your metal controller, you would add
  # something like this to <tt>config/routes.rb</tt>:
  #
  #   match 'hello', to: HelloController.action(:index)
  #
  # The +action+ method returns a valid Rack application for the \Rails
  # router to dispatch to.
  #
  # == Rendering Helpers
  #
  # <tt>ActionController::Metal</tt> by default provides no utilities for rendering
  # views, partials, or other responses aside from explicitly calling of
  # <tt>response_body=</tt>, <tt>content_type=</tt>, and <tt>status=</tt>. To
  # add the render helpers you're used to having in a normal controller, you
  # can do the following:
  #
  #   class HelloController < ActionController::Metal
  #     include ActionController::Rendering
  #     append_view_path "#{Rails.root}/app/views"
  #
  #     def index
  #       render "hello/index"
  #     end
  #   end
  #
  # == Redirection Helpers
  #
  # To add redirection helpers to your metal controller, do the following:
  #
  #   class HelloController < ActionController::Metal
  #     include ActionController::Redirecting
  #     include Rails.application.routes.url_helpers
  #
  #     def index
  #       redirect_to root_url
  #     end
  #   end
  #
  # == Other Helpers
  #
  # You can refer to the modules included in <tt>ActionController::Base</tt> to see
  # other features you can bring into your metal controller.
  #
  class Metal < AbstractController::Base
    abstract!

    attr_internal_writer :env

    def env
      @_env ||= {}
    end

    # Returns the last part of the controller's name, underscored, without the ending
    # <tt>Controller</tt>. For instance, PostsController returns <tt>posts</tt>.
    # Namespaces are left out, so Admin::PostsController returns <tt>posts</tt> as well.
    #
    # ==== Returns
    # * <tt>string</tt>
    def self.controller_name
      @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore
    end

    # Delegates to the class' <tt>controller_name</tt>
    def controller_name
      self.class.controller_name
    end

    # The details below can be overridden to support a specific
    # Request and Response object. The default ActionController::Base
    # implementation includes RackDelegation, which makes a request
    # and response object available. You might wish to control the
    # environment and response manually for performance reasons.

    attr_internal :headers, :response, :request
    delegate :session, :to => "@_request"

    def initialize
      @_headers = {"Content-Type" => "text/html"}
      @_status = 200
      @_request = nil
      @_response = nil
      @_routes = nil
      super
    end

    def params
      @_params ||= request.parameters
    end

    def params=(val)
      @_params = val
    end

    # Basic implementations for content_type=, location=, and headers are
    # provided to reduce the dependency on the RackDelegation module
    # in Renderer and Redirector.

    def content_type=(type)
      headers["Content-Type"] = type.to_s
    end

    def content_type
      headers["Content-Type"]
    end

    def location
      headers["Location"]
    end

    def location=(url)
      headers["Location"] = url
    end

    # basic url_for that can be overridden for more robust functionality
    def url_for(string)
      string
    end

    def status
      @_status
    end

    def status=(status)
      @_status = Rack::Utils.status_code(status)
    end

    def response_body=(body)
      body = [body] unless body.nil? || body.respond_to?(:each)
      super
    end

    def performed?
      response_body || (response && response.committed?)
    end

    def dispatch(name, request) #:nodoc:
      @_request = request
      @_env = request.env
      @_env['action_controller.instance'] = self
      process(name)
      to_a
    end

    def to_a #:nodoc:
      response ? response.to_a : [status, headers, response_body]
    end

    class_attribute :middleware_stack
    self.middleware_stack = ActionController::MiddlewareStack.new

    def self.inherited(base) # :nodoc:
      base.middleware_stack = middleware_stack.dup
      super
    end

    # Pushes the given Rack middleware and its arguments to the bottom of the
    # middleware stack.
    def self.use(*args, &block)
      middleware_stack.use(*args, &block)
    end

    # Alias for +middleware_stack+.
    def self.middleware
      middleware_stack
    end

    # Makes the controller a Rack endpoint that runs the action in the given
    # +env+'s +action_dispatch.request.path_parameters+ key.
    def self.call(env)
      action(env['action_dispatch.request.path_parameters'][:action]).call(env)
    end

    # Returns a Rack endpoint for the given action name.
    def self.action(name, klass = ActionDispatch::Request)
      middleware_stack.build(name.to_s) do |env|
        new.dispatch(name, klass.new(env))
      end
    end
  end
end
module ActionController
  class Middleware < Metal
    class ActionMiddleware
      def initialize(controller, app)
        @controller, @app = controller, app
      end

      def call(env)
        request = ActionDispatch::Request.new(env)
        @controller.build(@app).dispatch(:index, request)
      end
    end

    class << self
      alias build new

      def new(app)
        ActionMiddleware.new(self, app)
      end
    end

    attr_internal :app

    def process(action)
      response = super
      self.status, self.headers, self.response_body = response if response.is_a?(Array)
      response
    end

    def initialize(app)
      super()
      @_app = app
    end

    def index
      call(env)
    end
  end
endmodule ActionController
  module ModelNaming
    # Converts the given object to an ActiveModel compliant one.
    def convert_to_model(object)
      object.respond_to?(:to_model) ? object.to_model : object
    end

    def model_name_from_record_or_class(record_or_class)
      (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name
    end
  end
end
require "rails"
require "action_controller"
require "action_dispatch/railtie"
require "action_view/railtie"
require "abstract_controller/railties/routes_helpers"
require "action_controller/railties/helpers"

module ActionController
  class Railtie < Rails::Railtie #:nodoc:
    config.action_controller = ActiveSupport::OrderedOptions.new

    config.eager_load_namespaces << ActionController

    initializer "action_controller.assets_config", :group => :all do |app|
      app.config.action_controller.assets_dir ||= app.config.paths["public"].first
    end

    initializer "action_controller.set_helpers_path" do |app|
      ActionController::Helpers.helpers_path = app.helpers_paths
    end

    initializer "action_controller.parameters_config" do |app|
      options = app.config.action_controller

      ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
      ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
        (Rails.env.test? || Rails.env.development?) ? :log : false
      end
    end

    initializer "action_controller.set_configs" do |app|
      paths   = app.config.paths
      options = app.config.action_controller

      options.logger      ||= Rails.logger
      options.cache_store ||= Rails.cache

      options.javascripts_dir ||= paths["public/javascripts"].first
      options.stylesheets_dir ||= paths["public/stylesheets"].first

      # Ensure readers methods get compiled
      options.asset_host        ||= app.config.asset_host
      options.relative_url_root ||= app.config.relative_url_root

      ActiveSupport.on_load(:action_controller) do
        include app.routes.mounted_helpers
        extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
        extend ::ActionController::Railties::Helpers

        options.each do |k,v|
          k = "#{k}="
          if respond_to?(k)
            send(k, v)
          elsif !Base.respond_to?(k)
            raise "Invalid option key: #{k}"
          end
        end
      end
    end

    initializer "action_controller.compile_config_methods" do
      ActiveSupport.on_load(:action_controller) do
        config.compile_methods! if config.respond_to?(:compile_methods!)
      end
    end
  end
end
module ActionController
  module Railties
    module Helpers
      def inherited(klass)
        super
        return unless klass.respond_to?(:helpers_path=)

        if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) }
          paths = namespace.railtie_helpers_paths
        else
          paths = ActionController::Helpers.helpers_path
        end

        klass.helpers_path = paths

        if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers
          klass.helper :all
        end
      end
    end
  end
end
require 'action_view/record_identifier'

module ActionController
  module RecordIdentifier
    MODULE_MESSAGE = 'Calling ActionController::RecordIdentifier.%s is deprecated and ' \
      'will be removed in Rails 4.1, please call using ActionView::RecordIdentifier instead.'
    INSTANCE_MESSAGE = '%s method will no longer be included by default in controllers ' \
      'since Rails 4.1. If you would like to use it in controllers, please include ' \
      'ActionView::RecordIdentifier module.'

    def dom_id(record, prefix = nil)
      ActiveSupport::Deprecation.warn(INSTANCE_MESSAGE % 'dom_id')
      ActionView::RecordIdentifier.dom_id(record, prefix)
    end

    def dom_class(record, prefix = nil)
      ActiveSupport::Deprecation.warn(INSTANCE_MESSAGE % 'dom_class')
      ActionView::RecordIdentifier.dom_class(record, prefix)
    end

    def self.dom_id(record, prefix = nil)
      ActiveSupport::Deprecation.warn(MODULE_MESSAGE % 'dom_id')
      ActionView::RecordIdentifier.dom_id(record, prefix)
    end

    def self.dom_class(record, prefix = nil)
      ActiveSupport::Deprecation.warn(MODULE_MESSAGE % 'dom_class')
      ActionView::RecordIdentifier.dom_class(record, prefix)
    end
  end
end
require 'rack/session/abstract/id'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/hash/keys'

module ActionController
  module TemplateAssertions
    extend ActiveSupport::Concern

    included do
      setup :setup_subscriptions
      teardown :teardown_subscriptions
    end

    def setup_subscriptions
      @_partials = Hash.new(0)
      @_templates = Hash.new(0)
      @_layouts = Hash.new(0)

      ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload|
        path = payload[:layout]
        if path
          @_layouts[path] += 1
          if path =~ /^layouts\/(.*)/
            @_layouts[$1] += 1
          end
        end
      end

      ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload|
        path = payload[:virtual_path]
        next unless path
        partial = path =~ /^.*\/_[^\/]*$/

        if partial
          @_partials[path] += 1
          @_partials[path.split("/").last] += 1
        end

        @_templates[path] += 1
      end
    end

    def teardown_subscriptions
      ActiveSupport::Notifications.unsubscribe("render_template.action_view")
      ActiveSupport::Notifications.unsubscribe("!render_template.action_view")
    end

    def process(*args)
      @_partials = Hash.new(0)
      @_templates = Hash.new(0)
      @_layouts = Hash.new(0)
      super
    end

    # Asserts that the request was rendered with the appropriate template file or partials.
    #
    #   # assert that the "new" view template was rendered
    #   assert_template "new"
    #
    #   # assert that the exact template "admin/posts/new" was rendered
    #   assert_template %r{\Aadmin/posts/new\Z}
    #
    #   # assert that the layout 'admin' was rendered
    #   assert_template layout: 'admin'
    #   assert_template layout: 'layouts/admin'
    #   assert_template layout: :admin
    #
    #   # assert that no layout was rendered
    #   assert_template layout: nil
    #   assert_template layout: false
    #
    #   # assert that the "_customer" partial was rendered twice
    #   assert_template partial: '_customer', count: 2
    #
    #   # assert that no partials were rendered
    #   assert_template partial: false
    #
    # In a view test case, you can also assert that specific locals are passed
    # to partials:
    #
    #   # assert that the "_customer" partial was rendered with a specific object
    #   assert_template partial: '_customer', locals: { customer: @customer }
    def assert_template(options = {}, message = nil)
      # Force body to be read in case the template is being streamed.
      response.body

      case options
      when NilClass, Regexp, String, Symbol
        options = options.to_s if Symbol === options
        rendered = @_templates
        msg = message || sprintf("expecting <%s> but rendering with <%s>",
                options.inspect, rendered.keys)
        matches_template =
          case options
          when String
            !options.empty? && rendered.any? do |t, num|
              options_splited = options.split(File::SEPARATOR)
              t_splited = t.split(File::SEPARATOR)
              t_splited.last(options_splited.size) == options_splited
            end
          when Regexp
            rendered.any? { |t,num| t.match(options) }
          when NilClass
            rendered.blank?
          end
        assert matches_template, msg
      when Hash
        options.assert_valid_keys(:layout, :partial, :locals, :count)

        if options.key?(:layout)
          expected_layout = options[:layout]
          msg = message || sprintf("expecting layout <%s> but action rendered <%s>",
                  expected_layout, @_layouts.keys)

          case expected_layout
          when String, Symbol
            assert_includes @_layouts.keys, expected_layout.to_s, msg
          when Regexp
            assert(@_layouts.keys.any? {|l| l =~ expected_layout }, msg)
          when nil, false
            assert(@_layouts.empty?, msg)
          end
        end

        if expected_partial = options[:partial]
          if expected_locals = options[:locals]
            if defined?(@_rendered_views)
              view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')

              partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
              assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg

              msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
                                                                             expected_locals,
                                                                             @_rendered_views.locals_for(view)]
              assert(@_rendered_views.view_rendered?(view, options[:locals]), msg)
            else
              warn "the :locals option to #assert_template is only supported in a ActionView::TestCase"
            end
          elsif expected_count = options[:count]
            actual_count = @_partials[expected_partial]
            msg = message || sprintf("expecting %s to be rendered %s time(s) but rendered %s time(s)",
                     expected_partial, expected_count, actual_count)
            assert(actual_count == expected_count.to_i, msg)
          else
            msg = message || sprintf("expecting partial <%s> but action rendered <%s>",
                    options[:partial], @_partials.keys)
            assert_includes @_partials, expected_partial, msg
          end
        elsif options.key?(:partial)
          assert @_partials.empty?,
            "Expected no partials to be rendered"
        end
      else
        raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil"
      end
    end
  end

  class TestRequest < ActionDispatch::TestRequest #:nodoc:
    DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
    DEFAULT_ENV.delete 'PATH_INFO'

    def initialize(env = {})
      super

      self.session = TestSession.new
      self.session_options = TestSession::DEFAULT_OPTIONS.merge(:id => SecureRandom.hex(16))
    end

    def assign_parameters(routes, controller_path, action, parameters = {})
      parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
      extra_keys = routes.extra_keys(parameters)
      non_path_parameters = get? ? query_parameters : request_parameters
      parameters.each do |key, value|
        if value.is_a?(Array) && (value.frozen? || value.any?(&:frozen?))
          value = value.map{ |v| v.duplicable? ? v.dup : v }
        elsif value.is_a?(Hash) && (value.frozen? || value.any?{ |k,v| v.frozen? })
          value = Hash[value.map{ |k,v| [k, v.duplicable? ? v.dup : v] }]
        elsif value.frozen? && value.duplicable?
          value = value.dup
        end

        if extra_keys.include?(key.to_sym)
          non_path_parameters[key] = value
        else
          if value.is_a?(Array)
            value = value.map(&:to_param)
          else
            value = value.to_param
          end

          path_parameters[key.to_s] = value
        end
      end

      # Clear the combined params hash in case it was already referenced.
      @env.delete("action_dispatch.request.parameters")

      params = self.request_parameters.dup
      %w(controller action only_path).each do |k|
        params.delete(k)
        params.delete(k.to_sym)
      end
      data = params.to_query

      @env['CONTENT_LENGTH'] = data.length.to_s
      @env['rack.input'] = StringIO.new(data)
    end

    def recycle!
      @formats = nil
      @env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
      @env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
      @symbolized_path_params = nil
      @method = @request_method = nil
      @fullpath = @ip = @remote_ip = @protocol = nil
      @env['action_dispatch.request.query_parameters'] = {}
      @set_cookies ||= {}
      @set_cookies.update(Hash[cookie_jar.instance_variable_get("@set_cookies").map{ |k,o| [k,o[:value]] }])
      deleted_cookies = cookie_jar.instance_variable_get("@delete_cookies")
      @set_cookies.reject!{ |k,v| deleted_cookies.include?(k) }
      cookie_jar.update(rack_cookies)
      cookie_jar.update(cookies)
      cookie_jar.update(@set_cookies)
      cookie_jar.recycle!
    end

    private

    def default_env
      DEFAULT_ENV
    end
  end

  class TestResponse < ActionDispatch::TestResponse
    def recycle!
      initialize
    end
  end

  # Methods #destroy and #load! are overridden to avoid calling methods on the
  # @store object, which does not exist for the TestSession class.
  class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
    DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS

    def initialize(session = {})
      super(nil, nil)
      @id = SecureRandom.hex(16)
      @data = stringify_keys(session)
      @loaded = true
    end

    def exists?
      true
    end

    def keys
      @data.keys
    end

    def values
      @data.values
    end

    def destroy
      clear
    end

    private

      def load!
        @id
      end
  end

  # Superclass for ActionController functional tests. Functional tests allow you to
  # test a single controller action per test method. This should not be confused with
  # integration tests (see ActionDispatch::IntegrationTest), which are more like
  # "stories" that can involve multiple controllers and multiple actions (i.e. multiple
  # different HTTP requests).
  #
  # == Basic example
  #
  # Functional tests are written as follows:
  # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate
  #    an HTTP request.
  # 2. Then, one asserts whether the current state is as expected. "State" can be anything:
  #    the controller's HTTP response, the database contents, etc.
  #
  # For example:
  #
  #   class BooksControllerTest < ActionController::TestCase
  #     def test_create
  #       # Simulate a POST response with the given HTTP parameters.
  #       post(:create, book: { title: "Love Hina" })
  #
  #       # Assert that the controller tried to redirect us to
  #       # the created book's URI.
  #       assert_response :found
  #
  #       # Assert that the controller really put the book in the database.
  #       assert_not_nil Book.find_by_title("Love Hina")
  #     end
  #   end
  #
  # You can also send a real document in the simulated HTTP request.
  #
  #   def test_create
  #     json = {book: { title: "Love Hina" }}.to_json
  #     post :create, json
  #   end
  #
  # == Special instance variables
  #
  # ActionController::TestCase will also automatically provide the following instance
  # variables for use in the tests:
  #
  # <b>@controller</b>::
  #      The controller instance that will be tested.
  # <b>@request</b>::
  #      An ActionController::TestRequest, representing the current HTTP
  #      request. You can modify this object before sending the HTTP request. For example,
  #      you might want to set some session properties before sending a GET request.
  # <b>@response</b>::
  #      An ActionController::TestResponse object, representing the response
  #      of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
  #      after calling +post+. If the various assert methods are not sufficient, then you
  #      may use this object to inspect the HTTP response in detail.
  #
  # (Earlier versions of \Rails required each functional test to subclass
  # Test::Unit::TestCase and define @controller, @request, @response in +setup+.)
  #
  # == Controller is automatically inferred
  #
  # ActionController::TestCase will automatically infer the controller under test
  # from the test class name. If the controller cannot be inferred from the test
  # class name, you can explicitly set it with +tests+.
  #
  #   class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
  #     tests WidgetController
  #   end
  #
  # == \Testing controller internals
  #
  # In addition to these specific assertions, you also have easy access to various collections that the regular test/unit assertions
  # can be used against. These collections are:
  #
  # * assigns: Instance variables assigned in the action that are available for the view.
  # * session: Objects being saved in the session.
  # * flash: The flash objects currently in the session.
  # * cookies: \Cookies being sent to the user on this request.
  #
  # These collections can be used just like any other hash:
  #
  #   assert_not_nil assigns(:person) # makes sure that a @person instance variable was set
  #   assert_equal "Dave", cookies[:name] # makes sure that a cookie called :name was set as "Dave"
  #   assert flash.empty? # makes sure that there's nothing in the flash
  #
  # For historic reasons, the assigns hash uses string-based keys. So <tt>assigns[:person]</tt> won't work, but <tt>assigns["person"]</tt> will. To
  # appease our yearning for symbols, though, an alternative accessor has been devised using a method call instead of index referencing.
  # So <tt>assigns(:person)</tt> will work just like <tt>assigns["person"]</tt>, but again, <tt>assigns[:person]</tt> will not work.
  #
  # On top of the collections, you have the complete url that a given action redirected to available in <tt>redirect_to_url</tt>.
  #
  # For redirects within the same controller, you can even call follow_redirect and the redirect will be followed, triggering another
  # action call which can then be asserted against.
  #
  # == Manipulating session and cookie variables
  #
  # Sometimes you need to set up the session and cookie variables for a test.
  # To do this just assign a value to the session or cookie collection:
  #
  #   session[:key] = "value"
  #   cookies[:key] = "value"
  #
  # To clear the cookies for a test just clear the cookie collection:
  #
  #   cookies.clear
  #
  # == \Testing named routes
  #
  # If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
  #
  #  assert_redirected_to page_url(title: 'foo')
  class TestCase < ActiveSupport::TestCase
    module Behavior
      extend ActiveSupport::Concern
      include ActionDispatch::TestProcess
      include ActiveSupport::Testing::ConstantLookup

      attr_reader :response, :request

      module ClassMethods

        # Sets the controller class name. Useful if the name can't be inferred from test class.
        # Normalizes +controller_class+ before using.
        #
        #   tests WidgetController
        #   tests :widget
        #   tests 'widget'
        def tests(controller_class)
          case controller_class
          when String, Symbol
            self.controller_class = "#{controller_class.to_s.camelize}Controller".constantize
          when Class
            self.controller_class = controller_class
          else
            raise ArgumentError, "controller class must be a String, Symbol, or Class"
          end
        end

        def controller_class=(new_class)
          prepare_controller_class(new_class) if new_class
          self._controller_class = new_class
        end

        def controller_class
          if current_controller_class = self._controller_class
            current_controller_class
          else
            self.controller_class = determine_default_controller_class(name)
          end
        end

        def determine_default_controller_class(name)
          determine_constant_from_test_name(name) do |constant|
            Class === constant && constant < ActionController::Metal
          end
        end

        def prepare_controller_class(new_class)
          new_class.send :include, ActionController::TestCase::RaiseActionExceptions
        end

      end

      # Executes a request simulating GET HTTP method and set/volley the response
      def get(action, *args)
        process(action, "GET", *args)
      end

      # Executes a request simulating POST HTTP method and set/volley the response
      def post(action, *args)
        process(action, "POST", *args)
      end

      # Executes a request simulating PATCH HTTP method and set/volley the response
      def patch(action, *args)
        process(action, "PATCH", *args)
      end

      # Executes a request simulating PUT HTTP method and set/volley the response
      def put(action, *args)
        process(action, "PUT", *args)
      end

      # Executes a request simulating DELETE HTTP method and set/volley the response
      def delete(action, *args)
        process(action, "DELETE", *args)
      end

      # Executes a request simulating HEAD HTTP method and set/volley the response
      def head(action, *args)
        process(action, "HEAD", *args)
      end

      # Executes a request simulating OPTIONS HTTP method and set/volley the response
      def options(action, *args)
        process(action, "OPTIONS", *args)
      end

      def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
        @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
        @request.env['HTTP_ACCEPT'] ||=  [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
        __send__(request_method, action, parameters, session, flash).tap do
          @request.env.delete 'HTTP_X_REQUESTED_WITH'
          @request.env.delete 'HTTP_ACCEPT'
        end
      end
      alias xhr :xml_http_request

      def paramify_values(hash_or_array_or_value)
        case hash_or_array_or_value
        when Hash
          Hash[hash_or_array_or_value.map{|key, value| [key, paramify_values(value)] }]
        when Array
          hash_or_array_or_value.map {|i| paramify_values(i)}
        when Rack::Test::UploadedFile, ActionDispatch::Http::UploadedFile
          hash_or_array_or_value
        else
          hash_or_array_or_value.to_param
        end
      end

      def process(action, http_method = 'GET', *args)
        check_required_ivars
        http_method, args = handle_old_process_api(http_method, args, caller)

        if args.first.is_a?(String) && http_method != 'HEAD'
          @request.env['RAW_POST_DATA'] = args.shift
        end

        parameters, session, flash = args

        # Ensure that numbers and symbols passed as params are converted to
        # proper params, as is the case when engaging rack.
        parameters = paramify_values(parameters) if html_format?(parameters)

        @html_document = nil

        unless @controller.respond_to?(:recycle!)
          @controller.extend(Testing::Functional)
          @controller.class.class_eval { include Testing }
        end

        @request.recycle!
        @response.recycle!
        @controller.recycle!

        @request.env['REQUEST_METHOD'] = http_method

        parameters ||= {}
        controller_class_name = @controller.class.anonymous? ?
          "anonymous" :
          @controller.class.name.underscore.sub(/_controller$/, '')

        @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)

        @request.session.update(session) if session
        @request.flash.update(flash || {})

        @controller.request  = @request
        @controller.response = @response

        build_request_uri(action, parameters)

        name = @request.parameters[:action]

        @controller.process(name)

        if cookies = @request.env['action_dispatch.cookies']
          cookies.write(@response)
        end
        @response.prepare!

        @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
        @request.session['flash'] = @request.flash.to_session_value
        @request.session.delete('flash') if @request.session['flash'].blank?
        @response
      end

      def setup_controller_request_and_response
        @request          = build_request
        @response         = build_response
        @response.request = @request

        @controller = nil unless defined? @controller

        if klass = self.class.controller_class
          unless @controller
            begin
              @controller = klass.new
            rescue
              warn "could not construct controller #{klass}" if $VERBOSE
            end
          end
        end

        if @controller
          @controller.request = @request
          @controller.params = {}
        end
      end

      def build_request
        TestRequest.new
      end

      def build_response
        TestResponse.new
      end

      included do
        include ActionController::TemplateAssertions
        include ActionDispatch::Assertions
        class_attribute :_controller_class
        setup :setup_controller_request_and_response
      end

      private
      def check_required_ivars
        # Sanity check for required instance variables so we can give an
        # understandable error message.
        [:@routes, :@controller, :@request, :@response].each do |iv_name|
          if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
            raise "#{iv_name} is nil: make sure you set it in your test's setup method."
          end
        end
      end

      def handle_old_process_api(http_method, args, callstack)
        # 4.0: Remove this method.
        if http_method.is_a?(Hash)
          ActiveSupport::Deprecation.warn("TestCase#process now expects the HTTP method as second argument: process(action, http_method, params, session, flash)", callstack)
          args.unshift(http_method)
          http_method = args.last.is_a?(String) ? args.last : "GET"
        end

        [http_method, args]
      end

      def build_request_uri(action, parameters)
        unless @request.env["PATH_INFO"]
          options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
          options.update(
            :only_path => true,
            :action => action,
            :relative_url_root => nil,
            :_recall => @request.symbolized_path_parameters)

          url, query_string = @routes.url_for(options).split("?", 2)

          @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root
          @request.env["PATH_INFO"] = url
          @request.env["QUERY_STRING"] = query_string || ""
        end
      end

      def html_format?(parameters)
        return true unless parameters.is_a?(Hash)
        Mime.fetch(parameters[:format]) { Mime['html'] }.html?
      end
    end

    # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
    # (skipping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
    # rescue_action process takes place. This means you can test your rescue_action code by setting remote_addr to something else
    # than 0.0.0.0.
    #
    # The exception is stored in the exception accessor for further inspection.
    module RaiseActionExceptions
      def self.included(base) #:nodoc:
        unless base.method_defined?(:exception) && base.method_defined?(:exception=)
          base.class_eval do
            attr_accessor :exception
            protected :exception, :exception=
          end
        end
      end

      protected
        def rescue_action_without_handler(e)
          self.exception = e

          if request.remote_addr == "0.0.0.0"
            raise(e)
          else
            super(e)
          end
        end
    end

    include Behavior
  end
end
require 'action_view/vendor/html-scanner'
require 'active_support/deprecation'

ActiveSupport::Deprecation.warn 'Vendored html-scanner was moved to action_view, please require "action_view/vendor/html-scanner" instead. ' +
                                'This file will be removed in Rails 4.1'
require 'active_support/rails'
require 'abstract_controller'
require 'action_dispatch'
require 'action_controller/metal/live'
require 'action_controller/metal/strong_parameters'

module ActionController
  extend ActiveSupport::Autoload

  autoload :Base
  autoload :Caching
  autoload :Metal
  autoload :Middleware

  autoload_under "metal" do
    autoload :Compatibility
    autoload :ConditionalGet
    autoload :Cookies
    autoload :DataStreaming
    autoload :Flash
    autoload :ForceSSL
    autoload :Head
    autoload :Helpers
    autoload :HideActions
    autoload :HttpAuthentication
    autoload :ImplicitRender
    autoload :Instrumentation
    autoload :MimeResponds
    autoload :ParamsWrapper
    autoload :RackDelegation
    autoload :Redirecting
    autoload :Renderers
    autoload :Rendering
    autoload :RequestForgeryProtection
    autoload :Rescue
    autoload :Responder
    autoload :Streaming
    autoload :StrongParameters
    autoload :Testing
    autoload :UrlFor
  end

  autoload :Integration,        'action_controller/deprecated/integration_test'
  autoload :IntegrationTest,    'action_controller/deprecated/integration_test'
  autoload :Routing,            'action_controller/deprecated'
  autoload :TestCase,           'action_controller/test_case'
  autoload :TemplateAssertions, 'action_controller/test_case'

  eager_autoload do
    autoload :RecordIdentifier
  end

  def self.eager_load!
    super
    ActionController::Caching.eager_load!
    HTML.eager_load!
  end
end

# All of these simply register additional autoloads
require 'action_view'
require 'action_view/vendor/html-scanner'

ActiveSupport.on_load(:action_view) do
  ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
end

# Common Active Support usage in Action Controller
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/load_error'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/name_error'
require 'active_support/core_ext/uri'
require 'active_support/inflector'

module ActionDispatch
  module Http
    module Cache
      module Request

        HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze
        HTTP_IF_NONE_MATCH     = 'HTTP_IF_NONE_MATCH'.freeze

        def if_modified_since
          if since = env[HTTP_IF_MODIFIED_SINCE]
            Time.rfc2822(since) rescue nil
          end
        end

        def if_none_match
          env[HTTP_IF_NONE_MATCH]
        end

        def if_none_match_etags
          (if_none_match ? if_none_match.split(/\s*,\s*/) : []).collect do |etag|
            etag.gsub(/^\"|\"$/, "")
          end
        end

        def not_modified?(modified_at)
          if_modified_since && modified_at && if_modified_since >= modified_at
        end

        def etag_matches?(etag)
          if etag
            etag = etag.gsub(/^\"|\"$/, "")
            if_none_match_etags.include?(etag)
          end
        end

        # Check response freshness (Last-Modified and ETag) against request
        # If-Modified-Since and If-None-Match conditions. If both headers are
        # supplied, both must match, or the request is not considered fresh.
        def fresh?(response)
          last_modified = if_modified_since
          etag          = if_none_match

          return false unless last_modified || etag

          success = true
          success &&= not_modified?(response.last_modified) if last_modified
          success &&= etag_matches?(response.etag) if etag
          success
        end
      end

      module Response
        attr_reader :cache_control, :etag
        alias :etag? :etag

        def last_modified
          if last = headers[LAST_MODIFIED]
            Time.httpdate(last)
          end
        end

        def last_modified?
          headers.include?(LAST_MODIFIED)
        end

        def last_modified=(utc_time)
          headers[LAST_MODIFIED] = utc_time.httpdate
        end

        def date
          if date_header = headers['Date']
            Time.httpdate(date_header)
          end
        end

        def date?
          headers.include?('Date')
        end

        def date=(utc_time)
          headers['Date'] = utc_time.httpdate
        end

        def etag=(etag)
          key = ActiveSupport::Cache.expand_cache_key(etag)
          @etag = self[ETAG] = %("#{Digest::MD5.hexdigest(key)}")
        end

      private

        LAST_MODIFIED = "Last-Modified".freeze
        ETAG          = "ETag".freeze
        CACHE_CONTROL = "Cache-Control".freeze
        SPESHUL_KEYS  = %w[extras no-cache max-age public must-revalidate]

        def cache_control_segments
          if cache_control = self[CACHE_CONTROL]
            cache_control.delete(' ').split(',')
          else
            []
          end
        end

        def cache_control_headers
          cache_control = {}

          cache_control_segments.each do |segment|
            directive, argument = segment.split('=', 2)

            if SPESHUL_KEYS.include? directive
              key = directive.tr('-', '_')
              cache_control[key.to_sym] = argument || true
            else
              cache_control[:extras] ||= []
              cache_control[:extras] << segment
            end
          end

          cache_control
        end

        def prepare_cache_control!
          @cache_control = cache_control_headers
          @etag = self[ETAG]
        end

        def handle_conditional_get!
          if etag? || last_modified? || !@cache_control.empty?
            set_conditional_cache_control!
          end
        end

        DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate".freeze
        NO_CACHE              = "no-cache".freeze
        PUBLIC                = "public".freeze
        PRIVATE               = "private".freeze
        MUST_REVALIDATE       = "must-revalidate".freeze

        def set_conditional_cache_control!
          control = {}
          cc_headers = cache_control_headers
          if extras = cc_headers.delete(:extras)
            @cache_control[:extras] ||= []
            @cache_control[:extras] += extras
            @cache_control[:extras].uniq!
          end

          control.merge! cc_headers
          control.merge! @cache_control

          if control.empty?
            headers[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL
          elsif control[:no_cache]
            headers[CACHE_CONTROL] = NO_CACHE
            if control[:extras]
              headers[CACHE_CONTROL] += ", #{control[:extras].join(', ')}"
            end
          else
            extras  = control[:extras]
            max_age = control[:max_age]

            options = []
            options << "max-age=#{max_age.to_i}" if max_age
            options << (control[:public] ? PUBLIC : PRIVATE)
            options << MUST_REVALIDATE if control[:must_revalidate]
            options.concat(extras) if extras

            headers[CACHE_CONTROL] = options.join(", ")
          end
        end
      end
    end
  end
end
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/object/duplicable'
require 'action_dispatch/http/parameter_filter'

module ActionDispatch
  module Http
    # Allows you to specify sensitive parameters which will be replaced from
    # the request log by looking in the query string of the request and all
    # subhashes of the params hash to filter. If a block is given, each key and
    # value of the params hash and all subhashes is passed to it, the value
    # or key can be replaced using String#replace or similar method.
    #
    #   env["action_dispatch.parameter_filter"] = [:password]
    #   => replaces the value to all keys matching /password/i with "[FILTERED]"
    #
    #   env["action_dispatch.parameter_filter"] = [:foo, "bar"]
    #   => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
    #
    #   env["action_dispatch.parameter_filter"] = lambda do |k,v|
    #     v.reverse! if k =~ /secret/i
    #   end
    #   => reverses the value to all keys matching /secret/i
    module FilterParameters
      ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc:
      NULL_PARAM_FILTER = ParameterFilter.new # :nodoc:
      NULL_ENV_FILTER   = ParameterFilter.new ENV_MATCH # :nodoc:

      def initialize(env)
        super
        @filtered_parameters = nil
        @filtered_env        = nil
        @filtered_path       = nil
      end

      # Return a hash of parameters with all sensitive data replaced.
      def filtered_parameters
        @filtered_parameters ||= parameter_filter.filter(parameters)
      end

      # Return a hash of request.env with all sensitive data replaced.
      def filtered_env
        @filtered_env ||= env_filter.filter(@env)
      end

      # Reconstructed a path with all sensitive GET parameters replaced.
      def filtered_path
        @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
      end

    protected

      def parameter_filter
        parameter_filter_for @env.fetch("action_dispatch.parameter_filter") {
          return NULL_PARAM_FILTER
        }
      end

      def env_filter
        user_key = @env.fetch("action_dispatch.parameter_filter") {
          return NULL_ENV_FILTER
        }
        parameter_filter_for(Array(user_key) + ENV_MATCH)
      end

      def parameter_filter_for(filters)
        ParameterFilter.new(filters)
      end

      KV_RE   = '[^&;=]+'
      PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})}
      def filtered_query_string
        query_string.gsub(PAIR_RE) do |_|
          parameter_filter.filter([[$1, $2]]).first.join("=")
        end
      end
    end
  end
end
module ActionDispatch
  module Http
    module FilterRedirect

      FILTERED = '[FILTERED]'.freeze # :nodoc:

      def filtered_location
        if !location_filter.empty? && location_filter_match?
          FILTERED
        else
          location
        end
      end

    private

      def location_filter
        if request.present?
          request.env['action_dispatch.redirect_filter'] || []
        else
          []
        end
      end

      def location_filter_match?
        location_filter.any? do |filter|
          if String === filter
            location.include?(filter)
          elsif Regexp === filter
            location.match(filter)
          end
        end
      end

    end
  end
end
module ActionDispatch
  module Http
    class Headers
      include Enumerable

      def initialize(env = {})
        @headers = env
      end

      def [](header_name)
        @headers[env_name(header_name)]
      end

      def []=(k,v); @headers[k] = v; end
      def key?(k); @headers.key? k; end
      alias :include? :key?

      def fetch(header_name, *args, &block)
        @headers.fetch env_name(header_name), *args, &block
      end

      def each(&block)
        @headers.each(&block)
      end

      private

      # Converts a HTTP header name to an environment variable name if it is
      # not contained within the headers hash.
      def env_name(header_name)
        @headers.include?(header_name) ? header_name : cgi_name(header_name)
      end

      def cgi_name(k)
        "HTTP_#{k.upcase.gsub(/-/, '_')}"
      end
    end
  end
end
require 'active_support/core_ext/module/attribute_accessors'

module ActionDispatch
  module Http
    module MimeNegotiation
      extend ActiveSupport::Concern

      included do
        mattr_accessor :ignore_accept_header
        self.ignore_accept_header = false
      end

      # The MIME type of the HTTP request, such as Mime::XML.
      #
      # For backward compatibility, the post \format is extracted from the
      # X-Post-Data-Format HTTP header if present.
      def content_mime_type
        @env["action_dispatch.request.content_type"] ||= begin
          if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/
            Mime::Type.lookup($1.strip.downcase)
          else
            nil
          end
        end
      end

      def content_type
        content_mime_type && content_mime_type.to_s
      end

      # Returns the accepted MIME type for the request.
      def accepts
        @env["action_dispatch.request.accepts"] ||= begin
          header = @env['HTTP_ACCEPT'].to_s.strip

          if header.empty?
            [content_mime_type]
          else
            Mime::Type.parse(header)
          end
        end
      end

      # Returns the MIME type for the \format used in the request.
      #
      #   GET /posts/5.xml   | request.format => Mime::XML
      #   GET /posts/5.xhtml | request.format => Mime::HTML
      #   GET /posts/5       | request.format => Mime::HTML or MIME::JS, or request.accepts.first
      #
      def format(view_path = [])
        formats.first
      end

      def formats
        @env["action_dispatch.request.formats"] ||=
          if parameters[:format]
            Array(Mime[parameters[:format]])
          elsif use_accept_header && valid_accept_header
            accepts
          elsif xhr?
            [Mime::JS]
          else
            [Mime::HTML]
          end
      end

      # Sets the \format by string extension, which can be used to force custom formats
      # that are not controlled by the extension.
      #
      #   class ApplicationController < ActionController::Base
      #     before_action :adjust_format_for_iphone
      #
      #     private
      #       def adjust_format_for_iphone
      #         request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
      #       end
      #   end
      def format=(extension)
        parameters[:format] = extension.to_s
        @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])]
      end

      # Sets the \formats by string extensions. This differs from #format= by allowing you
      # to set multiple, ordered formats, which is useful when you want to have a fallback.
      #
      # In this example, the :iphone format will be used if it's available, otherwise it'll fallback
      # to the :html format.
      #
      #   class ApplicationController < ActionController::Base
      #     before_action :adjust_format_for_iphone_with_html_fallback
      #
      #     private
      #       def adjust_format_for_iphone_with_html_fallback
      #         request.formats = [ :iphone, :html ] if request.env["HTTP_USER_AGENT"][/iPhone/]
      #       end
      #   end
      def formats=(extensions)
        parameters[:format] = extensions.first.to_s
        @env["action_dispatch.request.formats"] = extensions.collect do |extension|
          Mime::Type.lookup_by_extension(extension)
        end
      end

      # Receives an array of mimes and return the first user sent mime that
      # matches the order array.
      #
      def negotiate_mime(order)
        formats.each do |priority|
          if priority == Mime::ALL
            return order.first
          elsif order.include?(priority)
            return priority
          end
        end

        order.include?(Mime::ALL) ? formats.first : nil
      end

      protected

      BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/

      def valid_accept_header
        (xhr? && (accept || content_mime_type)) ||
          (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS)
      end

      def use_accept_header
        !self.class.ignore_accept_header
      end
    end
  end
end
require 'set'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/string/starts_ends_with'

module Mime
  class Mimes < Array
    def symbols
      @symbols ||= map { |m| m.to_sym }
    end

    %w(<< concat shift unshift push pop []= clear compact! collect!
    delete delete_at delete_if flatten! map! insert reject! reverse!
    replace slice! sort! uniq!).each do |method|
      module_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{method}(*)
          @symbols = nil
          super
        end
      CODE
    end
  end

  SET              = Mimes.new
  EXTENSION_LOOKUP = {}
  LOOKUP           = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? }

  class << self
    def [](type)
      return type if type.is_a?(Type)
      Type.lookup_by_extension(type) || NullType.new
    end

    def fetch(type)
      return type if type.is_a?(Type)
      EXTENSION_LOOKUP.fetch(type.to_s) { |k| yield k }
    end
  end

  # Encapsulates the notion of a mime type. Can be used at render time, for example, with:
  #
  #   class PostsController < ActionController::Base
  #     def show
  #       @post = Post.find(params[:id])
  #
  #       respond_to do |format|
  #         format.html
  #         format.ics { render text: post.to_ics, mime_type: Mime::Type["text/calendar"]  }
  #         format.xml { render xml: @people }
  #       end
  #     end
  #   end
  class Type
    @@html_types = Set.new [:html, :all]
    cattr_reader :html_types

    # These are the content types which browsers can generate without using ajax, flash, etc
    # i.e. following a link, getting an image or posting a form. CSRF protection
    # only needs to protect against these types.
    @@browser_generated_types = Set.new [:html, :url_encoded_form, :multipart_form, :text]
    attr_reader :symbol

    @register_callbacks = []

    # A simple helper class used in parsing the accept header
    class AcceptItem #:nodoc:
      attr_accessor :index, :name, :q
      alias :to_s :name

      def initialize(index, name, q = nil)
        @index = index
        @name = name
        q ||= 0.0 if @name == Mime::ALL.to_s # default wildcard match to end of list
        @q = ((q || 1.0).to_f * 100).to_i
      end

      def <=>(item)
        result = item.q <=> @q
        result = @index <=> item.index if result == 0
        result
      end

      def ==(item)
        @name == item.to_s
      end
    end

    class AcceptList < Array #:nodoc:
      def assort!
        sort!

        # Take care of the broken text/xml entry by renaming or deleting it
        if text_xml_idx && app_xml_idx
          app_xml.q = [text_xml.q, app_xml.q].max # set the q value to the max of the two
          exchange_xml_items if app_xml_idx > text_xml_idx  # make sure app_xml is ahead of text_xml in the list
          delete_at(text_xml_idx)                 # delete text_xml from the list
        elsif text_xml_idx
          text_xml.name = Mime::XML.to_s
        end

        # Look for more specific XML-based types and sort them ahead of app/xml
        if app_xml_idx
          idx = app_xml_idx

          while idx < length
            type = self[idx]
            break if type.q < app_xml.q

            if type.name.ends_with? '+xml'
              self[app_xml_idx], self[idx] = self[idx], app_xml
              @app_xml_idx = idx
            end
            idx += 1
          end
        end

        map! { |i| Mime::Type.lookup(i.name) }.uniq!
        to_a
      end

      private
        def text_xml_idx
          @text_xml_idx ||= index('text/xml')
        end

        def app_xml_idx
          @app_xml_idx ||= index(Mime::XML.to_s)
        end

        def text_xml
          self[text_xml_idx]
        end

        def app_xml
          self[app_xml_idx]
        end

        def exchange_xml_items
          self[app_xml_idx], self[text_xml_idx] = text_xml, app_xml
          @app_xml_idx, @text_xml_idx = text_xml_idx, app_xml_idx
        end
    end

    class << self
      TRAILING_STAR_REGEXP = /(text|application)\/\*/
      PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/

      def register_callback(&block)
        @register_callbacks << block
      end

      def lookup(string)
        LOOKUP[string]
      end

      def lookup_by_extension(extension)
        EXTENSION_LOOKUP[extension.to_s]
      end

      # Registers an alias that's not used on mime type lookup, but can be referenced directly. Especially useful for
      # rendering different HTML versions depending on the user agent, like an iPhone.
      def register_alias(string, symbol, extension_synonyms = [])
        register(string, symbol, [], extension_synonyms, true)
      end

      def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
        Mime.const_set(symbol.upcase, Type.new(string, symbol, mime_type_synonyms))

        new_mime = Mime.const_get(symbol.upcase)
        SET << new_mime

        ([string] + mime_type_synonyms).each { |str| LOOKUP[str] = SET.last } unless skip_lookup
        ([symbol] + extension_synonyms).each { |ext| EXTENSION_LOOKUP[ext.to_s] = SET.last }

        @register_callbacks.each do |callback|
          callback.call(new_mime)
        end
      end

      def parse(accept_header)
        if accept_header !~ /,/
          accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
          parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)]
        else
          list, index = AcceptList.new, 0
          accept_header.split(',').each do |header|
            params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
            if params.present?
              params.strip!

              params = parse_trailing_star(params) || [params]

              params.each do |m|
                list << AcceptItem.new(index, m.to_s, q)
                index += 1
              end
            end
          end
          list.assort!
        end
      end

      def parse_trailing_star(accept_header)
        parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
      end

      # For an input of <tt>'text'</tt>, returns <tt>[Mime::JSON, Mime::XML, Mime::ICS,
      # Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]</tt>.
      #
      # For an input of <tt>'application'</tt>, returns <tt>[Mime::HTML, Mime::JS,
      # Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM]</tt>.
      def parse_data_with_trailing_star(input)
        Mime::SET.select { |m| m =~ input }
      end

      # This method is opposite of register method.
      #
      # Usage:
      #
      #   Mime::Type.unregister(:mobile)
      def unregister(symbol)
        symbol = symbol.upcase
        mime = Mime.const_get(symbol)
        Mime.instance_eval { remove_const(symbol) }

        SET.delete_if { |v| v.eql?(mime) }
        LOOKUP.delete_if { |k,v| v.eql?(mime) }
        EXTENSION_LOOKUP.delete_if { |k,v| v.eql?(mime) }
      end
    end

    def initialize(string, symbol = nil, synonyms = [])
      @symbol, @synonyms = symbol, synonyms
      @string = string
    end

    def to_s
      @string
    end

    def to_str
      to_s
    end

    def to_sym
      @symbol
    end

    def ref
      to_sym || to_s
    end

    def ===(list)
      if list.is_a?(Array)
        (@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
      else
        super
      end
    end

    def ==(mime_type)
      return false if mime_type.blank?
      (@synonyms + [ self ]).any? do |synonym|
        synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
      end
    end

    def =~(mime_type)
      return false if mime_type.blank?
      regexp = Regexp.new(Regexp.quote(mime_type.to_s))
      (@synonyms + [ self ]).any? do |synonym|
        synonym.to_s =~ regexp
      end
    end

    # Returns true if Action Pack should check requests using this Mime Type for possible request forgery. See
    # ActionController::RequestForgeryProtection.
    def verify_request?
      ActiveSupport::Deprecation.warn "Mime::Type#verify_request? is deprecated and will be removed in Rails 4.1"
      @@browser_generated_types.include?(to_sym)
    end

    def self.browser_generated_types
      ActiveSupport::Deprecation.warn "Mime::Type.browser_generated_types is deprecated and will be removed in Rails 4.1"
      @@browser_generated_types
    end

    def html?
      @@html_types.include?(to_sym) || @string =~ /html/
    end


    private

    def to_ary; end
    def to_a; end

    def method_missing(method, *args)
      if method.to_s.ends_with? '?'
        method[0..-2].downcase.to_sym == to_sym
      else
        super
      end
    end

    def respond_to_missing?(method, include_private = false) #:nodoc:
      method.to_s.ends_with? '?'
    end
  end
  
  class NullType
    def nil?
      true
    end

    private
    def method_missing(method, *args)
      false if method.to_s.ends_with? '?'
    end
  end
end

require 'action_dispatch/http/mime_types'
# Build list of Mime types for HTTP responses
# http://www.iana.org/assignments/media-types/

Mime::Type.register "text/html", :html, %w( application/xhtml+xml ), %w( xhtml )
Mime::Type.register "text/plain", :text, [], %w(txt)
Mime::Type.register "text/javascript", :js, %w( application/javascript application/x-javascript )
Mime::Type.register "text/css", :css
Mime::Type.register "text/calendar", :ics
Mime::Type.register "text/csv", :csv

Mime::Type.register "image/png", :png, [], %w(png)
Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg)
Mime::Type.register "image/gif", :gif, [], %w(gif)
Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)

Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe)

Mime::Type.register "application/xml", :xml, %w( text/xml application/x-xml )
Mime::Type.register "application/rss+xml", :rss
Mime::Type.register "application/atom+xml", :atom
Mime::Type.register "application/x-yaml", :yaml, %w( text/yaml )

Mime::Type.register "multipart/form-data", :multipart_form
Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form

# http://www.ietf.org/rfc/rfc4627.txt
# http://www.json.org/JSONRequest.html
Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )

Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
Mime::Type.register "application/zip", :zip, [], %w(zip)

# Create Mime::ALL but do not add it to the SET.
Mime::ALL = Mime::Type.new("*/*", :all, [])
module ActionDispatch
  module Http
    class ParameterFilter
      FILTERED = '[FILTERED]'.freeze # :nodoc:

      def initialize(filters = [])
        @filters = filters
      end

      def filter(params)
        compiled_filter.call(params)
      end

    private

      def compiled_filter
        @compiled_filter ||= CompiledFilter.compile(@filters)
      end

      class CompiledFilter # :nodoc:
        def self.compile(filters)
          return lambda { |params| params.dup } if filters.empty?

          strings, regexps, blocks = [], [], []

          filters.each do |item|
            case item
            when Proc
              blocks << item
            when Regexp
              regexps << item
            else
              strings << item.to_s
            end
          end

          regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
          new regexps, blocks
        end

        attr_reader :regexps, :blocks

        def initialize(regexps, blocks)
          @regexps = regexps
          @blocks  = blocks
        end

        def call(original_params)
          filtered_params = {}

          original_params.each do |key, value|
            if regexps.any? { |r| key =~ r }
              value = FILTERED
            elsif value.is_a?(Hash)
              value = call(value)
            elsif value.is_a?(Array)
              value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
            elsif blocks.any?
              key = key.dup
              value = value.dup if value.duplicable?
              blocks.each { |b| b.call(key, value) }
            end

            filtered_params[key] = value
          end

          filtered_params
        end
      end
    end
  end
end
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/indifferent_access'

module ActionDispatch
  module Http
    module Parameters
      def initialize(env)
        super
        @symbolized_path_params = nil
      end

      # Returns both GET and POST \parameters in a single hash.
      def parameters
        @env["action_dispatch.request.parameters"] ||= begin
          params = begin
            request_parameters.merge(query_parameters)
          rescue EOFError
            query_parameters.dup
          end
          params.merge!(path_parameters)
          encode_params(params).with_indifferent_access
        end
      end
      alias :params :parameters

      def path_parameters=(parameters) #:nodoc:
        @symbolized_path_params = nil
        @env.delete("action_dispatch.request.parameters")
        @env["action_dispatch.request.path_parameters"] = parameters
      end

      # The same as <tt>path_parameters</tt> with explicitly symbolized keys.
      def symbolized_path_parameters
        @symbolized_path_params ||= path_parameters.symbolize_keys
      end

      # Returns a hash with the \parameters used to form the \path of the request.
      # Returned hash keys are strings:
      #
      #   {'action' => 'my_action', 'controller' => 'my_controller'}
      #
      # See <tt>symbolized_path_parameters</tt> for symbolized keys.
      def path_parameters
        @env["action_dispatch.request.path_parameters"] ||= {}
      end

      def reset_parameters #:nodoc:
        @env.delete("action_dispatch.request.parameters")
      end

    private

      # TODO: Validate that the characters are UTF-8. If they aren't,
      # you'll get a weird error down the road, but our form handling
      # should really prevent that from happening
      def encode_params(params)
        if params.is_a?(String)
          return params.force_encoding(Encoding::UTF_8).encode!
        elsif !params.is_a?(Hash)
          return params
        end

        params.each do |k, v|
          case v
          when Hash
            encode_params(v)
          when Array
            v.map! {|el| encode_params(el) }
          else
            encode_params(v)
          end
        end
      end

      # Convert nested Hash to ActiveSupport::HashWithIndifferentAccess
      def normalize_parameters(value)
        case value
        when Hash
          h = {}
          value.each { |k, v| h[k] = normalize_parameters(v) }
          h.with_indifferent_access
        when Array
          value.map { |e| normalize_parameters(e) }
        else
          value
        end
      end
    end
  end
end
require "rack/cache"
require "rack/cache/context"
require "active_support/cache"

module ActionDispatch
  class RailsMetaStore < Rack::Cache::MetaStore
    def self.resolve(uri)
      new
    end

    def initialize(store = Rails.cache)
      @store = store
    end

    def read(key)
      if data = @store.read(key)
        Marshal.load(data)
      else
        []
      end
    end

    def write(key, value)
      @store.write(key, Marshal.dump(value))
    end

    ::Rack::Cache::MetaStore::RAILS = self
  end

  class RailsEntityStore < Rack::Cache::EntityStore
    def self.resolve(uri)
      new
    end

    def initialize(store = Rails.cache)
      @store = store
    end

    def exist?(key)
      @store.exist?(key)
    end

    def open(key)
      @store.read(key)
    end

    def read(key)
      body = open(key)
      body.join if body
    end

    def write(body)
      buf = []
      key, size = slurp(body) { |part| buf << part }
      @store.write(key, buf)
      [key, size]
    end

    ::Rack::Cache::EntityStore::RAILS = self
  end
end
require 'stringio'

require 'active_support/inflector'
require 'action_dispatch/http/headers'
require 'action_controller/metal/exceptions'
require 'rack/request'
require 'action_dispatch/http/cache'
require 'action_dispatch/http/mime_negotiation'
require 'action_dispatch/http/parameters'
require 'action_dispatch/http/filter_parameters'
require 'action_dispatch/http/upload'
require 'action_dispatch/http/url'
require 'active_support/core_ext/array/conversions'

module ActionDispatch
  class Request < Rack::Request
    include ActionDispatch::Http::Cache::Request
    include ActionDispatch::Http::MimeNegotiation
    include ActionDispatch::Http::Parameters
    include ActionDispatch::Http::FilterParameters
    include ActionDispatch::Http::Upload
    include ActionDispatch::Http::URL

    autoload :Session, 'action_dispatch/request/session'

    LOCALHOST   = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]

    ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
        PATH_TRANSLATED REMOTE_HOST
        REMOTE_IDENT REMOTE_USER REMOTE_ADDR
        SERVER_NAME SERVER_PROTOCOL

        HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
        HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM
        HTTP_NEGOTIATE HTTP_PRAGMA ].freeze

    ENV_METHODS.each do |env|
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{env.sub(/^HTTP_/n, '').downcase}  # def accept_charset
          @env["#{env}"]                        #   @env["HTTP_ACCEPT_CHARSET"]
        end                                     # end
      METHOD
    end

    def initialize(env)
      super
      @method            = nil
      @request_method    = nil
      @remote_ip         = nil
      @original_fullpath = nil
      @fullpath          = nil
      @ip                = nil
      @uuid              = nil
    end

    def key?(key)
      @env.key?(key)
    end

    # List of HTTP request methods from the following RFCs:
    # Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt)
    # HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt)
    # Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt)
    # Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
    # Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
    # Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
    # PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
    RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
    RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
    RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
    RFC3648 = %w(ORDERPATCH)
    RFC3744 = %w(ACL)
    RFC5323 = %w(SEARCH)
    RFC5789 = %w(PATCH)

    HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789

    HTTP_METHOD_LOOKUP = {}

    # Populate the HTTP method lookup cache
    HTTP_METHODS.each { |method|
      HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
    }

    # Returns the HTTP \method that the application should see.
    # In the case where the \method was overridden by a middleware
    # (for instance, if a HEAD request was converted to a GET,
    # or if a _method parameter was used to determine the \method
    # the application should use), this \method returns the overridden
    # value, not the original.
    def request_method
      @request_method ||= check_method(env["REQUEST_METHOD"])
    end

    # Returns a symbol form of the #request_method
    def request_method_symbol
      HTTP_METHOD_LOOKUP[request_method]
    end

    # Returns the original value of the environment's REQUEST_METHOD,
    # even if it was overridden by middleware. See #request_method for
    # more information.
    def method
      @method ||= check_method(env["rack.methodoverride.original_method"] || env['REQUEST_METHOD'])
    end

    # Returns a symbol form of the #method
    def method_symbol
      HTTP_METHOD_LOOKUP[method]
    end

    # Is this a GET (or HEAD) request?
    # Equivalent to <tt>request.request_method_symbol == :get</tt>.
    def get?
      HTTP_METHOD_LOOKUP[request_method] == :get
    end

    # Is this a POST request?
    # Equivalent to <tt>request.request_method_symbol == :post</tt>.
    def post?
      HTTP_METHOD_LOOKUP[request_method] == :post
    end

    # Is this a PATCH request?
    # Equivalent to <tt>request.request_method == :patch</tt>.
    def patch?
      HTTP_METHOD_LOOKUP[request_method] == :patch
    end

    # Is this a PUT request?
    # Equivalent to <tt>request.request_method_symbol == :put</tt>.
    def put?
      HTTP_METHOD_LOOKUP[request_method] == :put
    end

    # Is this a DELETE request?
    # Equivalent to <tt>request.request_method_symbol == :delete</tt>.
    def delete?
      HTTP_METHOD_LOOKUP[request_method] == :delete
    end

    # Is this a HEAD request?
    # Equivalent to <tt>request.request_method_symbol == :head</tt>.
    def head?
      HTTP_METHOD_LOOKUP[request_method] == :head
    end

    # Provides access to the request's HTTP headers, for example:
    #
    #   request.headers["Content-Type"] # => "text/plain"
    def headers
      Http::Headers.new(@env)
    end

    def original_fullpath
      @original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath)
    end

    def fullpath
      @fullpath ||= super
    end

    def original_url
      base_url + original_fullpath
    end

    def media_type
      content_mime_type.to_s
    end

    # Returns the content length of the request as an integer.
    def content_length
      super.to_i
    end

    # Returns true if the "X-Requested-With" header contains "XMLHttpRequest"
    # (case-insensitive). All major JavaScript libraries send this header with
    # every Ajax request.
    def xml_http_request?
      @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
    end
    alias :xhr? :xml_http_request?

    def ip
      @ip ||= super
    end

    # Originating IP address, usually set by the RemoteIp middleware.
    def remote_ip
      @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
    end

    # Returns the unique request id, which is based off either the X-Request-Id header that can
    # be generated by a firewall, load balancer, or web server or by the RequestId middleware
    # (which sets the action_dispatch.request_id environment variable).
    #
    # This unique ID is useful for tracing a request from end-to-end as part of logging or debugging.
    # This relies on the rack variable set by the ActionDispatch::RequestId middleware.
    def uuid
      @uuid ||= env["action_dispatch.request_id"]
    end

    # Returns the lowercase name of the HTTP server software.
    def server_software
      (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil
    end

    # Read the request \body. This is useful for web services that need to
    # work with raw requests directly.
    def raw_post
      unless @env.include? 'RAW_POST_DATA'
        raw_post_body = body
        @env['RAW_POST_DATA'] = raw_post_body.read(@env['CONTENT_LENGTH'].to_i)
        raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
      end
      @env['RAW_POST_DATA']
    end

    # The request body is an IO input stream. If the RAW_POST_DATA environment
    # variable is already set, wrap it in a StringIO.
    def body
      if raw_post = @env['RAW_POST_DATA']
        raw_post.force_encoding(Encoding::BINARY)
        StringIO.new(raw_post)
      else
        @env['rack.input']
      end
    end

    def form_data?
      FORM_DATA_MEDIA_TYPES.include?(content_mime_type.to_s)
    end

    def body_stream #:nodoc:
      @env['rack.input']
    end

    # TODO This should be broken apart into AD::Request::Session and probably
    # be included by the session middleware.
    def reset_session
      if session && session.respond_to?(:destroy)
        session.destroy
      else
        self.session = {}
      end
      @env['action_dispatch.request.flash_hash'] = nil
    end

    def session=(session) #:nodoc:
      Session.set @env, session
    end

    def session_options=(options)
      Session::Options.set @env, options
    end

    # Override Rack's GET method to support indifferent access
    def GET
      @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {})
    rescue TypeError => e
      raise ActionController::BadRequest.new(:query, e)
    end
    alias :query_parameters :GET

    # Override Rack's POST method to support indifferent access
    def POST
      @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {})
    rescue TypeError => e
      raise ActionController::BadRequest.new(:request, e)
    end
    alias :request_parameters :POST

    # Returns the authorization header regardless of whether it was specified directly or through one of the
    # proxy alternatives.
    def authorization
      @env['HTTP_AUTHORIZATION']   ||
      @env['X-HTTP_AUTHORIZATION'] ||
      @env['X_HTTP_AUTHORIZATION'] ||
      @env['REDIRECT_X_HTTP_AUTHORIZATION']
    end

    # True if the request came from localhost, 127.0.0.1.
    def local?
      LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
    end

    # Remove nils from the params hash
    def deep_munge(hash)
      hash.each do |k, v|
        case v
        when Array
          v.grep(Hash) { |x| deep_munge(x) }
          v.compact!
          hash[k] = nil if v.empty?
        when Hash
          deep_munge(v)
        end
      end

      hash
    end

    protected

    def parse_query(qs)
      deep_munge(super)
    end

    private

    def check_method(name)
      HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
      name
    end
  end
end
require 'active_support/core_ext/class/attribute_accessors'
require 'monitor'

module ActionDispatch # :nodoc:
  # Represents an HTTP response generated by a controller action. Use it to
  # retrieve the current state of the response, or customize the response. It can
  # either represent a real HTTP response (i.e. one that is meant to be sent
  # back to the web browser) or a TestResponse (i.e. one that is generated
  # from integration tests).
  #
  # \Response is mostly a Ruby on \Rails framework implementation detail, and
  # should never be used directly in controllers. Controllers should use the
  # methods defined in ActionController::Base instead. For example, if you want
  # to set the HTTP response's content MIME type, then use
  # ActionControllerBase#headers instead of Response#headers.
  #
  # Nevertheless, integration tests may want to inspect controller responses in
  # more detail, and that's when \Response can be useful for application
  # developers. Integration test methods such as
  # ActionDispatch::Integration::Session#get and
  # ActionDispatch::Integration::Session#post return objects of type
  # TestResponse (which are of course also of type \Response).
  #
  # For example, the following demo integration test prints the body of the
  # controller response to the console:
  #
  #  class DemoControllerTest < ActionDispatch::IntegrationTest
  #    def test_print_root_path_to_console
  #      get('/')
  #      puts response.body
  #    end
  #  end
  class Response
    attr_accessor :request, :header
    attr_reader :status
    attr_writer :sending_file

    alias_method :headers=, :header=
    alias_method :headers,  :header

    delegate :[], :[]=, :to => :@header
    delegate :each, :to => :@stream

    # Sets the HTTP response's content MIME type. For example, in the controller
    # you could write this:
    #
    #  response.content_type = "text/plain"
    #
    # If a character set has been defined for this response (see charset=) then
    # the character set information will also be included in the content type
    # information.
    attr_accessor :charset
    attr_reader   :content_type

    CONTENT_TYPE = "Content-Type".freeze
    SET_COOKIE   = "Set-Cookie".freeze
    LOCATION     = "Location".freeze

    cattr_accessor(:default_charset) { "utf-8" }
    cattr_accessor(:default_headers)

    include Rack::Response::Helpers
    include ActionDispatch::Http::FilterRedirect
    include ActionDispatch::Http::Cache::Response
    include MonitorMixin

    class Buffer # :nodoc:
      def initialize(response, buf)
        @response = response
        @buf      = buf
        @closed   = false
      end

      def write(string)
        raise IOError, "closed stream" if closed?

        @response.commit!
        @buf.push string
      end

      def each(&block)
        @buf.each(&block)
      end

      def close
        @response.commit!
        @closed = true
      end

      def closed?
        @closed
      end
    end

    attr_reader :stream

    def initialize(status = 200, header = {}, body = [])
      super()

      header = merge_default_headers(header, self.class.default_headers)

      self.body, self.header, self.status = body, header, status

      @sending_file = false
      @blank        = false
      @cv           = new_cond
      @committed    = false
      @content_type = nil
      @charset      = nil

      if content_type = self[CONTENT_TYPE]
        type, charset = content_type.split(/;\s*charset=/)
        @content_type = Mime::Type.lookup(type)
        @charset = charset || self.class.default_charset
      end

      prepare_cache_control!

      yield self if block_given?
    end

    def await_commit
      synchronize do
        @cv.wait_until { @committed }
      end
    end

    def commit!
      synchronize do
        @committed = true
        @cv.broadcast
      end
    end

    def committed?
      @committed
    end

    # Sets the HTTP status code.
    def status=(status)
      @status = Rack::Utils.status_code(status)
    end

    def content_type=(content_type)
      @content_type = content_type.to_s
    end

    # The response code of the request.
    def response_code
      @status
    end

    # Returns a string to ensure compatibility with <tt>Net::HTTPResponse</tt>.
    def code
      @status.to_s
    end

    # Returns the corresponding message for the current HTTP status code:
    #
    #   response.status = 200
    #   response.message # => "OK"
    #
    #   response.status = 404
    #   response.message # => "Not Found"
    #
    def message
      Rack::Utils::HTTP_STATUS_CODES[@status]
    end
    alias_method :status_message, :message

    def respond_to?(method)
      if method.to_s == 'to_path'
        stream.respond_to?(:to_path)
      else
        super
      end
    end

    def to_path
      stream.to_path
    end

    # Returns the content of the response as a string. This contains the contents
    # of any calls to <tt>render</tt>.
    def body
      strings = []
      each { |part| strings << part.to_s }
      strings.join
    end

    EMPTY = " "

    # Allows you to manually set or override the response body.
    def body=(body)
      @blank = true if body == EMPTY

      if body.respond_to?(:to_path)
        @stream = body
      else
        @stream = build_buffer self, munge_body_object(body)
      end
    end

    def body_parts
      parts = []
      @stream.each { |x| parts << x }
      parts
    end

    def set_cookie(key, value)
      ::Rack::Utils.set_cookie_header!(header, key, value)
    end

    def delete_cookie(key, value={})
      ::Rack::Utils.delete_cookie_header!(header, key, value)
    end

    def location
      headers[LOCATION]
    end
    alias_method :redirect_url, :location

    def location=(url)
      headers[LOCATION] = url
    end

    def close
      stream.close if stream.respond_to?(:close)
    end

    def to_a
      rack_response @status, @header.to_hash
    end
    alias prepare! to_a
    alias to_ary   to_a # For implicit splat on 1.9.2

    # Returns the response cookies, converted to a Hash of (name => value) pairs
    #
    #   assert_equal 'AuthorOfNewPage', r.cookies['author']
    def cookies
      cookies = {}
      if header = self[SET_COOKIE]
        header = header.split("\n") if header.respond_to?(:to_str)
        header.each do |cookie|
          if pair = cookie.split(';').first
            key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) }
            cookies[key] = value
          end
        end
      end
      cookies
    end

  private

    def merge_default_headers(original, default)
      return original unless default.respond_to?(:merge)

      default.merge(original)
    end

    def build_buffer(response, body)
      Buffer.new response, body
    end

    def munge_body_object(body)
      body.respond_to?(:each) ? body : [body]
    end

    def assign_default_content_type_and_charset!(headers)
      return if headers[CONTENT_TYPE].present?

      @content_type ||= Mime::HTML
      @charset      ||= self.class.default_charset unless @charset == false

      type = @content_type.to_s.dup
      type << "; charset=#{@charset}" if append_charset?

      headers[CONTENT_TYPE] = type
    end

    def append_charset?
      !@sending_file && @charset != false
    end

    def rack_response(status, header)
      assign_default_content_type_and_charset!(header)
      handle_conditional_get!

      header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join)

      if [204, 304].include?(@status)
        header.delete CONTENT_TYPE
        [status, header, []]
      else
        [status, header, self]
      end
    end
  end
end
module ActionDispatch
  module Http
    # Models uploaded files.
    #
    # The actual file is accessible via the +tempfile+ accessor, though some
    # of its interface is available directly for convenience.
    #
    # Uploaded files are temporary files whose lifespan is one request. When
    # the object is finalized Ruby unlinks the file, so there is not need to
    # clean them with a separate maintenance task.
    class UploadedFile
      # The basename of the file in the client.
      attr_accessor :original_filename

      # A string with the MIME type of the file.
      attr_accessor :content_type

      # A +Tempfile+ object with the actual uploaded file. Note that some of
      # its interface is available directly.
      attr_accessor :tempfile

      # A string with the headers of the multipart request.
      attr_accessor :headers

      def initialize(hash) # :nodoc:
        @tempfile          = hash[:tempfile]
        raise(ArgumentError, ':tempfile is required') unless @tempfile

        @original_filename = encode_filename(hash[:filename])
        @content_type      = hash[:type]
        @headers           = hash[:head]
      end

      # Shortcut for +tempfile.read+.
      def read(length=nil, buffer=nil)
        @tempfile.read(length, buffer)
      end

      # Shortcut for +tempfile.open+.
      def open
        @tempfile.open
      end

      # Shortcut for +tempfile.close+.
      def close(unlink_now=false)
        @tempfile.close(unlink_now)
      end

      # Shortcut for +tempfile.path+.
      def path
        @tempfile.path
      end

      # Shortcut for +tempfile.rewind+.
      def rewind
        @tempfile.rewind
      end

      # Shortcut for +tempfile.size+.
      def size
        @tempfile.size
      end

      # Shortcut for +tempfile.eof?+.
      def eof?
        @tempfile.eof?
      end

      private

      def encode_filename(filename)
        # Encode the filename in the utf8 encoding, unless it is nil
        filename.force_encoding(Encoding::UTF_8).encode! if filename
      end
    end

    module Upload # :nodoc:
      # Convert nested Hash to ActiveSupport::HashWithIndifferentAccess and replace
      # file upload hash with UploadedFile objects
      def normalize_parameters(value)
        if Hash === value && value.has_key?(:tempfile)
          UploadedFile.new(value)
        else
          super
        end
      end
      private :normalize_parameters
    end
  end
end
module ActionDispatch
  module Http
    module URL
      IP_HOST_REGEXP = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/

      mattr_accessor :tld_length
      self.tld_length = 1

      class << self
        def extract_domain(host, tld_length = @@tld_length)
          host.split('.').last(1 + tld_length).join('.') if named_host?(host)
        end

        def extract_subdomains(host, tld_length = @@tld_length)
          if named_host?(host)
            parts = host.split('.')
            parts[0..-(tld_length + 2)]
          else
            []
          end
        end

        def extract_subdomain(host, tld_length = @@tld_length)
          extract_subdomains(host, tld_length).join('.')
        end

        def url_for(options = {})
          path  = options.delete(:script_name).to_s.chomp("/")
          path << options.delete(:path).to_s

          params = options[:params].is_a?(Hash) ? options[:params] : options.slice(:params)
          params.reject! { |_,v| v.to_param.nil? }

          result = build_host_url(options)
          if options[:trailing_slash]
            if path.include?('?')
              result << path.sub(/\?/, '/\&')
            else
              result << path.sub(/[^\/]\z|\A\z/, '\&/')
            end
          else
            result << path
          end
          result << "?#{params.to_query}" unless params.empty?
          result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
          result
        end

        private

        def build_host_url(options)
          if options[:host].blank? && options[:only_path].blank?
            raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
          end

          result = ""

          unless options[:only_path]
            unless options[:protocol] == false
              result << (options[:protocol] || "http")
              result << ":" unless result.match(%r{:|//})
            end
            result << "//" unless result.match("//")
            result << rewrite_authentication(options)
            result << host_or_subdomain_and_domain(options)
            result << ":#{options.delete(:port)}" if options[:port]
          end
          result
        end

        def named_host?(host)
          host && IP_HOST_REGEXP !~ host
        end

        def rewrite_authentication(options)
          if options[:user] && options[:password]
            "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@"
          else
            ""
          end
        end

        def host_or_subdomain_and_domain(options)
          return options[:host] if !named_host?(options[:host]) || (options[:subdomain].nil? && options[:domain].nil?)

          tld_length = options[:tld_length] || @@tld_length

          host = ""
          unless options[:subdomain] == false
            host << (options[:subdomain] || extract_subdomain(options[:host], tld_length)).to_param
            host << "."
          end
          host << (options[:domain] || extract_domain(options[:host], tld_length))
          host
        end
      end

      def initialize(env)
        super
        @protocol = nil
        @port     = nil
      end

      # Returns the complete URL used for this request.
      def url
        protocol + host_with_port + fullpath
      end

      # Returns 'https://' if this is an SSL request and 'http://' otherwise.
      def protocol
        @protocol ||= ssl? ? 'https://' : 'http://'
      end

      # Returns the \host for this request, such as "example.com".
      def raw_host_with_port
        if forwarded = env["HTTP_X_FORWARDED_HOST"]
          forwarded.split(/,\s?/).last
        else
          env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}"
        end
      end

      # Returns the host for this request, such as example.com.
      def host
        raw_host_with_port.sub(/:\d+$/, '')
      end

      # Returns a \host:\port string for this request, such as "example.com" or
      # "example.com:8080".
      def host_with_port
        "#{host}#{port_string}"
      end

      # Returns the port number of this request as an integer.
      def port
        @port ||= begin
          if raw_host_with_port =~ /:(\d+)$/
            $1.to_i
          else
            standard_port
          end
        end
      end

      # Returns the standard \port number for this request's protocol.
      def standard_port
        case protocol
          when 'https://' then 443
          else 80
        end
      end

      # Returns whether this request is using the standard port
      def standard_port?
        port == standard_port
      end

      # Returns a number \port suffix like 8080 if the \port number of this request
      # is not the default HTTP \port 80 or HTTPS \port 443.
      def optional_port
        standard_port? ? nil : port
      end

      # Returns a string \port suffix, including colon, like ":8080" if the \port
      # number of this request is not the default HTTP \port 80 or HTTPS \port 443.
      def port_string
        standard_port? ? '' : ":#{port}"
      end

      def server_port
        @env['SERVER_PORT'].to_i
      end

      # Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
      # a different <tt>tld_length</tt>, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
      def domain(tld_length = @@tld_length)
        ActionDispatch::Http::URL.extract_domain(host, tld_length)
      end

      # Returns all the \subdomains as an array, so <tt>["dev", "www"]</tt> would be
      # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
      # such as 2 to catch <tt>["www"]</tt> instead of <tt>["www", "rubyonrails"]</tt>
      # in "www.rubyonrails.co.uk".
      def subdomains(tld_length = @@tld_length)
        ActionDispatch::Http::URL.extract_subdomains(host, tld_length)
      end

      # Returns all the \subdomains as a string, so <tt>"dev.www"</tt> would be
      # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
      # such as 2 to catch <tt>"www"</tt> instead of <tt>"www.rubyonrails"</tt>
      # in "www.rubyonrails.co.uk".
      def subdomain(tld_length = @@tld_length)
        ActionDispatch::Http::URL.extract_subdomain(host, tld_length)
      end
    end
  end
end
module Rack # :nodoc:
  Mount = ActionDispatch::Journey::Router
  Mount::RouteSet = ActionDispatch::Journey::Router
  Mount::RegexpWithNamedGroups = ActionDispatch::Journey::Path::Pattern
end
require 'action_controller/metal/exceptions'

module ActionDispatch
  module Journey
    # The Formatter class is used for formatting URLs. For example, parameters
    # passed to +url_for+ in rails will eventually call Formatter#generate.
    class Formatter # :nodoc:
      attr_reader :routes

      def initialize(routes)
        @routes = routes
        @cache  = nil
      end

      def generate(type, name, options, recall = {}, parameterize = nil)
        constraints = recall.merge(options)
        missing_keys = []

        match_route(name, constraints) do |route|
          parameterized_parts = extract_parameterized_parts(route, options, recall, parameterize)
          next if !name && route.requirements.empty? && route.parts.empty?

          missing_keys = missing_keys(route, parameterized_parts)
          next unless missing_keys.empty?
          params = options.dup.delete_if do |key, _|
            parameterized_parts.key?(key) || route.defaults.key?(key)
          end

          return [route.format(parameterized_parts), params]
        end

        message = "No route matches #{constraints.inspect}"
        message << " missing required keys: #{missing_keys.inspect}" if name

        raise ActionController::UrlGenerationError, message
      end

      def clear
        @cache = nil
      end

      private

        def extract_parameterized_parts(route, options, recall, parameterize = nil)
          parameterized_parts = recall.merge(options)

          keys_to_keep = route.parts.reverse.drop_while { |part|
            !options.key?(part) || (options[part] || recall[part]).nil?
          } | route.required_parts

          (parameterized_parts.keys - keys_to_keep).each do |bad_key|
            parameterized_parts.delete(bad_key)
          end

          if parameterize
            parameterized_parts.each do |k, v|
              parameterized_parts[k] = parameterize.call(k, v)
            end
          end

          parameterized_parts.keep_if { |_, v| v  }
          parameterized_parts
        end

        def named_routes
          routes.named_routes
        end

        def match_route(name, options)
          if named_routes.key?(name)
            yield named_routes[name]
          else
            routes = non_recursive(cache, options.to_a)

            hash = routes.group_by { |_, r| r.score(options) }

            hash.keys.sort.reverse_each do |score|
              next if score < 0

              hash[score].sort_by { |i, _| i }.each do |_, route|
                yield route
              end
            end
          end
        end

        def non_recursive(cache, options)
          routes = []
          stack  = [cache]

          while stack.any?
            c = stack.shift
            routes.concat(c[:___routes]) if c.key?(:___routes)

            options.each do |pair|
              stack << c[pair] if c.key?(pair)
            end
          end

          routes
        end

        # Returns an array populated with missing keys if any are present.
        def missing_keys(route, parts)
          missing_keys = []
          tests = route.path.requirements
          route.required_parts.each { |key|
            if tests.key?(key)
              missing_keys << key unless /\A#{tests[key]}\Z/ === parts[key]
            else
              missing_keys << key unless parts[key]
            end
          }
          missing_keys
        end

        def possibles(cache, options, depth = 0)
          cache.fetch(:___routes) { [] } + options.find_all { |pair|
            cache.key?(pair)
          }.map { |pair|
            possibles(cache[pair], options, depth + 1)
          }.flatten(1)
        end

        # Returns +true+ if no missing keys are present, otherwise +false+.
        def verify_required_parts!(route, parts)
          missing_keys(route, parts).empty?
        end

        def build_cache
          root = { ___routes: [] }
          routes.each_with_index do |route, i|
            leaf = route.required_defaults.inject(root) do |h, tuple|
              h[tuple] ||= {}
            end
            (leaf[:___routes] ||= []) << [i, route]
          end
          root
        end

        def cache
          @cache ||= build_cache
        end
    end
  end
end
require 'action_dispatch/journey/gtg/transition_table'

module ActionDispatch
  module Journey # :nodoc:
    module GTG # :nodoc:
      class Builder # :nodoc:
        DUMMY = Nodes::Dummy.new

        attr_reader :root, :ast, :endpoints

        def initialize(root)
          @root      = root
          @ast       = Nodes::Cat.new root, DUMMY
          @followpos = nil
        end

        def transition_table
          dtrans   = TransitionTable.new
          marked   = {}
          state_id = Hash.new { |h,k| h[k] = h.length }

          start   = firstpos(root)
          dstates = [start]
          until dstates.empty?
            s = dstates.shift
            next if marked[s]
            marked[s] = true # mark s

            s.group_by { |state| symbol(state) }.each do |sym, ps|
              u = ps.map { |l| followpos(l) }.flatten
              next if u.empty?

              if u.uniq == [DUMMY]
                from = state_id[s]
                to   = state_id[Object.new]
                dtrans[from, to] = sym

                dtrans.add_accepting(to)
                ps.each { |state| dtrans.add_memo(to, state.memo) }
              else
                dtrans[state_id[s], state_id[u]] = sym

                if u.include?(DUMMY)
                  to = state_id[u]

                  accepting = ps.find_all { |l| followpos(l).include?(DUMMY) }

                  accepting.each { |accepting_state|
                    dtrans.add_memo(to, accepting_state.memo)
                  }

                  dtrans.add_accepting(state_id[u])
                end
              end

              dstates << u
            end
          end

          dtrans
        end

        def nullable?(node)
          case node
          when Nodes::Group
            true
          when Nodes::Star
            true
          when Nodes::Or
            node.children.any? { |c| nullable?(c) }
          when Nodes::Cat
            nullable?(node.left) && nullable?(node.right)
          when Nodes::Terminal
            !node.left
          when Nodes::Unary
            nullable?(node.left)
          else
            raise ArgumentError, 'unknown nullable: %s' % node.class.name
          end
        end

        def firstpos(node)
          case node
          when Nodes::Star
            firstpos(node.left)
          when Nodes::Cat
            if nullable?(node.left)
              firstpos(node.left) | firstpos(node.right)
            else
              firstpos(node.left)
            end
          when Nodes::Or
            node.children.map { |c| firstpos(c) }.flatten.uniq
          when Nodes::Unary
            firstpos(node.left)
          when Nodes::Terminal
            nullable?(node) ? [] : [node]
          else
            raise ArgumentError, 'unknown firstpos: %s' % node.class.name
          end
        end

        def lastpos(node)
          case node
          when Nodes::Star
            firstpos(node.left)
          when Nodes::Or
            node.children.map { |c| lastpos(c) }.flatten.uniq
          when Nodes::Cat
            if nullable?(node.right)
              lastpos(node.left) | lastpos(node.right)
            else
              lastpos(node.right)
            end
          when Nodes::Terminal
            nullable?(node) ? [] : [node]
          when Nodes::Unary
            lastpos(node.left)
          else
            raise ArgumentError, 'unknown lastpos: %s' % node.class.name
          end
        end

        def followpos(node)
          followpos_table[node]
        end

        private

          def followpos_table
            @followpos ||= build_followpos
          end

          def build_followpos
            table = Hash.new { |h, k| h[k] = [] }
            @ast.each do |n|
              case n
              when Nodes::Cat
                lastpos(n.left).each do |i|
                  table[i] += firstpos(n.right)
                end
              when Nodes::Star
                lastpos(n).each do |i|
                  table[i] += firstpos(n)
                end
              end
            end
            table
          end

          def symbol(edge)
            case edge
            when Journey::Nodes::Symbol
              edge.regexp
            else
              edge.left
            end
          end
      end
    end
  end
end
require 'strscan'

module ActionDispatch
  module Journey # :nodoc:
    module GTG # :nodoc:
      class MatchData # :nodoc:
        attr_reader :memos

        def initialize(memos)
          @memos = memos
        end
      end

      class Simulator # :nodoc:
        attr_reader :tt

        def initialize(transition_table)
          @tt = transition_table
        end

        def simulate(string)
          input = StringScanner.new(string)
          state = [0]
          while sym = input.scan(%r([/.?]|[^/.?]+))
            state = tt.move(state, sym)
          end

          acceptance_states = state.find_all { |s|
            tt.accepting? s
          }

          return if acceptance_states.empty?

          memos = acceptance_states.map { |x| tt.memo(x) }.flatten.compact

          MatchData.new(memos)
        end

        alias :=~    :simulate
        alias :match :simulate
      end
    end
  end
end
require 'action_dispatch/journey/nfa/dot'

module ActionDispatch
  module Journey # :nodoc:
    module GTG # :nodoc:
      class TransitionTable # :nodoc:
        include Journey::NFA::Dot

        attr_reader :memos

        def initialize
          @regexp_states = Hash.new { |h,k| h[k] = {} }
          @string_states = Hash.new { |h,k| h[k] = {} }
          @accepting     = {}
          @memos         = Hash.new { |h,k| h[k] = [] }
        end

        def add_accepting(state)
          @accepting[state] = true
        end

        def accepting_states
          @accepting.keys
        end

        def accepting?(state)
          @accepting[state]
        end

        def add_memo(idx, memo)
          @memos[idx] << memo
        end

        def memo(idx)
          @memos[idx]
        end

        def eclosure(t)
          Array(t)
        end

        def move(t, a)
          move_string(t, a).concat(move_regexp(t, a))
        end

        def to_json
          require 'json'

          simple_regexp = Hash.new { |h,k| h[k] = {} }

          @regexp_states.each do |from, hash|
            hash.each do |re, to|
              simple_regexp[from][re.source] = to
            end
          end

          JSON.dump({
            regexp_states: simple_regexp,
            string_states: @string_states,
            accepting:     @accepting
          })
        end

        def to_svg
          svg = IO.popen('dot -Tsvg', 'w+') { |f|
            f.write(to_dot)
            f.close_write
            f.readlines
          }
          3.times { svg.shift }
          svg.join.sub(/width="[^"]*"/, '').sub(/height="[^"]*"/, '')
        end

        def visualizer(paths, title = 'FSM')
          viz_dir   = File.join File.dirname(__FILE__), '..', 'visualizer'
          fsm_js    = File.read File.join(viz_dir, 'fsm.js')
          fsm_css   = File.read File.join(viz_dir, 'fsm.css')
          erb       = File.read File.join(viz_dir, 'index.html.erb')
          states    = "function tt() { return #{to_json}; }"

          fun_routes = paths.shuffle.first(3).map do |ast|
            ast.map { |n|
              case n
              when Nodes::Symbol
                case n.left
                when ':id' then rand(100).to_s
                when ':format' then %w{ xml json }.shuffle.first
                else
                  'omg'
                end
              when Nodes::Terminal then n.symbol
              else
                nil
              end
            }.compact.join
          end

          stylesheets = [fsm_css]
          svg         = to_svg
          javascripts = [states, fsm_js]

          # Annoying hack for 1.9 warnings
          fun_routes  = fun_routes
          stylesheets = stylesheets
          svg         = svg
          javascripts = javascripts

          require 'erb'
          template = ERB.new erb
          template.result(binding)
        end

        def []=(from, to, sym)
          case sym
          when String
            @string_states[from][sym] = to
          when Regexp
            @regexp_states[from][sym] = to
          else
            raise ArgumentError, 'unknown symbol: %s' % sym.class
          end
        end

        def states
          ss = @string_states.keys + @string_states.values.map(&:values).flatten
          rs = @regexp_states.keys + @regexp_states.values.map(&:values).flatten
          (ss + rs).uniq
        end

        def transitions
          @string_states.map { |from, hash|
            hash.map { |s, to| [from, s, to] }
          }.flatten(1) + @regexp_states.map { |from, hash|
            hash.map { |s, to| [from, s, to] }
          }.flatten(1)
        end

        private

          def move_regexp(t, a)
            return [] if t.empty?

            t.map { |s|
              @regexp_states[s].map { |re, v| re === a ? v : nil }
            }.flatten.compact.uniq
          end

          def move_string(t, a)
            return [] if t.empty?

            t.map { |s| @string_states[s][a] }.compact
          end
      end
    end
  end
end
require 'action_dispatch/journey/nfa/transition_table'
require 'action_dispatch/journey/gtg/transition_table'

module ActionDispatch
  module Journey # :nodoc:
    module NFA # :nodoc:
      class Visitor < Visitors::Visitor # :nodoc:
        def initialize(tt)
          @tt = tt
          @i  = -1
        end

        def visit_CAT(node)
          left  = visit(node.left)
          right = visit(node.right)

          @tt.merge(left.last, right.first)

          [left.first, right.last]
        end

        def visit_GROUP(node)
          from  = @i += 1
          left  = visit(node.left)
          to    = @i += 1

          @tt.accepting = to

          @tt[from, left.first] = nil
          @tt[left.last, to] = nil
          @tt[from, to] = nil

          [from, to]
        end

        def visit_OR(node)
          from = @i += 1
          children = node.children.map { |c| visit(c) }
          to   = @i += 1

          children.each do |child|
            @tt[from, child.first] = nil
            @tt[child.last, to]    = nil
          end

          @tt.accepting = to

          [from, to]
        end

        def terminal(node)
          from_i = @i += 1 # new state
          to_i   = @i += 1 # new state

          @tt[from_i, to_i] = node
          @tt.accepting = to_i
          @tt.add_memo(to_i, node.memo)

          [from_i, to_i]
        end
      end

      class Builder # :nodoc:
        def initialize(ast)
          @ast = ast
        end

        def transition_table
          tt = TransitionTable.new
          Visitor.new(tt).accept(@ast)
          tt
        end
      end
    end
  end
end
# encoding: utf-8

module ActionDispatch
  module Journey # :nodoc:
    module NFA # :nodoc:
      module Dot # :nodoc:
        def to_dot
          edges = transitions.map { |from, sym, to|
            "  #{from} -> #{to} [label=\"#{sym || 'ε'}\"];"
          }

          #memo_nodes = memos.values.flatten.map { |n|
          #  label = n
          #  if Journey::Route === n
          #    label = "#{n.verb.source} #{n.path.spec}"
          #  end
          #  "  #{n.object_id} [label=\"#{label}\", shape=box];"
          #}
          #memo_edges = memos.map { |k, memos|
          #  (memos || []).map { |v| "  #{k} -> #{v.object_id};" }
          #}.flatten.uniq

        <<-eodot
digraph nfa {
  rankdir=LR;
  node [shape = doublecircle];
  #{accepting_states.join ' '};
  node [shape = circle];
#{edges.join "\n"}
}
        eodot
        end
      end
    end
  end
end
require 'strscan'

module ActionDispatch
  module Journey # :nodoc:
    module NFA # :nodoc:
      class MatchData # :nodoc:
        attr_reader :memos

        def initialize(memos)
          @memos = memos
        end
      end

      class Simulator # :nodoc:
        attr_reader :tt

        def initialize(transition_table)
          @tt = transition_table
        end

        def simulate(string)
          input = StringScanner.new(string)
          state = tt.eclosure(0)
          until input.eos?
            sym   = input.scan(%r([/.?]|[^/.?]+))

            # FIXME: tt.eclosure is not needed for the GTG
            state = tt.eclosure(tt.move(state, sym))
          end

          acceptance_states = state.find_all { |s|
            tt.accepting?(tt.eclosure(s).sort.last)
          }

          return if acceptance_states.empty?

          memos = acceptance_states.map { |x| tt.memo(x) }.flatten.compact

          MatchData.new(memos)
        end

        alias :=~    :simulate
        alias :match :simulate
      end
    end
  end
end
require 'action_dispatch/journey/nfa/dot'

module ActionDispatch
  module Journey # :nodoc:
    module NFA # :nodoc:
      class TransitionTable # :nodoc:
        include Journey::NFA::Dot

        attr_accessor :accepting
        attr_reader :memos

        def initialize
          @table     = Hash.new { |h,f| h[f] = {} }
          @memos     = {}
          @accepting = nil
          @inverted  = nil
        end

        def accepting?(state)
          accepting == state
        end

        def accepting_states
          [accepting]
        end

        def add_memo(idx, memo)
          @memos[idx] = memo
        end

        def memo(idx)
          @memos[idx]
        end

        def []=(i, f, s)
          @table[f][i] = s
        end

        def merge(left, right)
          @memos[right] = @memos.delete(left)
          @table[right] = @table.delete(left)
        end

        def states
          (@table.keys + @table.values.map(&:keys).flatten).uniq
        end

        # Returns a generalized transition graph with reduced states. The states
        # are reduced like a DFA, but the table must be simulated like an NFA.
        #
        # Edges of the GTG are regular expressions.
        def generalized_table
          gt       = GTG::TransitionTable.new
          marked   = {}
          state_id = Hash.new { |h,k| h[k] = h.length }
          alphabet = self.alphabet

          stack = [eclosure(0)]

          until stack.empty?
            state = stack.pop
            next if marked[state] || state.empty?

            marked[state] = true

            alphabet.each do |alpha|
              next_state = eclosure(following_states(state, alpha))
              next if next_state.empty?

              gt[state_id[state], state_id[next_state]] = alpha
              stack << next_state
            end
          end

          final_groups = state_id.keys.find_all { |s|
            s.sort.last == accepting
          }

          final_groups.each do |states|
            id = state_id[states]

            gt.add_accepting(id)
            save = states.find { |s|
              @memos.key?(s) && eclosure(s).sort.last == accepting
            }

            gt.add_memo(id, memo(save))
          end

          gt
        end

        # Returns set of NFA states to which there is a transition on ast symbol
        # +a+ from some state +s+ in +t+.
        def following_states(t, a)
          Array(t).map { |s| inverted[s][a] }.flatten.uniq
        end

        # Returns set of NFA states to which there is a transition on ast symbol
        # +a+ from some state +s+ in +t+.
        def move(t, a)
          Array(t).map { |s|
            inverted[s].keys.compact.find_all { |sym|
              sym === a
            }.map { |sym| inverted[s][sym] }
          }.flatten.uniq
        end

        def alphabet
          inverted.values.map(&:keys).flatten.compact.uniq.sort_by { |x| x.to_s }
        end

        # Returns a set of NFA states reachable from some NFA state +s+ in set
        # +t+ on nil-transitions alone.
        def eclosure(t)
          stack = Array(t)
          seen  = {}
          children = []

          until stack.empty?
            s = stack.pop
            next if seen[s]

            seen[s] = true
            children << s

            stack.concat(inverted[s][nil])
          end

          children.uniq
        end

        def transitions
          @table.map { |to, hash|
            hash.map { |from, sym| [from, sym, to] }
          }.flatten(1)
        end

        private

          def inverted
            return @inverted if @inverted

            @inverted = Hash.new { |h, from|
              h[from] = Hash.new { |j, s| j[s] = [] }
            }

            @table.each { |to, hash|
              hash.each { |from, sym|
                if sym
                  sym = Nodes::Symbol === sym ? sym.regexp : sym.left
                end

                @inverted[from][sym] << to
              }
            }

            @inverted
          end
      end
    end
  end
end
require 'action_dispatch/journey/visitors'

module ActionDispatch
  module Journey # :nodoc:
    module Nodes # :nodoc:
      class Node # :nodoc:
        include Enumerable

        attr_accessor :left, :memo

        def initialize(left)
          @left = left
          @memo = nil
        end

        def each(&block)
          Visitors::Each.new(block).accept(self)
        end

        def to_s
          Visitors::String.new.accept(self)
        end

        def to_dot
          Visitors::Dot.new.accept(self)
        end

        def to_sym
          name.to_sym
        end

        def name
          left.tr '*:', ''
        end

        def type
          raise NotImplementedError
        end

        def symbol?; false; end
        def literal?; false; end
      end

      class Terminal < Node # :nodoc:
        alias :symbol :left
      end

      class Literal < Terminal # :nodoc:
        def literal?; true; end
        def type; :LITERAL; end
      end

      class Dummy < Literal # :nodoc:
        def initialize(x = Object.new)
          super
        end

        def literal?; false; end
      end

      %w{ Symbol Slash Dot }.each do |t|
        class_eval <<-eoruby, __FILE__, __LINE__ + 1
          class #{t} < Terminal;
            def type; :#{t.upcase}; end
          end
        eoruby
      end

      class Symbol < Terminal # :nodoc:
        attr_accessor :regexp
        alias :symbol :regexp

        DEFAULT_EXP = /[^\.\/\?]+/
        def initialize(left)
          super
          @regexp = DEFAULT_EXP
        end

        def default_regexp?
          regexp == DEFAULT_EXP
        end

        def symbol?; true; end
      end

      class Unary < Node # :nodoc:
        def children; [left] end
      end

      class Group < Unary # :nodoc:
        def type; :GROUP; end
      end

      class Star < Unary # :nodoc:
        def type; :STAR; end
      end

      class Binary < Node # :nodoc:
        attr_accessor :right

        def initialize(left, right)
          super(left)
          @right = right
        end

        def children; [left, right] end
      end

      class Cat < Binary # :nodoc:
        def type; :CAT; end
      end

      class Or < Node # :nodoc:
        attr_reader :children

        def initialize(children)
          @children = children
        end

        def type; :OR; end
      end
    end
  end
end
#
# DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.4.9
# from Racc grammer file "".
#

require 'racc/parser.rb'


require 'action_dispatch/journey/parser_extras'
module ActionDispatch
  module Journey # :nodoc:
    class Parser < Racc::Parser # :nodoc:
##### State transition tables begin ###

racc_action_table = [
    17,    21,    13,    15,    14,     7,   nil,    16,     8,    19,
    13,    15,    14,     7,    23,    16,     8,    19,    13,    15,
    14,     7,   nil,    16,     8,    13,    15,    14,     7,   nil,
    16,     8,    13,    15,    14,     7,   nil,    16,     8 ]

racc_action_check = [
     1,    17,     1,     1,     1,     1,   nil,     1,     1,     1,
    20,    20,    20,    20,    20,    20,    20,    20,     7,     7,
     7,     7,   nil,     7,     7,    19,    19,    19,    19,   nil,
    19,    19,     0,     0,     0,     0,   nil,     0,     0 ]

racc_action_pointer = [
    30,     0,   nil,   nil,   nil,   nil,   nil,    16,   nil,   nil,
   nil,   nil,   nil,   nil,   nil,   nil,   nil,     1,   nil,    23,
     8,   nil,   nil,   nil ]

racc_action_default = [
   -18,   -18,    -2,    -3,    -4,    -5,    -6,   -18,    -9,   -10,
   -11,   -12,   -13,   -14,   -15,   -16,   -17,   -18,    -1,   -18,
   -18,    24,    -8,    -7 ]

racc_goto_table = [
    18,     1,   nil,   nil,   nil,   nil,   nil,   nil,    20,   nil,
   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,    22,    18 ]

racc_goto_check = [
     2,     1,   nil,   nil,   nil,   nil,   nil,   nil,     1,   nil,
   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,     2,     2 ]

racc_goto_pointer = [
   nil,     1,    -1,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
   nil ]

racc_goto_default = [
   nil,   nil,     2,     3,     4,     5,     6,     9,    10,    11,
    12 ]

racc_reduce_table = [
  0, 0, :racc_error,
  2, 11, :_reduce_1,
  1, 11, :_reduce_2,
  1, 11, :_reduce_none,
  1, 12, :_reduce_none,
  1, 12, :_reduce_none,
  1, 12, :_reduce_none,
  3, 15, :_reduce_7,
  3, 13, :_reduce_8,
  1, 16, :_reduce_9,
  1, 14, :_reduce_none,
  1, 14, :_reduce_none,
  1, 14, :_reduce_none,
  1, 14, :_reduce_none,
  1, 19, :_reduce_14,
  1, 17, :_reduce_15,
  1, 18, :_reduce_16,
  1, 20, :_reduce_17 ]

racc_reduce_n = 18

racc_shift_n = 24

racc_token_table = {
  false => 0,
  :error => 1,
  :SLASH => 2,
  :LITERAL => 3,
  :SYMBOL => 4,
  :LPAREN => 5,
  :RPAREN => 6,
  :DOT => 7,
  :STAR => 8,
  :OR => 9 }

racc_nt_base = 10

racc_use_result_var = true

Racc_arg = [
  racc_action_table,
  racc_action_check,
  racc_action_default,
  racc_action_pointer,
  racc_goto_table,
  racc_goto_check,
  racc_goto_default,
  racc_goto_pointer,
  racc_nt_base,
  racc_reduce_table,
  racc_token_table,
  racc_shift_n,
  racc_reduce_n,
  racc_use_result_var ]

Racc_token_to_s_table = [
  "$end",
  "error",
  "SLASH",
  "LITERAL",
  "SYMBOL",
  "LPAREN",
  "RPAREN",
  "DOT",
  "STAR",
  "OR",
  "$start",
  "expressions",
  "expression",
  "or",
  "terminal",
  "group",
  "star",
  "symbol",
  "literal",
  "slash",
  "dot" ]

Racc_debug_parser = false

##### State transition tables end #####

# reduce 0 omitted

def _reduce_1(val, _values, result)
 result = Cat.new(val.first, val.last)
    result
end

def _reduce_2(val, _values, result)
 result = val.first
    result
end

# reduce 3 omitted

# reduce 4 omitted

# reduce 5 omitted

# reduce 6 omitted

def _reduce_7(val, _values, result)
 result = Group.new(val[1])
    result
end

def _reduce_8(val, _values, result)
 result = Or.new([val.first, val.last])
    result
end

def _reduce_9(val, _values, result)
 result = Star.new(Symbol.new(val.last))
    result
end

# reduce 10 omitted

# reduce 11 omitted

# reduce 12 omitted

# reduce 13 omitted

def _reduce_14(val, _values, result)
 result = Slash.new('/')
    result
end

def _reduce_15(val, _values, result)
 result = Symbol.new(val.first)
    result
end

def _reduce_16(val, _values, result)
 result = Literal.new(val.first)
    result
end

def _reduce_17(val, _values, result)
 result = Dot.new(val.first)
    result
end

def _reduce_none(val, _values, result)
  val[0]
end

    end   # class Parser
    end   # module Journey
  end   # module ActionDispatch
require 'action_dispatch/journey/scanner'
require 'action_dispatch/journey/nodes/node'

module ActionDispatch
  module Journey # :nodoc:
    class Parser < Racc::Parser # :nodoc:
      include Journey::Nodes

      def initialize
        @scanner = Scanner.new
      end

      def parse(string)
        @scanner.scan_setup(string)
        do_parse
      end

      def next_token
        @scanner.next_token
      end
    end
  end
end
module ActionDispatch
  module Journey # :nodoc:
    module Path # :nodoc:
      class Pattern # :nodoc:
        attr_reader :spec, :requirements, :anchored

        def initialize(strexp)
          parser = Journey::Parser.new

          @anchored = true

          case strexp
          when String
            @spec         = parser.parse(strexp)
            @requirements = {}
            @separators   = "/.?"
          when Router::Strexp
            @spec         = parser.parse(strexp.path)
            @requirements = strexp.requirements
            @separators   = strexp.separators.join
            @anchored     = strexp.anchor
          else
            raise "wtf bro: #{strexp}"
          end

          @names          = nil
          @optional_names = nil
          @required_names = nil
          @re             = nil
          @offsets        = nil
        end

        def ast
          @spec.grep(Nodes::Symbol).each do |node|
            re = @requirements[node.to_sym]
            node.regexp = re if re
          end

          @spec.grep(Nodes::Star).each do |node|
            node = node.left
            node.regexp = @requirements[node.to_sym] || /(.+)/
          end

          @spec
        end

        def names
          @names ||= spec.grep(Nodes::Symbol).map { |n| n.name }
        end

        def required_names
          @required_names ||= names - optional_names
        end

        def optional_names
          @optional_names ||= spec.grep(Nodes::Group).map { |group|
            group.grep(Nodes::Symbol)
          }.flatten.map { |n| n.name }.uniq
        end

        class RegexpOffsets < Journey::Visitors::Visitor # :nodoc:
          attr_reader :offsets

          def initialize(matchers)
            @matchers      = matchers
            @capture_count = [0]
          end

          def visit(node)
            super
            @capture_count
          end

          def visit_SYMBOL(node)
            node = node.to_sym

            if @matchers.key?(node)
              re = /#{@matchers[node]}|/
              @capture_count.push((re.match('').length - 1) + (@capture_count.last || 0))
            else
              @capture_count << (@capture_count.last || 0)
            end
          end
        end

        class AnchoredRegexp < Journey::Visitors::Visitor # :nodoc:
          def initialize(separator, matchers)
            @separator = separator
            @matchers  = matchers
            @separator_re = "([^#{separator}]+)"
            super()
          end

          def accept(node)
            %r{\A#{visit node}\Z}
          end

          def visit_CAT(node)
            [visit(node.left), visit(node.right)].join
          end

          def visit_SYMBOL(node)
            node = node.to_sym

            return @separator_re unless @matchers.key?(node)

            re = @matchers[node]
            "(#{re})"
          end

          def visit_GROUP(node)
            "(?:#{visit node.left})?"
          end

          def visit_LITERAL(node)
            Regexp.escape(node.left)
          end
          alias :visit_DOT :visit_LITERAL

          def visit_SLASH(node)
            node.left
          end

          def visit_STAR(node)
            re = @matchers[node.left.to_sym] || '.+'
            "(#{re})"
          end
        end

        class UnanchoredRegexp < AnchoredRegexp # :nodoc:
          def accept(node)
            %r{\A#{visit node}}
          end
        end

        class MatchData # :nodoc:
          attr_reader :names

          def initialize(names, offsets, match)
            @names   = names
            @offsets = offsets
            @match   = match
          end

          def captures
            (length - 1).times.map { |i| self[i + 1] }
          end

          def [](x)
            idx = @offsets[x - 1] + x
            @match[idx]
          end

          def length
            @offsets.length
          end

          def post_match
            @match.post_match
          end

          def to_s
            @match.to_s
          end
        end

        def match(other)
          return unless match = to_regexp.match(other)
          MatchData.new(names, offsets, match)
        end
        alias :=~ :match

        def source
          to_regexp.source
        end

        def to_regexp
          @re ||= regexp_visitor.new(@separators, @requirements).accept spec
        end

        private

          def regexp_visitor
            @anchored ? AnchoredRegexp : UnanchoredRegexp
          end

          def offsets
            return @offsets if @offsets

            viz = RegexpOffsets.new(@requirements)
            @offsets = viz.accept(spec)
          end
      end
    end
  end
end
module ActionDispatch
  module Journey # :nodoc:
    class Route # :nodoc:
      attr_reader :app, :path, :defaults, :name

      attr_reader :constraints
      alias :conditions :constraints

      attr_accessor :precedence

      ##
      # +path+ is a path constraint.
      # +constraints+ is a hash of constraints to be applied to this route.
      def initialize(name, app, path, constraints, defaults = {})
        @name        = name
        @app         = app
        @path        = path

        @constraints = constraints
        @defaults    = defaults
        @required_defaults = nil
        @required_parts    = nil
        @parts             = nil
        @decorated_ast     = nil
        @precedence        = 0
      end

      def ast
        @decorated_ast ||= begin
          decorated_ast = path.ast
          decorated_ast.grep(Nodes::Terminal).each { |n| n.memo = self }
          decorated_ast
        end
      end

      def requirements # :nodoc:
        # needed for rails `rake routes`
        path.requirements.merge(@defaults).delete_if { |_,v|
          /.+?/ == v
        }
      end

      def segments
        path.names
      end

      def required_keys
        required_parts + required_defaults.keys
      end

      def score(constraints)
        required_keys = path.required_names
        supplied_keys = constraints.map { |k,v| v && k.to_s }.compact

        return -1 unless (required_keys - supplied_keys).empty?

        score = (supplied_keys & path.names).length
        score + (required_defaults.length * 2)
      end

      def parts
        @parts ||= segments.map { |n| n.to_sym }
      end
      alias :segment_keys :parts

      def format(path_options)
        path_options.delete_if do |key, value|
          value.to_s == defaults[key].to_s && !required_parts.include?(key)
        end

        Visitors::Formatter.new(path_options).accept(path.spec)
      end

      def optional_parts
        path.optional_names.map { |n| n.to_sym }
      end

      def required_parts
        @required_parts ||= path.required_names.map { |n| n.to_sym }
      end

      def required_default?(key)
        (constraints[:required_defaults] || []).include?(key)
      end

      def required_defaults
        @required_defaults ||= @defaults.dup.delete_if do |k,_|
          parts.include?(k) || !required_default?(k)
        end
      end

      def matches?(request)
        constraints.all? do |method, value|
          next true unless request.respond_to?(method)

          case value
          when Regexp, String
            value === request.send(method).to_s
          when Array
            value.include?(request.send(method))
          else
            value === request.send(method)
          end
        end
      end

      def ip
        constraints[:ip] || //
      end

      def verb
        constraints[:request_method] || //
      end
    end
  end
end
module ActionDispatch
  module Journey # :nodoc:
    class Router # :nodoc:
      class Strexp # :nodoc:
        class << self
          alias :compile :new
        end

        attr_reader :path, :requirements, :separators, :anchor

        def initialize(path, requirements, separators, anchor = true)
          @path         = path
          @requirements = requirements
          @separators   = separators
          @anchor       = anchor
        end

        def names
          @path.scan(/:\w+/).map { |s| s.tr(':', '') }
        end
      end
    end
  end
end
require 'uri'

module ActionDispatch
  module Journey # :nodoc:
    class Router # :nodoc:
      class Utils # :nodoc:
        # Normalizes URI path.
        #
        # Strips off trailing slash and ensures there is a leading slash.
        #
        #   normalize_path("/foo")  # => "/foo"
        #   normalize_path("/foo/") # => "/foo"
        #   normalize_path("foo")   # => "/foo"
        #   normalize_path("")      # => "/"
        def self.normalize_path(path)
          path = "/#{path}"
          path.squeeze!('/')
          path.sub!(%r{/+\Z}, '')
          path = '/' if path == ''
          path
        end

        # URI path and fragment escaping
        # http://tools.ietf.org/html/rfc3986
        module UriEscape # :nodoc:
          # Symbol captures can generate multiple path segments, so include /.
          reserved_segment  = '/'
          reserved_fragment = '/?'
          reserved_pchar    = ':@&=+$,;%'

          safe_pchar    = "#{URI::REGEXP::PATTERN::UNRESERVED}#{reserved_pchar}"
          safe_segment  = "#{safe_pchar}#{reserved_segment}"
          safe_fragment = "#{safe_pchar}#{reserved_fragment}"
          UNSAFE_SEGMENT  = Regexp.new("[^#{safe_segment}]", false).freeze
          UNSAFE_FRAGMENT = Regexp.new("[^#{safe_fragment}]", false).freeze
        end

        Parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI

        def self.escape_path(path)
          Parser.escape(path.to_s, UriEscape::UNSAFE_SEGMENT)
        end

        def self.escape_fragment(fragment)
          Parser.escape(fragment.to_s, UriEscape::UNSAFE_FRAGMENT)
        end

        def self.unescape_uri(uri)
          Parser.unescape(uri)
        end
      end
    end
  end
end
require 'action_dispatch/journey/router/utils'
require 'action_dispatch/journey/router/strexp'
require 'action_dispatch/journey/routes'
require 'action_dispatch/journey/formatter'

before = $-w
$-w = false
require 'action_dispatch/journey/parser'
$-w = before

require 'action_dispatch/journey/route'
require 'action_dispatch/journey/path/pattern'

module ActionDispatch
  module Journey # :nodoc:
    class Router # :nodoc:
      class RoutingError < ::StandardError # :nodoc:
      end

      # :nodoc:
      VERSION = '2.0.0'

      class NullReq # :nodoc:
        attr_reader :env
        def initialize(env)
          @env = env
        end

        def request_method
          env['REQUEST_METHOD']
        end

        def path_info
          env['PATH_INFO']
        end

        def ip
          env['REMOTE_ADDR']
        end

        def [](k); env[k]; end
      end

      attr_reader :request_class, :formatter
      attr_accessor :routes

      def initialize(routes, options)
        @options       = options
        @params_key    = options[:parameters_key]
        @request_class = options[:request_class] || NullReq
        @routes        = routes
      end

      def call(env)
        env['PATH_INFO'] = Utils.normalize_path(env['PATH_INFO'])

        find_routes(env).each do |match, parameters, route|
          script_name, path_info, set_params = env.values_at('SCRIPT_NAME',
                                                             'PATH_INFO',
                                                             @params_key)

          unless route.path.anchored
            env['SCRIPT_NAME'] = (script_name.to_s + match.to_s).chomp('/')
            env['PATH_INFO']   = match.post_match
          end

          env[@params_key] = (set_params || {}).merge parameters

          status, headers, body = route.app.call(env)

          if 'pass' == headers['X-Cascade']
            env['SCRIPT_NAME'] = script_name
            env['PATH_INFO']   = path_info
            env[@params_key]   = set_params
            next
          end

          return [status, headers, body]
        end

        return [404, {'X-Cascade' => 'pass'}, ['Not Found']]
      end

      def recognize(req)
        find_routes(req.env).each do |match, parameters, route|
          unless route.path.anchored
            req.env['SCRIPT_NAME'] = match.to_s
            req.env['PATH_INFO']   = match.post_match.sub(/^([^\/])/, '/\1')
          end

          yield(route, nil, parameters)
        end
      end

      def visualizer
        tt     = GTG::Builder.new(ast).transition_table
        groups = partitioned_routes.first.map(&:ast).group_by { |a| a.to_s }
        asts   = groups.values.map { |v| v.first }
        tt.visualizer(asts)
      end

      private

        def partitioned_routes
          routes.partitioned_routes
        end

        def ast
          routes.ast
        end

        def simulator
          routes.simulator
        end

        def custom_routes
          partitioned_routes.last
        end

        def filter_routes(path)
          return [] unless ast
          data = simulator.match(path)
          data ? data.memos : []
        end

        def find_routes env
          req = request_class.new(env)

          routes = filter_routes(req.path_info).concat custom_routes.find_all { |r|
            r.path.match(req.path_info)
          }
          routes.concat get_routes_as_head(routes)

          routes.sort_by!(&:precedence).select! { |r| r.matches?(req) }

          routes.map! { |r|
            match_data  = r.path.match(req.path_info)
            match_names = match_data.names.map { |n| n.to_sym }
            match_values = match_data.captures.map { |v| v && Utils.unescape_uri(v) }
            info = Hash[match_names.zip(match_values).find_all { |_, y| y }]

            [match_data, r.defaults.merge(info), r]
          }
        end

        def get_routes_as_head(routes)
          precedence = (routes.map(&:precedence).max || 0) + 1
          routes = routes.select { |r|
            r.verb === "GET" && !(r.verb === "HEAD")
          }.map! { |r|
            Route.new(r.name,
                      r.app,
                      r.path,
                      r.conditions.merge(request_method: "HEAD"),
                      r.defaults).tap do |route|
                        route.precedence = r.precedence + precedence
                      end
          }
          routes.flatten!
          routes
        end
    end
  end
end
module ActionDispatch
  module Journey # :nodoc:
    # The Routing table. Contains all routes for a system. Routes can be
    # added to the table by calling Routes#add_route.
    class Routes # :nodoc:
      include Enumerable

      attr_reader :routes, :named_routes

      def initialize
        @routes             = []
        @named_routes       = {}
        @ast                = nil
        @partitioned_routes = nil
        @simulator          = nil
      end

      def length
        routes.length
      end
      alias :size :length

      def last
        routes.last
      end

      def each(&block)
        routes.each(&block)
      end

      def clear
        routes.clear
      end

      def partitioned_routes
        @partitioned_routes ||= routes.partition do |r|
          r.path.anchored && r.ast.grep(Nodes::Symbol).all?(&:default_regexp?)
        end
      end

      def ast
        @ast ||= begin
          asts = partitioned_routes.first.map(&:ast)
          Nodes::Or.new(asts) unless asts.empty?
        end
      end

      def simulator
        @simulator ||= begin
          gtg = GTG::Builder.new(ast).transition_table
          GTG::Simulator.new(gtg)
        end
      end

      # Add a route to the routing table.
      def add_route(app, path, conditions, defaults, name = nil)
        route = Route.new(name, app, path, conditions, defaults)

        route.precedence = routes.length
        routes << route
        named_routes[name] = route if name && !named_routes[name]
        clear_cache!
        route
      end

      private

        def clear_cache!
          @ast                = nil
          @partitioned_routes = nil
          @simulator          = nil
        end
    end
  end
end
require 'strscan'

module ActionDispatch
  module Journey # :nodoc:
    class Scanner # :nodoc:
      def initialize
        @ss = nil
      end

      def scan_setup(str)
        @ss = StringScanner.new(str)
      end

      def eos?
        @ss.eos?
      end

      def pos
        @ss.pos
      end

      def pre_match
        @ss.pre_match
      end

      def next_token
        return if @ss.eos?

        until token = scan || @ss.eos?; end
        token
      end

      private

        def scan
          case
            # /
          when text = @ss.scan(/\//)
            [:SLASH, text]
          when text = @ss.scan(/\*\w+/)
            [:STAR, text]
          when text = @ss.scan(/\(/)
            [:LPAREN, text]
          when text = @ss.scan(/\)/)
            [:RPAREN, text]
          when text = @ss.scan(/\|/)
            [:OR, text]
          when text = @ss.scan(/\./)
            [:DOT, text]
          when text = @ss.scan(/:\w+/)
            [:SYMBOL, text]
          when text = @ss.scan(/[\w%\-~]+/)
            [:LITERAL, text]
            # any char
          when text = @ss.scan(/./)
            [:LITERAL, text]
          end
        end
    end
  end
end
# encoding: utf-8
module ActionDispatch
  module Journey # :nodoc:
    module Visitors # :nodoc:
      class Visitor # :nodoc:
        DISPATCH_CACHE = Hash.new { |h,k|
          h[k] = "visit_#{k}"
        }

        def accept(node)
          visit(node)
        end

        private

          def visit node
            send(DISPATCH_CACHE[node.type], node)
          end

          def binary(node)
            visit(node.left)
            visit(node.right)
          end
          def visit_CAT(n); binary(n); end

          def nary(node)
            node.children.each { |c| visit(c) }
          end
          def visit_OR(n); nary(n); end

          def unary(node)
            visit(node.left)
          end
          def visit_GROUP(n); unary(n); end
          def visit_STAR(n); unary(n); end

          def terminal(node); end
          %w{ LITERAL SYMBOL SLASH DOT }.each do |t|
            class_eval %{ def visit_#{t}(n); terminal(n); end }, __FILE__, __LINE__
          end
      end

      # Loop through the requirements AST
      class Each < Visitor # :nodoc:
        attr_reader :block

        def initialize(block)
          @block = block
        end

        def visit(node)
          super
          block.call(node)
        end
      end

      class String < Visitor # :nodoc:
        private

        def binary(node)
          [visit(node.left), visit(node.right)].join
        end

        def nary(node)
          node.children.map { |c| visit(c) }.join '|'
        end

        def terminal(node)
          node.left
        end

        def visit_GROUP(node)
          "(#{visit(node.left)})"
        end
      end

      # Used for formatting urls (url_for)
      class Formatter < Visitor # :nodoc:
        attr_reader :options, :consumed

        def initialize(options)
          @options  = options
          @consumed = {}
        end

        private

          def visit_GROUP(node)
            if consumed == options
              nil
            else
              route = visit(node.left)
              route.include?("\0") ? nil : route
            end
          end

          def terminal(node)
            node.left
          end

          def binary(node)
            [visit(node.left), visit(node.right)].join
          end

          def nary(node)
            node.children.map { |c| visit(c) }.join
          end

          def visit_SYMBOL(node)
            key = node.to_sym

            if value = options[key]
              consumed[key] = value
              Router::Utils.escape_path(value)
            else
              "\0"
            end
          end
      end

      class Dot < Visitor # :nodoc:
        def initialize
          @nodes = []
          @edges = []
        end

        def accept(node)
          super
          <<-eodot
  digraph parse_tree {
    size="8,5"
    node [shape = none];
    edge [dir = none];
    #{@nodes.join "\n"}
    #{@edges.join("\n")}
  }
          eodot
        end

        private

          def binary(node)
            node.children.each do |c|
              @edges << "#{node.object_id} -> #{c.object_id};"
            end
            super
          end

          def nary(node)
            node.children.each do |c|
              @edges << "#{node.object_id} -> #{c.object_id};"
            end
            super
          end

          def unary(node)
            @edges << "#{node.object_id} -> #{node.left.object_id};"
            super
          end

          def visit_GROUP(node)
            @nodes << "#{node.object_id} [label=\"()\"];"
            super
          end

          def visit_CAT(node)
            @nodes << "#{node.object_id} [label=\"○\"];"
            super
          end

          def visit_STAR(node)
            @nodes << "#{node.object_id} [label=\"*\"];"
            super
          end

          def visit_OR(node)
            @nodes << "#{node.object_id} [label=\"|\"];"
            super
          end

          def terminal(node)
            value = node.left

            @nodes << "#{node.object_id} [label=\"#{value}\"];"
          end
      end
    end
  end
end
require 'action_dispatch/journey/router'
require 'action_dispatch/journey/gtg/builder'
require 'action_dispatch/journey/gtg/simulator'
require 'action_dispatch/journey/nfa/builder'
require 'action_dispatch/journey/nfa/simulator'

module ActionDispatch
  # Provide callbacks to be executed before and after the request dispatch.
  class Callbacks
    include ActiveSupport::Callbacks

    define_callbacks :call

    class << self
      delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
    end

    def self.before(*args, &block)
      set_callback(:call, :before, *args, &block)
    end

    def self.after(*args, &block)
      set_callback(:call, :after, *args, &block)
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      error = nil
      result = run_callbacks :call do
        begin
          @app.call(env)
        rescue => error
        end
      end
      raise error if error
      result
    end
  end
end
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/key_generator'
require 'active_support/message_verifier'

module ActionDispatch
  class Request < Rack::Request
    def cookie_jar
      env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self)
    end
  end

  # \Cookies are read and written through ActionController#cookies.
  #
  # The cookies being read are the ones received along with the request, the cookies
  # being written will be sent out with the response. Reading a cookie does not get
  # the cookie object itself back, just the value it holds.
  #
  # Examples of writing:
  #
  #   # Sets a simple session cookie.
  #   # This cookie will be deleted when the user's browser is closed.
  #   cookies[:user_name] = "david"
  #
  #   # Assign an array of values to a cookie.
  #   cookies[:lat_lon] = [47.68, -122.37]
  #
  #   # Sets a cookie that expires in 1 hour.
  #   cookies[:login] = { value: "XJ-122", expires: 1.hour.from_now }
  #
  #   # Sets a signed cookie, which prevents users from tampering with its value.
  #   # The cookie is signed by your app's <tt>config.secret_key_base</tt> value.
  #   # It can be read using the signed method <tt>cookies.signed[:key]</tt>
  #   cookies.signed[:user_id] = current_user.id
  #
  #   # Sets a "permanent" cookie (which expires in 20 years from now).
  #   cookies.permanent[:login] = "XJ-122"
  #
  #   # You can also chain these methods:
  #   cookies.permanent.signed[:login] = "XJ-122"
  #
  # Examples of reading:
  #
  #   cookies[:user_name]    # => "david"
  #   cookies.size           # => 2
  #   cookies[:lat_lon]      # => [47.68, -122.37]
  #   cookies.signed[:login] # => "XJ-122"
  #
  # Example for deleting:
  #
  #   cookies.delete :user_name
  #
  # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
  #
  #  cookies[:key] = {
  #    value: 'a yummy cookie',
  #    expires: 1.year.from_now,
  #    domain: 'domain.com'
  #  }
  #
  #  cookies.delete(:key, domain: 'domain.com')
  #
  # The option symbols for setting cookies are:
  #
  # * <tt>:value</tt> - The cookie's value or list of values (as an array).
  # * <tt>:path</tt> - The path for which this cookie applies. Defaults to the root
  #   of the application.
  # * <tt>:domain</tt> - The domain for which this cookie applies so you can
  #   restrict to the domain level. If you use a schema like www.example.com
  #   and want to share session with user.example.com set <tt>:domain</tt>
  #   to <tt>:all</tt>. Make sure to specify the <tt>:domain</tt> option with
  #   <tt>:all</tt> again when deleting keys.
  #
  #     domain: nil  # Does not sets cookie domain. (default)
  #     domain: :all # Allow the cookie for the top most level
  #                       domain and subdomains.
  #
  # * <tt>:expires</tt> - The time at which this cookie expires, as a \Time object.
  # * <tt>:secure</tt> - Whether this cookie is a only transmitted to HTTPS servers.
  #   Default is +false+.
  # * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or
  #   only HTTP. Defaults to +false+.
  class Cookies
    HTTP_HEADER   = "Set-Cookie".freeze
    GENERATOR_KEY = "action_dispatch.key_generator".freeze
    SIGNED_COOKIE_SALT = "action_dispatch.signed_cookie_salt".freeze
    ENCRYPTED_COOKIE_SALT = "action_dispatch.encrypted_cookie_salt".freeze
    ENCRYPTED_SIGNED_COOKIE_SALT = "action_dispatch.encrypted_signed_cookie_salt".freeze
    TOKEN_KEY   = "action_dispatch.secret_token".freeze

    # Cookies can typically store 4096 bytes.
    MAX_COOKIE_SIZE = 4096

    # Raised when storing more than 4K of session data.
    CookieOverflow = Class.new StandardError

    class CookieJar #:nodoc:
      include Enumerable

      # This regular expression is used to split the levels of a domain.
      # The top level domain can be any string without a period or
      # **.**, ***.** style TLDs like co.uk or com.au
      #
      # www.example.co.uk gives:
      # $& => example.co.uk
      #
      # example.com gives:
      # $& => example.com
      #
      # lots.of.subdomains.example.local gives:
      # $& => example.local
      DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/

      def self.options_for_env(env) #:nodoc:
        { signed_cookie_salt: env[SIGNED_COOKIE_SALT] || '',
          encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT] || '',
          encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT] || '',
          token_key: env[TOKEN_KEY] }
      end

      def self.build(request)
        env = request.env
        key_generator = env[GENERATOR_KEY]
        options = options_for_env env

        host = request.host
        secure = request.ssl?

        new(key_generator, host, secure, options).tap do |hash|
          hash.update(request.cookies)
        end
      end

      def initialize(key_generator, host = nil, secure = false, options = {})
        @key_generator = key_generator
        @set_cookies = {}
        @delete_cookies = {}
        @host = host
        @secure = secure
        @options = options
        @cookies = {}
      end

      def each(&block)
        @cookies.each(&block)
      end

      # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
      def [](name)
        @cookies[name.to_s]
      end

      def fetch(name, *args, &block)
        @cookies.fetch(name.to_s, *args, &block)
      end

      def key?(name)
        @cookies.key?(name.to_s)
      end
      alias :has_key? :key?

      def update(other_hash)
        @cookies.update other_hash.stringify_keys
        self
      end

      def handle_options(options) #:nodoc:
        options[:path] ||= "/"

        if options[:domain] == :all
          # if there is a provided tld length then we use it otherwise default domain regexp
          domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP

          # if host is not ip and matches domain regexp
          # (ip confirms to domain regexp so we explicitly check for ip)
          options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ domain_regexp)
            ".#{$&}"
          end
        elsif options[:domain].is_a? Array
          # if host matches one of the supplied domains without a dot in front of it
          options[:domain] = options[:domain].find {|domain| @host.include? domain.sub(/^\./, '') }
        end
      end

      # Sets the cookie named +name+. The second argument may be the very cookie
      # value, or a hash of options as documented above.
      def []=(key, options)
        if options.is_a?(Hash)
          options.symbolize_keys!
          value = options[:value]
        else
          value = options
          options = { :value => value }
        end

        handle_options(options)

        if @cookies[key.to_s] != value or options[:expires]
          @cookies[key.to_s] = value
          @set_cookies[key.to_s] = options
          @delete_cookies.delete(key.to_s)
        end

        value
      end

      # Removes the cookie on the client machine by setting the value to an empty string
      # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
      # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
      def delete(key, options = {})
        return unless @cookies.has_key? key.to_s

        options.symbolize_keys!
        handle_options(options)

        value = @cookies.delete(key.to_s)
        @delete_cookies[key.to_s] = options
        value
      end

      # Whether the given cookie is to be deleted by this CookieJar.
      # Like <tt>[]=</tt>, you can pass in an options hash to test if a
      # deletion applies to a specific <tt>:path</tt>, <tt>:domain</tt> etc.
      def deleted?(key, options = {})
        options.symbolize_keys!
        handle_options(options)
        @delete_cookies[key.to_s] == options
      end

      # Removes all cookies on the client machine by calling <tt>delete</tt> for each cookie
      def clear(options = {})
        @cookies.each_key{ |k| delete(k, options) }
      end

      # Returns a jar that'll automatically set the assigned cookies to have an expiration date 20 years from now. Example:
      #
      #   cookies.permanent[:prefers_open_id] = true
      #   # => Set-Cookie: prefers_open_id=true; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
      #
      # This jar is only meant for writing. You'll read permanent cookies through the regular accessor.
      #
      # This jar allows chaining with the signed jar as well, so you can set permanent, signed cookies. Examples:
      #
      #   cookies.permanent.signed[:remember_me] = current_user.id
      #   # => Set-Cookie: remember_me=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
      def permanent
        @permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
      end

      # Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
      # the cookie again. This is useful for creating cookies with values that the user is not supposed to change. If a signed
      # cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
      # be raised.
      #
      # This jar requires that you set a suitable secret for the verification on your app's +config.secret_key_base+.
      #
      # Example:
      #
      #   cookies.signed[:discount] = 45
      #   # => Set-Cookie: discount=BAhpMg==--2c1c6906c90a3bc4fd54a51ffb41dffa4bf6b5f7; path=/
      #
      #   cookies.signed[:discount] # => 45
      def signed
        @signed ||= SignedCookieJar.new(self, @key_generator, @options)
      end

      # Only needed for supporting the +UpgradeSignatureToEncryptionCookieStore+, users and plugin authors should not use this
      def signed_using_old_secret #:nodoc:
        @signed_using_old_secret ||= SignedCookieJar.new(self, ActiveSupport::DummyKeyGenerator.new(@options[:token_key]), @options)
      end

      # Returns a jar that'll automatically encrypt cookie values before sending them to the client and will decrypt them for read.
      # If the cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception
      # will be raised.
      #
      # This jar requires that you set a suitable secret for the verification on your app's +config.secret_key_base+.
      #
      # Example:
      #
      #   cookies.encrypted[:discount] = 45
      #   # => Set-Cookie: discount=ZS9ZZ1R4cG1pcUJ1bm80anhQang3dz09LS1mbDZDSU5scGdOT3ltQ2dTdlhSdWpRPT0%3D--ab54663c9f4e3bc340c790d6d2b71e92f5b60315; path=/
      #
      #   cookies.encrypted[:discount] # => 45
      def encrypted
        @encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
      end

      def write(headers)
        @set_cookies.each { |k, v| ::Rack::Utils.set_cookie_header!(headers, k, v) if write_cookie?(v) }
        @delete_cookies.each { |k, v| ::Rack::Utils.delete_cookie_header!(headers, k, v) }
      end

      def recycle! #:nodoc:
        @set_cookies.clear
        @delete_cookies.clear
      end

      mattr_accessor :always_write_cookie
      self.always_write_cookie = false

      private

        def write_cookie?(cookie)
          @secure || !cookie[:secure] || always_write_cookie
        end
    end

    class PermanentCookieJar #:nodoc:
      def initialize(parent_jar, key_generator, options = {})
        @parent_jar = parent_jar
        @key_generator = key_generator
        @options = options
      end

      def [](key)
        @parent_jar[name.to_s]
      end

      def []=(key, options)
        if options.is_a?(Hash)
          options.symbolize_keys!
        else
          options = { :value => options }
        end

        options[:expires] = 20.years.from_now
        @parent_jar[key] = options
      end

      def permanent
        @permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
      end

      def signed
        @signed ||= SignedCookieJar.new(self, @key_generator, @options)
      end

      def encrypted
        @encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
      end

      def method_missing(method, *arguments, &block)
        ActiveSupport::Deprecation.warn "#{method} is deprecated with no replacement. " +
          "You probably want to try this method over the parent CookieJar."
      end
    end

    class SignedCookieJar #:nodoc:
      def initialize(parent_jar, key_generator, options = {})
        @parent_jar = parent_jar
        @options = options
        secret = key_generator.generate_key(@options[:signed_cookie_salt])
        @verifier   = ActiveSupport::MessageVerifier.new(secret)
      end

      def [](name)
        if signed_message = @parent_jar[name]
          @verifier.verify(signed_message)
        end
      rescue ActiveSupport::MessageVerifier::InvalidSignature
        nil
      end

      def []=(key, options)
        if options.is_a?(Hash)
          options.symbolize_keys!
          options[:value] = @verifier.generate(options[:value])
        else
          options = { :value => @verifier.generate(options) }
        end

        raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
        @parent_jar[key] = options
      end

      def permanent
        @permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
      end

      def signed
        @signed ||= SignedCookieJar.new(self, @key_generator, @options)
      end

      def encrypted
        @encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
      end

      def method_missing(method, *arguments, &block)
        ActiveSupport::Deprecation.warn "#{method} is deprecated with no replacement. " +
          "You probably want to try this method over the parent CookieJar."
      end
    end

    class EncryptedCookieJar #:nodoc:
      def initialize(parent_jar, key_generator, options = {})
        if ActiveSupport::DummyKeyGenerator === key_generator
          raise "Encrypted Cookies must be used in conjunction with config.secret_key_base." +
                "Set config.secret_key_base in config/initializers/secret_token.rb"
        end

        @parent_jar = parent_jar
        @options = options
        secret = key_generator.generate_key(@options[:encrypted_cookie_salt])
        sign_secret = key_generator.generate_key(@options[:encrypted_signed_cookie_salt])
        @encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
      end

      def [](key)
        if encrypted_message = @parent_jar[key]
          @encryptor.decrypt_and_verify(encrypted_message)
        end
      rescue ActiveSupport::MessageVerifier::InvalidSignature,
             ActiveSupport::MessageVerifier::InvalidMessage
        nil
      end

      def []=(key, options)
        if options.is_a?(Hash)
          options.symbolize_keys!
        else
          options = { :value => options }
        end
        options[:value] = @encryptor.encrypt_and_sign(options[:value])

        raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
        @parent_jar[key] = options
      end

      def permanent
        @permanent ||= PermanentCookieJar.new(self, @key_generator, @options)
      end

      def signed
        @signed ||= SignedCookieJar.new(self, @key_generator, @options)
      end

      def encrypted
        @encrypted ||= EncryptedCookieJar.new(self, @key_generator, @options)
      end

      def method_missing(method, *arguments, &block)
        ActiveSupport::Deprecation.warn "#{method} is deprecated with no replacement. " +
          "You probably want to try this method over the parent CookieJar."
      end
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      status, headers, body = @app.call(env)

      if cookie_jar = env['action_dispatch.cookies']
        cookie_jar.write(headers)
        if headers[HTTP_HEADER].respond_to?(:join)
          headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n")
        end
      end

      [status, headers, body]
    end
  end
end
require 'action_dispatch/http/request'
require 'action_dispatch/middleware/exception_wrapper'
require 'action_dispatch/routing/inspector'

module ActionDispatch
  # This middleware is responsible for logging exceptions and
  # showing a debugging page in case the request is local.
  class DebugExceptions
    RESCUES_TEMPLATE_PATH = File.expand_path('../templates', __FILE__)

    def initialize(app, routes_app = nil)
      @app        = app
      @routes_app = routes_app
    end

    def call(env)
      _, headers, body = response = @app.call(env)

      if headers['X-Cascade'] == 'pass'
        body.close if body.respond_to?(:close)
        raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
      end

      response
    rescue Exception => exception
      raise exception if env['action_dispatch.show_exceptions'] == false
      render_exception(env, exception)
    end

    private

    def render_exception(env, exception)
      wrapper = ExceptionWrapper.new(env, exception)
      log_error(env, wrapper)

      if env['action_dispatch.show_detailed_exceptions']
        template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
          :request => Request.new(env),
          :exception => wrapper.exception,
          :application_trace => wrapper.application_trace,
          :framework_trace => wrapper.framework_trace,
          :full_trace => wrapper.full_trace,
          :routes_inspector => routes_inspector(exception),
          :source_extract => wrapper.source_extract,
          :line_number => wrapper.line_number,
          :file => wrapper.file
        )
        file = "rescues/#{wrapper.rescue_template}"
        body = template.render(:template => file, :layout => 'rescues/layout')
        render(wrapper.status_code, body)
      else
        raise exception
      end
    end

    def render(status, body)
      [status, {'Content-Type' => "text/html; charset=#{Response.default_charset}", 'Content-Length' => body.bytesize.to_s}, [body]]
    end

    def log_error(env, wrapper)
      logger = logger(env)
      return unless logger

      exception = wrapper.exception

      trace = wrapper.application_trace
      trace = wrapper.framework_trace if trace.empty?

      ActiveSupport::Deprecation.silence do
        message = "\n#{exception.class} (#{exception.message}):\n"
        message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
        message << "  " << trace.join("\n  ")
        logger.fatal("#{message}\n\n")
      end
    end

    def logger(env)
      env['action_dispatch.logger'] || stderr_logger
    end

    def stderr_logger
      @stderr_logger ||= ActiveSupport::Logger.new($stderr)
    end

    def routes_inspector(exception)
      if @routes_app.respond_to?(:routes) && (exception.is_a?(ActionController::RoutingError) || exception.is_a?(ActionView::Template::Error))
        ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes)
      end
    end
  end
end
require 'action_controller/metal/exceptions'
require 'active_support/core_ext/class/attribute_accessors'

module ActionDispatch
  class ExceptionWrapper
    cattr_accessor :rescue_responses
    @@rescue_responses = Hash.new(:internal_server_error)
    @@rescue_responses.merge!(
      'ActionController::RoutingError'             => :not_found,
      'AbstractController::ActionNotFound'         => :not_found,
      'ActionController::MethodNotAllowed'         => :method_not_allowed,
      'ActionController::NotImplemented'           => :not_implemented,
      'ActionController::UnknownFormat'            => :not_acceptable,
      'ActionController::InvalidAuthenticityToken' => :unprocessable_entity,
      'ActionController::BadRequest'               => :bad_request,
      'ActionController::ParameterMissing'         => :bad_request
    )

    cattr_accessor :rescue_templates
    @@rescue_templates = Hash.new('diagnostics')
    @@rescue_templates.merge!(
      'ActionView::MissingTemplate'         => 'missing_template',
      'ActionController::RoutingError'      => 'routing_error',
      'AbstractController::ActionNotFound'  => 'unknown_action',
      'ActionView::Template::Error'         => 'template_error'
    )

    attr_reader :env, :exception, :line_number, :file

    def initialize(env, exception)
      @env = env
      @exception = original_exception(exception)
    end

    def rescue_template
      @@rescue_templates[@exception.class.name]
    end

    def status_code
      self.class.status_code_for_exception(@exception.class.name)
    end

    def application_trace
      clean_backtrace(:silent)
    end

    def framework_trace
      clean_backtrace(:noise)
    end

    def full_trace
      clean_backtrace(:all)
    end

    def self.status_code_for_exception(class_name)
      Rack::Utils.status_code(@@rescue_responses[class_name])
    end

    def source_extract
      if application_trace && trace = application_trace.first
        file, line, _ = trace.split(":")
        @file = file
        @line_number = line.to_i
        source_fragment(@file, @line_number)
      end
    end

    private

    def original_exception(exception)
      if registered_original_exception?(exception)
        exception.original_exception
      else
        exception
      end
    end

    def registered_original_exception?(exception)
      exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name)
    end

    def clean_backtrace(*args)
      if backtrace_cleaner
        backtrace_cleaner.clean(@exception.backtrace, *args)
      else
        @exception.backtrace
      end
    end

    def backtrace_cleaner
      @backtrace_cleaner ||= @env['action_dispatch.backtrace_cleaner']
    end

    def source_fragment(path, line)
      return unless Rails.respond_to?(:root) && Rails.root
      full_path = Rails.root.join(path)
      if File.exists?(full_path)
        File.open(full_path, "r") do |file|
          start = [line - 3, 0].max
          lines = file.each_line.drop(start).take(6)
          Hash[*(start+1..(lines.count+start)).zip(lines).flatten]
        end
      end
    end
  end
end
module ActionDispatch
  class Request < Rack::Request
    # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
    # read a notice you put there or <tt>flash["notice"] = "hello"</tt>
    # to put a new one.
    def flash
      @env[Flash::KEY] ||= Flash::FlashHash.from_session_value(session["flash"])
    end
  end

  # The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
  # to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
  # action that sets <tt>flash[:notice] = "Post successfully created"</tt> before redirecting to a display action that can
  # then expose the flash to its template. Actually, that exposure is automatically done.
  #
  #   class PostsController < ActionController::Base
  #     def create
  #       # save post
  #       flash[:notice] = "Post successfully created"
  #       redirect_to @post
  #     end
  #
  #     def show
  #       # doesn't need to assign the flash notice to the template, that's done automatically
  #     end
  #   end
  #
  #   show.html.erb
  #     <% if flash[:notice] %>
  #       <div class="notice"><%= flash[:notice] %></div>
  #     <% end %>
  #
  # Since the +notice+ and +alert+ keys are a common idiom, convenience accessors are available:
  #
  #   flash.alert = "You must be logged in"
  #   flash.notice = "Post successfully created"
  #
  # This example just places a string in the flash, but you can put any object in there. And of course, you can put as
  # many as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
  #
  # See docs on the FlashHash class for more details about the flash.
  class Flash
    KEY = 'action_dispatch.request.flash_hash'.freeze

    class FlashNow #:nodoc:
      attr_accessor :flash

      def initialize(flash)
        @flash = flash
      end

      def []=(k, v)
        @flash[k] = v
        @flash.discard(k)
        v
      end

      def [](k)
        @flash[k]
      end

      # Convenience accessor for <tt>flash.now[:alert]=</tt>.
      def alert=(message)
        self[:alert] = message
      end

      # Convenience accessor for <tt>flash.now[:notice]=</tt>.
      def notice=(message)
        self[:notice] = message
      end
    end

    class FlashHash
      include Enumerable

      def self.from_session_value(value)
        flash = case value
                when FlashHash # Rails 3.1, 3.2
                  new(value.instance_variable_get(:@flashes), value.instance_variable_get(:@used))
                when Hash # Rails 4.0
                  new(value['flashes'], value['discard'])
                else
                  new
                end

        flash.tap(&:sweep)
      end

      def to_session_value
        return nil if empty?
        {'discard' => @discard.to_a, 'flashes' => @flashes}
      end

      def initialize(flashes = {}, discard = []) #:nodoc:
        @discard = Set.new(discard)
        @flashes = flashes
        @now     = nil
      end

      def initialize_copy(other)
        if other.now_is_loaded?
          @now = other.now.dup
          @now.flash = self
        end
        super
      end

      def []=(k, v)
        @discard.delete k
        @flashes[k] = v
      end

      def [](k)
        @flashes[k]
      end

      def update(h) #:nodoc:
        @discard.subtract h.keys
        @flashes.update h
        self
      end

      def keys
        @flashes.keys
      end

      def key?(name)
        @flashes.key? name
      end

      def delete(key)
        @discard.delete key
        @flashes.delete key
        self
      end

      def to_hash
        @flashes.dup
      end

      def empty?
        @flashes.empty?
      end

      def clear
        @discard.clear
        @flashes.clear
      end

      def each(&block)
        @flashes.each(&block)
      end

      alias :merge! :update

      def replace(h) #:nodoc:
        @discard.clear
        @flashes.replace h
        self
      end

      # Sets a flash that will not be available to the next action, only to the current.
      #
      #     flash.now[:message] = "Hello current action"
      #
      # This method enables you to use the flash as a central messaging system in your app.
      # When you need to pass an object to the next action, you use the standard flash assign (<tt>[]=</tt>).
      # When you need to pass an object to the current action, you use <tt>now</tt>, and your object will
      # vanish when the current action is done.
      #
      # Entries set via <tt>now</tt> are accessed the same way as standard entries: <tt>flash['my-key']</tt>.
      #
      # Also, brings two convenience accessors:
      #
      #   flash.now.alert = "Beware now!"
      #   # Equivalent to flash.now[:alert] = "Beware now!"
      #
      #   flash.now.notice = "Good luck now!"
      #   # Equivalent to flash.now[:notice] = "Good luck now!"
      def now
        @now ||= FlashNow.new(self)
      end

      # Keeps either the entire current flash or a specific flash entry available for the next action:
      #
      #    flash.keep            # keeps the entire flash
      #    flash.keep(:notice)   # keeps only the "notice" entry, the rest of the flash is discarded
      def keep(k = nil)
        @discard.subtract Array(k || keys)
        k ? self[k] : self
      end

      # Marks the entire flash or a single flash entry to be discarded by the end of the current action:
      #
      #     flash.discard              # discard the entire flash at the end of the current action
      #     flash.discard(:warning)    # discard only the "warning" entry at the end of the current action
      def discard(k = nil)
        @discard.merge Array(k || keys)
        k ? self[k] : self
      end

      # Mark for removal entries that were kept, and delete unkept ones.
      #
      # This method is called automatically by filters, so you generally don't need to care about it.
      def sweep #:nodoc:
        @discard.each { |k| @flashes.delete k }
        @discard.replace @flashes.keys
      end

      # Convenience accessor for <tt>flash[:alert]</tt>.
      def alert
        self[:alert]
      end

      # Convenience accessor for <tt>flash[:alert]=</tt>.
      def alert=(message)
        self[:alert] = message
      end

      # Convenience accessor for <tt>flash[:notice]</tt>.
      def notice
        self[:notice]
      end

      # Convenience accessor for <tt>flash[:notice]=</tt>.
      def notice=(message)
        self[:notice] = message
      end

      protected
      def now_is_loaded?
        @now
      end
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      @app.call(env)
    ensure
      session    = Request::Session.find(env) || {}
      flash_hash = env[KEY]

      if flash_hash
        if !flash_hash.empty? || session.key?('flash')
          session["flash"] = flash_hash.to_session_value
          new_hash = flash_hash.dup
        else
          new_hash = flash_hash
        end

        env[KEY] = new_hash
      end

      if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?)
         session.key?('flash') && session['flash'].nil?
        session.delete('flash')
      end
    end
  end
end
require 'active_support/core_ext/hash/conversions'
require 'action_dispatch/http/request'
require 'active_support/core_ext/hash/indifferent_access'

module ActionDispatch
  class ParamsParser
    class ParseError < StandardError
      attr_reader :original_exception

      def initialize(message, original_exception)
        super(message)
        @original_exception = original_exception
      end
    end

    DEFAULT_PARSERS = {
      Mime::XML => :xml_simple,
      Mime::JSON => :json
    }

    def initialize(app, parsers = {})
      @app, @parsers = app, DEFAULT_PARSERS.merge(parsers)
    end

    def call(env)
      if params = parse_formatted_parameters(env)
        env["action_dispatch.request.request_parameters"] = params
      end

      @app.call(env)
    end

    private
      def parse_formatted_parameters(env)
        request = Request.new(env)

        return false if request.content_length.zero?

        mime_type = content_type_from_legacy_post_data_format_header(env) ||
          request.content_mime_type

        strategy = @parsers[mime_type]

        return false unless strategy

        case strategy
        when Proc
          strategy.call(request.raw_post)
        when :xml_simple, :xml_node
          data = request.deep_munge(Hash.from_xml(request.body.read) || {})
          data.with_indifferent_access
        when :json
          data = ActiveSupport::JSON.decode(request.body)
          data = {:_json => data} unless data.is_a?(Hash)
          request.deep_munge(data).with_indifferent_access
        else
          false
        end
      rescue Exception => e # YAML, XML or Ruby code block errors
        logger(env).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}"

        raise ParseError.new(e.message, e)
      end

      def content_type_from_legacy_post_data_format_header(env)
        if x_post_format = env['HTTP_X_POST_DATA_FORMAT']
          case x_post_format.to_s.downcase
          when 'yaml' then return Mime::YAML
          when 'xml'  then return Mime::XML
          end
        end

        nil
      end

      def logger(env)
        env['action_dispatch.logger'] || ActiveSupport::Logger.new($stderr)
      end
  end
end
module ActionDispatch
  class PublicExceptions
    attr_accessor :public_path

    def initialize(public_path)
      @public_path = public_path
    end

    def call(env)
      exception    = env["action_dispatch.exception"]
      status       = env["PATH_INFO"][1..-1]
      request      = ActionDispatch::Request.new(env)
      content_type = request.formats.first
      body         = { :status => status, :error => exception.message }

      render(status, content_type, body)
    end

    private

    def render(status, content_type, body)
      format = content_type && "to_#{content_type.to_sym}"
      if format && body.respond_to?(format)
        render_format(status, content_type, body.public_send(format))
      else
        render_html(status)
      end
    end

    def render_format(status, content_type, body)
      [status, {'Content-Type' => "#{content_type}; charset=#{ActionDispatch::Response.default_charset}",
                'Content-Length' => body.bytesize.to_s}, [body]]
    end

    def render_html(status)
      found = false
      path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
      path = "#{public_path}/#{status}.html" unless path && (found = File.exist?(path))

      if found || File.exist?(path)
        render_format(status, 'text/html', File.read(path))
      else
        [404, { "X-Cascade" => "pass" }, []]
      end
    end
  end
end
module ActionDispatch
  # ActionDispatch::Reloader provides prepare and cleanup callbacks,
  # intended to assist with code reloading during development.
  #
  # Prepare callbacks are run before each request, and cleanup callbacks
  # after each request. In this respect they are analogs of ActionDispatch::Callback's
  # before and after callbacks. However, cleanup callbacks are not called until the
  # request is fully complete -- that is, after #close has been called on
  # the response body. This is important for streaming responses such as the
  # following:
  #
  #     self.response_body = lambda { |response, output|
  #       # code here which refers to application models
  #     }
  #
  # Cleanup callbacks will not be called until after the response_body lambda
  # is evaluated, ensuring that it can refer to application models and other
  # classes before they are unloaded.
  #
  # By default, ActionDispatch::Reloader is included in the middleware stack
  # only in the development environment; specifically, when +config.cache_classes+
  # is false. Callbacks may be registered even when it is not included in the
  # middleware stack, but are executed only when <tt>ActionDispatch::Reloader.prepare!</tt>
  # or <tt>ActionDispatch::Reloader.cleanup!</tt> are called manually.
  #
  class Reloader
    include ActiveSupport::Callbacks

    define_callbacks :prepare, :scope => :name
    define_callbacks :cleanup, :scope => :name

    # Add a prepare callback. Prepare callbacks are run before each request, prior
    # to ActionDispatch::Callback's before callbacks.
    def self.to_prepare(*args, &block)
      set_callback(:prepare, *args, &block)
    end

    # Add a cleanup callback. Cleanup callbacks are run after each request is
    # complete (after #close is called on the response body).
    def self.to_cleanup(*args, &block)
      set_callback(:cleanup, *args, &block)
    end

    # Execute all prepare callbacks.
    def self.prepare!
      new(nil).prepare!
    end

    # Execute all cleanup callbacks.
    def self.cleanup!
      new(nil).cleanup!
    end

    def initialize(app, condition=nil)
      @app = app
      @condition = condition || lambda { true }
      @validated = true
    end

    def call(env)
      @validated = @condition.call
      prepare!

      response = @app.call(env)
      response[2] = ::Rack::BodyProxy.new(response[2]) { cleanup! }

      response
    rescue Exception
      cleanup!
      raise
    end

    def prepare! #:nodoc:
      run_callbacks :prepare if validated?
    end

    def cleanup! #:nodoc:
      run_callbacks :cleanup if validated?
    ensure
      @validated = true
    end

    private

    def validated? #:nodoc:
      @validated
    end
  end
end
module ActionDispatch
  # This middleware calculates the IP address of the remote client that is
  # making the request. It does this by checking various headers that could
  # contain the address, and then picking the last-set address that is not
  # on the list of trusted IPs. This follows the precedent set by e.g.
  # {the Tomcat server}[https://issues.apache.org/bugzilla/show_bug.cgi?id=50453],
  # with {reasoning explained at length}[http://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection]
  # by @gingerlime. A more detailed explanation of the algorithm is given
  # at GetIp#calculate_ip.
  #
  # Some Rack servers concatenate repeated headers, like {HTTP RFC 2616}[http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2]
  # requires. Some Rack servers simply drop preceeding headers, and only report
  # the value that was {given in the last header}[http://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-servers].
  # If you are behind multiple proxy servers (like Nginx to HAProxy to Unicorn)
  # then you should test your Rack server to make sure your data is good.
  #
  # IF YOU DON'T USE A PROXY, THIS MAKES YOU VULNERABLE TO IP SPOOFING.
  # This middleware assumes that there is at least one proxy sitting around
  # and setting headers with the client's remote IP address. If you don't use
  # a proxy, because you are hosted on e.g. Heroku without SSL, any client can
  # claim to have any IP address by setting the X-Forwarded-For header. If you
  # care about that, then you need to explicitly drop or ignore those headers
  # sometime before this middleware runs.
  class RemoteIp
    class IpSpoofAttackError < StandardError; end

    # The default trusted IPs list simply includes IP addresses that are
    # guaranteed by the IP specification to be private addresses. Those will
    # not be the ultimate client IP in production, and so are discarded. See
    # http://en.wikipedia.org/wiki/Private_network for details.
    TRUSTED_PROXIES = %r{
      ^127\.0\.0\.1$                | # localhost IPv4
      ^::1$                         | # localhost IPv6
      ^fc00:                        | # private IPv6 range fc00
      ^10\.                         | # private IPv4 range 10.x.x.x
      ^172\.(1[6-9]|2[0-9]|3[0-1])\.| # private IPv4 range 172.16.0.0 .. 172.31.255.255
      ^192\.168\.                     # private IPv4 range 192.168.x.x
    }x

    attr_reader :check_ip, :proxies

    # Create a new +RemoteIp+ middleware instance.
    #
    # The +check_ip_spoofing+ option is on by default. When on, an exception
    # is raised if it looks like the client is trying to lie about its own IP
    # address. It makes sense to turn off this check on sites aimed at non-IP
    # clients (like WAP devices), or behind proxies that set headers in an
    # incorrect or confusing way (like AWS ELB).
    #
    # The +custom_trusted+ argument can take a regex, which will be used
    # instead of +TRUSTED_PROXIES+, or a string, which will be used in addition
    # to +TRUSTED_PROXIES+. Any proxy setup will put the value you want in the
    # middle (or at the beginning) of the X-Forwarded-For list, with your proxy
    # servers after it. If your proxies aren't removed, pass them in via the
    # +custom_trusted+ parameter. That way, the middleware will ignore those
    # IP addresses, and return the one that you want.
    def initialize(app, check_ip_spoofing = true, custom_proxies = nil)
      @app = app
      @check_ip = check_ip_spoofing
      @proxies = case custom_proxies
        when Regexp
          custom_proxies
        when nil
          TRUSTED_PROXIES
        else
          Regexp.union(TRUSTED_PROXIES, custom_proxies)
        end
    end

    # Since the IP address may not be needed, we store the object here
    # without calculating the IP to keep from slowing down the majority of
    # requests. For those requests that do need to know the IP, the
    # GetIp#calculate_ip method will calculate the memoized client IP address.
    def call(env)
      env["action_dispatch.remote_ip"] = GetIp.new(env, self)
      @app.call(env)
    end

    # The GetIp class exists as a way to defer processing of the request data
    # into an actual IP address. If the ActionDispatch::Request#remote_ip method
    # is called, this class will calculate the value and then memoize it.
    class GetIp

      # This constant contains a regular expression that validates every known
      # form of IP v4 and v6 address, with or without abbreviations, adapted
      # from {this gist}[https://gist.github.com/1289635].
      VALID_IP = %r{
        (^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$)                                                        | # ip v4
        (^(
        (([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})                                                                                                                   | # ip v6 not abbreviated
        (([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})                                                                                                                  | # ip v6 with double colon in the end
        (([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})                                                                                              | # - ip addresses v6
        (([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})                                                                                          | # - with
        (([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})                                                                                          | # - double colon
        (([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})                                                                                          | # - in the middle
        (([0-9A-Fa-f]{1,4}:){6} ((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3} (\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))                            | # ip v6 with compatible to v4
        (([0-9A-Fa-f]{1,4}:){1,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))                           | # ip v6 with compatible to v4
        (([0-9A-Fa-f]{1,4}:){1}:([0-9A-Fa-f]{1,4}:){0,4}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))     | # ip v6 with compatible to v4
        (([0-9A-Fa-f]{1,4}:){0,2}:([0-9A-Fa-f]{1,4}:){0,3}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))   | # ip v6 with compatible to v4
        (([0-9A-Fa-f]{1,4}:){0,3}:([0-9A-Fa-f]{1,4}:){0,2}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))   | # ip v6 with compatible to v4
        (([0-9A-Fa-f]{1,4}:){0,4}:([0-9A-Fa-f]{1,4}:){1}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))     | # ip v6 with compatible to v4
        (::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d) |(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))                         | # ip v6 with compatible to v4
        ([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})                                                                                               | # ip v6 with compatible to v4
        (::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})                                                                                                               | # ip v6 with double colon at the begining
        (([0-9A-Fa-f]{1,4}:){1,7}:)                                                                                                                                  # ip v6 without ending
        )$)
      }x

      def initialize(env, middleware)
        @env      = env
        @check_ip = middleware.check_ip
        @proxies  = middleware.proxies
      end

      # Sort through the various IP address headers, looking for the IP most
      # likely to be the address of the actual remote client making this
      # request.
      #
      # REMOTE_ADDR will be correct if the request is made directly against the
      # Ruby process, on e.g. Heroku. When the request is proxied by another
      # server like HAProxy or Nginx, the IP address that made the original
      # request will be put in an X-Forwarded-For header. If there are multiple
      # proxies, that header may contain a list of IPs. Other proxy services
      # set the Client-Ip header instead, so we check that too.
      #
      # As discussed in {this post about Rails IP Spoofing}[http://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection/],
      # while the first IP in the list is likely to be the "originating" IP,
      # it could also have been set by the client maliciously.
      #
      # In order to find the first address that is (probably) accurate, we
      # take the list of IPs, remove known and trusted proxies, and then take
      # the last address left, which was presumably set by one of those proxies.
      def calculate_ip
        # Set by the Rack web server, this is a single value.
        remote_addr = ips_from('REMOTE_ADDR').last

        # Could be a CSV list and/or repeated headers that were concatenated.
        client_ips    = ips_from('HTTP_CLIENT_IP').reverse
        forwarded_ips = ips_from('HTTP_X_FORWARDED_FOR').reverse

        # +Client-Ip+ and +X-Forwarded-For+ should not, generally, both be set.
        # If they are both set, it means that this request passed through two
        # proxies with incompatible IP header conventions, and there is no way
        # for us to determine which header is the right one after the fact.
        # Since we have no idea, we give up and explode.
        should_check_ip = @check_ip && client_ips.last
        if should_check_ip && !forwarded_ips.include?(client_ips.last)
          # We don't know which came from the proxy, and which from the user
          raise IpSpoofAttackError, "IP spoofing attack?! " +
            "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect} " +
            "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}"
        end

        # We assume these things about the IP headers:
        #
        #   - X-Forwarded-For will be a list of IPs, one per proxy, or blank
        #   - Client-Ip is propagated from the outermost proxy, or is blank
        #   - REMOTE_ADDR will be the IP that made the request to Rack
        ips = [forwarded_ips, client_ips, remote_addr].flatten.compact

        # If every single IP option is in the trusted list, just return REMOTE_ADDR
        filter_proxies(ips).first || remote_addr
      end

      # Memoizes the value returned by #calculate_ip and returns it for
      # ActionDispatch::Request to use.
      def to_s
        @ip ||= calculate_ip
      end

    protected

      def ips_from(header)
        # Split the comma-separated list into an array of strings
        ips = @env[header] ? @env[header].strip.split(/[,\s]+/) : []
        # Only return IPs that are valid according to the regex
        ips.select{ |ip| ip =~ VALID_IP }
      end

      def filter_proxies(ips)
        ips.reject { |ip| ip =~ @proxies }
      end

    end

  end
end
require 'securerandom'
require 'active_support/core_ext/string/access'

module ActionDispatch
  # Makes a unique request id available to the action_dispatch.request_id env variable (which is then accessible through
  # ActionDispatch::Request#uuid) and sends the same id to the client via the X-Request-Id header.
  #
  # The unique request id is either based off the X-Request-Id header in the request, which would typically be generated
  # by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the
  # header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.
  #
  # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files
  # from multiple pieces of the stack.
  class RequestId
    def initialize(app)
      @app = app
    end

    def call(env)
      env["action_dispatch.request_id"] = external_request_id(env) || internal_request_id
      @app.call(env).tap { |status, headers, body| headers["X-Request-Id"] = env["action_dispatch.request_id"] }
    end

    private
      def external_request_id(env)
        if request_id = env["HTTP_X_REQUEST_ID"].presence
          request_id.gsub(/[^\w\-]/, "").first(255)
        end
      end

      def internal_request_id
        SecureRandom.uuid
      end
  end
end
require 'rack/utils'
require 'rack/request'
require 'rack/session/abstract/id'
require 'action_dispatch/middleware/cookies'
require 'action_dispatch/request/session'

module ActionDispatch
  module Session
    class SessionRestoreError < StandardError #:nodoc:
      attr_reader :original_exception

      def initialize(const_error)
        @original_exception = const_error

        super("Session contains objects whose class definition isn't available.\n" +
          "Remember to require the classes for all objects kept in the session.\n" +
          "(Original exception: #{const_error.message} [#{const_error.class}])\n")
      end
    end

    module Compatibility
      def initialize(app, options = {})
        options[:key] ||= '_session_id'
        super
      end

      def generate_sid
        sid = SecureRandom.hex(16)
        sid.encode!(Encoding::UTF_8)
        sid
      end

    protected

      def initialize_sid
        @default_options.delete(:sidbits)
        @default_options.delete(:secure_random)
      end
    end

    module StaleSessionCheck
      def load_session(env)
        stale_session_check! { super }
      end

      def extract_session_id(env)
        stale_session_check! { super }
      end

      def stale_session_check!
        yield
      rescue ArgumentError => argument_error
        if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
          begin
            # Note that the regexp does not allow $1 to end with a ':'
            $1.constantize
          rescue LoadError, NameError => e
            raise ActionDispatch::Session::SessionRestoreError, e, e.backtrace
          end
          retry
        else
          raise
        end
      end
    end

    module SessionObject # :nodoc:
      def prepare_session(env)
        Request::Session.create(self, env, @default_options)
      end

      def loaded_session?(session)
        !session.is_a?(Request::Session) || session.loaded?
      end
    end

    class AbstractStore < Rack::Session::Abstract::ID
      include Compatibility
      include StaleSessionCheck
      include SessionObject

      private

      def set_cookie(env, session_id, cookie)
        request = ActionDispatch::Request.new(env)
        request.cookie_jar[key] = cookie
      end
    end
  end
end
require 'action_dispatch/middleware/session/abstract_store'

module ActionDispatch
  module Session
    # Session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful
    # if you don't store critical data in your sessions and you don't need them to live for extended periods
    # of time.
    class CacheStore < AbstractStore
      # Create a new store. The cache to use can be passed in the <tt>:cache</tt> option. If it is
      # not specified, <tt>Rails.cache</tt> will be used.
      def initialize(app, options = {})
        @cache = options[:cache] || Rails.cache
        options[:expire_after] ||= @cache.options[:expires_in]
        super
      end

      # Get a session from the cache.
      def get_session(env, sid)
        sid ||= generate_sid
        session = @cache.read(cache_key(sid))
        session ||= {}
        [sid, session]
      end

      # Set a session in the cache.
      def set_session(env, sid, session, options)
        key = cache_key(sid)
        if session
          @cache.write(key, session, :expires_in => options[:expire_after])
        else
          @cache.delete(key)
        end
        sid
      end

      # Remove a session from the cache.
      def destroy_session(env, sid, options)
        @cache.delete(cache_key(sid))
        generate_sid
      end

      private
        # Turn the session id into a cache key.
        def cache_key(sid)
          "_session_id:#{sid}"
        end
    end
  end
end
require 'active_support/core_ext/hash/keys'
require 'action_dispatch/middleware/session/abstract_store'
require 'rack/session/cookie'

module ActionDispatch
  module Session
    # This cookie-based session store is the Rails default. Sessions typically
    # contain at most a user_id and flash message; both fit within the 4K cookie
    # size limit. Cookie-based sessions are dramatically faster than the
    # alternatives.
    #
    # If you have more than 4K of session data or don't want your data to be
    # visible to the user, pick another session store.
    #
    # CookieOverflow is raised if you attempt to store more than 4K of data.
    #
    # A message digest is included with the cookie to ensure data integrity:
    # a user cannot alter his +user_id+ without knowing the secret key
    # included in the hash. New apps are generated with a pregenerated secret
    # in config/environment.rb. Set your own for old apps you're upgrading.
    #
    # Session options:
    #
    # * <tt>:secret</tt>: An application-wide key string. It's important that
    #   the secret is not vulnerable to a dictionary attack. Therefore, you
    #   should choose a secret consisting of random numbers and letters and
    #   more than 30 characters.
    #
    #     secret: '449fe2e7daee471bffae2fd8dc02313d'
    #
    # * <tt>:digest</tt>: The message digest algorithm used to verify session
    #   integrity defaults to 'SHA1' but may be any digest provided by OpenSSL,
    #   such as 'MD5', 'RIPEMD160', 'SHA256', etc.
    #
    # To generate a secret key for an existing application, run
    # "rake secret" and set the key in config/initializers/secret_token.rb.
    #
    # Note that changing digest or secret invalidates all existing sessions!
    class CookieStore < Rack::Session::Abstract::ID
      include Compatibility
      include StaleSessionCheck
      include SessionObject

      def initialize(app, options={})
        super(app, options.merge!(:cookie_only => true))
      end

      def destroy_session(env, session_id, options)
        new_sid = generate_sid unless options[:drop]
        # Reset hash and Assign the new session id
        env["action_dispatch.request.unsigned_session_cookie"] = new_sid ? { "session_id" => new_sid } : {}
        new_sid
      end

      def load_session(env)
        stale_session_check! do
          data = unpacked_cookie_data(env)
          data = persistent_session_id!(data)
          [data["session_id"], data]
        end
      end

      private

      def extract_session_id(env)
        stale_session_check! do
          unpacked_cookie_data(env)["session_id"]
        end
      end

      def unpacked_cookie_data(env)
        env["action_dispatch.request.unsigned_session_cookie"] ||= begin
          stale_session_check! do
            if data = get_cookie(env)
              data.stringify_keys!
            end
            data || {}
          end
        end
      end

      def persistent_session_id!(data, sid=nil)
        data ||= {}
        data["session_id"] ||= sid || generate_sid
        data
      end

      def set_session(env, sid, session_data, options)
        session_data["session_id"] = sid
        session_data
      end

      def set_cookie(env, session_id, cookie)
        cookie_jar(env)[@key] = cookie
      end

      def get_cookie(env)
        cookie_jar(env)[@key]
      end

      def cookie_jar(env)
        request = ActionDispatch::Request.new(env)
        request.cookie_jar.signed
      end
    end

    class EncryptedCookieStore < CookieStore

      private

      def cookie_jar(env)
        request = ActionDispatch::Request.new(env)
        request.cookie_jar.encrypted
      end
    end

    # This cookie store helps you upgrading apps that use +CookieStore+ to the new default +EncryptedCookieStore+
    # To use this CookieStore set
    #
    # Myapp::Application.config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session'
    #
    # in your config/initializers/session_store.rb
    #
    # You will also need to add
    #
    # Myapp::Application.config.secret_key_base = 'some secret'
    #
    # in your config/initializers/secret_token.rb, but do not remove +Myapp::Application.config.secret_token = 'some secret'+
    class UpgradeSignatureToEncryptionCookieStore < EncryptedCookieStore
      private

      def get_cookie(env)
        signed_using_old_secret_cookie_jar(env)[@key] || cookie_jar(env)[@key]
      end

      def signed_using_old_secret_cookie_jar(env)
        request = ActionDispatch::Request.new(env)
        request.cookie_jar.signed_using_old_secret
      end
    end
  end
end
require 'action_dispatch/middleware/session/abstract_store'
begin
  require 'rack/session/dalli'
rescue LoadError => e
  $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
  raise e
end

module ActionDispatch
  module Session
    class MemCacheStore < Rack::Session::Dalli
      include Compatibility
      include StaleSessionCheck
      include SessionObject

      def initialize(app, options = {})
        options[:expire_after] ||= options[:expires]
        super
      end
    end
  end
end
require 'action_dispatch/http/request'
require 'action_dispatch/middleware/exception_wrapper'

module ActionDispatch
  # This middleware rescues any exception returned by the application
  # and calls an exceptions app that will wrap it in a format for the end user.
  #
  # The exceptions app should be passed as parameter on initialization
  # of ShowExceptions. Every time there is an exception, ShowExceptions will
  # store the exception in env["action_dispatch.exception"], rewrite the
  # PATH_INFO to the exception status code and call the rack app.
  #
  # If the application returns a "X-Cascade" pass response, this middleware
  # will send an empty response as result with the correct status code.
  # If any exception happens inside the exceptions app, this middleware
  # catches the exceptions and returns a FAILSAFE_RESPONSE.
  class ShowExceptions
    FAILSAFE_RESPONSE = [500, { 'Content-Type' => 'text/plain' },
      ["500 Internal Server Error\n" \
       "If you are the administrator of this website, then please read this web " \
       "application's log file and/or the web server's log file to find out what " \
       "went wrong."]]

    def initialize(app, exceptions_app)
      @app = app
      @exceptions_app = exceptions_app
    end

    def call(env)
      @app.call(env)
    rescue Exception => exception
      raise exception if env['action_dispatch.show_exceptions'] == false
      render_exception(env, exception)
    end

    private

    def render_exception(env, exception)
      wrapper = ExceptionWrapper.new(env, exception)
      status  = wrapper.status_code
      env["action_dispatch.exception"] = wrapper.exception
      env["PATH_INFO"] = "/#{status}"
      response = @exceptions_app.call(env)
      response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response
    rescue Exception => failsafe_error
      $stderr.puts "Error during failsafe response: #{failsafe_error}\n  #{failsafe_error.backtrace * "\n  "}"
      FAILSAFE_RESPONSE
    end

    def pass_response(status)
      [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []]
    end
  end
end
module ActionDispatch
  class SSL
    YEAR = 31536000

    def self.default_hsts_options
      { :expires => YEAR, :subdomains => false }
    end

    def initialize(app, options = {})
      @app = app

      @hsts = options.fetch(:hsts, {})
      @hsts = {} if @hsts == true
      @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts

      @host    = options[:host]
      @port    = options[:port]
    end

    def call(env)
      request = Request.new(env)

      if request.ssl?
        status, headers, body = @app.call(env)
        headers = hsts_headers.merge(headers)
        flag_cookies_as_secure!(headers)
        [status, headers, body]
      else
        redirect_to_https(request)
      end
    end

    private
      def redirect_to_https(request)
        url        = URI(request.url)
        url.scheme = "https"
        url.host   = @host if @host
        url.port   = @port if @port
        headers    = hsts_headers.merge('Content-Type' => 'text/html',
                                        'Location'     => url.to_s)

        [301, headers, []]
      end

      # http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
      def hsts_headers
        if @hsts
          value = "max-age=#{@hsts[:expires].to_i}"
          value += "; includeSubDomains" if @hsts[:subdomains]
          { 'Strict-Transport-Security' => value }
        else
          {}
        end
      end

      def flag_cookies_as_secure!(headers)
        if cookies = headers['Set-Cookie']
          cookies = cookies.split("\n")

          headers['Set-Cookie'] = cookies.map { |cookie|
            if cookie !~ /;\s+secure(;|$)/
              "#{cookie}; secure"
            else
              cookie
            end
          }.join("\n")
        end
      end
  end
end
require "active_support/inflector/methods"
require "active_support/dependencies"

module ActionDispatch
  class MiddlewareStack
    class Middleware
      attr_reader :args, :block, :name, :classcache

      def initialize(klass_or_name, *args, &block)
        @klass = nil

        if klass_or_name.respond_to?(:name)
          @klass = klass_or_name
          @name  = @klass.name
        else
          @name  = klass_or_name.to_s
        end

        @classcache = ActiveSupport::Dependencies::Reference
        @args, @block = args, block
      end

      def klass
        @klass || classcache[@name]
      end

      def ==(middleware)
        case middleware
        when Middleware
          klass == middleware.klass
        when Class
          klass == middleware
        else
          normalize(@name) == normalize(middleware)
        end
      end

      def inspect
        klass.to_s
      end

      def build(app)
        klass.new(app, *args, &block)
      end

    private

      def normalize(object)
        object.to_s.strip.sub(/^::/, '')
      end
    end

    include Enumerable

    attr_accessor :middlewares

    def initialize(*args)
      @middlewares = []
      yield(self) if block_given?
    end

    def each
      @middlewares.each { |x| yield x }
    end

    def size
      middlewares.size
    end

    def last
      middlewares.last
    end

    def [](i)
      middlewares[i]
    end

    def unshift(*args, &block)
      middleware = self.class::Middleware.new(*args, &block)
      middlewares.unshift(middleware)
    end

    def initialize_copy(other)
      self.middlewares = other.middlewares.dup
    end

    def insert(index, *args, &block)
      index = assert_index(index, :before)
      middleware = self.class::Middleware.new(*args, &block)
      middlewares.insert(index, middleware)
    end

    alias_method :insert_before, :insert

    def insert_after(index, *args, &block)
      index = assert_index(index, :after)
      insert(index + 1, *args, &block)
    end

    def swap(target, *args, &block)
      index = assert_index(target, :before)
      insert(index, *args, &block)
      middlewares.delete_at(index + 1)
    end

    def delete(target)
      middlewares.delete target
    end

    def use(*args, &block)
      middleware = self.class::Middleware.new(*args, &block)
      middlewares.push(middleware)
    end

    def build(app = nil, &block)
      app ||= block
      raise "MiddlewareStack#build requires an app" unless app
      middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
    end

  protected

    def assert_index(index, where)
      i = index.is_a?(Integer) ? index : middlewares.index(index)
      raise "No such middleware to insert #{where}: #{index.inspect}" unless i
      i
    end
  end
end
require 'rack/utils'
require 'active_support/core_ext/uri'

module ActionDispatch
  class FileHandler
    def initialize(root, cache_control)
      @root          = root.chomp('/')
      @compiled_root = /^#{Regexp.escape(root)}/
      headers = cache_control && { 'Cache-Control' => cache_control }
      @file_server   = ::Rack::File.new(@root, headers)
    end

    def match?(path)
      path = path.dup

      full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(unescape_path(path)))
      paths = "#{full_path}#{ext}"

      matches = Dir[paths]
      match = matches.detect { |m| File.file?(m) }
      if match
        match.sub!(@compiled_root, '')
        ::Rack::Utils.escape(match)
      end
    end

    def call(env)
      @file_server.call(env)
    end

    def ext
      @ext ||= begin
        ext = ::ActionController::Base.default_static_extension
        "{,#{ext},/index#{ext}}"
      end
    end

    def unescape_path(path)
      URI.parser.unescape(path)
    end

    def escape_glob_chars(path)
      path.force_encoding('binary') if path.respond_to? :force_encoding
      path.gsub(/[*?{}\[\]]/, "\\\\\\&")
    end
  end

  class Static
    def initialize(app, path, cache_control=nil)
      @app = app
      @file_handler = FileHandler.new(path, cache_control)
    end

    def call(env)
      case env['REQUEST_METHOD']
      when 'GET', 'HEAD'
        path = env['PATH_INFO'].chomp('/')
        if match = @file_handler.match?(path)
          env["PATH_INFO"] = match
          return @file_handler.call(env)
        end
      end

      @app.call(env)
    end
  end
end
require "action_dispatch"

module ActionDispatch
  class Railtie < Rails::Railtie # :nodoc:
    config.action_dispatch = ActiveSupport::OrderedOptions.new
    config.action_dispatch.x_sendfile_header = nil
    config.action_dispatch.ip_spoofing_check = true
    config.action_dispatch.show_exceptions = true
    config.action_dispatch.tld_length = 1
    config.action_dispatch.ignore_accept_header = false
    config.action_dispatch.rescue_templates = { }
    config.action_dispatch.rescue_responses = { }
    config.action_dispatch.default_charset = nil
    config.action_dispatch.rack_cache = false
    config.action_dispatch.http_auth_salt = 'http authentication'
    config.action_dispatch.signed_cookie_salt = 'signed cookie'
    config.action_dispatch.encrypted_cookie_salt = 'encrypted cookie'
    config.action_dispatch.encrypted_signed_cookie_salt = 'signed encrypted cookie'

    config.action_dispatch.default_headers = {
      'X-Frame-Options' => 'SAMEORIGIN',
      'X-XSS-Protection' => '1; mode=block',
      'X-Content-Type-Options' => 'nosniff',
      'X-UA-Compatible' => 'chrome=1'
    }

    config.eager_load_namespaces << ActionDispatch

    initializer "action_dispatch.configure" do |app|
      ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
      ActionDispatch::Request.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
      ActionDispatch::Response.default_charset = app.config.action_dispatch.default_charset || app.config.encoding
      ActionDispatch::Response.default_headers = app.config.action_dispatch.default_headers

      ActionDispatch::ExceptionWrapper.rescue_responses.merge!(config.action_dispatch.rescue_responses)
      ActionDispatch::ExceptionWrapper.rescue_templates.merge!(config.action_dispatch.rescue_templates)

      config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
      ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie

      ActionDispatch.test_app = app
    end
  end
end
require 'rack/session/abstract/id'

module ActionDispatch
  class Request < Rack::Request
    # Session is responsible for lazily loading the session from store.
    class Session # :nodoc:
      ENV_SESSION_KEY         = Rack::Session::Abstract::ENV_SESSION_KEY # :nodoc:
      ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY # :nodoc:

      def self.create(store, env, default_options)
        session_was = find env
        session     = Request::Session.new(store, env)
        session.merge! session_was if session_was

        set(env, session)
        Options.set(env, Request::Session::Options.new(store, env, default_options))
        session
      end

      def self.find(env)
        env[ENV_SESSION_KEY]
      end

      def self.set(env, session)
        env[ENV_SESSION_KEY] = session
      end

      class Options #:nodoc:
        def self.set(env, options)
          env[ENV_SESSION_OPTIONS_KEY] = options
        end

        def self.find(env)
          env[ENV_SESSION_OPTIONS_KEY]
        end

        def initialize(by, env, default_options)
          @by       = by
          @env      = env
          @delegate = default_options.dup
        end

        def [](key)
          if key == :id
            @delegate.fetch(key) {
              @delegate[:id] = @by.send(:extract_session_id, @env)
            }
          else
            @delegate[key]
          end
        end

        def []=(k,v);         @delegate[k] = v; end
        def to_hash;          @delegate.dup; end
        def values_at(*args); @delegate.values_at(*args); end
      end

      def initialize(by, env)
        @by       = by
        @env      = env
        @delegate = {}
        @loaded   = false
        @exists   = nil # we haven't checked yet
      end

      def id
        options[:id]
      end

      def options
        Options.find @env
      end

      def destroy
        clear
        options = self.options || {}
        new_sid = @by.send(:destroy_session, @env, options[:id], options)
        options[:id] = new_sid # Reset session id with a new value or nil

        # Load the new sid to be written with the response
        @loaded = false
        load_for_write!
      end

      def [](key)
        load_for_read!
        @delegate[key.to_s]
      end

      def has_key?(key)
        load_for_read!
        @delegate.key?(key.to_s)
      end
      alias :key? :has_key?
      alias :include? :has_key?

      def keys
        @delegate.keys
      end

      def values
        @delegate.values
      end

      def []=(key, value)
        load_for_write!
        @delegate[key.to_s] = value
      end

      def clear
        load_for_write!
        @delegate.clear
      end

      def to_hash
        load_for_read!
        @delegate.dup.delete_if { |_,v| v.nil? }
      end

      def update(hash)
        load_for_write!
        @delegate.update stringify_keys(hash)
      end

      def delete(key)
        load_for_write!
        @delegate.delete key.to_s
      end

      def inspect
        if loaded?
          super
        else
          "#<#{self.class}:0x#{(object_id << 1).to_s(16)} not yet loaded>"
        end
      end

      def exists?
        return @exists unless @exists.nil?
        @exists = @by.send(:session_exists?, @env)
      end

      def loaded?
        @loaded
      end

      def empty?
        load_for_read!
        @delegate.empty?
      end

      def merge!(other)
        load_for_write!
        @delegate.merge!(other)
      end

      private

      def load_for_read!
        load! if !loaded? && exists?
      end

      def load_for_write!
        load! unless loaded?
      end

      def load!
        id, session = @by.load_session @env
        options[:id] = id
        @delegate.replace(stringify_keys(session))
        @loaded = true
      end

      def stringify_keys(other)
        other.each_with_object({}) { |(key, value), hash|
          hash[key.to_s] = value
        }
      end
    end
  end
end
require 'delegate'

module ActionDispatch
  module Routing
    class RouteWrapper < SimpleDelegator
      def endpoint
        rack_app ? rack_app.inspect : "#{controller}##{action}"
      end

      def constraints
        requirements.except(:controller, :action)
      end

      def rack_app(app = self.app)
        @rack_app ||= begin
          class_name = app.class.name.to_s
          if class_name == "ActionDispatch::Routing::Mapper::Constraints"
            rack_app(app.app)
          elsif ActionDispatch::Routing::Redirect === app || class_name !~ /^ActionDispatch::Routing/
            app
          end
        end
      end

      def verb
        super.source.gsub(/[$^]/, '')
      end

      def path
        super.spec.to_s
      end

      def name
        super.to_s
      end

      def regexp
        __getobj__.path.to_regexp
      end

      def json_regexp
        str = regexp.inspect.
              sub('\\A' , '^').
              sub('\\Z' , '$').
              sub('\\z' , '$').
              sub(/^\// , '').
              sub(/\/[a-z]*$/ , '').
              gsub(/\(\?#.+\)/ , '').
              gsub(/\(\?-\w+:/ , '(').
              gsub(/\s/ , '')
        Regexp.new(str).source
      end

      def reqs
        @reqs ||= begin
          reqs = endpoint
          reqs += " #{constraints.to_s}" unless constraints.empty?
          reqs
        end
      end

      def controller
        requirements[:controller] || ':controller'
      end

      def action
        requirements[:action] || ':action'
      end

      def internal?
        controller =~ %r{\Arails/(info|welcome)} || path =~ %r{\A#{Rails.application.config.assets.prefix}}
      end

      def engine?
        rack_app && rack_app.respond_to?(:routes)
      end
    end

    ##
    # This class is just used for displaying route information when someone
    # executes `rake routes` or looks at the RoutingError page.
    # People should not use this class.
    class RoutesInspector # :nodoc:
      def initialize(routes)
        @engines = {}
        @routes = routes
      end

      def format(formatter, filter = nil)
        routes_to_display = filter_routes(filter)

        routes = collect_routes(routes_to_display)
        formatter.section routes

        @engines.each do |name, engine_routes|
          formatter.section_title "Routes for #{name}"
          formatter.section engine_routes
        end

        formatter.result
      end

      private

      def filter_routes(filter)
        if filter
          @routes.select { |route| route.defaults[:controller] == filter }
        else
          @routes
        end
      end

      def collect_routes(routes)
        routes.collect do |route|
          RouteWrapper.new(route)
        end.reject do |route|
          route.internal?
        end.collect do |route|
          collect_engine_routes(route)

          { name:   route.name,
            verb:   route.verb,
            path:   route.path,
            reqs:   route.reqs,
            regexp: route.json_regexp }
        end
      end

      def collect_engine_routes(route)
        name = route.endpoint
        return unless route.engine?
        return if @engines[name]

        routes = route.rack_app.routes
        if routes.is_a?(ActionDispatch::Routing::RouteSet)
          @engines[name] = collect_routes(routes.routes)
        end
      end
    end

    class ConsoleFormatter
      def initialize
        @buffer = []
      end

      def result
        @buffer.join("\n")
      end

      def section_title(title)
        @buffer << "\n#{title}:"
      end

      def section(routes)
        @buffer << draw_section(routes)
      end

      private
        def draw_section(routes)
          name_width = routes.map { |r| r[:name].length }.max
          verb_width = routes.map { |r| r[:verb].length }.max
          path_width = routes.map { |r| r[:path].length }.max

          routes.map do |r|
            "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
          end
        end
    end

    class HtmlTableFormatter
      def initialize(view)
        @view = view
        @buffer = []
      end

      def section_title(title)
        @buffer << %(<tr><th colspan="4">#{title}</th></tr>)
      end

      def section(routes)
        @buffer << @view.render(partial: "routes/route", collection: routes)
      end

      def result
        @view.raw @view.render(layout: "routes/table") {
          @view.raw @buffer.join("\n")
        }
      end
    end
  end
end
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/array/extract_options'
require 'active_support/inflector'
require 'action_dispatch/routing/redirection'

module ActionDispatch
  module Routing
    class Mapper
      URL_OPTIONS = [:protocol, :subdomain, :domain, :host, :port]

      class Constraints #:nodoc:
        def self.new(app, constraints, request = Rack::Request)
          if constraints.any?
            super(app, constraints, request)
          else
            app
          end
        end

        attr_reader :app, :constraints

        def initialize(app, constraints, request)
          @app, @constraints, @request = app, constraints, request
        end

        def matches?(env)
          req = @request.new(env)

          @constraints.all? do |constraint|
            (constraint.respond_to?(:matches?) && constraint.matches?(req)) ||
              (constraint.respond_to?(:call) && constraint.call(*constraint_args(constraint, req)))
          end
        ensure
          req.reset_parameters
        end

        def call(env)
          matches?(env) ? @app.call(env) : [ 404, {'X-Cascade' => 'pass'}, [] ]
        end

        private
          def constraint_args(constraint, request)
            constraint.arity == 1 ? [request] : [request.symbolized_path_parameters, request]
          end
      end

      class Mapping #:nodoc:
        IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix, :format]
        ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
        SHORTHAND_REGEX = %r{/[\w/]+$}
        WILDCARD_PATH = %r{\*([^/\)]+)\)?$}

        attr_reader :scope, :path, :options, :requirements, :conditions, :defaults

        def initialize(set, scope, path, options)
          @set, @scope, @path, @options = set, scope, path, options
          @requirements, @conditions, @defaults = {}, {}, {}

          normalize_path!
          normalize_options!
          normalize_requirements!
          normalize_conditions!
          normalize_defaults!
        end

        def to_route
          [ app, conditions, requirements, defaults, options[:as], options[:anchor] ]
        end

        private

          def normalize_path!
            raise ArgumentError, "path is required" if @path.blank?
            @path = Mapper.normalize_path(@path)

            if required_format?
              @path = "#{@path}.:format"
            elsif optional_format?
              @path = "#{@path}(.:format)"
            end
          end

          def required_format?
            options[:format] == true
          end

          def optional_format?
            options[:format] != false && !path.include?(':format') && !path.end_with?('/')
          end

          def normalize_options!
            @options.reverse_merge!(scope[:options]) if scope[:options]
            path_without_format = path.sub(/\(\.:format\)$/, '')

            # Add a constraint for wildcard route to make it non-greedy and match the
            # optional format part of the route by default
            if path_without_format.match(WILDCARD_PATH) && @options[:format] != false
              @options[$1.to_sym] ||= /.+?/
            end

            if path_without_format.match(':controller')
              raise ArgumentError, ":controller segment is not allowed within a namespace block" if scope[:module]

              # Add a default constraint for :controller path segments that matches namespaced
              # controllers with default routes like :controller/:action/:id(.:format), e.g:
              # GET /admin/products/show/1
              # => { controller: 'admin/products', action: 'show', id: '1' }
              @options[:controller] ||= /.+?/
            end

            if using_match_shorthand?(path_without_format, @options)
              to_shorthand    = @options[:to].blank?
              @options[:to] ||= path_without_format.gsub(/\(.*\)/, "")[1..-1].sub(%r{/([^/]*)$}, '#\1')
            end

            @options.merge!(default_controller_and_action(to_shorthand))
          end

          # match "account/overview"
          def using_match_shorthand?(path, options)
            path && (options[:to] || options[:action]).nil? && path =~ SHORTHAND_REGEX
          end

          def normalize_format!
            if options[:format] == true
              options[:format] = /.+/
            elsif options[:format] == false
              options.delete(:format)
            end
          end

          def normalize_requirements!
            constraints.each do |key, requirement|
              next unless segment_keys.include?(key) || key == :controller

              if requirement.source =~ ANCHOR_CHARACTERS_REGEX
                raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
              end

              if requirement.multiline?
                raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
              end

              @requirements[key] = requirement
            end

            if options[:format] == true
              @requirements[:format] = /.+/
            elsif Regexp === options[:format]
              @requirements[:format] = options[:format]
            elsif String === options[:format]
              @requirements[:format] = Regexp.compile(options[:format])
            end
          end

          def normalize_defaults!
            @defaults.merge!(scope[:defaults]) if scope[:defaults]
            @defaults.merge!(options[:defaults]) if options[:defaults]

            options.each do |key, default|
              next if Regexp === default || IGNORE_OPTIONS.include?(key)
              @defaults[key] = default
            end

            if options[:constraints].is_a?(Hash)
              options[:constraints].each do |key, default|
                next unless URL_OPTIONS.include?(key) && (String === default || Fixnum === default)
                @defaults[key] ||= default
              end
            end

            if Regexp === options[:format]
              @defaults[:format] = nil
            elsif String === options[:format]
              @defaults[:format] = options[:format]
            end
          end

          def normalize_conditions!
            @conditions.merge!(:path_info => path)

            constraints.each do |key, condition|
              next if segment_keys.include?(key) || key == :controller
              @conditions[key] = condition
            end

            @conditions[:required_defaults] = []
            options.each do |key, required_default|
              next if segment_keys.include?(key) || IGNORE_OPTIONS.include?(key)
              next if Regexp === required_default
              @conditions[:required_defaults] << key
            end

            via_all = options.delete(:via) if options[:via] == :all

            if !via_all && options[:via].blank?
              msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \
                    "If you want to expose your action to GET, use `get` in the router:\n\n" \
                    "  Instead of: match \"controller#action\"\n" \
                    "  Do: get \"controller#action\""
              raise msg
            end

            if via = options[:via]
              list = Array(via).map { |m| m.to_s.dasherize.upcase }
              @conditions.merge!(:request_method => list)
            end
          end

          def app
            Constraints.new(endpoint, blocks, @set.request_class)
          end

          def default_controller_and_action(to_shorthand=nil)
            if to.respond_to?(:call)
              { }
            else
              if to.is_a?(String)
                controller, action = to.split('#')
              elsif to.is_a?(Symbol)
                action = to.to_s
              end

              controller ||= default_controller
              action     ||= default_action

              unless controller.is_a?(Regexp) || to_shorthand
                controller = [@scope[:module], controller].compact.join("/").presence
              end

              if controller.is_a?(String) && controller =~ %r{\A/}
                raise ArgumentError, "controller name should not start with a slash"
              end

              controller = controller.to_s unless controller.is_a?(Regexp)
              action     = action.to_s     unless action.is_a?(Regexp)

              if controller.blank? && segment_keys.exclude?(:controller)
                raise ArgumentError, "missing :controller"
              end

              if action.blank? && segment_keys.exclude?(:action)
                raise ArgumentError, "missing :action"
              end

              if controller.is_a?(String) && controller !~ /\A[a-z_0-9\/]*\z/
                message = "'#{controller}' is not a supported controller name. This can lead to potential routing problems."
                message << " See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use"
                raise ArgumentError, message
              end

              hash = {}
              hash[:controller] = controller unless controller.blank?
              hash[:action]     = action unless action.blank?
              hash
            end
          end

          def blocks
            if options[:constraints].present? && !options[:constraints].is_a?(Hash)
              [options[:constraints]]
            else
              scope[:blocks] || []
            end
          end

          def constraints
            @constraints ||= {}.tap do |constraints|
              constraints.merge!(scope[:constraints]) if scope[:constraints]

              options.except(*IGNORE_OPTIONS).each do |key, option|
                constraints[key] = option if Regexp === option
              end

              constraints.merge!(options[:constraints]) if options[:constraints].is_a?(Hash)
            end
          end

          def segment_keys
            @segment_keys ||= path_pattern.names.map{ |s| s.to_sym }
          end

          def path_pattern
            Journey::Path::Pattern.new(strexp)
          end

          def strexp
            Journey::Router::Strexp.compile(path, requirements, SEPARATORS)
          end

          def endpoint
            to.respond_to?(:call) ? to : dispatcher
          end

          def dispatcher
            Routing::RouteSet::Dispatcher.new(:defaults => defaults)
          end

          def to
            options[:to]
          end

          def default_controller
            options[:controller] || scope[:controller]
          end

          def default_action
            options[:action] || scope[:action]
          end
      end

      # Invokes Rack::Mount::Utils.normalize path and ensure that
      # (:locale) becomes (/:locale) instead of /(:locale). Except
      # for root cases, where the latter is the correct one.
      def self.normalize_path(path)
        path = Journey::Router::Utils.normalize_path(path)
        path.gsub!(%r{/(\(+)/?}, '\1/') unless path =~ %r{^/\(+[^)]+\)$}
        path
      end

      def self.normalize_name(name)
        normalize_path(name)[1..-1].tr("/", "_")
      end

      module Base
        # You can specify what Rails should route "/" to with the root method:
        #
        #   root to: 'pages#main'
        #
        # For options, see +match+, as +root+ uses it internally.
        #
        # You can also pass a string which will expand
        #
        #   root 'pages#main'
        #
        # You should put the root route at the top of <tt>config/routes.rb</tt>,
        # because this means it will be matched first. As this is the most popular route
        # of most Rails applications, this is beneficial.
        def root(options = {})
          options = { :to => options } if options.is_a?(String)
          match '/', { :as => :root, :via => :get }.merge!(options)
        end

        # Matches a url pattern to one or more routes. Any symbols in a pattern
        # are interpreted as url query parameters and thus available as +params+
        # in an action:
        #
        #   # sets :controller, :action and :id in params
        #   match ':controller/:action/:id'
        #
        # Two of these symbols are special, +:controller+ maps to the controller
        # and +:action+ to the controller's action. A pattern can also map
        # wildcard segments (globs) to params:
        #
        #   match 'songs/*category/:title', to: 'songs#show'
        #
        #   # 'songs/rock/classic/stairway-to-heaven' sets
        #   #  params[:category] = 'rock/classic'
        #   #  params[:title] = 'stairway-to-heaven'
        #
        # When a pattern points to an internal route, the route's +:action+ and
        # +:controller+ should be set in options or hash shorthand. Examples:
        #
        #   match 'photos/:id' => 'photos#show'
        #   match 'photos/:id', to: 'photos#show'
        #   match 'photos/:id', controller: 'photos', action: 'show'
        #
        # A pattern can also point to a +Rack+ endpoint i.e. anything that
        # responds to +call+:
        #
        #   match 'photos/:id', to: lambda {|hash| [200, {}, ["Coming soon"]] }
        #   match 'photos/:id', to: PhotoRackApp
        #   # Yes, controller actions are just rack endpoints
        #   match 'photos/:id', to: PhotosController.action(:show)
        #
        # Because request various HTTP verbs with a single action has security
        # implications, is recommendable use HttpHelpers[rdoc-ref:HttpHelpers]
        # instead +match+
        #
        # === Options
        #
        # Any options not seen here are passed on as params with the url.
        #
        # [:controller]
        #   The route's controller.
        #
        # [:action]
        #   The route's action.
        #
        # [:path]
        #   The path prefix for the routes.
        #
        # [:module]
        #   The namespace for :controller.
        #
        #     match 'path', to: 'c#a', module: 'sekret', controller: 'posts'
        #     #=> Sekret::PostsController
        #
        #   See <tt>Scoping#namespace</tt> for its scope equivalent.
        #
        # [:as]
        #   The name used to generate routing helpers.
        #
        # [:via]
        #   Allowed HTTP verb(s) for route.
        #
        #      match 'path', to: 'c#a', via: :get
        #      match 'path', to: 'c#a', via: [:get, :post]
        #      match 'path', to: 'c#a', via: :all
        #
        # [:to]
        #   Points to a +Rack+ endpoint. Can be an object that responds to
        #   +call+ or a string representing a controller's action.
        #
        #      match 'path', to: 'controller#action'
        #      match 'path', to: lambda { |env| [200, {}, ["Success!"]] }
        #      match 'path', to: RackApp
        #
        # [:on]
        #   Shorthand for wrapping routes in a specific RESTful context. Valid
        #   values are +:member+, +:collection+, and +:new+. Only use within
        #   <tt>resource(s)</tt> block. For example:
        #
        #      resource :bar do
        #        match 'foo', to: 'c#a', on: :member, via: [:get, :post]
        #      end
        #
        #   Is equivalent to:
        #
        #      resource :bar do
        #        member do
        #          match 'foo', to: 'c#a', via: [:get, :post]
        #        end
        #      end
        #
        # [:constraints]
        #   Constrains parameters with a hash of regular expressions or an
        #   object that responds to <tt>matches?</tt>
        #
        #     match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }
        #
        #     class Blacklist
        #       def matches?(request) request.remote_ip == '1.2.3.4' end
        #     end
        #     match 'path', to: 'c#a', constraints: Blacklist.new
        #
        #   See <tt>Scoping#constraints</tt> for more examples with its scope
        #   equivalent.
        #
        # [:defaults]
        #   Sets defaults for parameters
        #
        #     # Sets params[:format] to 'jpg' by default
        #     match 'path', to: 'c#a', defaults: { format: 'jpg' }
        #
        #   See <tt>Scoping#defaults</tt> for its scope equivalent.
        #
        # [:anchor]
        #   Boolean to anchor a <tt>match</tt> pattern. Default is true. When set to
        #   false, the pattern matches any request prefixed with the given path.
        #
        #     # Matches any request starting with 'path'
        #     match 'path', to: 'c#a', anchor: false
        #
        # [:format]
        #   Allows you to specify the default value for optional +format+
        #   segment or disable it by supplying +false+.
        def match(path, options=nil)
        end

        # Mount a Rack-based application to be used within the application.
        #
        #   mount SomeRackApp, at: "some_route"
        #
        # Alternatively:
        #
        #   mount(SomeRackApp => "some_route")
        #
        # For options, see +match+, as +mount+ uses it internally.
        #
        # All mounted applications come with routing helpers to access them.
        # These are named after the class specified, so for the above example
        # the helper is either +some_rack_app_path+ or +some_rack_app_url+.
        # To customize this helper's name, use the +:as+ option:
        #
        #   mount(SomeRackApp => "some_route", as: "exciting")
        #
        # This will generate the +exciting_path+ and +exciting_url+ helpers
        # which can be used to navigate to this mounted app.
        def mount(app, options = nil)
          if options
            path = options.delete(:at)
          else
            unless Hash === app
              raise ArgumentError, "must be called with mount point"
            end

            options = app
            app, path = options.find { |k, v| k.respond_to?(:call) }
            options.delete(app) if app
          end

          raise "A rack application must be specified" unless path

          options[:as]  ||= app_name(app)
          options[:via] ||= :all

          match(path, options.merge(:to => app, :anchor => false, :format => false))

          define_generate_prefix(app, options[:as])
          self
        end

        def default_url_options=(options)
          @set.default_url_options = options
        end
        alias_method :default_url_options, :default_url_options=

        def with_default_scope(scope, &block)
          scope(scope) do
            instance_exec(&block)
          end
        end

        private
          def app_name(app)
            return unless app.respond_to?(:routes)

            if app.respond_to?(:railtie_name)
              app.railtie_name
            else
              class_name = app.class.is_a?(Class) ? app.name : app.class.name
              ActiveSupport::Inflector.underscore(class_name).tr("/", "_")
            end
          end

          def define_generate_prefix(app, name)
            return unless app.respond_to?(:routes) && app.routes.respond_to?(:define_mounted_helper)

            _route = @set.named_routes.routes[name.to_sym]
            _routes = @set
            app.routes.define_mounted_helper(name)
            app.routes.singleton_class.class_eval do
              define_method :mounted? do
                true
              end

              define_method :_generate_prefix do |options|
                prefix_options = options.slice(*_route.segment_keys)
                # we must actually delete prefix segment keys to avoid passing them to next url_for
                _route.segment_keys.each { |k| options.delete(k) }
                _routes.url_helpers.send("#{name}_path", prefix_options)
              end
            end
          end
      end

      module HttpHelpers
        # Define a route that only recognizes HTTP GET.
        # For supported arguments, see match[rdoc-ref:Base#match]
        #
        #   get 'bacon', to: 'food#bacon'
        def get(*args, &block)
          map_method(:get, args, &block)
        end

        # Define a route that only recognizes HTTP POST.
        # For supported arguments, see match[rdoc-ref:Base#match]
        #
        #   post 'bacon', to: 'food#bacon'
        def post(*args, &block)
          map_method(:post, args, &block)
        end

        # Define a route that only recognizes HTTP PATCH.
        # For supported arguments, see match[rdoc-ref:Base#match]
        #
        #   patch 'bacon', to: 'food#bacon'
        def patch(*args, &block)
          map_method(:patch, args, &block)
        end

        # Define a route that only recognizes HTTP PUT.
        # For supported arguments, see match[rdoc-ref:Base#match]
        #
        #   put 'bacon', to: 'food#bacon'
        def put(*args, &block)
          map_method(:put, args, &block)
        end

        # Define a route that only recognizes HTTP DELETE.
        # For supported arguments, see match[rdoc-ref:Base#match]
        #
        #   delete 'broccoli', to: 'food#broccoli'
        def delete(*args, &block)
          map_method(:delete, args, &block)
        end

        private
          def map_method(method, args, &block)
            options = args.extract_options!
            options[:via]    = method
            options[:path] ||= args.first if args.first.is_a?(String)
            match(*args, options, &block)
            self
          end
      end

      # You may wish to organize groups of controllers under a namespace.
      # Most commonly, you might group a number of administrative controllers
      # under an +admin+ namespace. You would place these controllers under
      # the <tt>app/controllers/admin</tt> directory, and you can group them
      # together in your router:
      #
      #   namespace "admin" do
      #     resources :posts, :comments
      #   end
      #
      # This will create a number of routes for each of the posts and comments
      # controller. For <tt>Admin::PostsController</tt>, Rails will create:
      #
      #   GET       /admin/posts
      #   GET       /admin/posts/new
      #   POST      /admin/posts
      #   GET       /admin/posts/1
      #   GET       /admin/posts/1/edit
      #   PATCH/PUT /admin/posts/1
      #   DELETE    /admin/posts/1
      #
      # If you want to route /posts (without the prefix /admin) to
      # <tt>Admin::PostsController</tt>, you could use
      #
      #   scope module: "admin" do
      #     resources :posts
      #   end
      #
      # or, for a single case
      #
      #   resources :posts, module: "admin"
      #
      # If you want to route /admin/posts to +PostsController+
      # (without the Admin:: module prefix), you could use
      #
      #   scope "/admin" do
      #     resources :posts
      #   end
      #
      # or, for a single case
      #
      #   resources :posts, path: "/admin/posts"
      #
      # In each of these cases, the named routes remain the same as if you did
      # not use scope. In the last case, the following paths map to
      # +PostsController+:
      #
      #   GET       /admin/posts
      #   GET       /admin/posts/new
      #   POST      /admin/posts
      #   GET       /admin/posts/1
      #   GET       /admin/posts/1/edit
      #   PATCH/PUT /admin/posts/1
      #   DELETE    /admin/posts/1
      module Scoping
        # Scopes a set of routes to the given default options.
        #
        # Take the following route definition as an example:
        #
        #   scope path: ":account_id", as: "account" do
        #     resources :projects
        #   end
        #
        # This generates helpers such as +account_projects_path+, just like +resources+ does.
        # The difference here being that the routes generated are like /:account_id/projects,
        # rather than /accounts/:account_id/projects.
        #
        # === Options
        #
        # Takes same options as <tt>Base#match</tt> and <tt>Resources#resources</tt>.
        #
        #   # route /posts (without the prefix /admin) to <tt>Admin::PostsController</tt>
        #   scope module: "admin" do
        #     resources :posts
        #   end
        #
        #   # prefix the posts resource's requests with '/admin'
        #   scope path: "/admin" do
        #     resources :posts
        #   end
        #
        #   # prefix the routing helper name: +sekret_posts_path+ instead of +posts_path+
        #   scope as: "sekret" do
        #     resources :posts
        #   end
        def scope(*args)
          options = args.extract_options!.dup
          recover = {}

          options[:path] = args.flatten.join('/') if args.any?
          options[:constraints] ||= {}

          if options[:constraints].is_a?(Hash)
            defaults = options[:constraints].select do
              |k, v| URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Fixnum))
            end

            (options[:defaults] ||= {}).reverse_merge!(defaults)
          else
            block, options[:constraints] = options[:constraints], {}
          end

          scope_options.each do |option|
            if value = options.delete(option)
              recover[option] = @scope[option]
              @scope[option]  = send("merge_#{option}_scope", @scope[option], value)
            end
          end

          recover[:blocks] = @scope[:blocks]
          @scope[:blocks]  = merge_blocks_scope(@scope[:blocks], block)

          recover[:options] = @scope[:options]
          @scope[:options]  = merge_options_scope(@scope[:options], options)

          yield
          self
        ensure
          @scope.merge!(recover)
        end

        # Scopes routes to a specific controller
        #
        #   controller "food" do
        #     match "bacon", action: "bacon"
        #   end
        def controller(controller, options={})
          options[:controller] = controller
          scope(options) { yield }
        end

        # Scopes routes to a specific namespace. For example:
        #
        #   namespace :admin do
        #     resources :posts
        #   end
        #
        # This generates the following routes:
        #
        #       admin_posts GET       /admin/posts(.:format)          admin/posts#index
        #       admin_posts POST      /admin/posts(.:format)          admin/posts#create
        #    new_admin_post GET       /admin/posts/new(.:format)      admin/posts#new
        #   edit_admin_post GET       /admin/posts/:id/edit(.:format) admin/posts#edit
        #        admin_post GET       /admin/posts/:id(.:format)      admin/posts#show
        #        admin_post PATCH/PUT /admin/posts/:id(.:format)      admin/posts#update
        #        admin_post DELETE    /admin/posts/:id(.:format)      admin/posts#destroy
        #
        # === Options
        #
        # The +:path+, +:as+, +:module+, +:shallow_path+ and +:shallow_prefix+
        # options all default to the name of the namespace.
        #
        # For options, see <tt>Base#match</tt>. For +:shallow_path+ option, see
        # <tt>Resources#resources</tt>.
        #
        #   # accessible through /sekret/posts rather than /admin/posts
        #   namespace :admin, path: "sekret" do
        #     resources :posts
        #   end
        #
        #   # maps to <tt>Sekret::PostsController</tt> rather than <tt>Admin::PostsController</tt>
        #   namespace :admin, module: "sekret" do
        #     resources :posts
        #   end
        #
        #   # generates +sekret_posts_path+ rather than +admin_posts_path+
        #   namespace :admin, as: "sekret" do
        #     resources :posts
        #   end
        def namespace(path, options = {})
          path = path.to_s
          options = { :path => path, :as => path, :module => path,
                      :shallow_path => path, :shallow_prefix => path }.merge!(options)
          scope(options) { yield }
        end

        # === Parameter Restriction
        # Allows you to constrain the nested routes based on a set of rules.
        # For instance, in order to change the routes to allow for a dot character in the +id+ parameter:
        #
        #   constraints(id: /\d+\.\d+/) do
        #     resources :posts
        #   end
        #
        # Now routes such as +/posts/1+ will no longer be valid, but +/posts/1.1+ will be.
        # The +id+ parameter must match the constraint passed in for this example.
        #
        # You may use this to also restrict other parameters:
        #
        #   resources :posts do
        #     constraints(post_id: /\d+\.\d+/) do
        #       resources :comments
        #     end
        #   end
        #
        # === Restricting based on IP
        #
        # Routes can also be constrained to an IP or a certain range of IP addresses:
        #
        #   constraints(ip: /192\.168\.\d+\.\d+/) do
        #     resources :posts
        #   end
        #
        # Any user connecting from the 192.168.* range will be able to see this resource,
        # where as any user connecting outside of this range will be told there is no such route.
        #
        # === Dynamic request matching
        #
        # Requests to routes can be constrained based on specific criteria:
        #
        #    constraints(lambda { |req| req.env["HTTP_USER_AGENT"] =~ /iPhone/ }) do
        #      resources :iphones
        #    end
        #
        # You are able to move this logic out into a class if it is too complex for routes.
        # This class must have a +matches?+ method defined on it which either returns +true+
        # if the user should be given access to that route, or +false+ if the user should not.
        #
        #    class Iphone
        #      def self.matches?(request)
        #        request.env["HTTP_USER_AGENT"] =~ /iPhone/
        #      end
        #    end
        #
        # An expected place for this code would be +lib/constraints+.
        #
        # This class is then used like this:
        #
        #    constraints(Iphone) do
        #      resources :iphones
        #    end
        def constraints(constraints = {})
          scope(:constraints => constraints) { yield }
        end

        # Allows you to set default parameters for a route, such as this:
        #   defaults id: 'home' do
        #     match 'scoped_pages/(:id)', to: 'pages#show'
        #   end
        # Using this, the +:id+ parameter here will default to 'home'.
        def defaults(defaults = {})
          scope(:defaults => defaults) { yield }
        end

        private
          def scope_options #:nodoc:
            @scope_options ||= private_methods.grep(/^merge_(.+)_scope$/) { $1.to_sym }
          end

          def merge_path_scope(parent, child) #:nodoc:
            Mapper.normalize_path("#{parent}/#{child}")
          end

          def merge_shallow_path_scope(parent, child) #:nodoc:
            Mapper.normalize_path("#{parent}/#{child}")
          end

          def merge_as_scope(parent, child) #:nodoc:
            parent ? "#{parent}_#{child}" : child
          end

          def merge_shallow_prefix_scope(parent, child) #:nodoc:
            parent ? "#{parent}_#{child}" : child
          end

          def merge_module_scope(parent, child) #:nodoc:
            parent ? "#{parent}/#{child}" : child
          end

          def merge_controller_scope(parent, child) #:nodoc:
            child
          end

          def merge_path_names_scope(parent, child) #:nodoc:
            merge_options_scope(parent, child)
          end

          def merge_constraints_scope(parent, child) #:nodoc:
            merge_options_scope(parent, child)
          end

          def merge_defaults_scope(parent, child) #:nodoc:
            merge_options_scope(parent, child)
          end

          def merge_blocks_scope(parent, child) #:nodoc:
            merged = parent ? parent.dup : []
            merged << child if child
            merged
          end

          def merge_options_scope(parent, child) #:nodoc:
            (parent || {}).except(*override_keys(child)).merge!(child)
          end

          def merge_shallow_scope(parent, child) #:nodoc:
            child ? true : false
          end

          def override_keys(child) #:nodoc:
            child.key?(:only) || child.key?(:except) ? [:only, :except] : []
          end
      end

      # Resource routing allows you to quickly declare all of the common routes
      # for a given resourceful controller. Instead of declaring separate routes
      # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+
      # actions, a resourceful route declares them in a single line of code:
      #
      #  resources :photos
      #
      # Sometimes, you have a resource that clients always look up without
      # referencing an ID. A common example, /profile always shows the profile of
      # the currently logged in user. In this case, you can use a singular resource
      # to map /profile (rather than /profile/:id) to the show action.
      #
      #  resource :profile
      #
      # It's common to have resources that are logically children of other
      # resources:
      #
      #   resources :magazines do
      #     resources :ads
      #   end
      #
      # You may wish to organize groups of controllers under a namespace. Most
      # commonly, you might group a number of administrative controllers under
      # an +admin+ namespace. You would place these controllers under the
      # <tt>app/controllers/admin</tt> directory, and you can group them together
      # in your router:
      #
      #   namespace "admin" do
      #     resources :posts, :comments
      #   end
      #
      # By default the +:id+ parameter doesn't accept dots. If you need to
      # use dots as part of the +:id+ parameter add a constraint which
      # overrides this restriction, e.g:
      #
      #   resources :articles, id: /[^\/]+/
      #
      # This allows any character other than a slash as part of your +:id+.
      #
      module Resources
        # CANONICAL_ACTIONS holds all actions that does not need a prefix or
        # a path appended since they fit properly in their scope level.
        VALID_ON_OPTIONS  = [:new, :collection, :member]
        RESOURCE_OPTIONS  = [:as, :controller, :path, :only, :except, :param, :concerns]
        CANONICAL_ACTIONS = %w(index create new show update destroy)

        class Resource #:nodoc:
          attr_reader :controller, :path, :options, :param

          def initialize(entities, options = {})
            @name       = entities.to_s
            @path       = (options[:path] || @name).to_s
            @controller = (options[:controller] || @name).to_s
            @as         = options[:as]
            @param      = (options[:param] || :id).to_sym
            @options    = options
          end

          def default_actions
            [:index, :create, :new, :show, :update, :destroy, :edit]
          end

          def actions
            if only = @options[:only]
              Array(only).map(&:to_sym)
            elsif except = @options[:except]
              default_actions - Array(except).map(&:to_sym)
            else
              default_actions
            end
          end

          def name
            @as || @name
          end

          def plural
            @plural ||= name.to_s
          end

          def singular
            @singular ||= name.to_s.singularize
          end

          alias :member_name :singular

          # Checks for uncountable plurals, and appends "_index" if the plural
          # and singular form are the same.
          def collection_name
            singular == plural ? "#{plural}_index" : plural
          end

          def resource_scope
            { :controller => controller }
          end

          alias :collection_scope :path

          def member_scope
            "#{path}/:#{param}"
          end

          alias :shallow_scope :member_scope

          def new_scope(new_path)
            "#{path}/#{new_path}"
          end

          def nested_param
            :"#{singular}_#{param}"
          end

          def nested_scope
            "#{path}/:#{nested_param}"
          end

        end

        class SingletonResource < Resource #:nodoc:
          def initialize(entities, options)
            super
            @as         = nil
            @controller = (options[:controller] || plural).to_s
            @as         = options[:as]
          end

          def default_actions
            [:show, :create, :update, :destroy, :new, :edit]
          end

          def plural
            @plural ||= name.to_s.pluralize
          end

          def singular
            @singular ||= name.to_s
          end

          alias :member_name :singular
          alias :collection_name :singular

          alias :member_scope :path
          alias :nested_scope :path
        end

        def resources_path_names(options)
          @scope[:path_names].merge!(options)
        end

        # Sometimes, you have a resource that clients always look up without
        # referencing an ID. A common example, /profile always shows the
        # profile of the currently logged in user. In this case, you can use
        # a singular resource to map /profile (rather than /profile/:id) to
        # the show action:
        #
        #   resource :geocoder
        #
        # creates six different routes in your application, all mapping to
        # the +GeoCoders+ controller (note that the controller is named after
        # the plural):
        #
        #   GET       /geocoder/new
        #   POST      /geocoder
        #   GET       /geocoder
        #   GET       /geocoder/edit
        #   PATCH/PUT /geocoder
        #   DELETE    /geocoder
        #
        # === Options
        # Takes same options as +resources+.
        def resource(*resources, &block)
          options = resources.extract_options!.dup

          if apply_common_behavior_for(:resource, resources, options, &block)
            return self
          end

          resource_scope(:resource, SingletonResource.new(resources.pop, options)) do
            yield if block_given?

            concerns(options[:concerns]) if options[:concerns]

            collection do
              post :create
            end if parent_resource.actions.include?(:create)

            new do
              get :new
            end if parent_resource.actions.include?(:new)

            set_member_mappings_for_resource
          end

          self
        end

        # In Rails, a resourceful route provides a mapping between HTTP verbs
        # and URLs and controller actions. By convention, each action also maps
        # to particular CRUD operations in a database. A single entry in the
        # routing file, such as
        #
        #   resources :photos
        #
        # creates seven different routes in your application, all mapping to
        # the +Photos+ controller:
        #
        #   GET       /photos
        #   GET       /photos/new
        #   POST      /photos
        #   GET       /photos/:id
        #   GET       /photos/:id/edit
        #   PATCH/PUT /photos/:id
        #   DELETE    /photos/:id
        #
        # Resources can also be nested infinitely by using this block syntax:
        #
        #   resources :photos do
        #     resources :comments
        #   end
        #
        # This generates the following comments routes:
        #
        #   GET       /photos/:photo_id/comments
        #   GET       /photos/:photo_id/comments/new
        #   POST      /photos/:photo_id/comments
        #   GET       /photos/:photo_id/comments/:id
        #   GET       /photos/:photo_id/comments/:id/edit
        #   PATCH/PUT /photos/:photo_id/comments/:id
        #   DELETE    /photos/:photo_id/comments/:id
        #
        # === Options
        # Takes same options as <tt>Base#match</tt> as well as:
        #
        # [:path_names]
        #   Allows you to change the segment component of the +edit+ and +new+ actions.
        #   Actions not specified are not changed.
        #
        #     resources :posts, path_names: { new: "brand_new" }
        #
        #   The above example will now change /posts/new to /posts/brand_new
        #
        # [:path]
        #   Allows you to change the path prefix for the resource.
        #
        #     resources :posts, path: 'postings'
        #
        #   The resource and all segments will now route to /postings instead of /posts
        #
        # [:only]
        #   Only generate routes for the given actions.
        #
        #     resources :cows, only: :show
        #     resources :cows, only: [:show, :index]
        #
        # [:except]
        #   Generate all routes except for the given actions.
        #
        #     resources :cows, except: :show
        #     resources :cows, except: [:show, :index]
        #
        # [:shallow]
        #   Generates shallow routes for nested resource(s). When placed on a parent resource,
        #   generates shallow routes for all nested resources.
        #
        #     resources :posts, shallow: true do
        #       resources :comments
        #     end
        #
        #   Is the same as:
        #
        #     resources :posts do
        #       resources :comments, except: [:show, :edit, :update, :destroy]
        #     end
        #     resources :comments, only: [:show, :edit, :update, :destroy]
        #
        #   This allows URLs for resources that otherwise would be deeply nested such
        #   as a comment on a blog post like <tt>/posts/a-long-permalink/comments/1234</tt>
        #   to be shortened to just <tt>/comments/1234</tt>.
        #
        # [:shallow_path]
        #   Prefixes nested shallow routes with the specified path.
        #
        #     scope shallow_path: "sekret" do
        #       resources :posts do
        #         resources :comments, shallow: true
        #       end
        #     end
        #
        #   The +comments+ resource here will have the following routes generated for it:
        #
        #     post_comments    GET       /posts/:post_id/comments(.:format)
        #     post_comments    POST      /posts/:post_id/comments(.:format)
        #     new_post_comment GET       /posts/:post_id/comments/new(.:format)
        #     edit_comment     GET       /sekret/comments/:id/edit(.:format)
        #     comment          GET       /sekret/comments/:id(.:format)
        #     comment          PATCH/PUT /sekret/comments/:id(.:format)
        #     comment          DELETE    /sekret/comments/:id(.:format)
        #
        # [:shallow_prefix]
        #   Prefixes nested shallow route names with specified prefix.
        #
        #     scope shallow_prefix: "sekret" do
        #       resources :posts do
        #         resources :comments, shallow: true
        #       end
        #     end
        #
        #   The +comments+ resource here will have the following routes generated for it:
        #
        #     post_comments           GET       /posts/:post_id/comments(.:format)
        #     post_comments           POST      /posts/:post_id/comments(.:format)
        #     new_post_comment        GET       /posts/:post_id/comments/new(.:format)
        #     edit_sekret_comment     GET       /comments/:id/edit(.:format)
        #     sekret_comment          GET       /comments/:id(.:format)
        #     sekret_comment          PATCH/PUT /comments/:id(.:format)
        #     sekret_comment          DELETE    /comments/:id(.:format)
        #
        # [:format]
        #   Allows you to specify the default value for optional +format+
        #   segment or disable it by supplying +false+.
        #
        # === Examples
        #
        #   # routes call <tt>Admin::PostsController</tt>
        #   resources :posts, module: "admin"
        #
        #   # resource actions are at /admin/posts.
        #   resources :posts, path: "admin/posts"
        def resources(*resources, &block)
          options = resources.extract_options!.dup

          if apply_common_behavior_for(:resources, resources, options, &block)
            return self
          end

          resource_scope(:resources, Resource.new(resources.pop, options)) do
            yield if block_given?

            concerns(options[:concerns]) if options[:concerns]

            collection do
              get  :index if parent_resource.actions.include?(:index)
              post :create if parent_resource.actions.include?(:create)
            end

            new do
              get :new
            end if parent_resource.actions.include?(:new)

            set_member_mappings_for_resource
          end

          self
        end

        # To add a route to the collection:
        #
        #   resources :photos do
        #     collection do
        #       get 'search'
        #     end
        #   end
        #
        # This will enable Rails to recognize paths such as <tt>/photos/search</tt>
        # with GET, and route to the search action of +PhotosController+. It will also
        # create the <tt>search_photos_url</tt> and <tt>search_photos_path</tt>
        # route helpers.
        def collection
          unless resource_scope?
            raise ArgumentError, "can't use collection outside resource(s) scope"
          end

          with_scope_level(:collection) do
            scope(parent_resource.collection_scope) do
              yield
            end
          end
        end

        # To add a member route, add a member block into the resource block:
        #
        #   resources :photos do
        #     member do
        #       get 'preview'
        #     end
        #   end
        #
        # This will recognize <tt>/photos/1/preview</tt> with GET, and route to the
        # preview action of +PhotosController+. It will also create the
        # <tt>preview_photo_url</tt> and <tt>preview_photo_path</tt> helpers.
        def member
          unless resource_scope?
            raise ArgumentError, "can't use member outside resource(s) scope"
          end

          with_scope_level(:member) do
            scope(parent_resource.member_scope) do
              yield
            end
          end
        end

        def new
          unless resource_scope?
            raise ArgumentError, "can't use new outside resource(s) scope"
          end

          with_scope_level(:new) do
            scope(parent_resource.new_scope(action_path(:new))) do
              yield
            end
          end
        end

        def nested
          unless resource_scope?
            raise ArgumentError, "can't use nested outside resource(s) scope"
          end

          with_scope_level(:nested) do
            if shallow?
              with_exclusive_scope do
                if @scope[:shallow_path].blank?
                  scope(parent_resource.nested_scope, nested_options) { yield }
                else
                  scope(@scope[:shallow_path], :as => @scope[:shallow_prefix]) do
                    scope(parent_resource.nested_scope, nested_options) { yield }
                  end
                end
              end
            else
              scope(parent_resource.nested_scope, nested_options) { yield }
            end
          end
        end

        # See ActionDispatch::Routing::Mapper::Scoping#namespace
        def namespace(path, options = {})
          if resource_scope?
            nested { super }
          else
            super
          end
        end

        def shallow
          scope(:shallow => true, :shallow_path => @scope[:path]) do
            yield
          end
        end

        def shallow?
          parent_resource.instance_of?(Resource) && @scope[:shallow]
        end

        # match 'path' => 'controller#action'
        # match 'path', to: 'controller#action'
        # match 'path', 'otherpath', on: :member, via: :get
        def match(path, *rest)
          if rest.empty? && Hash === path
            options  = path
            path, to = options.find { |name, value| name.is_a?(String) }
            options[:to] = to
            options.delete(path)
            paths = [path]
          else
            options = rest.pop || {}
            paths = [path] + rest
          end

          options[:anchor] = true unless options.key?(:anchor)

          if options[:on] && !VALID_ON_OPTIONS.include?(options[:on])
            raise ArgumentError, "Unknown scope #{on.inspect} given to :on"
          end

          paths.each { |_path| decomposed_match(_path, options.dup) }
          self
        end

        def decomposed_match(path, options) # :nodoc:
          if on = options.delete(:on)
            send(on) { decomposed_match(path, options) }
          else
            case @scope[:scope_level]
            when :resources
              nested { decomposed_match(path, options) }
            when :resource
              member { decomposed_match(path, options) }
            else
              add_route(path, options)
            end
          end
        end

        def add_route(action, options) # :nodoc:
          path = path_for_action(action, options.delete(:path))
          action = action.to_s.dup

          if action =~ /^[\w\/]+$/
            options[:action] ||= action unless action.include?("/")
          else
            action = nil
          end

          if !options.fetch(:as, true)
            options.delete(:as)
          else
            options[:as] = name_for_action(options[:as], action)
          end

          mapping = Mapping.new(@set, @scope, URI.parser.escape(path), options)
          app, conditions, requirements, defaults, as, anchor = mapping.to_route
          @set.add_route(app, conditions, requirements, defaults, as, anchor)
        end

        def root(options={})
          if @scope[:scope_level] == :resources
            with_scope_level(:root) do
              scope(parent_resource.path) do
                super(options)
              end
            end
          else
            super(options)
          end
        end

        protected

          def parent_resource #:nodoc:
            @scope[:scope_level_resource]
          end

          def apply_common_behavior_for(method, resources, options, &block) #:nodoc:
            if resources.length > 1
              resources.each { |r| send(method, r, options, &block) }
              return true
            end

            if resource_scope?
              nested { send(method, resources.pop, options, &block) }
              return true
            end

            options.keys.each do |k|
              (options[:constraints] ||= {})[k] = options.delete(k) if options[k].is_a?(Regexp)
            end

            scope_options = options.slice!(*RESOURCE_OPTIONS)
            unless scope_options.empty?
              scope(scope_options) do
                send(method, resources.pop, options, &block)
              end
              return true
            end

            unless action_options?(options)
              options.merge!(scope_action_options) if scope_action_options?
            end

            false
          end

          def action_options?(options) #:nodoc:
            options[:only] || options[:except]
          end

          def scope_action_options? #:nodoc:
            @scope[:options] && (@scope[:options][:only] || @scope[:options][:except])
          end

          def scope_action_options #:nodoc:
            @scope[:options].slice(:only, :except)
          end

          def resource_scope? #:nodoc:
            [:resource, :resources].include? @scope[:scope_level]
          end

          def resource_method_scope? #:nodoc:
            [:collection, :member, :new].include? @scope[:scope_level]
          end

          def with_exclusive_scope
            begin
              old_name_prefix, old_path = @scope[:as], @scope[:path]
              @scope[:as], @scope[:path] = nil, nil

              with_scope_level(:exclusive) do
                yield
              end
            ensure
              @scope[:as], @scope[:path] = old_name_prefix, old_path
            end
          end

          def with_scope_level(kind, resource = parent_resource)
            old, @scope[:scope_level] = @scope[:scope_level], kind
            old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource
            yield
          ensure
            @scope[:scope_level] = old
            @scope[:scope_level_resource] = old_resource
          end

          def resource_scope(kind, resource) #:nodoc:
            with_scope_level(kind, resource) do
              scope(parent_resource.resource_scope) do
                yield
              end
            end
          end

          def nested_options #:nodoc:
            options = { :as => parent_resource.member_name }
            options[:constraints] = {
              parent_resource.nested_param => param_constraint
            } if param_constraint?

            options
          end

          def param_constraint? #:nodoc:
            @scope[:constraints] && @scope[:constraints][parent_resource.param].is_a?(Regexp)
          end

          def param_constraint #:nodoc:
            @scope[:constraints][parent_resource.param]
          end

          def canonical_action?(action, flag) #:nodoc:
            flag && resource_method_scope? && CANONICAL_ACTIONS.include?(action.to_s)
          end

          def shallow_scoping? #:nodoc:
            shallow? && @scope[:scope_level] == :member
          end

          def path_for_action(action, path) #:nodoc:
            prefix = shallow_scoping? ?
              "#{@scope[:shallow_path]}/#{parent_resource.shallow_scope}" : @scope[:path]

            if canonical_action?(action, path.blank?)
              prefix.to_s
            else
              "#{prefix}/#{action_path(action, path)}"
            end
          end

          def action_path(name, path = nil) #:nodoc:
            name = name.to_sym if name.is_a?(String)
            path || @scope[:path_names][name] || name.to_s
          end

          def prefix_name_for_action(as, action) #:nodoc:
            if as
              as.to_s
            elsif !canonical_action?(action, @scope[:scope_level])
              action.to_s
            end
          end

          def name_for_action(as, action) #:nodoc:
            prefix = prefix_name_for_action(as, action)
            prefix = Mapper.normalize_name(prefix) if prefix
            name_prefix = @scope[:as]

            if parent_resource
              return nil unless as || action

              collection_name = parent_resource.collection_name
              member_name = parent_resource.member_name
            end

            name = case @scope[:scope_level]
            when :nested
              [name_prefix, prefix]
            when :collection
              [prefix, name_prefix, collection_name]
            when :new
              [prefix, :new, name_prefix, member_name]
            when :member
              [prefix, shallow_scoping? ? @scope[:shallow_prefix] : name_prefix, member_name]
            when :root
              [name_prefix, collection_name, prefix]
            else
              [name_prefix, member_name, prefix]
            end

            if candidate = name.select(&:present?).join("_").presence
              # If a name was not explicitly given, we check if it is valid
              # and return nil in case it isn't. Otherwise, we pass the invalid name
              # forward so the underlying router engine treats it and raises an exception.
              if as.nil?
                candidate unless @set.routes.find { |r| r.name == candidate } || candidate !~ /\A[_a-z]/i
              else
                candidate
              end
            end
          end

          def set_member_mappings_for_resource
            member do
              get :edit if parent_resource.actions.include?(:edit)
              get :show if parent_resource.actions.include?(:show)
              if parent_resource.actions.include?(:update)
                patch :update
                put   :update
              end
              delete :destroy if parent_resource.actions.include?(:destroy)
            end
          end
      end

      # Routing Concerns allow you to declare common routes that can be reused
      # inside others resources and routes.
      #
      #   concern :commentable do
      #     resources :comments
      #   end
      #
      #   concern :image_attachable do
      #     resources :images, only: :index
      #   end
      #
      # These concerns are used in Resources routing:
      #
      #   resources :messages, concerns: [:commentable, :image_attachable]
      #
      # or in a scope or namespace:
      #
      #   namespace :posts do
      #     concerns :commentable
      #   end
      module Concerns
        # Define a routing concern using a name.
        #
        # Concerns may be defined inline, using a block, or handled by
        # another object, by passing that object as the second parameter.
        #
        # The concern object, if supplied, should respond to <tt>call</tt>,
        # which will receive two parameters:
        #
        #   * The current mapper
        #   * A hash of options which the concern object may use
        #
        # Options may also be used by concerns defined in a block by accepting
        # a block parameter. So, using a block, you might do something as
        # simple as limit the actions available on certain resources, passing
        # standard resource options through the concern:
        #
        #   concern :commentable do |options|
        #     resources :comments, options
        #   end
        #
        #   resources :posts, concerns: :commentable
        #   resources :archived_posts do
        #     # Don't allow comments on archived posts
        #     concerns :commentable, only: [:index, :show]
        #   end
        #
        # Or, using a callable object, you might implement something more
        # specific to your application, which would be out of place in your
        # routes file.
        #
        #   # purchasable.rb
        #   class Purchasable
        #     def initialize(defaults = {})
        #       @defaults = defaults
        #     end
        #
        #     def call(mapper, options = {})
        #       options = @defaults.merge(options)
        #       mapper.resources :purchases
        #       mapper.resources :receipts
        #       mapper.resources :returns if options[:returnable]
        #     end
        #   end
        #
        #   # routes.rb
        #   concern :purchasable, Purchasable.new(returnable: true)
        #
        #   resources :toys, concerns: :purchasable
        #   resources :electronics, concerns: :purchasable
        #   resources :pets do
        #     concerns :purchasable, returnable: false
        #   end
        #
        # Any routing helpers can be used inside a concern. If using a
        # callable, they're accessible from the Mapper that's passed to
        # <tt>call</tt>.
        def concern(name, callable = nil, &block)
          callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) }
          @concerns[name] = callable
        end

        # Use the named concerns
        #
        #   resources :posts do
        #     concerns :commentable
        #   end
        #
        # concerns also work in any routes helper that you want to use:
        #
        #   namespace :posts do
        #     concerns :commentable
        #   end
        def concerns(*args)
          options = args.extract_options!
          args.flatten.each do |name|
            if concern = @concerns[name]
              concern.call(self, options)
            else
              raise ArgumentError, "No concern named #{name} was found!"
            end
          end
        end
      end

      def initialize(set) #:nodoc:
        @set = set
        @scope = { :path_names => @set.resources_path_names }
        @concerns = {}
      end

      include Base
      include HttpHelpers
      include Redirection
      include Scoping
      include Concerns
      include Resources
    end
  end
end
require 'action_controller/model_naming'

module ActionDispatch
  module Routing
    # Polymorphic URL helpers are methods for smart resolution to a named route call when
    # given an Active Record model instance. They are to be used in combination with
    # ActionController::Resources.
    #
    # These methods are useful when you want to generate correct URL or path to a RESTful
    # resource without having to know the exact type of the record in question.
    #
    # Nested resources and/or namespaces are also supported, as illustrated in the example:
    #
    #   polymorphic_url([:admin, @article, @comment])
    #
    # results in:
    #
    #   admin_article_comment_url(@article, @comment)
    #
    # == Usage within the framework
    #
    # Polymorphic URL helpers are used in a number of places throughout the \Rails framework:
    #
    # * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
    #   <tt>url_for(@article)</tt>;
    # * ActionView::Helpers::FormHelper uses <tt>polymorphic_path</tt>, so you can write
    #   <tt>form_for(@article)</tt> without having to specify <tt>:url</tt> parameter for the form
    #   action;
    # * <tt>redirect_to</tt> (which, in fact, uses <tt>url_for</tt>) so you can write
    #   <tt>redirect_to(post)</tt> in your controllers;
    # * ActionView::Helpers::AtomFeedHelper, so you don't have to explicitly specify URLs
    #   for feed entries.
    #
    # == Prefixed polymorphic helpers
    #
    # In addition to <tt>polymorphic_url</tt> and <tt>polymorphic_path</tt> methods, a
    # number of prefixed helpers are available as a shorthand to <tt>action: "..."</tt>
    # in options. Those are:
    #
    # * <tt>edit_polymorphic_url</tt>, <tt>edit_polymorphic_path</tt>
    # * <tt>new_polymorphic_url</tt>, <tt>new_polymorphic_path</tt>
    #
    # Example usage:
    #
    #   edit_polymorphic_path(@post)              # => "/posts/1/edit"
    #   polymorphic_path(@post, format: :pdf)  # => "/posts/1.pdf"
    #
    # == Usage with mounted engines
    #
    # If you are using a mounted engine and you need to use a polymorphic_url
    # pointing at the engine's routes, pass in the engine's route proxy as the first
    # argument to the method. For example:
    #
    #   polymorphic_url([blog, @post])  # calls blog.post_path(@post)
    #   form_for([blog, @post])         # => "/blog/posts/1"
    #
    module PolymorphicRoutes
      include ActionController::ModelNaming

      # Constructs a call to a named RESTful route for the given record and returns the
      # resulting URL string. For example:
      #
      #   # calls post_url(post)
      #   polymorphic_url(post) # => "http://example.com/posts/1"
      #   polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
      #   polymorphic_url([:admin, blog, post]) # => "http://example.com/admin/blogs/1/posts/1"
      #   polymorphic_url([user, :blog, post]) # => "http://example.com/users/1/blog/posts/1"
      #   polymorphic_url(Comment) # => "http://example.com/comments"
      #
      # ==== Options
      #
      # * <tt>:action</tt> - Specifies the action prefix for the named route:
      #   <tt>:new</tt> or <tt>:edit</tt>. Default is no prefix.
      # * <tt>:routing_type</tt> - Allowed values are <tt>:path</tt> or <tt>:url</tt>.
      #   Default is <tt>:url</tt>.
      #
      #   # an Article record
      #   polymorphic_url(record)  # same as article_url(record)
      #
      #   # a Comment record
      #   polymorphic_url(record)  # same as comment_url(record)
      #
      #   # it recognizes new records and maps to the collection
      #   record = Comment.new
      #   polymorphic_url(record)  # same as comments_url()
      #
      #   # the class of a record will also map to the collection
      #   polymorphic_url(Comment) # same as comments_url()
      #
      def polymorphic_url(record_or_hash_or_array, options = {})
        if record_or_hash_or_array.kind_of?(Array)
          record_or_hash_or_array = record_or_hash_or_array.compact
          if record_or_hash_or_array.first.is_a?(ActionDispatch::Routing::RoutesProxy)
            proxy = record_or_hash_or_array.shift
          end
          record_or_hash_or_array = record_or_hash_or_array[0] if record_or_hash_or_array.size == 1
        end

        record = extract_record(record_or_hash_or_array)
        record = convert_to_model(record)

        args = Array === record_or_hash_or_array ?
          record_or_hash_or_array.dup :
          [ record_or_hash_or_array ]

        inflection = if options[:action] && options[:action].to_s == "new"
          args.pop
          :singular
        elsif (record.respond_to?(:persisted?) && !record.persisted?)
          args.pop
          :plural
        elsif record.is_a?(Class)
          args.pop
          :plural
        else
          :singular
        end

        args.delete_if {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
        named_route = build_named_route_call(record_or_hash_or_array, inflection, options)

        url_options = options.except(:action, :routing_type)
        unless url_options.empty?
          args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
        end

        args.collect! { |a| convert_to_model(a) }

        (proxy || self).send(named_route, *args)
      end

      # Returns the path component of a URL for the given record. It uses
      # <tt>polymorphic_url</tt> with <tt>routing_type: :path</tt>.
      def polymorphic_path(record_or_hash_or_array, options = {})
        polymorphic_url(record_or_hash_or_array, options.merge(:routing_type => :path))
      end

      %w(edit new).each do |action|
        module_eval <<-EOT, __FILE__, __LINE__ + 1
          def #{action}_polymorphic_url(record_or_hash, options = {})         # def edit_polymorphic_url(record_or_hash, options = {})
            polymorphic_url(                                                  #   polymorphic_url(
              record_or_hash,                                                 #     record_or_hash,
              options.merge(:action => "#{action}"))                          #     options.merge(:action => "edit"))
          end                                                                 # end
                                                                              #
          def #{action}_polymorphic_path(record_or_hash, options = {})        # def edit_polymorphic_path(record_or_hash, options = {})
            polymorphic_url(                                                  #   polymorphic_url(
              record_or_hash,                                                 #     record_or_hash,
              options.merge(:action => "#{action}", :routing_type => :path))  #     options.merge(:action => "edit", :routing_type => :path))
          end                                                                 # end
        EOT
      end

      private
        def action_prefix(options)
          options[:action] ? "#{options[:action]}_" : ''
        end

        def routing_type(options)
          options[:routing_type] || :url
        end

        def build_named_route_call(records, inflection, options = {})
          if records.is_a?(Array)
            record = records.pop
            route = records.map do |parent|
              if parent.is_a?(Symbol) || parent.is_a?(String)
                parent
              else
                model_name_from_record_or_class(parent).singular_route_key
              end
            end
          else
            record = extract_record(records)
            route  = []
          end

          if record.is_a?(Symbol) || record.is_a?(String)
            route << record
          elsif record
            if inflection == :singular
              route << model_name_from_record_or_class(record).singular_route_key
            else
              route << model_name_from_record_or_class(record).route_key
            end
          else
            raise ArgumentError, "Nil location provided. Can't build URI."
          end

          route << routing_type(options)

          action_prefix(options) + route.join("_")
        end

        def extract_record(record_or_hash_or_array)
          case record_or_hash_or_array
            when Array; record_or_hash_or_array.last
            when Hash;  record_or_hash_or_array[:id]
            else        record_or_hash_or_array
          end
        end
    end
  end
end

require 'action_dispatch/http/request'
require 'active_support/core_ext/uri'
require 'active_support/core_ext/array/extract_options'
require 'rack/utils'
require 'action_controller/metal/exceptions'

module ActionDispatch
  module Routing
    class Redirect # :nodoc:
      attr_reader :status, :block

      def initialize(status, block)
        @status = status
        @block  = block
      end

      def call(env)
        req = Request.new(env)

        # If any of the path parameters has a invalid encoding then
        # raise since it's likely to trigger errors further on.
        req.symbolized_path_parameters.each do |key, value|
          unless value.valid_encoding?
            raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
          end
        end

        uri = URI.parse(path(req.symbolized_path_parameters, req))
        uri.scheme ||= req.scheme
        uri.host   ||= req.host
        uri.port   ||= req.port unless req.standard_port?

        body = %(<html><body>You are being <a href="#{ERB::Util.h(uri.to_s)}">redirected</a>.</body></html>)

        headers = {
          'Location' => uri.to_s,
          'Content-Type' => 'text/html',
          'Content-Length' => body.length.to_s
        }

        [ status, headers, [body] ]
      end

      def path(params, request)
        block.call params, request
      end

      def inspect
        "redirect(#{status})"
      end
    end

    class PathRedirect < Redirect
      def path(params, request)
        (params.empty? || !block.match(/%\{\w*\}/)) ? block : (block % escape(params))
      end

      def inspect
        "redirect(#{status}, #{block})"
      end

      private
        def escape(params)
          Hash[params.map{ |k,v| [k, Rack::Utils.escape(v)] }]
        end
    end

    class OptionRedirect < Redirect # :nodoc:
      alias :options :block

      def path(params, request)
        url_options = {
          :protocol => request.protocol,
          :host     => request.host,
          :port     => request.optional_port,
          :path     => request.path,
          :params   => request.query_parameters
        }.merge! options

        if !params.empty? && url_options[:path].match(/%\{\w*\}/)
          url_options[:path] = (url_options[:path] % escape_path(params))
        end

        ActionDispatch::Http::URL.url_for url_options
      end

      def inspect
        "redirect(#{status}, #{options.map{ |k,v| "#{k}: #{v}" }.join(', ')})"
      end

      private
        def escape_path(params)
          Hash[params.map{ |k,v| [k, URI.parser.escape(v)] }]
        end
    end

    module Redirection

      # Redirect any path to another path:
      #
      #   get "/stories" => redirect("/posts")
      #
      # You can also use interpolation in the supplied redirect argument:
      #
      #   get 'docs/:article', to: redirect('/wiki/%{article}')
      #
      # Alternatively you can use one of the other syntaxes:
      #
      # The block version of redirect allows for the easy encapsulation of any logic associated with
      # the redirect in question. Either the params and request are supplied as arguments, or just
      # params, depending of how many arguments your block accepts. A string is required as a
      # return value.
      #
      #   get 'jokes/:number', to: redirect { |params, request|
      #     path = (params[:number].to_i.even? ? "wheres-the-beef" : "i-love-lamp")
      #     "http://#{request.host_with_port}/#{path}"
      #   }
      #
      # Note that the +do end+ syntax for the redirect block wouldn't work, as Ruby would pass
      # the block to +get+ instead of +redirect+. Use <tt>{ ... }</tt> instead.
      #
      # The options version of redirect allows you to supply only the parts of the url which need
      # to change, it also supports interpolation of the path similar to the first example.
      #
      #   get 'stores/:name',       to: redirect(subdomain: 'stores', path: '/%{name}')
      #   get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}')
      #
      # Finally, an object which responds to call can be supplied to redirect, allowing you to reuse
      # common redirect routes. The call method must accept two arguments, params and request, and return
      # a string.
      #
      #   get 'accounts/:name' => redirect(SubdomainRedirector.new('api'))
      #
      def redirect(*args, &block)
        options = args.extract_options!
        status  = options.delete(:status) || 301
        path    = args.shift

        return OptionRedirect.new(status, options) if options.any?
        return PathRedirect.new(status, path) if String === path

        block = path if path.respond_to? :call
        raise ArgumentError, "redirection argument not supported" unless block
        Redirect.new status, block
      end
    end
  end
end
require 'action_dispatch/journey'
require 'forwardable'
require 'thread_safe'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/module/remove_method'
require 'active_support/core_ext/array/extract_options'
require 'action_controller/metal/exceptions'

module ActionDispatch
  module Routing
    class RouteSet #:nodoc:
      # Since the router holds references to many parts of the system
      # like engines, controllers and the application itself, inspecting
      # the route set can actually be really slow, therefore we default
      # alias inspect to to_s.
      alias inspect to_s

      PARAMETERS_KEY = 'action_dispatch.request.path_parameters'

      class Dispatcher #:nodoc:
        def initialize(options={})
          @defaults = options[:defaults]
          @glob_param = options.delete(:glob)
          @controller_class_names = ThreadSafe::Cache.new
        end

        def call(env)
          params = env[PARAMETERS_KEY]

          # If any of the path parameters has a invalid encoding then
          # raise since it's likely to trigger errors further on.
          params.each do |key, value|
            unless value.valid_encoding?
              raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
            end
          end

          prepare_params!(params)

          # Just raise undefined constant errors if a controller was specified as default.
          unless controller = controller(params, @defaults.key?(:controller))
            return [404, {'X-Cascade' => 'pass'}, []]
          end

          dispatch(controller, params[:action], env)
        end

        def prepare_params!(params)
          normalize_controller!(params)
          merge_default_action!(params)
          split_glob_param!(params) if @glob_param
        end

        # If this is a default_controller (i.e. a controller specified by the user)
        # we should raise an error in case it's not found, because it usually means
        # a user error. However, if the controller was retrieved through a dynamic
        # segment, as in :controller(/:action), we should simply return nil and
        # delegate the control back to Rack cascade. Besides, if this is not a default
        # controller, it means we should respect the @scope[:module] parameter.
        def controller(params, default_controller=true)
          if params && params.key?(:controller)
            controller_param = params[:controller]
            controller_reference(controller_param)
          end
        rescue NameError => e
          raise ActionController::RoutingError, e.message, e.backtrace if default_controller
        end

      private

        def controller_reference(controller_param)
          const_name = @controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller"
          ActiveSupport::Dependencies.constantize(const_name)
        end

        def dispatch(controller, action, env)
          controller.action(action).call(env)
        end

        def normalize_controller!(params)
          params[:controller] = params[:controller].underscore if params.key?(:controller)
        end

        def merge_default_action!(params)
          params[:action] ||= 'index'
        end

        def split_glob_param!(params)
          params[@glob_param] = params[@glob_param].split('/').map { |v| URI.parser.unescape(v) }
        end
      end

      # A NamedRouteCollection instance is a collection of named routes, and also
      # maintains an anonymous module that can be used to install helpers for the
      # named routes.
      class NamedRouteCollection #:nodoc:
        include Enumerable
        attr_reader :routes, :helpers, :module

        def initialize
          @routes  = {}
          @helpers = []
          @module  = Module.new
        end

        def helper_names
          @helpers.map(&:to_s)
        end

        def clear!
          @helpers.each do |helper|
            @module.remove_possible_method helper
          end

          @routes.clear
          @helpers.clear
        end

        def add(name, route)
          routes[name.to_sym] = route
          define_named_route_methods(name, route)
        end

        def get(name)
          routes[name.to_sym]
        end

        alias []=   add
        alias []    get
        alias clear clear!

        def each
          routes.each { |name, route| yield name, route }
          self
        end

        def names
          routes.keys
        end

        def length
          routes.length
        end

        class UrlHelper # :nodoc:
          def self.create(route, options)
            if optimize_helper?(route)
              OptimizedUrlHelper.new(route, options)
            else
              new route, options
            end
          end

          def self.optimize_helper?(route)
            route.requirements.except(:controller, :action).empty?
          end

          class OptimizedUrlHelper < UrlHelper # :nodoc:
            attr_reader :arg_size

            def initialize(route, options)
              super
              @path_parts   = @route.required_parts
              @arg_size     = @path_parts.size
              @string_route = string_route(route)
            end

            def call(t, args)
              if args.size == arg_size && !args.last.is_a?(Hash) && optimize_routes_generation?(t)
                @options.merge!(t.url_options) if t.respond_to?(:url_options)
                @options[:path] = optimized_helper(args)
                ActionDispatch::Http::URL.url_for(@options)
              else
                super
              end
            end

            private

            def string_route(route)
              string_route = route.ast.to_s.dup
              while string_route.gsub!(/\([^\)]*\)/, "")
                true
              end
              string_route
            end

            def optimized_helper(args)
              path = @string_route.dup
              klass = Journey::Router::Utils

              @path_parts.zip(args) do |part, arg|
                # Replace each route parameter
                # e.g. :id for regular parameter or *path for globbing
                # with ruby string interpolation code
                path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(arg.to_param))
              end
              path
            end

            def optimize_routes_generation?(t)
              t.send(:optimize_routes_generation?)
            end
          end

          def initialize(route, options)
            @options      = options
            @segment_keys = route.segment_keys
            @route        = route
          end

          def call(t, args)
            t.url_for(handle_positional_args(t, args, @options, @segment_keys))
          end

          def handle_positional_args(t, args, options, keys)
            inner_options = args.extract_options!
            result = options.dup

            if args.size > 0
              if args.size < keys.size - 1 # take format into account
                keys -= t.url_options.keys if t.respond_to?(:url_options)
                keys -= options.keys
              end
              result.merge!(Hash[keys.zip(args)])
            end

            result.merge!(inner_options)
          end
        end

        private
        # Create a url helper allowing ordered parameters to be associated
        # with corresponding dynamic segments, so you can do:
        #
        #   foo_url(bar, baz, bang)
        #
        # Instead of:
        #
        #   foo_url(bar: bar, baz: baz, bang: bang)
        #
        # Also allow options hash, so you can do:
        #
        #   foo_url(bar, baz, bang, sort_by: 'baz')
        #
        def define_url_helper(route, name, options)
          helper = UrlHelper.create(route, options.dup)

          @module.remove_possible_method name
          @module.module_eval do
            define_method(name) do |*args|
              helper.call self, args
            end
          end

          helpers << name
        end

        def define_named_route_methods(name, route)
          define_url_helper route, :"#{name}_path",
            route.defaults.merge(:use_route => name, :only_path => true)
          define_url_helper route, :"#{name}_url",
            route.defaults.merge(:use_route => name, :only_path => false)
        end
      end

      attr_accessor :formatter, :set, :named_routes, :default_scope, :router
      attr_accessor :disable_clear_and_finalize, :resources_path_names
      attr_accessor :default_url_options, :request_class

      alias :routes :set

      def self.default_resources_path_names
        { :new => 'new', :edit => 'edit' }
      end

      def initialize(request_class = ActionDispatch::Request)
        self.named_routes = NamedRouteCollection.new
        self.resources_path_names = self.class.default_resources_path_names.dup
        self.default_url_options = {}
        self.request_class = request_class

        @append                     = []
        @prepend                    = []
        @disable_clear_and_finalize = false
        @finalized                  = false

        @set    = Journey::Routes.new
        @router = Journey::Router.new(@set, {
          :parameters_key => PARAMETERS_KEY,
          :request_class  => request_class})
        @formatter = Journey::Formatter.new @set
      end

      def draw(&block)
        clear! unless @disable_clear_and_finalize
        eval_block(block)
        finalize! unless @disable_clear_and_finalize
        nil
      end

      def append(&block)
        @append << block
      end

      def prepend(&block)
        @prepend << block
      end

      def eval_block(block)
        if block.arity == 1
          raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
            "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
        end
        mapper = Mapper.new(self)
        if default_scope
          mapper.with_default_scope(default_scope, &block)
        else
          mapper.instance_exec(&block)
        end
      end

      def finalize!
        return if @finalized
        @append.each { |blk| eval_block(blk) }
        @finalized = true
      end

      def clear!
        @finalized = false
        named_routes.clear
        set.clear
        formatter.clear
        @prepend.each { |blk| eval_block(blk) }
      end

      module MountedHelpers #:nodoc:
        extend ActiveSupport::Concern
        include UrlFor
      end

      # Contains all the mounted helpers accross different
      # engines and the `main_app` helper for the application.
      # You can include this in your classes if you want to
      # access routes for other engines.
      def mounted_helpers
        MountedHelpers
      end

      def define_mounted_helper(name)
        return if MountedHelpers.method_defined?(name)

        routes = self
        MountedHelpers.class_eval do
          define_method "_#{name}" do
            RoutesProxy.new(routes, _routes_context)
          end
        end

        MountedHelpers.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
          def #{name}
            @_#{name} ||= _#{name}
          end
        RUBY
      end

      def url_helpers
        @url_helpers ||= begin
          routes = self

          Module.new do
            extend ActiveSupport::Concern
            include UrlFor

            # Define url_for in the singleton level so one can do:
            # Rails.application.routes.url_helpers.url_for(args)
            @_routes = routes
            class << self
              delegate :url_for, :optimize_routes_generation?, :to => '@_routes'
            end

            # Make named_routes available in the module singleton
            # as well, so one can do:
            # Rails.application.routes.url_helpers.posts_path
            extend routes.named_routes.module

            # Any class that includes this module will get all
            # named routes...
            include routes.named_routes.module

            # plus a singleton class method called _routes ...
            included do
              singleton_class.send(:redefine_method, :_routes) { routes }
            end

            # And an instance method _routes. Note that
            # UrlFor (included in this module) add extra
            # conveniences for working with @_routes.
            define_method(:_routes) { @_routes || routes }
          end
        end
      end

      def empty?
        routes.empty?
      end

      def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
        raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)

        path = build_path(conditions.delete(:path_info), requirements, SEPARATORS, anchor)
        conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })

        route = @set.add_route(app, path, conditions, defaults, name)
        named_routes[name] = route if name && !named_routes[name]
        route
      end

      def build_path(path, requirements, separators, anchor)
        strexp = Journey::Router::Strexp.new(
            path,
            requirements,
            SEPARATORS,
            anchor)

        pattern = Journey::Path::Pattern.new(strexp)

        builder = Journey::GTG::Builder.new pattern.spec

        # Get all the symbol nodes followed by literals that are not the
        # dummy node.
        symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n|
          builder.followpos(n).first.literal?
        }

        # Get all the symbol nodes preceded by literals.
        symbols.concat pattern.spec.find_all(&:literal?).map { |n|
          builder.followpos(n).first
        }.find_all(&:symbol?)

        symbols.each { |x|
          x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/
        }

        pattern
      end
      private :build_path

      def build_conditions(current_conditions, path_values)
        conditions = current_conditions.dup

        # Rack-Mount requires that :request_method be a regular expression.
        # :request_method represents the HTTP verb that matches this route.
        #
        # Here we munge values before they get sent on to rack-mount.
        verbs = conditions[:request_method] || []
        unless verbs.empty?
          conditions[:request_method] = %r[^#{verbs.join('|')}$]
        end

        conditions.keep_if do |k, _|
          k == :action || k == :controller || k == :required_defaults ||
            @request_class.public_method_defined?(k) || path_values.include?(k)
        end
      end
      private :build_conditions

      class Generator #:nodoc:
        PARAMETERIZE = lambda do |name, value|
          if name == :controller
            value
          elsif value.is_a?(Array)
            value.map { |v| v.to_param }.join('/')
          elsif param = value.to_param
            param
          end
        end

        attr_reader :options, :recall, :set, :named_route

        def initialize(options, recall, set)
          @named_route = options.delete(:use_route)
          @options     = options.dup
          @recall      = recall.dup
          @set         = set

          normalize_options!
          normalize_controller_action_id!
          use_relative_controller!
          normalize_controller!
          handle_nil_action!
        end

        def controller
          @options[:controller]
        end

        def current_controller
          @recall[:controller]
        end

        def use_recall_for(key)
          if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
            if !named_route_exists? || segment_keys.include?(key)
              @options[key] = @recall.delete(key)
            end
          end
        end

        def normalize_options!
          # If an explicit :controller was given, always make :action explicit
          # too, so that action expiry works as expected for things like
          #
          #   generate({controller: 'content'}, {controller: 'content', action: 'show'})
          #
          # (the above is from the unit tests). In the above case, because the
          # controller was explicitly given, but no action, the action is implied to
          # be "index", not the recalled action of "show".

          if options[:controller]
            options[:action]     ||= 'index'
            options[:controller]   = options[:controller].to_s
          end

          if options[:action]
            options[:action] = options[:action].to_s
          end
        end

        # This pulls :controller, :action, and :id out of the recall.
        # The recall key is only used if there is no key in the options
        # or if the key in the options is identical. If any of
        # :controller, :action or :id is not found, don't pull any
        # more keys from the recall.
        def normalize_controller_action_id!
          @recall[:action] ||= 'index' if current_controller

          use_recall_for(:controller) or return
          use_recall_for(:action) or return
          use_recall_for(:id)
        end

        # if the current controller is "foo/bar/baz" and controller: "baz/bat"
        # is specified, the controller becomes "foo/baz/bat"
        def use_relative_controller!
          if !named_route && different_controller? && !controller.start_with?("/")
            old_parts = current_controller.split('/')
            size = controller.count("/") + 1
            parts = old_parts[0...-size] << controller
            @options[:controller] = parts.join("/")
          end
        end

        # Remove leading slashes from controllers
        def normalize_controller!
          @options[:controller] = controller.sub(%r{^/}, '') if controller
        end

        # This handles the case of action: nil being explicitly passed.
        # It is identical to action: "index"
        def handle_nil_action!
          if options.has_key?(:action) && options[:action].nil?
            options[:action] = 'index'
          end
          recall[:action] = options.delete(:action) if options[:action] == 'index'
        end

        # Generates a path from routes, returns [path, params].
        # If no route is generated the formatter will raise ActionController::UrlGenerationError
        def generate
          @set.formatter.generate(:path_info, named_route, options, recall, PARAMETERIZE)
        end

        def different_controller?
          return false unless current_controller
          controller.to_param != current_controller.to_param
        end

        private
          def named_route_exists?
            named_route && set.named_routes[named_route]
          end

          def segment_keys
            set.named_routes[named_route].segment_keys
          end
      end

      # Generate the path indicated by the arguments, and return an array of
      # the keys that were not used to generate it.
      def extra_keys(options, recall={})
        generate_extras(options, recall).last
      end

      def generate_extras(options, recall={})
        path, params = generate(options, recall)
        return path, params.keys
      end

      def generate(options, recall = {})
        Generator.new(options, recall, self).generate
      end

      RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
                          :trailing_slash, :anchor, :params, :only_path, :script_name,
                          :original_script_name]

      def mounted?
        false
      end

      def optimize_routes_generation?
        !mounted? && default_url_options.empty?
      end

      def _generate_prefix(options = {})
        nil
      end

      # The +options+ argument must be +nil+ or a hash whose keys are *symbols*.
      def url_for(options)
        options = default_url_options.merge(options || {})

        user, password = extract_authentication(options)
        recall  = options.delete(:_recall)

        original_script_name = options.delete(:original_script_name).presence
        script_name = options.delete(:script_name).presence || _generate_prefix(options)

        if script_name && original_script_name
          script_name = original_script_name + script_name
        end

        path_options = options.except(*RESERVED_OPTIONS)
        path_options = yield(path_options) if block_given?

        path, params = generate(path_options, recall || {})
        params.merge!(options[:params] || {})

        ActionDispatch::Http::URL.url_for(options.merge!({
          :path => path,
          :script_name => script_name,
          :params => params,
          :user => user,
          :password => password
        }))
      end

      def call(env)
        @router.call(env)
      end

      def recognize_path(path, environment = {})
        method = (environment[:method] || "GET").to_s.upcase
        path = Journey::Router::Utils.normalize_path(path) unless path =~ %r{://}
        extras = environment[:extras] || {}

        begin
          env = Rack::MockRequest.env_for(path, {:method => method})
        rescue URI::InvalidURIError => e
          raise ActionController::RoutingError, e.message
        end

        req = @request_class.new(env)
        @router.recognize(req) do |route, matches, params|
          params.merge!(extras)
          params.each do |key, value|
            if value.is_a?(String)
              value = value.dup.force_encoding(Encoding::BINARY)
              params[key] = URI.parser.unescape(value)
            end
          end
          old_params = env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
          env[::ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] = (old_params || {}).merge(params)
          dispatcher = route.app
          while dispatcher.is_a?(Mapper::Constraints) && dispatcher.matches?(env) do
            dispatcher = dispatcher.app
          end

          if dispatcher.is_a?(Dispatcher)
            if dispatcher.controller(params, false)
              dispatcher.prepare_params!(params)
              return params
            else
              raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller"
            end
          end
        end

        raise ActionController::RoutingError, "No route matches #{path.inspect}"
      end

      private

        def extract_authentication(options)
          if options[:user] && options[:password]
            [options.delete(:user), options.delete(:password)]
          else
            nil
          end
        end

    end
  end
end
require 'active_support/core_ext/array/extract_options'

module ActionDispatch
  module Routing
    class RoutesProxy #:nodoc:
      include ActionDispatch::Routing::UrlFor

      attr_accessor :scope, :routes
      alias :_routes :routes

      def initialize(routes, scope)
        @routes, @scope = routes, scope
      end

      def url_options
        scope.send(:_with_routes, routes) do
          scope.url_options
        end
      end

      def respond_to?(method, include_private = false)
        super || routes.url_helpers.respond_to?(method)
      end

      def method_missing(method, *args)
        if routes.url_helpers.respond_to?(method)
          self.class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{method}(*args)
              options = args.extract_options!
              args << url_options.merge((options || {}).symbolize_keys)
              routes.url_helpers.#{method}(*args)
            end
          RUBY
          send(method, *args)
        else
          super
        end
      end
    end
  end
end
module ActionDispatch
  module Routing
    # In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
    # is also possible: an URL can be generated from one of your routing definitions.
    # URL generation functionality is centralized in this module.
    #
    # See ActionDispatch::Routing for general information about routing and routes.rb.
    #
    # <b>Tip:</b> If you need to generate URLs from your models or some other place,
    # then ActionController::UrlFor is what you're looking for. Read on for
    # an introduction. In general, this module should not be included on its own,
    # as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
    #
    # == URL generation from parameters
    #
    # As you may know, some functions, such as ActionController::Base#url_for
    # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
    # of parameters. For example, you've probably had the chance to write code
    # like this in one of your views:
    #
    #   <%= link_to('Click here', controller: 'users',
    #           action: 'new', message: 'Welcome!') %>
    #   # => "/users/new?message=Welcome%21"
    #
    # link_to, and all other functions that require URL generation functionality,
    # actually use ActionController::UrlFor under the hood. And in particular,
    # they use the ActionController::UrlFor#url_for method. One can generate
    # the same path as the above example by using the following code:
    #
    #   include UrlFor
    #   url_for(controller: 'users',
    #           action: 'new',
    #           message: 'Welcome!',
    #           only_path: true)
    #   # => "/users/new?message=Welcome%21"
    #
    # Notice the <tt>only_path: true</tt> part. This is because UrlFor has no
    # information about the website hostname that your Rails app is serving. So if you
    # want to include the hostname as well, then you must also pass the <tt>:host</tt>
    # argument:
    #
    #   include UrlFor
    #   url_for(controller: 'users',
    #           action: 'new',
    #           message: 'Welcome!',
    #           host: 'www.example.com')
    #   # => "http://www.example.com/users/new?message=Welcome%21"
    #
    # By default, all controllers and views have access to a special version of url_for,
    # that already knows what the current hostname is. So if you use url_for in your
    # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
    # argument.
    #
    # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
    # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for'
    # in full. However, mailers don't have hostname information, and that's why you'll still
    # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
    #
    #
    # == URL generation for named routes
    #
    # UrlFor also allows one to access methods that have been auto-generated from
    # named routes. For example, suppose that you have a 'users' resource in your
    # <tt>config/routes.rb</tt>:
    #
    #   resources :users
    #
    # This generates, among other things, the method <tt>users_path</tt>. By default,
    # this method is accessible from your controllers, views and mailers. If you need
    # to access this auto-generated method from other places (such as a model), then
    # you can do that by including Rails.application.routes.url_helpers in your class:
    #
    #   class User < ActiveRecord::Base
    #     include Rails.application.routes.url_helpers
    #
    #     def base_uri
    #       user_path(self)
    #     end
    #   end
    #
    #   User.find(1).base_uri # => "/users/1"
    #
    module UrlFor
      extend ActiveSupport::Concern
      include PolymorphicRoutes

      included do
        unless method_defined?(:default_url_options)
          # Including in a class uses an inheritable hash. Modules get a plain hash.
          if respond_to?(:class_attribute)
            class_attribute :default_url_options
          else
            mattr_writer :default_url_options
          end

          self.default_url_options = {}
        end

        include(*_url_for_modules) if respond_to?(:_url_for_modules)
      end

      def initialize(*)
        @_routes = nil
        super
      end

      # Hook overridden in controller to add request information
      # with `default_url_options`. Application logic should not
      # go into url_options.
      def url_options
        default_url_options
      end

      # Generate a url based on the options provided, default_url_options and the
      # routes defined in routes.rb. The following options are supported:
      #
      # * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
      # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
      # * <tt>:host</tt> - Specifies the host the link should be targeted at.
      #   If <tt>:only_path</tt> is false, this option must be
      #   provided either explicitly, or via +default_url_options+.
      # * <tt>:subdomain</tt> - Specifies the subdomain of the link, using the +tld_length+
      #   to split the subdomain from the host.
      #   If false, removes all subdomains from the host part of the link.
      # * <tt>:domain</tt> - Specifies the domain of the link, using the +tld_length+
      #   to split the domain from the host.
      # * <tt>:tld_length</tt> - Number of labels the TLD id composed of, only used if
      #   <tt>:subdomain</tt> or <tt>:domain</tt> are supplied. Defaults to
      #   <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1.
      # * <tt>:port</tt> - Optionally specify the port to connect to.
      # * <tt>:anchor</tt> - An anchor name to be appended to the path.
      # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
      # * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
      #
      # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
      # +url_for+ is forwarded to the Routes module.
      #
      #    url_for controller: 'tasks', action: 'testing', host: 'somehost.org', port: '8080'
      #    # => 'http://somehost.org:8080/tasks/testing'
      #    url_for controller: 'tasks', action: 'testing', host: 'somehost.org', anchor: 'ok', only_path: true
      #    # => '/tasks/testing#ok'
      #    url_for controller: 'tasks', action: 'testing', trailing_slash: true
      #    # => 'http://somehost.org/tasks/testing/'
      #    url_for controller: 'tasks', action: 'testing', host: 'somehost.org', number: '33'
      #    # => 'http://somehost.org/tasks/testing?number=33'
      #    url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp"
      #    # => 'http://somehost.org/myapp/tasks/testing'
      #    url_for controller: 'tasks', action: 'testing', host: 'somehost.org', script_name: "/myapp", only_path: true
      #    # => '/myapp/tasks/testing'
      def url_for(options = nil)
        case options
        when nil
          _routes.url_for(url_options.symbolize_keys)
        when Hash
          _routes.url_for(options.symbolize_keys.reverse_merge!(url_options))
        when String
          options
        else
          polymorphic_url(options)
        end
      end

      protected

      def optimize_routes_generation?
        return @_optimized_routes if defined?(@_optimized_routes)
        @_optimized_routes = _routes.optimize_routes_generation? && default_url_options.empty?
      end

      def _with_routes(routes)
        old_routes, @_routes = @_routes, routes
        yield
      ensure
        @_routes = old_routes
      end

      def _routes_context
        self
      end
    end
  end
end
# encoding: UTF-8
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/regexp'

module ActionDispatch
  # The routing module provides URL rewriting in native Ruby. It's a way to
  # redirect incoming requests to controllers and actions. This replaces
  # mod_rewrite rules. Best of all, Rails' \Routing works with any web server.
  # Routes are defined in <tt>config/routes.rb</tt>.
  #
  # Think of creating routes as drawing a map for your requests. The map tells
  # them where to go based on some predefined pattern:
  #
  #   AppName::Application.routes.draw do
  #     Pattern 1 tells some request to go to one place
  #     Pattern 2 tell them to go to another
  #     ...
  #   end
  #
  # The following symbols are special:
  #
  #   :controller maps to your controller name
  #   :action     maps to an action with your controllers
  #
  # Other names simply map to a parameter as in the case of <tt>:id</tt>.
  #
  # == Resources
  #
  # Resource routing allows you to quickly declare all of the common routes
  # for a given resourceful controller. Instead of declaring separate routes
  # for your +index+, +show+, +new+, +edit+, +create+, +update+ and +destroy+
  # actions, a resourceful route declares them in a single line of code:
  #
  #  resources :photos
  #
  # Sometimes, you have a resource that clients always look up without
  # referencing an ID. A common example, /profile always shows the profile of
  # the currently logged in user. In this case, you can use a singular resource
  # to map /profile (rather than /profile/:id) to the show action.
  #
  #  resource :profile
  #
  # It's common to have resources that are logically children of other
  # resources:
  #
  #   resources :magazines do
  #     resources :ads
  #   end
  #
  # You may wish to organize groups of controllers under a namespace. Most
  # commonly, you might group a number of administrative controllers under
  # an +admin+ namespace. You would place these controllers under the
  # <tt>app/controllers/admin</tt> directory, and you can group them together
  # in your router:
  #
  #   namespace "admin" do
  #     resources :posts, :comments
  #   end
  #
  # Alternately, you can add prefixes to your path without using a separate
  # directory by using +scope+. +scope+ takes additional options which
  # apply to all enclosed routes.
  #
  #   scope path: "/cpanel", as: 'admin' do
  #     resources :posts, :comments
  #   end
  #
  # For more, see <tt>Routing::Mapper::Resources#resources</tt>,
  # <tt>Routing::Mapper::Scoping#namespace</tt>, and
  # <tt>Routing::Mapper::Scoping#scope</tt>.
  #
  # == Named routes
  #
  # Routes can be named by passing an <tt>:as</tt> option,
  # allowing for easy reference within your source as +name_of_route_url+
  # for the full URL and +name_of_route_path+ for the URI path.
  #
  # Example:
  #
  #   # In routes.rb
  #   match '/login' => 'accounts#login', as: 'login'
  #
  #   # With render, redirect_to, tests, etc.
  #   redirect_to login_url
  #
  # Arguments can be passed as well.
  #
  #   redirect_to show_item_path(id: 25)
  #
  # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
  #
  #   # In routes.rb
  #   root to: 'blogs#index'
  #
  #   # would recognize http://www.example.com/ as
  #   params = { controller: 'blogs', action: 'index' }
  #
  #   # and provide these named routes
  #   root_url   # => 'http://www.example.com/'
  #   root_path  # => '/'
  #
  # Note: when using +controller+, the route is simply named after the
  # method you call on the block parameter rather than map.
  #
  #   # In routes.rb
  #   controller :blog do
  #     match 'blog/show'     => :list
  #     match 'blog/delete'   => :delete
  #     match 'blog/edit/:id' => :edit
  #   end
  #
  #   # provides named routes for show, delete, and edit
  #   link_to @article.title, show_path(id: @article.id)
  #
  # == Pretty URLs
  #
  # Routes can generate pretty URLs. For example:
  #
  #   match '/articles/:year/:month/:day' => 'articles#find_by_id', constraints: {
  #     year:       /\d{4}/,
  #     month:      /\d{1,2}/,
  #     day:        /\d{1,2}/
  #   }
  #
  # Using the route above, the URL "http://localhost:3000/articles/2005/11/06"
  # maps to
  #
  #   params = {year: '2005', month: '11', day: '06'}
  #
  # == Regular Expressions and parameters
  # You can specify a regular expression to define a format for a parameter.
  #
  #   controller 'geocode' do
  #     match 'geocode/:postalcode' => :show, constraints: {
  #       postalcode: /\d{5}(-\d{4})?/
  #     }
  #
  # Constraints can include the 'ignorecase' and 'extended syntax' regular
  # expression modifiers:
  #
  #   controller 'geocode' do
  #     match 'geocode/:postalcode' => :show, constraints: {
  #       postalcode: /hx\d\d\s\d[a-z]{2}/i
  #     }
  #   end
  #
  #   controller 'geocode' do
  #     match 'geocode/:postalcode' => :show, constraints: {
  #       postalcode: /# Postcode format
  #          \d{5} #Prefix
  #          (-\d{4})? #Suffix
  #          /x
  #     }
  #   end
  #
  # Using the multiline match modifier will raise an +ArgumentError+.
  # Encoding regular expression modifiers are silently ignored. The
  # match will always use the default encoding or ASCII.
  #
  # == Default route
  #
  # Consider the following route, which you will find commented out at the
  # bottom of your generated <tt>config/routes.rb</tt>:
  #
  #   match ':controller(/:action(/:id))(.:format)'
  #
  # This route states that it expects requests to consist of a
  # <tt>:controller</tt> followed optionally by an <tt>:action</tt> that in
  # turn is followed optionally by an <tt>:id</tt>, which in turn is followed
  # optionally by a <tt>:format</tt>.
  #
  # Suppose you get an incoming request for <tt>/blog/edit/22</tt>, you'll end
  # up with:
  #
  #   params = { controller: 'blog',
  #              action:     'edit',
  #              id:         '22'
  #           }
  #
  # By not relying on default routes, you improve the security of your
  # application since not all controller actions, which includes actions you
  # might add at a later time, are exposed by default.
  #
  # == HTTP Methods
  #
  # Using the <tt>:via</tt> option when specifying a route allows you to
  # restrict it to a specific HTTP method.  Possible values are <tt>:post</tt>,
  # <tt>:get</tt>, <tt>:patch</tt>, <tt>:put</tt>, <tt>:delete</tt> and
  # <tt>:any</tt>.  If your route needs to respond to more than one method you
  # can use an array, e.g. <tt>[ :get, :post ]</tt>.  The default value is
  # <tt>:any</tt> which means that the route will respond to any of the HTTP
  # methods.
  #
  #   match 'post/:id' => 'posts#show', via: :get
  #   match 'post/:id' => 'posts#create_comment', via: :post
  #
  # Now, if you POST to <tt>/posts/:id</tt>, it will route to the <tt>create_comment</tt> action. A GET on the same
  # URL will route to the <tt>show</tt> action.
  #
  # === HTTP helper methods
  #
  # An alternative method of specifying which HTTP method a route should respond to is to use the helper
  # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
  #
  #   get 'post/:id' => 'posts#show'
  #   post 'post/:id' => 'posts#create_comment'
  #
  # This syntax is less verbose and the intention is more apparent to someone else reading your code,
  # however if your route needs to respond to more than one HTTP method (or all methods) then using the
  # <tt>:via</tt> option on <tt>match</tt> is preferable.
  #
  # == External redirects
  #
  # You can redirect any path to another path using the redirect helper in your router:
  #
  #   match "/stories" => redirect("/posts")
  #
  # == Unicode character routes
  #
  # You can specify unicode character routes in your router:
  #
  #   match "こんにちは" => "welcome#index"
  #
  # == Routing to Rack Applications
  #
  # Instead of a String, like <tt>posts#index</tt>, which corresponds to the
  # index action in the PostsController, you can specify any Rack application
  # as the endpoint for a matcher:
  #
  #   match "/application.js" => Sprockets
  #
  # == Reloading routes
  #
  # You can reload routes if you feel you must:
  #
  #   Rails.application.reload_routes!
  #
  # This will clear all named routes and reload routes.rb if the file has been modified from
  # last load. To absolutely force reloading, use <tt>reload!</tt>.
  #
  # == Testing Routes
  #
  # The two main methods for testing your routes:
  #
  # === +assert_routing+
  #
  #   def test_movie_route_properly_splits
  #    opts = {controller: "plugin", action: "checkout", id: "2"}
  #    assert_routing "plugin/checkout/2", opts
  #   end
  #
  # +assert_routing+ lets you test whether or not the route properly resolves into options.
  #
  # === +assert_recognizes+
  #
  #   def test_route_has_options
  #    opts = {controller: "plugin", action: "show", id: "12"}
  #    assert_recognizes opts, "/plugins/show/12"
  #   end
  #
  # Note the subtle difference between the two: +assert_routing+ tests that
  # a URL fits options while +assert_recognizes+ tests that a URL
  # breaks into parameters properly.
  #
  # In tests you can simply pass the URL or named route to +get+ or +post+.
  #
  #   def send_to_jail
  #     get '/jail'
  #     assert_response :success
  #     assert_template "jail/front"
  #   end
  #
  #   def goes_to_login
  #     get login_url
  #     #...
  #   end
  #
  # == View a list of all your routes
  #
  #   rake routes
  #
  # Target specific controllers by prefixing the command with <tt>CONTROLLER=x</tt>.
  #
  module Routing
    autoload :Mapper, 'action_dispatch/routing/mapper'
    autoload :RouteSet, 'action_dispatch/routing/route_set'
    autoload :RoutesProxy, 'action_dispatch/routing/routes_proxy'
    autoload :UrlFor, 'action_dispatch/routing/url_for'
    autoload :PolymorphicRoutes, 'action_dispatch/routing/polymorphic_routes'

    SEPARATORS = %w( / . ? ) #:nodoc:
    HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
  end
end
require 'action_view/vendor/html-scanner'

module ActionDispatch
  module Assertions
    module DomAssertions
      # \Test two HTML strings for equivalency (e.g., identical up to reordering of attributes)
      #
      #   # assert that the referenced method generates the appropriate HTML string
      #   assert_dom_equal '<a href="http://www.example.com">Apples</a>', link_to("Apples", "http://www.example.com")
      def assert_dom_equal(expected, actual, message = "")
        expected_dom = HTML::Document.new(expected).root
        actual_dom   = HTML::Document.new(actual).root
        assert_equal expected_dom, actual_dom
      end

      # The negated form of +assert_dom_equivalent+.
      #
      #   # assert that the referenced method does not generate the specified HTML string
      #   assert_dom_not_equal '<a href="http://www.example.com">Apples</a>', link_to("Oranges", "http://www.example.com")
      def assert_dom_not_equal(expected, actual, message = "")
        expected_dom = HTML::Document.new(expected).root
        actual_dom   = HTML::Document.new(actual).root
        assert_not_equal expected_dom, actual_dom
      end
    end
  end
end

module ActionDispatch
  module Assertions
    # A small suite of assertions that test responses from \Rails applications.
    module ResponseAssertions
      # Asserts that the response is one of the following types:
      #
      # * <tt>:success</tt>   - Status code was in the 200-299 range
      # * <tt>:redirect</tt>  - Status code was in the 300-399 range
      # * <tt>:missing</tt>   - Status code was 404
      # * <tt>:error</tt>     - Status code was in the 500-599 range
      #
      # You can also pass an explicit status number like <tt>assert_response(501)</tt>
      # or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
      # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
      #
      #   # assert that the response was a redirection
      #   assert_response :redirect
      #
      #   # assert that the response code was status code 401 (unauthorized)
      #   assert_response 401
      def assert_response(type, message = nil)
        message ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>"

        if Symbol === type
          if [:success, :missing, :redirect, :error].include?(type)
            assert @response.send("#{type}?"), message
          else
            code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
            assert_equal code, @response.response_code, message
          end
        else
          assert_equal type, @response.response_code, message
        end
      end

      # Assert that the redirection options passed in match those of the redirect called in the latest action.
      # This match can be partial, such that <tt>assert_redirected_to(controller: "weblog")</tt> will also
      # match the redirection of <tt>redirect_to(controller: "weblog", action: "show")</tt> and so on.
      #
      #   # assert that the redirection was to the "index" action on the WeblogController
      #   assert_redirected_to controller: "weblog", action: "index"
      #
      #   # assert that the redirection was to the named route login_url
      #   assert_redirected_to login_url
      #
      #   # assert that the redirection was to the url for @customer
      #   assert_redirected_to @customer
      #
      #   # asserts that the redirection matches the regular expression
      #   assert_redirected_to %r(\Ahttp://example.org)
      def assert_redirected_to(options = {}, message=nil)
        assert_response(:redirect, message)
        return true if options === @response.location

        redirect_is       = normalize_argument_to_redirection(@response.location)
        redirect_expected = normalize_argument_to_redirection(options)

        message ||= "Expected response to be a redirect to <#{redirect_expected}> but was a redirect to <#{redirect_is}>"
        assert_operator redirect_expected, :===, redirect_is, message
      end

      private
        # Proxy to to_param if the object will respond to it.
        def parameterize(value)
          value.respond_to?(:to_param) ? value.to_param : value
        end

        def normalize_argument_to_redirection(fragment)
          normalized = case fragment
            when Regexp
              fragment
            when %r{^\w[A-Za-z\d+.-]*:.*}
              fragment
            when String
              @request.protocol + @request.host_with_port + fragment
            when :back
              raise RedirectBackError unless refer = @request.headers["Referer"]
              refer
            else
              @controller.url_for(fragment)
            end

          normalized.respond_to?(:delete) ? normalized.delete("\0\r\n") : normalized
        end
    end
  end
end
require 'uri'
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/string/access'
require 'action_controller/metal/exceptions'

module ActionDispatch
  module Assertions
    # Suite of assertions to test routes generated by \Rails and the handling of requests made to them.
    module RoutingAssertions
      # Asserts that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash)
      # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+.
      #
      # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes
      # requiring a specific HTTP method. The hash should contain a :path with the incoming request path
      # and a :method containing the required HTTP verb.
      #
      #   # assert that POSTing to /items will call the create action on ItemsController
      #   assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
      #
      # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
      # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the
      # extras argument, appending the query string on the path directly will not work. For example:
      #
      #   # assert that a path of '/items/list/1?view=print' returns the correct options
      #   assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
      #
      # The +message+ parameter allows you to pass in an error message that is displayed upon failure.
      #
      #   # Check the default route (i.e., the index action)
      #   assert_recognizes({controller: 'items', action: 'index'}, 'items')
      #
      #   # Test a specific action
      #   assert_recognizes({controller: 'items', action: 'list'}, 'items/list')
      #
      #   # Test an action with a parameter
      #   assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1')
      #
      #   # Test a custom route
      #   assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
      def assert_recognizes(expected_options, path, extras={}, msg=nil)
        request = recognized_request_for(path, extras)

        expected_options = expected_options.clone

        expected_options.stringify_keys!

        msg = message(msg, "") {
          sprintf("The recognized options <%s> did not match <%s>, difference:",
                  request.path_parameters, expected_options)
        }

        assert_equal(expected_options, request.path_parameters, msg)
      end

      # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+.
      # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in
      # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures.
      #
      # The +defaults+ parameter is unused.
      #
      #   # Asserts that the default action is generated for a route with no action
      #   assert_generates "/items", controller: "items", action: "index"
      #
      #   # Tests that the list action is properly routed
      #   assert_generates "/items/list", controller: "items", action: "list"
      #
      #   # Tests the generation of a route with a parameter
      #   assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" }
      #
      #   # Asserts that the generated route gives us our custom route
      #   assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" }
      def assert_generates(expected_path, options, defaults={}, extras = {}, message=nil)
        if expected_path =~ %r{://}
          fail_on(URI::InvalidURIError) do
            uri = URI.parse(expected_path)
            expected_path = uri.path.to_s.empty? ? "/" : uri.path
          end
        else
          expected_path = "/#{expected_path}" unless expected_path.first == '/'
        end
        # Load routes.rb if it hasn't been loaded.

        generated_path, extra_keys = @routes.generate_extras(options, defaults)
        found_extras = options.reject {|k, v| ! extra_keys.include? k}

        msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
        assert_equal(extras, found_extras, msg)

        msg = message || sprintf("The generated path <%s> did not match <%s>", generated_path,
            expected_path)
        assert_equal(expected_path, generated_path, msg)
      end

      # Asserts that path and options match both ways; in other words, it verifies that <tt>path</tt> generates
      # <tt>options</tt> and then that <tt>options</tt> generates <tt>path</tt>. This essentially combines +assert_recognizes+
      # and +assert_generates+ into one step.
      #
      # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
      # +message+ parameter allows you to specify a custom error message to display upon failure.
      #
      #  # Assert a basic route: a controller with the default action (index)
      #  assert_routing '/home', controller: 'home', action: 'index'
      #
      #  # Test a route generated with a specific controller, action, and parameter (id)
      #  assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
      #
      #  # Assert a basic route (controller + default action), with an error message if it fails
      #  assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
      #
      #  # Tests a route, providing a defaults hash
      #  assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
      #
      #  # Tests a route with a HTTP method
      #  assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" })
      def assert_routing(path, options, defaults={}, extras={}, message=nil)
        assert_recognizes(options, path, extras, message)

        controller, default_controller = options[:controller], defaults[:controller]
        if controller && controller.include?(?/) && default_controller && default_controller.include?(?/)
          options[:controller] = "/#{controller}"
        end

        generate_options = options.dup.delete_if{ |k,v| defaults.key?(k) }
        assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message)
      end

      # A helper to make it easier to test different route configurations.
      # This method temporarily replaces @routes
      # with a new RouteSet instance.
      #
      # The new instance is yielded to the passed block. Typically the block
      # will create some routes using <tt>set.draw { match ... }</tt>:
      #
      #   with_routing do |set|
      #     set.draw do
      #       resources :users
      #     end
      #     assert_equal "/users", users_path
      #   end
      #
      def with_routing
        old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
        if defined?(@controller) && @controller
          old_controller, @controller = @controller, @controller.clone
          _routes = @routes

          # Unfortunately, there is currently an abstraction leak between AC::Base
          # and AV::Base which requires having the URL helpers in both AC and AV.
          # To do this safely at runtime for tests, we need to bump up the helper serial
          # to that the old AV subclass isn't cached.
          #
          # TODO: Make this unnecessary
          @controller.singleton_class.send(:include, _routes.url_helpers)
          @controller.view_context_class = Class.new(@controller.view_context_class) do
            include _routes.url_helpers
          end
        end
        yield @routes
      ensure
        @routes = old_routes
        if defined?(@controller) && @controller
          @controller = old_controller
        end
      end

      # ROUTES TODO: These assertions should really work in an integration context
      def method_missing(selector, *args, &block)
        if defined?(@controller) && @controller && @routes && @routes.named_routes.helpers.include?(selector)
          @controller.send(selector, *args, &block)
        else
          super
        end
      end

      private
        # Recognizes the route for a given path.
        def recognized_request_for(path, extras = {})
          if path.is_a?(Hash)
            method = path[:method]
            path   = path[:path]
          else
            method = :get
          end

          # Assume given controller
          request = ActionController::TestRequest.new

          if path =~ %r{://}
            fail_on(URI::InvalidURIError) do
              uri = URI.parse(path)
              request.env["rack.url_scheme"] = uri.scheme || "http"
              request.host = uri.host if uri.host
              request.port = uri.port if uri.port
              request.path = uri.path.to_s.empty? ? "/" : uri.path
            end
          else
            path = "/#{path}" unless path.first == "/"
            request.path = path
          end

          request.request_method = method if method

          params = fail_on(ActionController::RoutingError) do
            @routes.recognize_path(path, { :method => method, :extras => extras })
          end
          request.path_parameters = params.with_indifferent_access

          request
        end

        def fail_on(exception_class)
          yield
        rescue exception_class => e
          raise MiniTest::Assertion, e.message
        end
    end
  end
end
require 'action_view/vendor/html-scanner'
require 'active_support/core_ext/object/inclusion'

#--
# Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
# Under MIT and/or CC By license.
#++

module ActionDispatch
  module Assertions
    NO_STRIP = %w{pre script style textarea}

    # Adds the +assert_select+ method for use in Rails functional
    # test cases, which can be used to make assertions on the response HTML of a controller
    # action. You can also call +assert_select+ within another +assert_select+ to
    # make assertions on elements selected by the enclosing assertion.
    #
    # Use +css_select+ to select elements without making an assertions, either
    # from the response HTML or elements selected by the enclosing assertion.
    #
    # In addition to HTML responses, you can make the following assertions:
    #
    # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
    # * +assert_select_email+ - Assertions on the HTML body of an e-mail.
    #
    # Also see HTML::Selector to learn how to use selectors.
    module SelectorAssertions
      # Select and return all matching elements.
      #
      # If called with a single argument, uses that argument as a selector
      # to match all elements of the current page. Returns an empty array
      # if no match is found.
      #
      # If called with two arguments, uses the first argument as the base
      # element and the second argument as the selector. Attempts to match the
      # base element and any of its children. Returns an empty array if no
      # match is found.
      #
      # The selector may be a CSS selector expression (String), an expression
      # with substitution values (Array) or an HTML::Selector object.
      #
      #   # Selects all div tags
      #   divs = css_select("div")
      #
      #   # Selects all paragraph tags and does something interesting
      #   pars = css_select("p")
      #   pars.each do |par|
      #     # Do something fun with paragraphs here...
      #   end
      #
      #   # Selects all list items in unordered lists
      #   items = css_select("ul>li")
      #
      #   # Selects all form tags and then all inputs inside the form
      #   forms = css_select("form")
      #   forms.each do |form|
      #     inputs = css_select(form, "input")
      #     ...
      #   end
      def css_select(*args)
        # See assert_select to understand what's going on here.
        arg = args.shift

        if arg.is_a?(HTML::Node)
          root = arg
          arg = args.shift
        elsif arg == nil
          raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
        elsif defined?(@selected) && @selected
          matches = []

          @selected.each do |selected|
            subset = css_select(selected, HTML::Selector.new(arg.dup, args.dup))
            subset.each do |match|
              matches << match unless matches.any? { |m| m.equal?(match) }
            end
          end

          return matches
        else
          root = response_from_page
        end

        case arg
          when String
            selector = HTML::Selector.new(arg, args)
          when Array
            selector = HTML::Selector.new(*arg)
          when HTML::Selector
            selector = arg
          else raise ArgumentError, "Expecting a selector as the first argument"
        end

        selector.select(root)
      end

      # An assertion that selects elements and makes one or more equality tests.
      #
      # If the first argument is an element, selects all matching elements
      # starting from (and including) that element and all its children in
      # depth-first order.
      #
      # If no element if specified, calling +assert_select+ selects from the
      # response HTML unless +assert_select+ is called from within an +assert_select+ block.
      #
      # When called with a block +assert_select+ passes an array of selected elements
      # to the block. Calling +assert_select+ from the block, with no element specified,
      # runs the assertion on the complete set of elements selected by the enclosing assertion.
      # Alternatively the array may be iterated through so that +assert_select+ can be called
      # separately for each element.
      #
      #
      # ==== Example
      # If the response contains two ordered lists, each with four list elements then:
      #   assert_select "ol" do |elements|
      #     elements.each do |element|
      #       assert_select element, "li", 4
      #     end
      #   end
      #
      # will pass, as will:
      #   assert_select "ol" do
      #     assert_select "li", 8
      #   end
      #
      # The selector may be a CSS selector expression (String), an expression
      # with substitution values, or an HTML::Selector object.
      #
      # === Equality Tests
      #
      # The equality test may be one of the following:
      # * <tt>true</tt> - Assertion is true if at least one element selected.
      # * <tt>false</tt> - Assertion is true if no element selected.
      # * <tt>String/Regexp</tt> - Assertion is true if the text value of at least
      #   one element matches the string or regular expression.
      # * <tt>Integer</tt> - Assertion is true if exactly that number of
      #   elements are selected.
      # * <tt>Range</tt> - Assertion is true if the number of selected
      #   elements fit the range.
      # If no equality test specified, the assertion is true if at least one
      # element selected.
      #
      # To perform more than one equality tests, use a hash with the following keys:
      # * <tt>:text</tt> - Narrow the selection to elements that have this text
      #   value (string or regexp).
      # * <tt>:html</tt> - Narrow the selection to elements that have this HTML
      #   content (string or regexp).
      # * <tt>:count</tt> - Assertion is true if the number of selected elements
      #   is equal to this value.
      # * <tt>:minimum</tt> - Assertion is true if the number of selected
      #   elements is at least this value.
      # * <tt>:maximum</tt> - Assertion is true if the number of selected
      #   elements is at most this value.
      #
      # If the method is called with a block, once all equality tests are
      # evaluated the block is called with an array of all matched elements.
      #
      #   # At least one form element
      #   assert_select "form"
      #
      #   # Form element includes four input fields
      #   assert_select "form input", 4
      #
      #   # Page title is "Welcome"
      #   assert_select "title", "Welcome"
      #
      #   # Page title is "Welcome" and there is only one title element
      #   assert_select "title", {count: 1, text: "Welcome"},
      #       "Wrong title or more than one title element"
      #
      #   # Page contains no forms
      #   assert_select "form", false, "This page must contain no forms"
      #
      #   # Test the content and style
      #   assert_select "body div.header ul.menu"
      #
      #   # Use substitution values
      #   assert_select "ol>li#?", /item-\d+/
      #
      #   # All input fields in the form have a name
      #   assert_select "form input" do
      #     assert_select "[name=?]", /.+/  # Not empty
      #   end
      def assert_select(*args, &block)
        # Start with optional element followed by mandatory selector.
        arg = args.shift
        @selected ||= nil

        if arg.is_a?(HTML::Node)
          # First argument is a node (tag or text, but also HTML root),
          # so we know what we're selecting from.
          root = arg
          arg = args.shift
        elsif arg == nil
          # This usually happens when passing a node/element that
          # happens to be nil.
          raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
        elsif @selected
          root = HTML::Node.new(nil)
          root.children.concat @selected
        else
          # Otherwise just operate on the response document.
          root = response_from_page
        end

        # First or second argument is the selector: string and we pass
        # all remaining arguments. Array and we pass the argument. Also
        # accepts selector itself.
        case arg
          when String
            selector = HTML::Selector.new(arg, args)
          when Array
            selector = HTML::Selector.new(*arg)
          when HTML::Selector
            selector = arg
          else raise ArgumentError, "Expecting a selector as the first argument"
        end

        # Next argument is used for equality tests.
        equals = {}
        case arg = args.shift
          when Hash
            equals = arg
          when String, Regexp
            equals[:text] = arg
          when Integer
            equals[:count] = arg
          when Range
            equals[:minimum] = arg.begin
            equals[:maximum] = arg.end
          when FalseClass
            equals[:count] = 0
          when NilClass, TrueClass
            equals[:minimum] = 1
          else raise ArgumentError, "I don't understand what you're trying to match"
        end

        # By default we're looking for at least one match.
        if equals[:count]
          equals[:minimum] = equals[:maximum] = equals[:count]
        else
          equals[:minimum] = 1 unless equals[:minimum]
        end

        # Last argument is the message we use if the assertion fails.
        message = args.shift
        #- message = "No match made with selector #{selector.inspect}" unless message
        if args.shift
          raise ArgumentError, "Not expecting that last argument, you either have too many arguments, or they're the wrong type"
        end

        matches = selector.select(root)
        # If text/html, narrow down to those elements that match it.
        content_mismatch = nil
        if match_with = equals[:text]
          matches.delete_if do |match|
            text = ""
            stack = match.children.reverse
            while node = stack.pop
              if node.tag?
                stack.concat node.children.reverse
              else
                content = node.content
                text << content
              end
            end
            text.strip! unless NO_STRIP.include?(match.name)
            text.sub!(/\A\n/, '') if match.name == "textarea"
            unless match_with.is_a?(Regexp) ? (text =~ match_with) : (text == match_with.to_s)
              content_mismatch ||= sprintf("<%s> expected but was\n<%s>.", match_with, text)
              true
            end
          end
        elsif match_with = equals[:html]
          matches.delete_if do |match|
            html = match.children.map(&:to_s).join
            html.strip! unless NO_STRIP.include?(match.name)
            unless match_with.is_a?(Regexp) ? (html =~ match_with) : (html == match_with.to_s)
              content_mismatch ||= sprintf("<%s> expected but was\n<%s>.", match_with, html)
              true
            end
          end
        end
        # Expecting foo found bar element only if found zero, not if
        # found one but expecting two.
        message ||= content_mismatch if matches.empty?
        # Test minimum/maximum occurrence.
        min, max, count = equals[:minimum], equals[:maximum], equals[:count]

        # FIXME: minitest provides messaging when we use assert_operator,
        # so is this custom message really needed?
        message = message || %(Expected #{count_description(min, max, count)} matching "#{selector.to_s}", found #{matches.size}.)
        if count
          assert_equal matches.size, count, message
        else
          assert_operator matches.size, :>=, min, message if min
          assert_operator matches.size, :<=, max, message if max
        end

        # If a block is given call that block. Set @selected to allow
        # nested assert_select, which can be nested several levels deep.
        if block_given? && !matches.empty?
          begin
            in_scope, @selected = @selected, matches
            yield matches
          ensure
            @selected = in_scope
          end
        end

        # Returns all matches elements.
        matches
      end

      def count_description(min, max, count) #:nodoc:
        pluralize = lambda {|word, quantity| word << (quantity == 1 ? '' : 's')}

        if min && max && (max != min)
          "between #{min} and #{max} elements"
        elsif min && max && max == min && count
          "exactly #{count} #{pluralize['element', min]}"
        elsif min && !(min == 1 && max == 1)
          "at least #{min} #{pluralize['element', min]}"
        elsif max
          "at most #{max} #{pluralize['element', max]}"
        end
      end

      # Extracts the content of an element, treats it as encoded HTML and runs
      # nested assertion on it.
      #
      # You typically call this method within another assertion to operate on
      # all currently selected elements. You can also pass an element or array
      # of elements.
      #
      # The content of each element is un-encoded, and wrapped in the root
      # element +encoded+. It then calls the block with all un-encoded elements.
      #
      #   # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix)
      #   assert_select "feed[xmlns='http://www.w3.org/2005/Atom']" do
      #     # Select each entry item and then the title item
      #     assert_select "entry>title" do
      #       # Run assertions on the encoded title elements
      #       assert_select_encoded do
      #         assert_select "b"
      #       end
      #     end
      #   end
      #
      #
      #   # Selects all paragraph tags from within the description of an RSS feed
      #   assert_select "rss[version=2.0]" do
      #     # Select description element of each feed item.
      #     assert_select "channel>item>description" do
      #       # Run assertions on the encoded elements.
      #       assert_select_encoded do
      #         assert_select "p"
      #       end
      #     end
      #   end
      def assert_select_encoded(element = nil, &block)
        case element
          when Array
            elements = element
          when HTML::Node
            elements = [element]
          when nil
            unless elements = @selected
              raise ArgumentError, "First argument is optional, but must be called from a nested assert_select"
            end
          else
            raise ArgumentError, "Argument is optional, and may be node or array of nodes"
        end

        fix_content = lambda do |node|
          # Gets around a bug in the Rails 1.1 HTML parser.
          node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) }
        end

        selected = elements.map do |_element|
          text = _element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
          root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root
          css_select(root, "encoded:root", &block)[0]
        end

        begin
          old_selected, @selected = @selected, selected
          assert_select ":root", &block
        ensure
          @selected = old_selected
        end
      end

      # Extracts the body of an email and runs nested assertions on it.
      #
      # You must enable deliveries for this assertion to work, use:
      #   ActionMailer::Base.perform_deliveries = true
      #
      #  assert_select_email do
      #    assert_select "h1", "Email alert"
      #  end
      #
      #  assert_select_email do
      #    items = assert_select "ol>li"
      #    items.each do
      #       # Work with items here...
      #    end
      #  end
      def assert_select_email(&block)
        deliveries = ActionMailer::Base.deliveries
        assert !deliveries.empty?, "No e-mail in delivery list"

        deliveries.each do |delivery|
          (delivery.parts.empty? ? [delivery] : delivery.parts).each do |part|
            if part["Content-Type"].to_s =~ /^text\/html\W/
              root = HTML::Document.new(part.body.to_s).root
              assert_select root, ":root", &block
            end
          end
        end
      end

      protected
        # +assert_select+ and +css_select+ call this to obtain the content in the HTML page.
        def response_from_page
          html_document.root
        end
    end
  end
end
require 'action_view/vendor/html-scanner'

module ActionDispatch
  module Assertions
    # Pair of assertions to testing elements in the HTML output of the response.
    module TagAssertions
      # Asserts that there is a tag/node/element in the body of the response
      # that meets all of the given conditions. The +conditions+ parameter must
      # be a hash of any of the following keys (all are optional):
      #
      # * <tt>:tag</tt>: the node type must match the corresponding value
      # * <tt>:attributes</tt>: a hash. The node's attributes must match the
      #   corresponding values in the hash.
      # * <tt>:parent</tt>: a hash. The node's parent must match the
      #   corresponding hash.
      # * <tt>:child</tt>: a hash. At least one of the node's immediate children
      #   must meet the criteria described by the hash.
      # * <tt>:ancestor</tt>: a hash. At least one of the node's ancestors must
      #   meet the criteria described by the hash.
      # * <tt>:descendant</tt>: a hash. At least one of the node's descendants
      #   must meet the criteria described by the hash.
      # * <tt>:sibling</tt>: a hash. At least one of the node's siblings must
      #   meet the criteria described by the hash.
      # * <tt>:after</tt>: a hash. The node must be after any sibling meeting
      #   the criteria described by the hash, and at least one sibling must match.
      # * <tt>:before</tt>: a hash. The node must be before any sibling meeting
      #   the criteria described by the hash, and at least one sibling must match.
      # * <tt>:children</tt>: a hash, for counting children of a node. Accepts
      #   the keys:
      #   * <tt>:count</tt>: either a number or a range which must equal (or
      #     include) the number of children that match.
      #   * <tt>:less_than</tt>: the number of matching children must be less
      #     than this number.
      #   * <tt>:greater_than</tt>: the number of matching children must be
      #     greater than this number.
      #   * <tt>:only</tt>: another hash consisting of the keys to use
      #     to match on the children, and only matching children will be
      #     counted.
      # * <tt>:content</tt>: the textual content of the node must match the
      #   given value. This will not match HTML tags in the body of a
      #   tag--only text.
      #
      # Conditions are matched using the following algorithm:
      #
      # * if the condition is a string, it must be a substring of the value.
      # * if the condition is a regexp, it must match the value.
      # * if the condition is a number, the value must match number.to_s.
      # * if the condition is +true+, the value must not be +nil+.
      # * if the condition is +false+ or +nil+, the value must be +nil+.
      #
      #   # Assert that there is a "span" tag
      #   assert_tag tag: "span"
      #
      #   # Assert that there is a "span" tag with id="x"
      #   assert_tag tag: "span", attributes: { id: "x" }
      #
      #   # Assert that there is a "span" tag using the short-hand
      #   assert_tag :span
      #
      #   # Assert that there is a "span" tag with id="x" using the short-hand
      #   assert_tag :span, attributes: { id: "x" }
      #
      #   # Assert that there is a "span" inside of a "div"
      #   assert_tag tag: "span", parent: { tag: "div" }
      #
      #   # Assert that there is a "span" somewhere inside a table
      #   assert_tag tag: "span", ancestor: { tag: "table" }
      #
      #   # Assert that there is a "span" with at least one "em" child
      #   assert_tag tag: "span", child: { tag: "em" }
      #
      #   # Assert that there is a "span" containing a (possibly nested)
      #   # "strong" tag.
      #   assert_tag tag: "span", descendant: { tag: "strong" }
      #
      #   # Assert that there is a "span" containing between 2 and 4 "em" tags
      #   # as immediate children
      #   assert_tag tag: "span",
      #              children: { count: 2..4, only: { tag: "em" } }
      #
      #   # Get funky: assert that there is a "div", with an "ul" ancestor
      #   # and an "li" parent (with "class" = "enum"), and containing a
      #   # "span" descendant that contains text matching /hello world/
      #   assert_tag tag: "div",
      #              ancestor: { tag: "ul" },
      #              parent: { tag: "li",
      #                           attributes: { class: "enum" } },
      #              descendant: { tag: "span",
      #                               child: /hello world/ }
      #
      # <b>Please note</b>: +assert_tag+ and +assert_no_tag+ only work
      # with well-formed XHTML. They recognize a few tags as implicitly self-closing
      # (like br and hr and such) but will not work correctly with tags
      # that allow optional closing tags (p, li, td). <em>You must explicitly
      # close all of your tags to use these assertions.</em>
      def assert_tag(*opts)
        opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first
        tag = find_tag(opts)
        assert tag, "expected tag, but no tag found matching #{opts.inspect} in:\n#{@response.body.inspect}"
      end

      # Identical to +assert_tag+, but asserts that a matching tag does _not_
      # exist. (See +assert_tag+ for a full discussion of the syntax.)
      #
      #   # Assert that there is not a "div" containing a "p"
      #   assert_no_tag tag: "div", descendant: { tag: "p" }
      #
      #   # Assert that an unordered list is empty
      #   assert_no_tag tag: "ul", descendant: { tag: "li" }
      #
      #   # Assert that there is not a "p" tag with between 1 to 3 "img" tags
      #   # as immediate children
      #   assert_no_tag tag: "p",
      #              children: { count: 1..3, only: { tag: "img" } }
      def assert_no_tag(*opts)
        opts = opts.size > 1 ? opts.last.merge({ :tag => opts.first.to_s }) : opts.first
        tag = find_tag(opts)
        assert !tag, "expected no tag, but found tag matching #{opts.inspect} in:\n#{@response.body.inspect}"
      end

      def find_tag(conditions)
        html_document.find(conditions)
      end

      def find_all_tag(conditions)
        html_document.find_all(conditions)
      end

      def html_document
        xml = @response.content_type =~ /xml$/
        @html_document ||= HTML::Document.new(@response.body, false, xml)
      end
    end
  end
end
module ActionDispatch
  module Assertions
    autoload :DomAssertions, 'action_dispatch/testing/assertions/dom'
    autoload :ResponseAssertions, 'action_dispatch/testing/assertions/response'
    autoload :RoutingAssertions, 'action_dispatch/testing/assertions/routing'
    autoload :SelectorAssertions, 'action_dispatch/testing/assertions/selector'
    autoload :TagAssertions, 'action_dispatch/testing/assertions/tag'

    extend ActiveSupport::Concern

    include DomAssertions
    include ResponseAssertions
    include RoutingAssertions
    include SelectorAssertions
    include TagAssertions
  end
end

require 'stringio'
require 'uri'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/object/try'
require 'rack/test'
require 'minitest/unit'

module ActionDispatch
  module Integration #:nodoc:
    module RequestHelpers
      # Performs a GET request with the given parameters.
      #
      # - +path+: The URI (as a String) on which you want to perform a GET
      #   request.
      # - +parameters+: The HTTP parameters that you want to pass. This may
      #   be +nil+,
      #   a Hash, or a String that is appropriately encoded
      #   (<tt>application/x-www-form-urlencoded</tt> or
      #   <tt>multipart/form-data</tt>).
      # - +headers+: Additional headers to pass, as a Hash. The headers will be
      #   merged into the Rack env hash.
      #
      # This method returns a Response object, which one can use to
      # inspect the details of the response. Furthermore, if this method was
      # called from an ActionDispatch::IntegrationTest object, then that
      # object's <tt>@response</tt> instance variable will point to the same
      # response object.
      #
      # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with
      # +#post+, +#patch+, +#put+, +#delete+, and +#head+.
      def get(path, parameters = nil, headers = nil)
        process :get, path, parameters, headers
      end

      # Performs a POST request with the given parameters. See +#get+ for more
      # details.
      def post(path, parameters = nil, headers = nil)
        process :post, path, parameters, headers
      end

      # Performs a PATCH request with the given parameters. See +#get+ for more
      # details.
      def patch(path, parameters = nil, headers = nil)
        process :patch, path, parameters, headers
      end

      # Performs a PUT request with the given parameters. See +#get+ for more
      # details.
      def put(path, parameters = nil, headers = nil)
        process :put, path, parameters, headers
      end

      # Performs a DELETE request with the given parameters. See +#get+ for
      # more details.
      def delete(path, parameters = nil, headers = nil)
        process :delete, path, parameters, headers
      end

      # Performs a HEAD request with the given parameters. See +#get+ for more
      # details.
      def head(path, parameters = nil, headers = nil)
        process :head, path, parameters, headers
      end

      # Performs a OPTIONS request with the given parameters. See +#get+ for
      # more details.
      def options(path, parameters = nil, headers = nil)
        process :options, path, parameters, headers
      end

      # Performs an XMLHttpRequest request with the given parameters, mirroring
      # a request from the Prototype library.
      #
      # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
      # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
      # string; the headers are a hash.
      def xml_http_request(request_method, path, parameters = nil, headers = nil)
        headers ||= {}
        headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
        headers['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
        process(request_method, path, parameters, headers)
      end
      alias xhr :xml_http_request

      # Follow a single redirect response. If the last response was not a
      # redirect, an exception will be raised. Otherwise, the redirect is
      # performed on the location header.
      def follow_redirect!
        raise "not a redirect! #{status} #{status_message}" unless redirect?
        get(response.location)
        status
      end

      # Performs a request using the specified method, following any subsequent
      # redirect. Note that the redirects are followed until the response is
      # not a redirect--this means you may run into an infinite loop if your
      # redirect loops back to itself.
      def request_via_redirect(http_method, path, parameters = nil, headers = nil)
        process(http_method, path, parameters, headers)
        follow_redirect! while redirect?
        status
      end

      # Performs a GET request, following any subsequent redirect.
      # See +request_via_redirect+ for more information.
      def get_via_redirect(path, parameters = nil, headers = nil)
        request_via_redirect(:get, path, parameters, headers)
      end

      # Performs a POST request, following any subsequent redirect.
      # See +request_via_redirect+ for more information.
      def post_via_redirect(path, parameters = nil, headers = nil)
        request_via_redirect(:post, path, parameters, headers)
      end

      # Performs a PATCH request, following any subsequent redirect.
      # See +request_via_redirect+ for more information.
      def patch_via_redirect(path, parameters = nil, headers = nil)
        request_via_redirect(:patch, path, parameters, headers)
      end

      # Performs a PUT request, following any subsequent redirect.
      # See +request_via_redirect+ for more information.
      def put_via_redirect(path, parameters = nil, headers = nil)
        request_via_redirect(:put, path, parameters, headers)
      end

      # Performs a DELETE request, following any subsequent redirect.
      # See +request_via_redirect+ for more information.
      def delete_via_redirect(path, parameters = nil, headers = nil)
        request_via_redirect(:delete, path, parameters, headers)
      end
    end

    # An instance of this class represents a set of requests and responses
    # performed sequentially by a test process. Because you can instantiate
    # multiple sessions and run them side-by-side, you can also mimic (to some
    # limited extent) multiple simultaneous users interacting with your system.
    #
    # Typically, you will instantiate a new session using
    # IntegrationTest#open_session, rather than instantiating
    # Integration::Session directly.
    class Session
      DEFAULT_HOST = "www.example.com"

      include MiniTest::Assertions
      include TestProcess, RequestHelpers, Assertions

      %w( status status_message headers body redirect? ).each do |method|
        delegate method, :to => :response, :allow_nil => true
      end

      %w( path ).each do |method|
        delegate method, :to => :request, :allow_nil => true
      end

      # The hostname used in the last request.
      def host
        @host || DEFAULT_HOST
      end
      attr_writer :host

      # The remote_addr used in the last request.
      attr_accessor :remote_addr

      # The Accept header to send.
      attr_accessor :accept

      # A map of the cookies returned by the last response, and which will be
      # sent with the next request.
      def cookies
        _mock_session.cookie_jar
      end

      # A reference to the controller instance used by the last request.
      attr_reader :controller

      # A reference to the request instance used by the last request.
      attr_reader :request

      # A reference to the response instance used by the last request.
      attr_reader :response

      # A running counter of the number of requests processed.
      attr_accessor :request_count

      include ActionDispatch::Routing::UrlFor

      # Create and initialize a new Session instance.
      def initialize(app)
        super()
        @app = app

        # If the app is a Rails app, make url_helpers available on the session
        # This makes app.url_for and app.foo_path available in the console
        if app.respond_to?(:routes)
          singleton_class.class_eval do
            include app.routes.url_helpers if app.routes.respond_to?(:url_helpers)
            include app.routes.mounted_helpers if app.routes.respond_to?(:mounted_helpers)
          end
        end

        reset!
      end

      def url_options
        @url_options ||= default_url_options.dup.tap do |url_options|
          url_options.reverse_merge!(controller.url_options) if controller

          if @app.respond_to?(:routes) && @app.routes.respond_to?(:default_url_options)
            url_options.reverse_merge!(@app.routes.default_url_options)
          end

          url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http")
        end
      end

      # Resets the instance. This can be used to reset the state information
      # in an existing session instance, so it can be used from a clean-slate
      # condition.
      #
      #   session.reset!
      def reset!
        @https = false
        @controller = @request = @response = nil
        @_mock_session = nil
        @request_count = 0
        @url_options = nil

        self.host        = DEFAULT_HOST
        self.remote_addr = "127.0.0.1"
        self.accept      = "text/xml,application/xml,application/xhtml+xml," +
                           "text/html;q=0.9,text/plain;q=0.8,image/png," +
                           "*/*;q=0.5"

        unless defined? @named_routes_configured
          # the helpers are made protected by default--we make them public for
          # easier access during testing and troubleshooting.
          @named_routes_configured = true
        end
      end

      # Specify whether or not the session should mimic a secure HTTPS request.
      #
      #   session.https!
      #   session.https!(false)
      def https!(flag = true)
        @https = flag
      end

      # Return +true+ if the session is mimicking a secure HTTPS request.
      #
      #   if session.https?
      #     ...
      #   end
      def https?
        @https
      end

      # Set the host name to use in the next request.
      #
      #   session.host! "www.example.com"
      alias :host! :host=

      private
        def _mock_session
          @_mock_session ||= Rack::MockSession.new(@app, host)
        end

        # Performs the actual request.
        def process(method, path, parameters = nil, rack_env = nil)
          rack_env ||= {}
          if path =~ %r{://}
            location = URI.parse(path)
            https! URI::HTTPS === location if location.scheme
            host! "#{location.host}:#{location.port}" if location.host
            path = location.query ? "#{location.path}?#{location.query}" : location.path
          end

          unless ActionController::Base < ActionController::Testing
            ActionController::Base.class_eval do
              include ActionController::Testing
            end
          end

          hostname, port = host.split(':')

          env = {
            :method => method,
            :params => parameters,

            "SERVER_NAME"     => hostname,
            "SERVER_PORT"     => port || (https? ? "443" : "80"),
            "HTTPS"           => https? ? "on" : "off",
            "rack.url_scheme" => https? ? "https" : "http",

            "REQUEST_URI"    => path,
            "HTTP_HOST"      => host,
            "REMOTE_ADDR"    => remote_addr,
            "CONTENT_TYPE"   => "application/x-www-form-urlencoded",
            "HTTP_ACCEPT"    => accept
          }

          session = Rack::Test::Session.new(_mock_session)

          env.merge!(rack_env)

          # NOTE: rack-test v0.5 doesn't build a default uri correctly
          # Make sure requested path is always a full uri
          uri = URI.parse('/')
          uri.scheme ||= env['rack.url_scheme']
          uri.host   ||= env['SERVER_NAME']
          uri.port   ||= env['SERVER_PORT'].try(:to_i)
          uri += path

          session.request(uri.to_s, env)

          @request_count += 1
          @request  = ActionDispatch::Request.new(session.last_request.env)
          response = _mock_session.last_response
          @response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body)
          @html_document = nil
          @url_options = nil

          @controller = session.last_request.env['action_controller.instance']

          return response.status
        end
    end

    module Runner
      include ActionDispatch::Assertions

      def app
        @app ||= nil
      end

      # Reset the current session. This is useful for testing multiple sessions
      # in a single test case.
      def reset!
        @integration_session = Integration::Session.new(app)
      end

      %w(get post patch put head delete options cookies assigns
         xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
        define_method(method) do |*args|
          reset! unless integration_session
          # reset the html_document variable, but only for new get/post calls
          @html_document = nil unless method == 'cookies' || method == 'assigns'
          integration_session.__send__(method, *args).tap do
            copy_session_variables!
          end
        end
      end

      # Open a new session instance. If a block is given, the new session is
      # yielded to the block before being returned.
      #
      #   session = open_session do |sess|
      #     sess.extend(CustomAssertions)
      #   end
      #
      # By default, a single session is automatically created for you, but you
      # can use this method to open multiple sessions that ought to be tested
      # simultaneously.
      def open_session(app = nil)
        dup.tap do |session|
          yield session if block_given?
        end
      end

      # Copy the instance variables from the current session instance into the
      # test instance.
      def copy_session_variables! #:nodoc:
        return unless integration_session
        %w(controller response request).each do |var|
          instance_variable_set("@#{var}", @integration_session.__send__(var))
        end
      end

      def default_url_options
        reset! unless integration_session
        integration_session.default_url_options
      end

      def default_url_options=(options)
        reset! unless integration_session
        integration_session.default_url_options = options
      end

      def respond_to?(method, include_private = false)
        integration_session.respond_to?(method, include_private) || super
      end

      # Delegate unhandled messages to the current session instance.
      def method_missing(sym, *args, &block)
        reset! unless integration_session
        if integration_session.respond_to?(sym)
          integration_session.__send__(sym, *args, &block).tap do
            copy_session_variables!
          end
        else
          super
        end
      end

      private
        def integration_session
          @integration_session ||= nil
        end
    end
  end

  # An integration test spans multiple controllers and actions,
  # tying them all together to ensure they work together as expected. It tests
  # more completely than either unit or functional tests do, exercising the
  # entire stack, from the dispatcher to the database.
  #
  # At its simplest, you simply extend <tt>IntegrationTest</tt> and write your tests
  # using the get/post methods:
  #
  #   require "test_helper"
  #
  #   class ExampleTest < ActionDispatch::IntegrationTest
  #     fixtures :people
  #
  #     def test_login
  #       # get the login page
  #       get "/login"
  #       assert_equal 200, status
  #
  #       # post the login and follow through to the home page
  #       post "/login", username: people(:jamis).username,
  #         password: people(:jamis).password
  #       follow_redirect!
  #       assert_equal 200, status
  #       assert_equal "/home", path
  #     end
  #   end
  #
  # However, you can also have multiple session instances open per test, and
  # even extend those instances with assertions and methods to create a very
  # powerful testing DSL that is specific for your application. You can even
  # reference any named routes you happen to have defined.
  #
  #   require "test_helper"
  #
  #   class AdvancedTest < ActionDispatch::IntegrationTest
  #     fixtures :people, :rooms
  #
  #     def test_login_and_speak
  #       jamis, david = login(:jamis), login(:david)
  #       room = rooms(:office)
  #
  #       jamis.enter(room)
  #       jamis.speak(room, "anybody home?")
  #
  #       david.enter(room)
  #       david.speak(room, "hello!")
  #     end
  #
  #     private
  #
  #       module CustomAssertions
  #         def enter(room)
  #           # reference a named route, for maximum internal consistency!
  #           get(room_url(id: room.id))
  #           assert(...)
  #           ...
  #         end
  #
  #         def speak(room, message)
  #           xml_http_request "/say/#{room.id}", message: message
  #           assert(...)
  #           ...
  #         end
  #       end
  #
  #       def login(who)
  #         open_session do |sess|
  #           sess.extend(CustomAssertions)
  #           who = people(who)
  #           sess.post "/login", username: who.username,
  #             password: who.password
  #           assert(...)
  #         end
  #       end
  #   end
  class IntegrationTest < ActiveSupport::TestCase
    include Integration::Runner
    include ActionController::TemplateAssertions
    include ActionDispatch::Routing::UrlFor

    @@app = nil

    def self.app
      if !@@app && !ActionDispatch.test_app
        ActiveSupport::Deprecation.warn "Rails application fallback is deprecated and no longer works, please set ActionDispatch.test_app"
      end

      @@app || ActionDispatch.test_app
    end

    def self.app=(app)
      @@app = app
    end

    def app
      super || self.class.app
    end

    def url_options
      reset! unless integration_session
      integration_session.url_options
    end
  end
end
require 'action_dispatch/middleware/cookies'
require 'action_dispatch/middleware/flash'
require 'active_support/core_ext/hash/indifferent_access'

module ActionDispatch
  module TestProcess
    def assigns(key = nil)
      assigns = {}.with_indifferent_access
      @controller.view_assigns.each {|k, v| assigns.regular_writer(k, v)}
      key.nil? ? assigns : assigns[key]
    end

    def session
      @request.session
    end

    def flash
      @request.flash
    end

    def cookies
      @request.cookie_jar
    end

    def redirect_to_url
      @response.redirect_url
    end

    # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionController::TestCase.fixture_path, path), type)</tt>:
    #
    #   post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png')
    #
    # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
    # This will not affect other platforms:
    #
    #   post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary)
    def fixture_file_upload(path, mime_type = nil, binary = false)
      if self.class.respond_to?(:fixture_path) && self.class.fixture_path
        path = File.join(self.class.fixture_path, path)
      end
      Rack::Test::UploadedFile.new(path, mime_type, binary)
    end
  end
end
require 'active_support/core_ext/hash/indifferent_access'
require 'rack/utils'

module ActionDispatch
  class TestRequest < Request
    DEFAULT_ENV = Rack::MockRequest.env_for('/')

    def self.new(env = {})
      super
    end

    def initialize(env = {})
      env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application
      super(default_env.merge(env))

      self.host        = 'test.host'
      self.remote_addr = '0.0.0.0'
      self.user_agent  = 'Rails Testing'
    end

    def request_method=(method)
      @env['REQUEST_METHOD'] = method.to_s.upcase
    end

    def host=(host)
      @env['HTTP_HOST'] = host
    end

    def port=(number)
      @env['SERVER_PORT'] = number.to_i
    end

    def request_uri=(uri)
      @env['REQUEST_URI'] = uri
    end

    def path=(path)
      @env['PATH_INFO'] = path
    end

    def action=(action_name)
      path_parameters["action"] = action_name.to_s
    end

    def if_modified_since=(last_modified)
      @env['HTTP_IF_MODIFIED_SINCE'] = last_modified
    end

    def if_none_match=(etag)
      @env['HTTP_IF_NONE_MATCH'] = etag
    end

    def remote_addr=(addr)
      @env['REMOTE_ADDR'] = addr
    end

    def user_agent=(user_agent)
      @env['HTTP_USER_AGENT'] = user_agent
    end

    def accept=(mime_types)
      @env.delete('action_dispatch.request.accepts')
      @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",")
    end

    alias :rack_cookies :cookies

    def cookies
      @cookies ||= {}.with_indifferent_access
    end

    private

    def default_env
      DEFAULT_ENV
    end
  end
end
module ActionDispatch
  # Integration test methods such as ActionDispatch::Integration::Session#get
  # and ActionDispatch::Integration::Session#post return objects of class
  # TestResponse, which represent the HTTP response results of the requested
  # controller actions.
  #
  # See Response for more information on controller response objects.
  class TestResponse < Response
    def self.from_response(response)
      new.tap do |resp|
        resp.status  = response.status
        resp.headers = response.headers
        resp.body    = response.body
      end
    end

    # Was the response successful?
    alias_method :success?, :successful?

    # Was the URL not found?
    alias_method :missing?, :not_found?

    # Were we redirected?
    alias_method :redirect?, :redirection?

    # Was there a server-side error?
    alias_method :error?, :server_error?
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'active_support'
require 'active_support/rails'
require 'active_support/core_ext/module/attribute_accessors'

require 'action_pack'
require 'rack'

module Rack
  autoload :Test, 'rack/test'
end

module ActionDispatch
  extend ActiveSupport::Autoload

  class IllegalStateError < StandardError
  end

  eager_autoload do
    autoload_under 'http' do
      autoload :Request
      autoload :Response
    end
  end

  autoload_under 'middleware' do
    autoload :RequestId
    autoload :Callbacks
    autoload :Cookies
    autoload :DebugExceptions
    autoload :ExceptionWrapper
    autoload :Flash
    autoload :Head
    autoload :ParamsParser
    autoload :PublicExceptions
    autoload :Reloader
    autoload :RemoteIp
    autoload :ShowExceptions
    autoload :SSL
    autoload :Static
  end

  autoload :Journey
  autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
  autoload :Routing

  module Http
    extend ActiveSupport::Autoload

    autoload :Cache
    autoload :Headers
    autoload :MimeNegotiation
    autoload :Parameters
    autoload :ParameterFilter
    autoload :FilterParameters
    autoload :FilterRedirect
    autoload :Upload
    autoload :UploadedFile, 'action_dispatch/http/upload'
    autoload :URL
  end

  module Session
    autoload :AbstractStore,                           'action_dispatch/middleware/session/abstract_store'
    autoload :CookieStore,                             'action_dispatch/middleware/session/cookie_store'
    autoload :EncryptedCookieStore,                    'action_dispatch/middleware/session/cookie_store'
    autoload :UpgradeSignatureToEncryptionCookieStore, 'action_dispatch/middleware/session/cookie_store'
    autoload :MemCacheStore,                           'action_dispatch/middleware/session/mem_cache_store'
    autoload :CacheStore,                              'action_dispatch/middleware/session/cache_store'
  end

  mattr_accessor :test_app

  autoload_under 'testing' do
    autoload :Assertions
    autoload :Integration
    autoload :IntegrationTest, 'action_dispatch/testing/integration'
    autoload :TestProcess
    autoload :TestRequest
    autoload :TestResponse
  end
end

autoload :Mime, 'action_dispatch/http/mime_type'

ActiveSupport.on_load(:action_view) do
  ActionView::Base.default_formats ||= Mime::SET.symbols
  ActionView::Template::Types.delegate_to Mime
end
module ActionPack
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'action_pack/version'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/ordered_options'
require 'action_view/log_subscriber'

module ActionView #:nodoc:
  # = Action View Base
  #
  # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERB
  # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then Jim Weirich's Builder::XmlMarkup library is used.
  #
  # == ERB
  #
  # You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
  # following loop for names:
  #
  #   <b>Names of all the people</b>
  #   <% @people.each do |person| %>
  #     Name: <%= person.name %><br/>
  #   <% end %>
  #
  # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this
  # is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
  #
  #   <%# WRONG %>
  #   Hi, Mr. <% puts "Frodo" %>
  #
  # If you absolutely must write from within a function use +concat+.
  #
  # <%- and -%> suppress leading and trailing whitespace, including the trailing newline, and can be used interchangeably with <% and %>.
  #
  # === Using sub templates
  #
  # Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The
  # classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):
  #
  #   <%= render "shared/header" %>
  #   Something really specific and terrific
  #   <%= render "shared/footer" %>
  #
  # As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the
  # result of the rendering. The output embedding writes it to the current template.
  #
  # But you don't have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance
  # variables defined using the regular embedding tags. Like this:
  #
  #   <% @page_title = "A Wonderful Hello" %>
  #   <%= render "shared/header" %>
  #
  # Now the header can pick up on the <tt>@page_title</tt> variable and use it for outputting a title tag:
  #
  #   <title><%= @page_title %></title>
  #
  # === Passing local variables to sub templates
  #
  # You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
  #
  #   <%= render "shared/header", { headline: "Welcome", person: person } %>
  #
  # These can now be accessed in <tt>shared/header</tt> with:
  #
  #   Headline: <%= headline %>
  #   First name: <%= person.first_name %>
  #
  # If you need to find out whether a certain local variable has been assigned a value in a particular render call,
  # you need to use the following pattern:
  #
  #   <% if local_assigns.has_key? :headline %>
  #     Headline: <%= headline %>
  #   <% end %>
  #
  # Testing using <tt>defined? headline</tt> will not work. This is an implementation restriction.
  #
  # === Template caching
  #
  # By default, Rails will compile each template to a method in order to render it. When you alter a template,
  # Rails will check the file's modification time and recompile it in development mode.
  #
  # == Builder
  #
  # Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object
  # named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
  #
  # Here are some basic examples:
  #
  #   xml.em("emphasized")                                 # => <em>emphasized</em>
  #   xml.em { xml.b("emph & bold") }                      # => <em><b>emph &amp; bold</b></em>
  #   xml.a("A Link", "href" => "http://onestepback.org")  # => <a href="http://onestepback.org">A Link</a>
  #   xml.target("name" => "compile", "option" => "fast")  # => <target option="fast" name="compile"\>
  #                                                        # NOTE: order of attributes is not specified.
  #
  # Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
  #
  #   xml.div do
  #     xml.h1(@person.name)
  #     xml.p(@person.bio)
  #   end
  #
  # would produce something like:
  #
  #   <div>
  #     <h1>David Heinemeier Hansson</h1>
  #     <p>A product of Danish Design during the Winter of '79...</p>
  #   </div>
  #
  # A full-length RSS example actually used on Basecamp:
  #
  #   xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
  #     xml.channel do
  #       xml.title(@feed_title)
  #       xml.link(@url)
  #       xml.description "Basecamp: Recent items"
  #       xml.language "en-us"
  #       xml.ttl "40"
  #
  #       @recent_items.each do |item|
  #         xml.item do
  #           xml.title(item_title(item))
  #           xml.description(item_description(item)) if item_description(item)
  #           xml.pubDate(item_pubDate(item))
  #           xml.guid(@person.firm.account.url + @recent_items.url(item))
  #           xml.link(@person.firm.account.url + @recent_items.url(item))
  #
  #           xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
  #         end
  #       end
  #     end
  #   end
  #
  # More builder documentation can be found at http://builder.rubyforge.org.
  class Base
    include Helpers, ::ERB::Util, Context

    # Specify the proc used to decorate input tags that refer to attributes with errors.
    cattr_accessor :field_error_proc
    @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }

    # How to complete the streaming when an exception occurs.
    # This is our best guess: first try to close the attribute, then the tag.
    cattr_accessor :streaming_completion_on_exception
    @@streaming_completion_on_exception = %("><script>window.location = "/500.html"</script></html>)

    # Specify whether rendering within namespaced controllers should prefix
    # the partial paths for ActiveModel objects with the namespace.
    # (e.g., an Admin::PostsController would render @post using /admin/posts/_post.erb)
    cattr_accessor :prefix_partial_path_with_controller_namespace
    @@prefix_partial_path_with_controller_namespace = true

    # Specify default_formats that can be rendered.
    cattr_accessor :default_formats

    class_attribute :_routes
    class_attribute :logger

    class << self
      delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'

      def cache_template_loading
        ActionView::Resolver.caching?
      end

      def cache_template_loading=(value)
        ActionView::Resolver.caching = value
      end

      def xss_safe? #:nodoc:
        true
      end
    end

    attr_accessor :view_renderer
    attr_internal :config, :assigns

    delegate :lookup_context, :to => :view_renderer
    delegate :formats, :formats=, :locale, :locale=, :view_paths, :view_paths=, :to => :lookup_context

    def assign(new_assigns) # :nodoc:
      @_assigns = new_assigns.each { |key, value| instance_variable_set("@#{key}", value) }
    end

    def initialize(context = nil, assigns = {}, controller = nil, formats = nil) #:nodoc:
      @_config = ActiveSupport::InheritableOptions.new

      if context.is_a?(ActionView::Renderer)
        @view_renderer = context
      else
        lookup_context = context.is_a?(ActionView::LookupContext) ?
          context : ActionView::LookupContext.new(context)
        lookup_context.formats  = formats if formats
        lookup_context.prefixes = controller._prefixes if controller
        @view_renderer = ActionView::Renderer.new(lookup_context)
      end

      assign(assigns)
      assign_controller(controller)
      _prepare_context
    end

    ActiveSupport.run_load_hooks(:action_view, self)
  end
end
require 'active_support/core_ext/string/output_safety'

module ActionView
  class OutputBuffer < ActiveSupport::SafeBuffer #:nodoc:
    def initialize(*)
      super
      encode!
    end

    def <<(value)
      super(value.to_s)
    end
    alias :append= :<<
    alias :safe_append= :safe_concat
  end

  class StreamingBuffer #:nodoc:
    def initialize(block)
      @block = block
    end

    def <<(value)
      value = value.to_s
      value = ERB::Util.h(value) unless value.html_safe?
      @block.call(value)
    end
    alias :concat  :<<
    alias :append= :<<

    def safe_concat(value)
      @block.call(value.to_s)
    end
    alias :safe_append= :safe_concat

    def html_safe?
      true
    end

    def html_safe
      self
    end
  end
end
module ActionView
  module CompiledTemplates #:nodoc:
    # holds compiled template code
  end

  # = Action View Context
  #
  # Action View contexts are supplied to Action Controller to render a template.
  # The default Action View context is ActionView::Base.
  #
  # In order to work with ActionController, a Context must just include this module.
  # The initialization of the variables used by the context (@output_buffer, @view_flow,
  # and @virtual_path) is responsibility of the object that includes this module
  # (although you can call _prepare_context defined below).
  module Context
    include CompiledTemplates
    attr_accessor :output_buffer, :view_flow

    # Prepares the context by setting the appropriate instance variables.
    # :api: plugin
    def _prepare_context
      @view_flow     = OutputFlow.new
      @output_buffer = nil
      @virtual_path  = nil
    end

    # Encapsulates the interaction with the view flow so it
    # returns the correct buffer on +yield+. This is usually
    # overwritten by helpers to add more behavior.
    # :api: plugin
    def _layout_for(name=nil)
      name ||= :layout
      view_flow.get(name).html_safe
    end
  end
end
require 'thread_safe'

module ActionView
  class Digestor
    EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/

    # Matches:
    #   render partial: "comments/comment", collection: commentable.comments
    #   render "comments/comments"
    #   render 'comments/comments'
    #   render('comments/comments')
    #
    #   render(@topic)         => render("topics/topic")
    #   render(topics)         => render("topics/topic")
    #   render(message.topics) => render("topics/topic")
    RENDER_DEPENDENCY = /
      render\s*                     # render, followed by optional whitespace
      \(?                           # start an optional parenthesis for the render call
      (partial:|:partial\s+=>)?\s*  # naming the partial, used with collection -- 1st capture
      ([@a-z"'][@a-z_\/\."']+)      # the template name itself -- 2nd capture
    /x

    cattr_reader(:cache)
    @@cache = ThreadSafe::Cache.new

    def self.digest(name, format, finder, options = {})
      cache_key = [name, format] + Array.wrap(options[:dependencies])
      @@cache[cache_key.join('.')] ||= begin
        klass = options[:partial] || name.include?("/_") ? PartialDigestor : Digestor
        klass.new(name, format, finder, options).digest
      end
    end

    attr_reader :name, :format, :finder, :options

    def initialize(name, format, finder, options={})
      @name, @format, @finder, @options = name, format, finder, options
    end

    def digest
      Digest::MD5.hexdigest("#{source}-#{dependency_digest}").tap do |digest|
        logger.try :info, "Cache digest for #{name}.#{format}: #{digest}"
      end
    rescue ActionView::MissingTemplate
      logger.try :error, "Couldn't find template for digesting: #{name}.#{format}"
      ''
    end

    def dependencies
      render_dependencies + explicit_dependencies
    rescue ActionView::MissingTemplate
      [] # File doesn't exist, so no dependencies
    end

    def nested_dependencies
      dependencies.collect do |dependency|
        dependencies = PartialDigestor.new(dependency, format, finder).nested_dependencies
        dependencies.any? ? { dependency => dependencies } : dependency
      end
    end

    private

      def logger
        ActionView::Base.logger
      end

      def logical_name
        name.gsub(%r|/_|, "/")
      end

      def directory
        name.split("/")[0..-2].join("/")
      end

      def partial?
        false
      end

      def source
        @source ||= finder.find(logical_name, [], partial?, formats: [ format ]).source
      end

      def dependency_digest
        template_digests = dependencies.collect do |template_name|
          Digestor.digest(template_name, format, finder, partial: true)
        end

        (template_digests + injected_dependencies).join("-")
      end

      def render_dependencies
        source.scan(RENDER_DEPENDENCY).
          collect(&:second).uniq.

          # render(@topic)         => render("topics/topic")
          # render(topics)         => render("topics/topic")
          # render(message.topics) => render("topics/topic")
          collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }.

          # render("headline") => render("message/headline")
          collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }.

          # replace quotes from string renders
          collect { |name| name.gsub(/["']/, "") }
      end

      def explicit_dependencies
        source.scan(EXPLICIT_DEPENDENCY).flatten.uniq
      end

      def injected_dependencies
        Array.wrap(options[:dependencies])
      end
  end

  class PartialDigestor < Digestor # :nodoc:
    def partial?
      true
    end
  end
end
require 'active_support/core_ext/string/output_safety'

module ActionView
  class OutputFlow #:nodoc:
    attr_reader :content

    def initialize
      @content = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
    end

    # Called by _layout_for to read stored values.
    def get(key)
      @content[key]
    end

    # Called by each renderer object to set the layout contents.
    def set(key, value)
      @content[key] = value
    end

    # Called by content_for
    def append(key, value)
      @content[key] << value
    end
    alias_method :append!, :append

  end

  class StreamingFlow < OutputFlow #:nodoc:
    def initialize(view, fiber)
      @view    = view
      @parent  = nil
      @child   = view.output_buffer
      @content = view.view_flow.content
      @fiber   = fiber
      @root    = Fiber.current.object_id
    end

    # Try to get an stored content. If the content
    # is not available and we are inside the layout
    # fiber, we set that we are waiting for the given
    # key and yield.
    def get(key)
      return super if @content.key?(key)

      if inside_fiber?
        view = @view

        begin
          @waiting_for = key
          view.output_buffer, @parent = @child, view.output_buffer
          Fiber.yield
        ensure
          @waiting_for = nil
          view.output_buffer, @child = @parent, view.output_buffer
        end
      end

      super
    end

    # Appends the contents for the given key. This is called
    # by provides and resumes back to the fiber if it is
    # the key it is waiting for.
    def append!(key, value)
      super
      @fiber.resume if @waiting_for == key
    end

    private

    def inside_fiber?
      Fiber.current.object_id != @root
    end
  end
endrequire 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/enumerable'

module ActionView
  # = Active Model Helpers
  module Helpers
    module ActiveModelHelper
    end

    module ActiveModelInstanceTag
      def object
        @active_model_object ||= begin
          object = super
          object.respond_to?(:to_model) ? object.to_model : object
        end
      end

      def content_tag(*)
        error_wrapping(super)
      end

      def tag(type, options, *)
        tag_generate_errors?(options) ? error_wrapping(super) : super
      end

      def error_wrapping(html_tag)
        if object_has_errors?
          Base.field_error_proc.call(html_tag, self)
        else
          html_tag
        end
      end

      def error_message
        object.errors[@method_name]
      end

      private

      def object_has_errors?
        object.respond_to?(:errors) && object.errors.respond_to?(:[]) && error_message.present?
      end

      def tag_generate_errors?(options)
        options['type'] != 'hidden'
      end
    end
  end
end
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/hash/keys'
require 'action_view/helpers/asset_url_helper'
require 'action_view/helpers/tag_helper'

module ActionView
  # = Action View Asset Tag Helpers
  module Helpers #:nodoc:
    # This module provides methods for generating HTML that links views to assets such
    # as images, javascripts, stylesheets, and feeds. These methods do not verify
    # the assets exist before linking to them:
    #
    #   image_tag("rails.png")
    #   # => <img alt="Rails" src="/assets/rails.png" />
    #   stylesheet_link_tag("application")
    #   # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
    #
    module AssetTagHelper
      extend ActiveSupport::Concern

      include AssetUrlHelper
      include TagHelper

      # Returns an HTML script tag for each of the +sources+ provided.
      #
      # Sources may be paths to JavaScript files. Relative paths are assumed to be relative
      # to <tt>assets/javascripts</tt>, full paths are assumed to be relative to the document
      # root. Relative paths are idiomatic, use absolute paths only when needed.
      #
      # When passing paths, the ".js" extension is optional.
      #
      # You can modify the HTML attributes of the script tag by passing a hash as the
      # last argument.
      #
      # When the Asset Pipeline is enabled, you can pass the name of your manifest as
      # source, and include other JavaScript or CoffeeScript files inside the manifest.
      #
      #   javascript_include_tag "xmlhr"
      #   # => <script src="/assets/xmlhr.js?1284139606"></script>
      #
      #   javascript_include_tag "xmlhr.js"
      #   # => <script src="/assets/xmlhr.js?1284139606"></script>
      #
      #   javascript_include_tag "common.javascript", "/elsewhere/cools"
      #   # => <script src="/assets/common.javascript?1284139606"></script>
      #   #    <script src="/elsewhere/cools.js?1423139606"></script>
      #
      #   javascript_include_tag "http://www.example.com/xmlhr"
      #   # => <script src="http://www.example.com/xmlhr"></script>
      #
      #   javascript_include_tag "http://www.example.com/xmlhr.js"
      #   # => <script src="http://www.example.com/xmlhr.js"></script>
      #
      def javascript_include_tag(*sources)
        options = sources.extract_options!.stringify_keys
        path_options = options.extract!('protocol').symbolize_keys

        sources.uniq.map { |source|
          tag_options = {
            "src" => path_to_javascript(source, path_options)
          }.merge(options)
          content_tag(:script, "", tag_options)
        }.join("\n").html_safe
      end

      # Returns a stylesheet link tag for the sources specified as arguments. If
      # you don't specify an extension, <tt>.css</tt> will be appended automatically.
      # You can modify the link attributes by passing a hash as the last argument.
      # For historical reasons, the 'media' attribute will always be present and defaults
      # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to
      # apply to all media types.
      #
      #   stylesheet_link_tag "style"
      #   # => <link href="/assets/style.css" media="screen" rel="stylesheet" />
      #
      #   stylesheet_link_tag "style.css"
      #   # => <link href="/assets/style.css" media="screen" rel="stylesheet" />
      #
      #   stylesheet_link_tag "http://www.example.com/style.css"
      #   # => <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" />
      #
      #   stylesheet_link_tag "style", media: "all"
      #   # => <link href="/assets/style.css" media="all" rel="stylesheet" />
      #
      #   stylesheet_link_tag "style", media: "print"
      #   # => <link href="/assets/style.css" media="print" rel="stylesheet" />
      #
      #   stylesheet_link_tag "random.styles", "/css/stylish"
      #   # => <link href="/assets/random.styles" media="screen" rel="stylesheet" />
      #   #    <link href="/css/stylish.css" media="screen" rel="stylesheet" />
      #
      def stylesheet_link_tag(*sources)
        options = sources.extract_options!.stringify_keys
        path_options = options.extract!('protocol').symbolize_keys

        sources.uniq.map { |source|
          tag_options = {
            "rel" => "stylesheet",
            "media" => "screen",
            "href" => path_to_stylesheet(source, path_options)
          }.merge(options)
          tag(:link, tag_options)
        }.join("\n").html_safe
      end

      # Returns a link tag that browsers and news readers can use to auto-detect
      # an RSS or Atom feed. The +type+ can either be <tt>:rss</tt> (default) or
      # <tt>:atom</tt>. Control the link options in url_for format using the
      # +url_options+. You can modify the LINK tag itself in +tag_options+.
      #
      # ==== Options
      # * <tt>:rel</tt>  - Specify the relation of this link, defaults to "alternate"
      # * <tt>:type</tt>  - Override the auto-generated mime type
      # * <tt>:title</tt>  - Specify the title of the link, defaults to the +type+
      #
      #   auto_discovery_link_tag
      #   # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
      #   auto_discovery_link_tag(:atom)
      #   # => <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.currenthost.com/controller/action" />
      #   auto_discovery_link_tag(:rss, {action: "feed"})
      #   # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/feed" />
      #   auto_discovery_link_tag(:rss, {action: "feed"}, {title: "My RSS"})
      #   # => <link rel="alternate" type="application/rss+xml" title="My RSS" href="http://www.currenthost.com/controller/feed" />
      #   auto_discovery_link_tag(:rss, {controller: "news", action: "feed"})
      #   # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/news/feed" />
      #   auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {title: "Example RSS"})
      #   # => <link rel="alternate" type="application/rss+xml" title="Example RSS" href="http://www.example.com/feed" />
      def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
        if !(type == :rss || type == :atom) && tag_options[:type].blank?
          message = "You have passed type other than :rss or :atom to auto_discovery_link_tag and haven't supplied " +
                    "the :type option key. This behavior is deprecated and will be remove in Rails 4.1. You should pass " +
                    ":type option explicitly if you want to use other types, for example: " +
                    "auto_discovery_link_tag(:xml, '/feed.xml', :type => 'application/xml')"
          ActiveSupport::Deprecation.warn message
        end

        tag(
          "link",
          "rel"   => tag_options[:rel] || "alternate",
          "type"  => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s,
          "title" => tag_options[:title] || type.to_s.upcase,
          "href"  => url_options.is_a?(Hash) ? url_for(url_options.merge(:only_path => false)) : url_options
        )
      end

      # Returns a link loading a favicon file. You may specify a different file
      # in the first argument. The helper accepts an additional options hash where
      # you can override "rel" and "type".
      #
      # ==== Options
      # * <tt>:rel</tt>   - Specify the relation of this link, defaults to 'shortcut icon'
      # * <tt>:type</tt>  - Override the auto-generated mime type, defaults to 'image/vnd.microsoft.icon'
      #
      #   favicon_link_tag '/myicon.ico'
      #   # => <link href="/assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
      #
      # Mobile Safari looks for a different <link> tag, pointing to an image that
      # will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
      # The following call would generate such a tag:
      #
      #   favicon_link_tag '/mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
      #   # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
      #
      def favicon_link_tag(source='favicon.ico', options={})
        tag('link', {
          :rel  => 'shortcut icon',
          :type => 'image/vnd.microsoft.icon',
          :href => path_to_image(source)
        }.merge(options.symbolize_keys))
      end

      # Returns an HTML image tag for the +source+. The +source+ can be a full
      # path or a file.
      #
      # ==== Options
      # You can add HTML attributes using the +options+. The +options+ supports
      # three additional keys for convenience and conformance:
      #
      # * <tt>:alt</tt>  - If no alt text is given, the file name part of the
      #   +source+ is used (capitalized and without the extension)
      # * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes
      #   width="30" and height="45", and "50" becomes width="50" and height="50".
      #   <tt>:size</tt> will be ignored if the value is not in the correct format.
      #
      # ==== Examples
      #
      #   image_tag("icon")
      #   # => <img alt="Icon" src="/assets/icon" />
      #   image_tag("icon.png")
      #   # => <img alt="Icon" src="/assets/icon.png" />
      #   image_tag("icon.png", size: "16x10", alt: "Edit Entry")
      #   # => <img src="/assets/icon.png" width="16" height="10" alt="Edit Entry" />
      #   image_tag("/icons/icon.gif", size: "16")
      #   # => <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
      #   image_tag("/icons/icon.gif", height: '32', width: '32')
      #   # => <img alt="Icon" height="32" src="/icons/icon.gif" width="32" />
      #   image_tag("/icons/icon.gif", class: "menu_icon")
      #   # => <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
      def image_tag(source, options={})
        options = options.symbolize_keys

        src = options[:src] = path_to_image(source)

        unless src =~ /^(?:cid|data):/ || src.blank?
          options[:alt] = options.fetch(:alt){ image_alt(src) }
        end

        if size = options.delete(:size)
          options[:width], options[:height] = size.split("x") if size =~ %r{\A\d+x\d+\z}
          options[:width] = options[:height] = size if size =~ %r{\A\d+\z}
        end

        tag("img", options)
      end

      # Returns a string suitable for an html image tag alt attribute.
      # The +src+ argument is meant to be an image file path.
      # The method removes the basename of the file path and the digest,
      # if any. It also removes hyphens and underscores from file names and
      # replaces them with spaces, returning a space-separated, titleized
      # string.
      #
      # ==== Examples
      #
      #   image_tag('rails.png')
      #   # => <img alt="Rails" src="/assets/rails.png" />
      #
      #   image_tag('hyphenated-file-name.png')
      #   # => <img alt="Hyphenated file name" src="/assets/hyphenated-file-name.png" />
      #
      #   image_tag('underscored_file_name.png')
      #   # => <img alt="Underscored file name" src="/assets/underscored_file_name.png" />
      def image_alt(src)
        File.basename(src, '.*').sub(/-[[:xdigit:]]{32}\z/, '').tr('-_', ' ').capitalize
      end

      # Returns an html video tag for the +sources+. If +sources+ is a string,
      # a single video tag will be returned. If +sources+ is an array, a video
      # tag with nested source tags for each source will be returned. The
      # +sources+ can be full paths or files that exists in your public videos
      # directory.
      #
      # ==== Options
      # You can add HTML attributes using the +options+. The +options+ supports
      # two additional keys for convenience and conformance:
      #
      # * <tt>:poster</tt> - Set an image (like a screenshot) to be shown
      #   before the video loads. The path is calculated like the +src+ of +image_tag+.
      # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
      #   width="30" and height="45". <tt>:size</tt> will be ignored if the
      #   value is not in the correct format.
      #
      #   video_tag("trailer")
      #   # => <video src="/videos/trailer" />
      #   video_tag("trailer.ogg")
      #   # => <video src="/videos/trailer.ogg" />
      #   video_tag("trailer.ogg", controls: true, autobuffer: true)
      #   # => <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" />
      #   video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png")
      #   # => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png" />
      #   video_tag("/trailers/hd.avi", size: "16x16")
      #   # => <video src="/trailers/hd.avi" width="16" height="16" />
      #   video_tag("/trailers/hd.avi", height: '32', width: '32')
      #   # => <video height="32" src="/trailers/hd.avi" width="32" />
      #   video_tag("trailer.ogg", "trailer.flv")
      #   # => <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
      #   video_tag(["trailer.ogg", "trailer.flv"])
      #   # => <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
      #   video_tag(["trailer.ogg", "trailer.flv"], size: "160x120")
      #   # => <video height="120" width="160"><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
      def video_tag(*sources)
        multiple_sources_tag('video', sources) do |options|
          options[:poster] = path_to_image(options[:poster]) if options[:poster]

          if size = options.delete(:size)
            options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
          end
        end
      end

      # Returns an HTML audio tag for the +source+.
      # The +source+ can be full path or file that exists in
      # your public audios directory.
      #
      #   audio_tag("sound")
      #   # => <audio src="/audios/sound" />
      #   audio_tag("sound.wav")
      #   # => <audio src="/audios/sound.wav" />
      #   audio_tag("sound.wav", autoplay: true, controls: true)
      #   # => <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" />
      #   audio_tag("sound.wav", "sound.mid")
      #   # => <audio><source src="/audios/sound.wav" /><source src="/audios/sound.mid" /></audio>
      def audio_tag(*sources)
        multiple_sources_tag('audio', sources)
      end

      private
        def multiple_sources_tag(type, sources)
          options = sources.extract_options!.symbolize_keys
          sources.flatten!

          yield options if block_given?

          if sources.size > 1
            content_tag(type, options) do
              safe_join sources.map { |source| tag("source", :src => send("path_to_#{type}", source)) }
            end
          else
            options[:src] = send("path_to_#{type}", sources.first)
            content_tag(type, nil, options)
          end
        end
    end
  end
end
require 'zlib'

module ActionView
  # = Action View Asset URL Helpers
  module Helpers
    # This module provides methods for generating asset paths and
    # urls.
    #
    #   image_path("rails.png")
    #   # => "/assets/rails.png"
    #
    #   image_url("rails.png")
    #   # => "http://www.example.com/assets/rails.png"
    #
    # === Using asset hosts
    #
    # By default, Rails links to these assets on the current host in the public
    # folder, but you can direct Rails to link to assets from a dedicated asset
    # server by setting <tt>ActionController::Base.asset_host</tt> in the application
    # configuration, typically in <tt>config/environments/production.rb</tt>.
    # For example, you'd define <tt>assets.example.com</tt> to be your asset
    # host this way, inside the <tt>configure</tt> block of your environment-specific
    # configuration files or <tt>config/application.rb</tt>:
    #
    #   config.action_controller.asset_host = "assets.example.com"
    #
    # Helpers take that into account:
    #
    #   image_tag("rails.png")
    #   # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
    #   stylesheet_link_tag("application")
    #   # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
    #
    # Browsers typically open at most two simultaneous connections to a single
    # host, which means your assets often have to wait for other assets to finish
    # downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the
    # +asset_host+. For example, "assets%d.example.com". If that wildcard is
    # present Rails distributes asset requests among the corresponding four hosts
    # "assets0.example.com", ..., "assets3.example.com". With this trick browsers
    # will open eight simultaneous connections rather than two.
    #
    #   image_tag("rails.png")
    #   # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
    #   stylesheet_link_tag("application")
    #   # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
    #
    # To do this, you can either setup four actual hosts, or you can use wildcard
    # DNS to CNAME the wildcard to a single asset host. You can read more about
    # setting up your DNS CNAME records from your ISP.
    #
    # Note: This is purely a browser performance optimization and is not meant
    # for server load balancing. See http://www.die.net/musings/page_load_time/
    # for background.
    #
    # Alternatively, you can exert more control over the asset host by setting
    # +asset_host+ to a proc like this:
    #
    #   ActionController::Base.asset_host = Proc.new { |source|
    #     "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
    #   }
    #   image_tag("rails.png")
    #   # => <img alt="Rails" src="http://assets1.example.com/assets/rails.png" />
    #   stylesheet_link_tag("application")
    #   # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
    #
    # The example above generates "http://assets1.example.com" and
    # "http://assets2.example.com". This option is useful for example if
    # you need fewer/more than four hosts, custom host names, etc.
    #
    # As you see the proc takes a +source+ parameter. That's a string with the
    # absolute path of the asset, for example "/assets/rails.png".
    #
    #    ActionController::Base.asset_host = Proc.new { |source|
    #      if source.ends_with?('.css')
    #        "http://stylesheets.example.com"
    #      else
    #        "http://assets.example.com"
    #      end
    #    }
    #   image_tag("rails.png")
    #   # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
    #   stylesheet_link_tag("application")
    #   # => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
    #
    # Alternatively you may ask for a second parameter +request+. That one is
    # particularly useful for serving assets from an SSL-protected page. The
    # example proc below disables asset hosting for HTTPS connections, while
    # still sending assets for plain HTTP requests from asset hosts. If you don't
    # have SSL certificates for each of the asset hosts this technique allows you
    # to avoid warnings in the client about mixed media.
    #
    #   config.action_controller.asset_host = Proc.new { |source, request|
    #     if request.ssl?
    #       "#{request.protocol}#{request.host_with_port}"
    #     else
    #       "#{request.protocol}assets.example.com"
    #     end
    #   }
    #
    # You can also implement a custom asset host object that responds to +call+
    # and takes either one or two parameters just like the proc.
    #
    #   config.action_controller.asset_host = AssetHostingWithMinimumSsl.new(
    #     "http://asset%d.example.com", "https://asset1.example.com"
    #   )
    #
    module AssetUrlHelper
      URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}

      # Computes the path to asset in public directory. If :type
      # options is set, a file extension will be appended and scoped
      # to the corresponding public directory.
      #
      # All other asset *_path helpers delegate through this method.
      #
      #   asset_path "application.js"                     # => /application.js
      #   asset_path "application", type: :javascript     # => /javascripts/application.js
      #   asset_path "application", type: :stylesheet     # => /stylesheets/application.css
      #   asset_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
      def asset_path(source, options = {})
        source = source.to_s
        return "" unless source.present?
        return source if source =~ URI_REGEXP

        tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, '')

        if extname = compute_asset_extname(source, options)
          source = "#{source}#{extname}"
        end

        if source[0] != ?/
          source = compute_asset_path(source, options)
        end

        relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
        if relative_url_root
          source = "#{relative_url_root}#{source}" unless source.starts_with?("#{relative_url_root}/")
        end

        if host = compute_asset_host(source, options)
          source = "#{host}#{source}"
        end

        "#{source}#{tail}"
      end
      alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with a asset_path named route

      # Computes the full URL to a asset in the public directory. This
      # will use +asset_path+ internally, so most of their behaviors
      # will be the same.
      def asset_url(source, options = {})
        path_to_asset(source, options.merge(:protocol => :request))
      end
      alias_method :url_to_asset, :asset_url # aliased to avoid conflicts with an asset_url named route

      ASSET_EXTENSIONS = {
        javascript: '.js',
        stylesheet: '.css'
      }

      # Compute extname to append to asset path. Returns nil if
      # nothing should be added.
      def compute_asset_extname(source, options = {})
        return if options[:extname] == false
        extname = options[:extname] || ASSET_EXTENSIONS[options[:type]]
        extname if extname && File.extname(source) != extname
      end

      # Maps asset types to public directory.
      ASSET_PUBLIC_DIRECTORIES = {
        audio:      '/audios',
        font:       '/fonts',
        image:      '/images',
        javascript: '/javascripts',
        stylesheet: '/stylesheets',
        video:      '/videos'
      }

      # Computes asset path to public directory. Plugins and
      # extensions can override this method to point to custom assets
      # or generate digested paths or query strings.
      def compute_asset_path(source, options = {})
        dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
        File.join(dir, source)
      end

      # Pick an asset host for this source. Returns +nil+ if no host is set,
      # the host if no wildcard is set, the host interpolated with the
      # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
      # or the value returned from invoking call on an object responding to call
      # (proc or otherwise).
      def compute_asset_host(source = "", options = {})
        request = self.request if respond_to?(:request)
        host = config.asset_host if defined? config.asset_host
        host ||= request.base_url if request && options[:protocol] == :request
        return unless host

        if host.respond_to?(:call)
          arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity
          args = [source]
          args << request if request && (arity > 1 || arity < 0)
          host = host.call(*args)
        elsif host =~ /%d/
          host = host % (Zlib.crc32(source) % 4)
        end

        if host =~ URI_REGEXP
          host
        else
          protocol = options[:protocol] || config.default_asset_host_protocol || (request ? :request : :relative)
          case protocol
          when :relative
            "//#{host}"
          when :request
            "#{request.protocol}#{host}"
          else
            "#{protocol}://#{host}"
          end
        end
      end

      # Computes the path to a javascript asset in the public javascripts directory.
      # If the +source+ filename has no extension, .js will be appended (except for explicit URIs)
      # Full paths from the document root will be passed through.
      # Used internally by javascript_include_tag to build the script path.
      #
      #   javascript_path "xmlhr"                              # => /javascripts/xmlhr.js
      #   javascript_path "dir/xmlhr.js"                       # => /javascripts/dir/xmlhr.js
      #   javascript_path "/dir/xmlhr"                         # => /dir/xmlhr.js
      #   javascript_path "http://www.example.com/js/xmlhr"    # => http://www.example.com/js/xmlhr
      #   javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
      def javascript_path(source, options = {})
        path_to_asset(source, {type: :javascript}.merge!(options))
      end
      alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route

      # Computes the full URL to a javascript asset in the public javascripts directory.
      # This will use +javascript_path+ internally, so most of their behaviors will be the same.
      def javascript_url(source, options = {})
        url_to_asset(source, {type: :javascript}.merge!(options))
      end
      alias_method :url_to_javascript, :javascript_url # aliased to avoid conflicts with a javascript_url named route

      # Computes the path to a stylesheet asset in the public stylesheets directory.
      # If the +source+ filename has no extension, <tt>.css</tt> will be appended (except for explicit URIs).
      # Full paths from the document root will be passed through.
      # Used internally by +stylesheet_link_tag+ to build the stylesheet path.
      #
      #   stylesheet_path "style"                                  # => /stylesheets/style.css
      #   stylesheet_path "dir/style.css"                          # => /stylesheets/dir/style.css
      #   stylesheet_path "/dir/style.css"                         # => /dir/style.css
      #   stylesheet_path "http://www.example.com/css/style"       # => http://www.example.com/css/style
      #   stylesheet_path "http://www.example.com/css/style.css"   # => http://www.example.com/css/style.css
      def stylesheet_path(source, options = {})
        path_to_asset(source, {type: :stylesheet}.merge!(options))
      end
      alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route

      # Computes the full URL to a stylesheet asset in the public stylesheets directory.
      # This will use +stylesheet_path+ internally, so most of their behaviors will be the same.
      def stylesheet_url(source, options = {})
        url_to_asset(source, {type: :stylesheet}.merge!(options))
      end
      alias_method :url_to_stylesheet, :stylesheet_url # aliased to avoid conflicts with a stylesheet_url named route

      # Computes the path to an image asset.
      # Full paths from the document root will be passed through.
      # Used internally by +image_tag+ to build the image path:
      #
      #   image_path("edit")                                         # => "/assets/edit"
      #   image_path("edit.png")                                     # => "/assets/edit.png"
      #   image_path("icons/edit.png")                               # => "/assets/icons/edit.png"
      #   image_path("/icons/edit.png")                              # => "/icons/edit.png"
      #   image_path("http://www.example.com/img/edit.png")          # => "http://www.example.com/img/edit.png"
      #
      # If you have images as application resources this method may conflict with their named routes.
      # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
      # plugin authors are encouraged to do so.
      def image_path(source, options = {})
        path_to_asset(source, {type: :image}.merge!(options))
      end
      alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route

      # Computes the full URL to an image asset.
      # This will use +image_path+ internally, so most of their behaviors will be the same.
      def image_url(source, options = {})
        url_to_asset(source, {type: :image}.merge!(options))
      end
      alias_method :url_to_image, :image_url # aliased to avoid conflicts with an image_url named route

      # Computes the path to a video asset in the public videos directory.
      # Full paths from the document root will be passed through.
      # Used internally by +video_tag+ to build the video path.
      #
      #   video_path("hd")                                            # => /videos/hd
      #   video_path("hd.avi")                                        # => /videos/hd.avi
      #   video_path("trailers/hd.avi")                               # => /videos/trailers/hd.avi
      #   video_path("/trailers/hd.avi")                              # => /trailers/hd.avi
      #   video_path("http://www.example.com/vid/hd.avi")             # => http://www.example.com/vid/hd.avi
      def video_path(source, options = {})
        path_to_asset(source, {type: :video}.merge!(options))
      end
      alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route

      # Computes the full URL to a video asset in the public videos directory.
      # This will use +video_path+ internally, so most of their behaviors will be the same.
      def video_url(source, options = {})
        url_to_asset(source, {type: :video}.merge!(options))
      end
      alias_method :url_to_video, :video_url # aliased to avoid conflicts with an video_url named route

      # Computes the path to an audio asset in the public audios directory.
      # Full paths from the document root will be passed through.
      # Used internally by +audio_tag+ to build the audio path.
      #
      #   audio_path("horse")                                            # => /audios/horse
      #   audio_path("horse.wav")                                        # => /audios/horse.wav
      #   audio_path("sounds/horse.wav")                                 # => /audios/sounds/horse.wav
      #   audio_path("/sounds/horse.wav")                                # => /sounds/horse.wav
      #   audio_path("http://www.example.com/sounds/horse.wav")          # => http://www.example.com/sounds/horse.wav
      def audio_path(source, options = {})
        path_to_asset(source, {type: :audio}.merge!(options))
      end
      alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route

      # Computes the full URL to an audio asset in the public audios directory.
      # This will use +audio_path+ internally, so most of their behaviors will be the same.
      def audio_url(source, options = {})
        url_to_asset(source, {type: :audio}.merge!(options))
      end
      alias_method :url_to_audio, :audio_url # aliased to avoid conflicts with an audio_url named route

      # Computes the path to a font asset.
      # Full paths from the document root will be passed through.
      #
      #   font_path("font")                                           # => /assets/font
      #   font_path("font.ttf")                                       # => /assets/font.ttf
      #   font_path("dir/font.ttf")                                   # => /assets/dir/font.ttf
      #   font_path("/dir/font.ttf")                                  # => /dir/font.ttf
      #   font_path("http://www.example.com/dir/font.ttf")            # => http://www.example.com/dir/font.ttf
      def font_path(source, options = {})
        path_to_asset(source, {type: :font}.merge!(options))
      end
      alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route

      # Computes the full URL to a font asset.
      # This will use +font_path+ internally, so most of their behaviors will be the same.
      def font_url(source, options = {})
        url_to_asset(source, {type: :font}.merge!(options))
      end
      alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route
    end
  end
end
require 'set'

module ActionView
  # = Action View Atom Feed Helpers
  module Helpers
    module AtomFeedHelper
      # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other
      # template languages).
      #
      # Full usage example:
      #
      #   config/routes.rb:
      #     Basecamp::Application.routes.draw do
      #       resources :posts
      #       root to: "posts#index"
      #     end
      #
      #   app/controllers/posts_controller.rb:
      #     class PostsController < ApplicationController::Base
      #       # GET /posts.html
      #       # GET /posts.atom
      #       def index
      #         @posts = Post.all
      #
      #         respond_to do |format|
      #           format.html
      #           format.atom
      #         end
      #       end
      #     end
      #
      #   app/views/posts/index.atom.builder:
      #     atom_feed do |feed|
      #       feed.title("My great blog!")
      #       feed.updated(@posts[0].created_at) if @posts.length > 0
      #
      #       @posts.each do |post|
      #         feed.entry(post) do |entry|
      #           entry.title(post.title)
      #           entry.content(post.body, type: 'html')
      #
      #           entry.author do |author|
      #             author.name("DHH")
      #           end
      #         end
      #       end
      #     end
      #
      # The options for atom_feed are:
      #
      # * <tt>:language</tt>: Defaults to "en-US".
      # * <tt>:root_url</tt>: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
      # * <tt>:url</tt>: The URL for this feed. Defaults to the current URL.
      # * <tt>:id</tt>: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}"
      # * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
      #   created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
      #   2005 is used (as an "I don't care" value).
      # * <tt>:instruct</tt>: Hash of XML processing instructions in the form {target => {attribute => value, }} or {target => [{attribute => value, }, ]}
      #
      # Other namespaces can be added to the root element:
      #
      #   app/views/posts/index.atom.builder:
      #     atom_feed({'xmlns:app' => 'http://www.w3.org/2007/app',
      #         'xmlns:openSearch' => 'http://a9.com/-/spec/opensearch/1.1/'}) do |feed|
      #       feed.title("My great blog!")
      #       feed.updated((@posts.first.created_at))
      #       feed.tag!(openSearch:totalResults, 10)
      #
      #       @posts.each do |post|
      #         feed.entry(post) do |entry|
      #           entry.title(post.title)
      #           entry.content(post.body, type: 'html')
      #           entry.tag!('app:edited', Time.now)
      #
      #           entry.author do |author|
      #             author.name("DHH")
      #           end
      #         end
      #       end
      #     end
      #
      # The Atom spec defines five elements (content rights title subtitle
      # summary) which may directly contain xhtml content if type: 'xhtml'
      # is specified as an attribute. If so, this helper will take care of
      # the enclosing div and xhtml namespace declaration. Example usage:
      #
      #    entry.summary type: 'xhtml' do |xhtml|
      #      xhtml.p pluralize(order.line_items.count, "line item")
      #      xhtml.p "Shipped to #{order.address}"
      #      xhtml.p "Paid by #{order.pay_type}"
      #    end
      #
      #
      # <tt>atom_feed</tt> yields an +AtomFeedBuilder+ instance. Nested elements yield
      # an +AtomBuilder+ instance.
      def atom_feed(options = {}, &block)
        if options[:schema_date]
          options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
        else
          options[:schema_date] = "2005" # The Atom spec copyright date
        end

        xml = options.delete(:xml) || eval("xml", block.binding)
        xml.instruct!
        if options[:instruct]
          options[:instruct].each do |target,attrs|
            if attrs.respond_to?(:keys)
              xml.instruct!(target, attrs)
            elsif attrs.respond_to?(:each)
              attrs.each { |attr_group| xml.instruct!(target, attr_group) }
            end
          end
        end

        feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
        feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}

        xml.feed(feed_opts) do
          xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}")
          xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port))
          xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url)

          yield AtomFeedBuilder.new(xml, self, options)
        end
      end

      class AtomBuilder #:nodoc:
        XHTML_TAG_NAMES = %w(content rights title subtitle summary).to_set

        def initialize(xml)
          @xml = xml
        end

        private
          # Delegate to xml builder, first wrapping the element in a xhtml
          # namespaced div element if the method and arguments indicate
          # that an xhtml_block? is desired.
          def method_missing(method, *arguments, &block)
            if xhtml_block?(method, arguments)
              @xml.__send__(method, *arguments) do
                @xml.div(:xmlns => 'http://www.w3.org/1999/xhtml') do |xhtml|
                  block.call(xhtml)
                end
              end
            else
              @xml.__send__(method, *arguments, &block)
            end
          end

          # True if the method name matches one of the five elements defined
          # in the Atom spec as potentially containing XHTML content and
          # if type: 'xhtml' is, in fact, specified.
          def xhtml_block?(method, arguments)
            if XHTML_TAG_NAMES.include?(method.to_s)
              last = arguments.last
              last.is_a?(Hash) && last[:type].to_s == 'xhtml'
            end
          end
      end

      class AtomFeedBuilder < AtomBuilder #:nodoc:
        def initialize(xml, view, feed_options = {})
          @xml, @view, @feed_options = xml, view, feed_options
        end

        # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used.
        def updated(date_or_time = nil)
          @xml.updated((date_or_time || Time.now.utc).xmlschema)
        end

        # Creates an entry tag for a specific record and prefills the id using class and id.
        #
        # Options:
        #
        # * <tt>:published</tt>: Time first published. Defaults to the created_at attribute on the record if one such exists.
        # * <tt>:updated</tt>: Time of update. Defaults to the updated_at attribute on the record if one such exists.
        # * <tt>:url</tt>: The URL for this entry. Defaults to the polymorphic_url for the record.
        # * <tt>:id</tt>: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}"
        # * <tt>:type</tt>: The TYPE for this entry. Defaults to "text/html".
        def entry(record, options = {})
          @xml.entry do
            @xml.id(options[:id] || "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}")

            if options[:published] || (record.respond_to?(:created_at) && record.created_at)
              @xml.published((options[:published] || record.created_at).xmlschema)
            end

            if options[:updated] || (record.respond_to?(:updated_at) && record.updated_at)
              @xml.updated((options[:updated] || record.updated_at).xmlschema)
            end

            type = options.fetch(:type, 'text/html')

            @xml.link(:rel => 'alternate', :type => type, :href => options[:url] || @view.polymorphic_url(record))

            yield AtomBuilder.new(@xml)
          end
        end
      end

    end
  end
end
module ActionView
  # = Action View Cache Helper
  module Helpers
    module CacheHelper
      # This helper exposes a method for caching fragments of a view
      # rather than an entire action or page. This technique is useful
      # caching pieces like menus, lists of newstopics, static HTML
      # fragments, and so on. This method takes a block that contains
      # the content you wish to cache.
      #
      # The best way to use this is by doing key-based cache expiration
      # on top of a cache store like Memcached that'll automatically
      # kick out old entries. For more on key-based expiration, see:
      # http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works
      #
      # When using this method, you list the cache dependency as the name of the cache, like so:
      #
      #   <% cache project do %>
      #     <b>All the topics on this project</b>
      #     <%= render project.topics %>
      #   <% end %>
      #
      # This approach will assume that when a new topic is added, you'll touch
      # the project. The cache key generated from this call will be something like:
      #
      #   views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9
      #         ^class   ^id ^updated_at    ^template tree digest
      #
      # The cache is thus automatically bumped whenever the project updated_at is touched.
      #
      # If your template cache depends on multiple sources (try to avoid this to keep things simple),
      # you can name all these dependencies as part of an array:
      #
      #   <% cache [ project, current_user ] do %>
      #     <b>All the topics on this project</b>
      #     <%= render project.topics %>
      #   <% end %>
      #
      # This will include both records as part of the cache key and updating either of them will
      # expire the cache.
      #
      # ==== Template digest
      #
      # The template digest that's added to the cache key is computed by taking an md5 of the
      # contents of the entire template file. This ensures that your caches will automatically
      # expire when you change the template file.
      #
      # Note that the md5 is taken of the entire template file, not just what's within the
      # cache do/end call. So it's possible that changing something outside of that call will
      # still expire the cache.
      #
      # Additionally, the digestor will automatically look through your template file for
      # explicit and implicit dependencies, and include those as part of the digest.
      #
      # The digestor can be bypassed by passing skip_digest: true as an option to the cache call:
      #
      #   <% cache project, skip_digest: true do %>
      #     <b>All the topics on this project</b>
      #     <%= render project.topics %>
      #   <% end %>
      #
      # ==== Implicit dependencies
      #
      # Most template dependencies can be derived from calls to render in the template itself.
      # Here are some examples of render calls that Cache Digests knows how to decode:
      #
      #   render partial: "comments/comment", collection: commentable.comments
      #   render "comments/comments"
      #   render 'comments/comments'
      #   render('comments/comments')
      #
      #   render "header" => render("comments/header")
      #
      #   render(@topic)         => render("topics/topic")
      #   render(topics)         => render("topics/topic")
      #   render(message.topics) => render("topics/topic")
      #
      # It's not possible to derive all render calls like that, though. Here are a few examples of things that can't be derived:
      #
      #   render group_of_attachments
      #   render @project.documents.where(published: true).order('created_at')
      #
      # You will have to rewrite those to the explicit form:
      #
      #   render partial: 'attachments/attachment', collection: group_of_attachments
      #   render partial: 'documents/document', collection: @project.documents.where(published: true).order('created_at')
      #
      # === Explicit dependencies
      #
      # Some times you'll have template dependencies that can't be derived at all. This is typically
      # the case when you have template rendering that happens in helpers. Here's an example:
      #
      #   <%= render_sortable_todolists @project.todolists %>
      #
      # You'll need to use a special comment format to call those out:
      #
      #   <%# Template Dependency: todolists/todolist %>
      #   <%= render_sortable_todolists @project.todolists %>
      #
      # The pattern used to match these is /# Template Dependency: ([^ ]+)/, so it's important that you type it out just so.
      # You can only declare one template dependency per line.
      #
      # === External dependencies
      #
      # If you use a helper method, for example, inside of a cached block and you then update that helper,
      # you'll have to bump the cache as well. It doesn't really matter how you do it, but the md5 of the template file
      # must change. One recommendation is to simply be explicit in a comment, like:
      #
      #   <%# Helper Dependency Updated: May 6, 2012 at 6pm %>
      #   <%= some_helper_method(person) %>
      #
      # Now all you'll have to do is change that timestamp when the helper method changes.
      def cache(name = {}, options = nil, &block)
        if controller.perform_caching
          safe_concat(fragment_for(cache_fragment_name(name, options), options, &block))
        else
          yield
        end

        nil
      end

      # Cache fragments of a view if +condition+ is true
      #
      #   <%= cache_if admin?, project do %>
      #     <b>All the topics on this project</b>
      #     <%= render project.topics %>
      #   <% end %>
      def cache_if(condition, name = {}, options = nil, &block)
        if condition
          cache(name, options, &block)
        else
          yield
        end

        nil
      end

      # Cache fragments of a view unless +condition+ is true
      #
      #   <%= cache_unless admin?, project do %>
      #     <b>All the topics on this project</b>
      #     <%= render project.topics %>
      #   <% end %>
      def cache_unless(condition, name = {}, options = nil, &block)
        cache_if !condition, name, options, &block
      end

      # This helper returns the name of a cache key for a given fragment cache
      # call. By supplying skip_digest: true to cache, the digestion of cache
      # fragments can be manually bypassed. This is useful when cache fragments
      # cannot be manually expired unless you know the exact key which is the
      # case when using memcached.
      def cache_fragment_name(name = {}, options = nil)
        skip_digest = options && options[:skip_digest]

        if skip_digest
          name
        else
          fragment_name_with_digest(name)
        end
      end

    private

      def fragment_name_with_digest(name) #:nodoc:
        if @virtual_path
          [
            *Array(name.is_a?(Hash) ? controller.url_for(name).split("://").last : name),
            Digestor.digest(@virtual_path, formats.last.to_sym, lookup_context, dependencies: view_cache_dependencies)
          ]
        else
          name
        end
      end

      # TODO: Create an object that has caching read/write on it
      def fragment_for(name = {}, options = nil, &block) #:nodoc:
        if fragment = controller.read_fragment(name, options)
          fragment
        else
          # VIEW TODO: Make #capture usable outside of ERB
          # This dance is needed because Builder can't use capture
          pos = output_buffer.length
          yield
          output_safe = output_buffer.html_safe?
          fragment = output_buffer.slice!(pos..-1)
          if output_safe
            self.output_buffer = output_buffer.class.new(output_buffer)
          end
          controller.write_fragment(name, fragment, options)
        end
      end
    end
  end
end
require 'active_support/core_ext/string/output_safety'

module ActionView
  # = Action View Capture Helper
  module Helpers
    # CaptureHelper exposes methods to let you extract generated markup which
    # can be used in other parts of a template or layout file.
    #
    # It provides a method to capture blocks into variables through capture and
    # a way to capture a block of markup for use in a layout through content_for.
    module CaptureHelper
      # The capture method allows you to extract part of a template into a
      # variable. You can then use this variable anywhere in your templates or layout.
      #
      # The capture method can be used in ERB templates...
      #
      #   <% @greeting = capture do %>
      #     Welcome to my shiny new web page!  The date and time is
      #     <%= Time.now %>
      #   <% end %>
      #
      # ...and Builder (RXML) templates.
      #
      #   @timestamp = capture do
      #     "The current timestamp is #{Time.now}."
      #   end
      #
      # You can then use that variable anywhere else. For example:
      #
      #   <html>
      #   <head><title><%= @greeting %></title></head>
      #   <body>
      #   <b><%= @greeting %></b>
      #   </body></html>
      #
      def capture(*args)
        value = nil
        buffer = with_output_buffer { value = yield(*args) }
        if string = buffer.presence || value and string.is_a?(String)
          ERB::Util.html_escape string
        end
      end

      # Calling content_for stores a block of markup in an identifier for later use.
      # In order to access this stored content in other templates, helper modules
      # or the layout, you would pass the identifier as an argument to <tt>content_for</tt>.
      #
      # Note: <tt>yield</tt> can still be used to retrieve the stored content, but calling
      # <tt>yield</tt> doesn't work in helper modules, while <tt>content_for</tt> does.
      #
      #   <% content_for :not_authorized do %>
      #     alert('You are not authorized to do that!')
      #   <% end %>
      #
      # You can then use <tt>content_for :not_authorized</tt> anywhere in your templates.
      #
      #   <%= content_for :not_authorized if current_user.nil? %>
      #
      # This is equivalent to:
      #
      #   <%= yield :not_authorized if current_user.nil? %>
      #
      # <tt>content_for</tt>, however, can also be used in helper modules.
      #
      #   module StorageHelper
      #     def stored_content
      #       content_for(:storage) || "Your storage is empty"
      #     end
      #   end
      #
      # This helper works just like normal helpers.
      #
      #   <%= stored_content %>
      #
      # You can also use the <tt>yield</tt> syntax alongside an existing call to
      # <tt>yield</tt> in a layout. For example:
      #
      #   <%# This is the layout %>
      #   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
      #   <head>
      #     <title>My Website</title>
      #     <%= yield :script %>
      #   </head>
      #   <body>
      #     <%= yield %>
      #   </body>
      #   </html>
      #
      # And now, we'll create a view that has a <tt>content_for</tt> call that
      # creates the <tt>script</tt> identifier.
      #
      #   <%# This is our view %>
      #   Please login!
      #
      #   <% content_for :script do %>
      #     <script>alert('You are not authorized to view this page!')</script>
      #   <% end %>
      #
      # Then, in another view, you could to do something like this:
      #
      #   <%= link_to 'Logout', action: 'logout', remote: true %>
      #
      #   <% content_for :script do %>
      #     <%= javascript_include_tag :defaults %>
      #   <% end %>
      #
      # That will place +script+ tags for your default set of JavaScript files on the page;
      # this technique is useful if you'll only be using these scripts in a few views.
      #
      # Note that content_for concatenates (default) the blocks it is given for a particular
      # identifier in order. For example:
      #
      #   <% content_for :navigation do %>
      #     <li><%= link_to 'Home', action: 'index' %></li>
      #   <% end %>
      #
      #  And in other place:
      #
      #   <% content_for :navigation do %>
      #     <li><%= link_to 'Login', action: 'login' %></li>
      #   <% end %>
      #
      # Then, in another template or layout, this code would render both links in order:
      #
      #   <ul><%= content_for :navigation %></ul>
      #
      # If the flush parameter is true content_for replaces the blocks it is given. For example:
      #
      #   <% content_for :navigation do %>
      #     <li><%= link_to 'Home', action: 'index' %></li>
      #   <% end %>
      #
      #   <%#  Add some other content, or use a different template: %>
      #
      #   <% content_for :navigation, flush: true do %>
      #     <li><%= link_to 'Login', action: 'login' %></li>
      #   <% end %>
      #
      # Then, in another template or layout, this code would render only the last link:
      #
      #   <ul><%= content_for :navigation %></ul>
      #
      # Lastly, simple content can be passed as a parameter:
      #
      #   <% content_for :script, javascript_include_tag(:defaults) %>
      #
      # WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
      def content_for(name, content = nil, options = {}, &block)
        if content || block_given?
          if block_given?
            options = content if content
            content = capture(&block)
          end
          if content
            options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content)
          end
          nil
        else
          @view_flow.get(name)
        end
      end

      # The same as +content_for+ but when used with streaming flushes
      # straight back to the layout. In other words, if you want to
      # concatenate several times to the same buffer when rendering a given
      # template, you should use +content_for+, if not, use +provide+ to tell
      # the layout to stop looking for more contents.
      def provide(name, content = nil, &block)
        content = capture(&block) if block_given?
        result = @view_flow.append!(name, content) if content
        result unless content
      end

      # content_for? checks whether any content has been captured yet using `content_for`.
      # Useful to render parts of your layout differently based on what is in your views.
      #
      #   <%# This is the layout %>
      #   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
      #   <head>
      #     <title>My Website</title>
      #     <%= yield :script %>
      #   </head>
      #   <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
      #     <%= yield %>
      #     <%= yield :right_col %>
      #   </body>
      #   </html>
      def content_for?(name)
        @view_flow.get(name).present?
      end

      # Use an alternate output buffer for the duration of the block.
      # Defaults to a new empty string.
      def with_output_buffer(buf = nil) #:nodoc:
        unless buf
          buf = ActionView::OutputBuffer.new
          buf.force_encoding(output_buffer.encoding) if output_buffer
        end
        self.output_buffer, old_buffer = buf, output_buffer
        yield
        output_buffer
      ensure
        self.output_buffer = old_buffer
      end

      # Add the output buffer to the response body and start a new one.
      def flush_output_buffer #:nodoc:
        if output_buffer && !output_buffer.empty?
          response.stream.write output_buffer
          self.output_buffer = output_buffer.respond_to?(:clone_empty) ? output_buffer.clone_empty : output_buffer[0, 0]
          nil
        end
      end
    end
  end
end
require 'active_support/core_ext/module/attr_internal'

module ActionView
  module Helpers
    # This module keeps all methods and behavior in ActionView
    # that simply delegates to the controller.
    module ControllerHelper #:nodoc:
      attr_internal :controller, :request

      delegate :request_forgery_protection_token, :params, :session, :cookies, :response, :headers,
               :flash, :action_name, :controller_name, :controller_path, :to => :controller

      def assign_controller(controller)
        if @_controller = controller
          @_request = controller.request if controller.respond_to?(:request)
          @_config  = controller.config.inheritable_copy if controller.respond_to?(:config)
        end
      end

      def logger
        controller.logger if controller.respond_to?(:logger)
      end
    end
  end
end
module ActionView
  # = Action View CSRF Helper
  module Helpers
    module CsrfHelper
      # Returns meta tags "csrf-param" and "csrf-token" with the name of the cross-site
      # request forgery protection parameter and token, respectively.
      #
      #   <head>
      #     <%= csrf_meta_tags %>
      #   </head>
      #
      # These are used to generate the dynamic forms that implement non-remote links with
      # <tt>:method</tt>.
      #
      # Note that regular forms generate hidden fields, and that Ajax calls are whitelisted,
      # so they do not use these tags.
      def csrf_meta_tags
        if protect_against_forgery?
          [
            tag('meta', :name => 'csrf-param', :content => request_forgery_protection_token),
            tag('meta', :name => 'csrf-token', :content => form_authenticity_token)
          ].join("\n").html_safe
        end
      end

      # For backwards compatibility.
      alias csrf_meta_tag csrf_meta_tags
    end
  end
end
require 'date'
require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/date/conversions'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/with_options'

module ActionView
  module Helpers
    # = Action View Date Helpers
    #
    # The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
    # elements. All of the select-type methods share a number of common options that are as follows:
    #
    # * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
    #   would give \birthday[month] instead of \date[month] if passed to the <tt>select_month</tt> method.
    # * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
    # * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true,
    #   the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
    #   of \date[month].
    module DateHelper
      # Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
      # Pass <tt>include_seconds: true</tt> if you want more detailed approximations when distance < 1 min, 29 secs.
      # Distances are reported based on the following table:
      #
      #   0 <-> 29 secs                                                             # => less than a minute
      #   30 secs <-> 1 min, 29 secs                                                # => 1 minute
      #   1 min, 30 secs <-> 44 mins, 29 secs                                       # => [2..44] minutes
      #   44 mins, 30 secs <-> 89 mins, 29 secs                                     # => about 1 hour
      #   89 mins, 30 secs <-> 23 hrs, 59 mins, 29 secs                             # => about [2..24] hours
      #   23 hrs, 59 mins, 30 secs <-> 41 hrs, 59 mins, 29 secs                     # => 1 day
      #   41 hrs, 59 mins, 30 secs  <-> 29 days, 23 hrs, 59 mins, 29 secs           # => [2..29] days
      #   29 days, 23 hrs, 59 mins, 30 secs <-> 44 days, 23 hrs, 59 mins, 29 secs   # => about 1 month
      #   44 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs   # => about 2 months
      #   59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec                    # => [2..12] months
      #   1 yr <-> 1 yr, 3 months                                                   # => about 1 year
      #   1 yr, 3 months <-> 1 yr, 9 months                                         # => over 1 year
      #   1 yr, 9 months <-> 2 yr minus 1 sec                                       # => almost 2 years
      #   2 yrs <-> max time or date                                                # => (same rules as 1 yr)
      #
      # With <tt>include_seconds: true</tt> and the difference < 1 minute 29 seconds:
      #   0-4   secs      # => less than 5 seconds
      #   5-9   secs      # => less than 10 seconds
      #   10-19 secs      # => less than 20 seconds
      #   20-39 secs      # => half a minute
      #   40-59 secs      # => less than a minute
      #   60-89 secs      # => 1 minute
      #
      #   from_time = Time.now
      #   distance_of_time_in_words(from_time, from_time + 50.minutes)                                # => about 1 hour
      #   distance_of_time_in_words(from_time, 50.minutes.from_now)                                   # => about 1 hour
      #   distance_of_time_in_words(from_time, from_time + 15.seconds)                                # => less than a minute
      #   distance_of_time_in_words(from_time, from_time + 15.seconds, include_seconds: true)      # => less than 20 seconds
      #   distance_of_time_in_words(from_time, 3.years.from_now)                                      # => about 3 years
      #   distance_of_time_in_words(from_time, from_time + 60.hours)                                  # => 3 days
      #   distance_of_time_in_words(from_time, from_time + 45.seconds, include_seconds: true)      # => less than a minute
      #   distance_of_time_in_words(from_time, from_time - 45.seconds, include_seconds: true)      # => less than a minute
      #   distance_of_time_in_words(from_time, 76.seconds.from_now)                                   # => 1 minute
      #   distance_of_time_in_words(from_time, from_time + 1.year + 3.days)                           # => about 1 year
      #   distance_of_time_in_words(from_time, from_time + 3.years + 6.months)                        # => over 3 years
      #   distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years
      #
      #   to_time = Time.now + 6.years + 19.days
      #   distance_of_time_in_words(from_time, to_time, include_seconds: true)                     # => about 6 years
      #   distance_of_time_in_words(to_time, from_time, include_seconds: true)                     # => about 6 years
      #   distance_of_time_in_words(Time.now, Time.now)                                               # => less than a minute
      def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
        if include_seconds_or_options.is_a?(Hash)
          options = include_seconds_or_options
        else
          ActiveSupport::Deprecation.warn "distance_of_time_in_words and time_ago_in_words now accept :include_seconds " +
                                          "as a part of options hash, not a boolean argument"
          options[:include_seconds] ||= !!include_seconds_or_options
        end

        options = {
          scope: :'datetime.distance_in_words'
        }.merge!(options)

        from_time = from_time.to_time if from_time.respond_to?(:to_time)
        to_time = to_time.to_time if to_time.respond_to?(:to_time)
        from_time, to_time = to_time, from_time if from_time > to_time
        distance_in_minutes = ((to_time - from_time)/60.0).round
        distance_in_seconds = (to_time - from_time).round

        I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale|
          case distance_in_minutes
            when 0..1
              return distance_in_minutes == 0 ?
                     locale.t(:less_than_x_minutes, :count => 1) :
                     locale.t(:x_minutes, :count => distance_in_minutes) unless options[:include_seconds]

              case distance_in_seconds
                when 0..4   then locale.t :less_than_x_seconds, :count => 5
                when 5..9   then locale.t :less_than_x_seconds, :count => 10
                when 10..19 then locale.t :less_than_x_seconds, :count => 20
                when 20..39 then locale.t :half_a_minute
                when 40..59 then locale.t :less_than_x_minutes, :count => 1
                else             locale.t :x_minutes,           :count => 1
              end

            when 2...45           then locale.t :x_minutes,      :count => distance_in_minutes
            when 45...90          then locale.t :about_x_hours,  :count => 1
            # 90 mins up to 24 hours
            when 90...1440        then locale.t :about_x_hours,  :count => (distance_in_minutes.to_f / 60.0).round
            # 24 hours up to 42 hours
            when 1440...2520      then locale.t :x_days,         :count => 1
            # 42 hours up to 30 days
            when 2520...43200     then locale.t :x_days,         :count => (distance_in_minutes.to_f / 1440.0).round
            # 30 days up to 60 days
            when 43200...86400    then locale.t :about_x_months, :count => (distance_in_minutes.to_f / 43200.0).round
            # 60 days up to 365 days
            when 86400...525600   then locale.t :x_months,       :count => (distance_in_minutes.to_f / 43200.0).round
            else
              if from_time.acts_like?(:time) && to_time.acts_like?(:time)
                fyear = from_time.year
                fyear += 1 if from_time.month >= 3
                tyear = to_time.year
                tyear -= 1 if to_time.month < 3
                leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
                minute_offset_for_leap_year = leap_years * 1440
                # Discount the leap year days when calculating year distance.
                # e.g. if there are 20 leap year days between 2 dates having the same day
                # and month then the based on 365 days calculation
                # the distance in years will come out to over 80 years when in written
                # english it would read better as about 80 years.
                minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
              else
                minutes_with_offset = distance_in_minutes
              end
              remainder                   = (minutes_with_offset % 525600)
              distance_in_years           = (minutes_with_offset.div 525600)
              if remainder < 131400
                locale.t(:about_x_years,  :count => distance_in_years)
              elsif remainder < 394200
                locale.t(:over_x_years,   :count => distance_in_years)
              else
                locale.t(:almost_x_years, :count => distance_in_years + 1)
              end
          end
        end
      end

      # Like <tt>distance_of_time_in_words</tt>, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
      #
      #   time_ago_in_words(3.minutes.from_now)                 # => 3 minutes
      #   time_ago_in_words(3.minutes.ago)                      # => 3 minutes
      #   time_ago_in_words(Time.now - 15.hours)                # => about 15 hours
      #   time_ago_in_words(Time.now)                           # => less than a minute
      #   time_ago_in_words(Time.now, include_seconds: true) # => less than 5 seconds
      #
      #   from_time = Time.now - 3.days - 14.minutes - 25.seconds
      #   time_ago_in_words(from_time)      # => 3 days
      #
      #   from_time = (3.days + 14.minutes + 25.seconds).ago
      #   time_ago_in_words(from_time)      # => 3 days
      #
      # Note that you cannot pass a <tt>Numeric</tt> value to <tt>time_ago_in_words</tt>.
      #
      def time_ago_in_words(from_time, include_seconds_or_options = {})
        distance_of_time_in_words(from_time, Time.now, include_seconds_or_options)
      end

      alias_method :distance_of_time_in_words_to_now, :time_ago_in_words

      # Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based
      # attribute (identified by +method+) on an object assigned to the template (identified by +object+).
      #
      # ==== Options
      # * <tt>:use_month_numbers</tt> - Set to true if you want to use month numbers rather than month names (e.g.
      #   "2" instead of "February").
      # * <tt>:use_two_digit_numbers</tt> - Set to true if you want to display two digit month and day numbers (e.g.
      #   "02" instead of "February" and "08" instead of "8").
      # * <tt>:use_short_month</tt>   - Set to true if you want to use abbreviated month names instead of full
      #   month names (e.g. "Feb" instead of "February").
      # * <tt>:add_month_numbers</tt>  - Set to true if you want to use both month numbers and month names (e.g.
      #   "2 - February" instead of "February").
      # * <tt>:use_month_names</tt>   - Set to an array with 12 month names if you want to customize month names.
      #   Note: You can also use Rails' i18n functionality for this.
      # * <tt>:date_separator</tt>    - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
      # * <tt>:start_year</tt>        - Set the start year for the year select. Default is <tt>Time.now.year - 5</tt>.
      # * <tt>:end_year</tt>          - Set the end year for the year select. Default is <tt>Time.now.year + 5</tt>.
      # * <tt>:discard_day</tt>       - Set to true if you don't want to show a day select. This includes the day
      #   as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the
      #   first of the given month in order to not create invalid dates like 31 February.
      # * <tt>:discard_month</tt>     - Set to true if you don't want to show a month select. This includes the month
      #   as a hidden field instead of showing a select field. Also note that this implicitly sets :discard_day to true.
      # * <tt>:discard_year</tt>      - Set to true if you don't want to show a year select. This includes the year
      #   as a hidden field instead of showing a select field.
      # * <tt>:order</tt>             - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> to
      #   customize the order in which the select fields are shown. If you leave out any of the symbols, the respective
      #   select will not be shown (like when you set <tt>discard_xxx: true</tt>. Defaults to the order defined in
      #   the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
      # * <tt>:include_blank</tt>     - Include a blank option in every select field so it's possible to set empty
      #   dates.
      # * <tt>:default</tt>           - Set a default date if the affected date isn't set or is nil.
      # * <tt>:selected</tt>          - Set a date that overrides the actual value.
      # * <tt>:disabled</tt>          - Set to true if you want show the select fields as disabled.
      # * <tt>:prompt</tt>            - Set to true (for a generic prompt), a prompt string or a hash of prompt strings
      #   for <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:minute</tt> and <tt>:second</tt>.
      #   Setting this option prepends a select option with a generic prompt  (Day, Month, Year, Hour, Minute, Seconds)
      #   or the given prompt string.
      # * <tt>:with_css_classes</tt>   - Set to true if you want assign different styles for 'select' tags. This option
      #   automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags.
      #
      # If anything is passed in the +html_options+ hash it will be applied to every select tag in the set.
      #
      # NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
      #   date_select("article", "written_on")
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
      #   # with the year in the year drop down box starting at 1995.
      #   date_select("article", "written_on", start_year: 1995)
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
      #   # with the year in the year drop down box starting at 1995, numbers used for months instead of words,
      #   # and without a day select box.
      #   date_select("article", "written_on", start_year: 1995, use_month_numbers: true,
      #                                     discard_day: true, include_blank: true)
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
      #   # with two digit numbers used for months and days.
      #   date_select("article", "written_on", use_two_digit_numbers: true)
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
      #   # with the fields ordered as day, month, year rather than month, day, year.
      #   date_select("article", "written_on", order: [:day, :month, :year])
      #
      #   # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
      #   # lacking a year field.
      #   date_select("user", "birthday", order: [:month, :day])
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
      #   # which is initially set to the date 3 days from the current date
      #   date_select("article", "written_on", default: 3.days.from_now)
      #
      #   # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
      #   # which is set in the form with todays date, regardless of the value in the Active Record object.
      #   date_select("article", "written_on", selected: Date.today)
      #
      #   # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
      #   # that will have a default day of 20.
      #   date_select("credit_card", "bill_due", default: { day: 20 })
      #
      #   # Generates a date select with custom prompts.
      #   date_select("article", "written_on", prompt: { day: 'Select day', month: 'Select month', year: 'Select year' })
      #
      # The selects are prepared for multi-parameter assignment to an Active Record object.
      #
      # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
      # all month choices are valid.
      def date_select(object_name, method, options = {}, html_options = {})
        Tags::DateSelect.new(object_name, method, self, options, html_options).render
      end

      # Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
      # specified time-based attribute (identified by +method+) on an object assigned to the template (identified by
      # +object+). You can include the seconds with <tt>:include_seconds</tt>. You can get hours in the AM/PM format
      # with <tt>:ampm</tt> option.
      #
      # This method will also generate 3 input hidden tags, for the actual year, month and day unless the option
      # <tt>:ignore_date</tt> is set to +true+. If you set the <tt>:ignore_date</tt> to +true+, you must have a
      # +date_select+ on the same method within the form otherwise an exception will be raised.
      #
      # If anything is passed in the html_options hash it will be applied to every select tag in the set.
      #
      #   # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
      #   time_select("article", "sunrise")
      #
      #   # Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in
      #   # the sunrise attribute.
      #   time_select("article", "start_time", include_seconds: true)
      #
      #   # You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30 and 45.
      #   time_select 'game', 'game_time', {minute_step: 15}
      #
      #   # Creates a time select tag with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
      #   time_select("article", "written_on", prompt: {hour: 'Choose hour', minute: 'Choose minute', second: 'Choose seconds'})
      #   time_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
      #   time_select("article", "written_on", prompt: true) # generic prompts for all
      #
      #   # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
      #   time_select 'game', 'game_time', {ampm: true}
      #
      # The selects are prepared for multi-parameter assignment to an Active Record object.
      #
      # Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that
      # all month choices are valid.
      def time_select(object_name, method, options = {}, html_options = {})
        Tags::TimeSelect.new(object_name, method, self, options, html_options).render
      end

      # Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a
      # specified datetime-based attribute (identified by +method+) on an object assigned to the template (identified
      # by +object+).
      #
      # If anything is passed in the html_options hash it will be applied to every select tag in the set.
      #
      #   # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
      #   # attribute.
      #   datetime_select("article", "written_on")
      #
      #   # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
      #   # article variable in the written_on attribute.
      #   datetime_select("article", "written_on", start_year: 1995)
      #
      #   # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
      #   # be stored in the trip variable in the departing attribute.
      #   datetime_select("trip", "departing", default: 3.days.from_now)
      #
      #   # Generate a datetime select with hours in the AM/PM format
      #   datetime_select("article", "written_on", ampm: true)
      #
      #   # Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable
      #   # as the written_on attribute.
      #   datetime_select("article", "written_on", discard_type: true)
      #
      #   # Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
      #   datetime_select("article", "written_on", prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
      #   datetime_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
      #   datetime_select("article", "written_on", prompt: true) # generic prompts for all
      #
      # The selects are prepared for multi-parameter assignment to an Active Record object.
      def datetime_select(object_name, method, options = {}, html_options = {})
        Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render
      end

      # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the
      # +datetime+. It's also possible to explicitly set the order of the tags using the <tt>:order</tt> option with
      # an array of symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not
      # supply a Symbol, it will be appended onto the <tt>:order</tt> passed in. You can also add
      # <tt>:date_separator</tt>, <tt>:datetime_separator</tt> and <tt>:time_separator</tt> keys to the +options+ to
      # control visual display of the elements.
      #
      # If anything is passed in the html_options hash it will be applied to every select tag in the set.
      #
      #   my_date_time = Time.now + 4.days
      #
      #   # Generates a datetime select that defaults to the datetime in my_date_time (four days after today).
      #   select_datetime(my_date_time)
      #
      #   # Generates a datetime select that defaults to today (no specified datetime)
      #   select_datetime()
      #
      #   # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
      #   # with the fields ordered year, month, day rather than month, day, year.
      #   select_datetime(my_date_time, order: [:year, :month, :day])
      #
      #   # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
      #   # with a '/' between each date field.
      #   select_datetime(my_date_time, date_separator: '/')
      #
      #   # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
      #   # with a date fields separated by '/', time fields separated by '' and the date and time fields
      #   # separated by a comma (',').
      #   select_datetime(my_date_time, date_separator: '/', time_separator: '', datetime_separator: ',')
      #
      #   # Generates a datetime select that discards the type of the field and defaults to the datetime in
      #   # my_date_time (four days after today)
      #   select_datetime(my_date_time, discard_type: true)
      #
      #   # Generate a datetime field with hours in the AM/PM format
      #   select_datetime(my_date_time, ampm: true)
      #
      #   # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
      #   # prefixed with 'payday' rather than 'date'
      #   select_datetime(my_date_time, prefix: 'payday')
      #
      #   # Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
      #   select_datetime(my_date_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
      #   select_datetime(my_date_time, prompt: {hour: true}) # generic prompt for hours
      #   select_datetime(my_date_time, prompt: true) # generic prompts for all
      def select_datetime(datetime = Time.current, options = {}, html_options = {})
        DateTimeSelector.new(datetime, options, html_options).select_datetime
      end

      # Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+.
      # It's possible to explicitly set the order of the tags using the <tt>:order</tt> option with an array of
      # symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order.
      # If the array passed to the <tt>:order</tt> option does not contain all the three symbols, all tags will be hidden.
      #
      # If anything is passed in the html_options hash it will be applied to every select tag in the set.
      #
      #   my_date = Time.now + 6.days
      #
      #   # Generates a date select that defaults to the date in my_date (six days after today).
      #   select_date(my_date)
      #
      #   # Generates a date select that defaults to today (no specified date).
      #   select_date()
      #
      #   # Generates a date select that defaults to the date in my_date (six days after today)
      #   # with the fields ordered year, month, day rather than month, day, year.
      #   select_date(my_date, order: [:year, :month, :day])
      #
      #   # Generates a date select that discards the type of the field and defaults to the date in
      #   # my_date (six days after today).
      #   select_date(my_date, discard_type: true)
      #
      #   # Generates a date select that defaults to the date in my_date,
      #   # which has fields separated by '/'.
      #   select_date(my_date, date_separator: '/')
      #
      #   # Generates a date select that defaults to the datetime in my_date (six days after today)
      #   # prefixed with 'payday' rather than 'date'.
      #   select_date(my_date, prefix: 'payday')
      #
      #   # Generates a date select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
      #   select_date(my_date, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
      #   select_date(my_date, prompt: {hour: true}) # generic prompt for hours
      #   select_date(my_date, prompt: true) # generic prompts for all
      def select_date(date = Date.current, options = {}, html_options = {})
        DateTimeSelector.new(date, options, html_options).select_date
      end

      # Returns a set of html select-tags (one for hour and minute).
      # You can set <tt>:time_separator</tt> key to format the output, and
      # the <tt>:include_seconds</tt> option to include an input for seconds.
      #
      # If anything is passed in the html_options hash it will be applied to every select tag in the set.
      #
      #   my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
      #
      #   # Generates a time select that defaults to the time in my_time.
      #   select_time(my_time)
      #
      #   # Generates a time select that defaults to the current time (no specified time).
      #   select_time()
      #
      #   # Generates a time select that defaults to the time in my_time,
      #   # which has fields separated by ':'.
      #   select_time(my_time, time_separator: ':')
      #
      #   # Generates a time select that defaults to the time in my_time,
      #   # that also includes an input for seconds.
      #   select_time(my_time, include_seconds: true)
      #
      #   # Generates a time select that defaults to the time in my_time, that has fields
      #   # separated by ':' and includes an input for seconds.
      #   select_time(my_time, time_separator: ':', include_seconds: true)
      #
      #   # Generate a time select field with hours in the AM/PM format
      #   select_time(my_time, ampm: true)
      #
      #   # Generates a time select field with hours that range from 2 to 14
      #   select_time(my_time, start_hour: 2, end_hour: 14)
      #
      #   # Generates a time select with a custom prompt. Use <tt>:prompt</tt> to true for generic prompts.
      #   select_time(my_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
      #   select_time(my_time, prompt: {hour: true}) # generic prompt for hours
      #   select_time(my_time, prompt: true) # generic prompts for all
      def select_time(datetime = Time.current, options = {}, html_options = {})
        DateTimeSelector.new(datetime, options, html_options).select_time
      end

      # Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
      # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
      # Override the field name using the <tt>:field_name</tt> option, 'second' by default.
      #
      #   my_time = Time.now + 16.minutes
      #
      #   # Generates a select field for seconds that defaults to the seconds for the time in my_time.
      #   select_second(my_time)
      #
      #   # Generates a select field for seconds that defaults to the number given.
      #   select_second(33)
      #
      #   # Generates a select field for seconds that defaults to the seconds for the time in my_time
      #   # that is named 'interval' rather than 'second'.
      #   select_second(my_time, field_name: 'interval')
      #
      #   # Generates a select field for seconds with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_second(14, prompt: 'Choose seconds')
      def select_second(datetime, options = {}, html_options = {})
        DateTimeSelector.new(datetime, options, html_options).select_second
      end

      # Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
      # Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute
      # selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
      # Override the field name using the <tt>:field_name</tt> option, 'minute' by default.
      #
      #   my_time = Time.now + 6.hours
      #
      #   # Generates a select field for minutes that defaults to the minutes for the time in my_time.
      #   select_minute(my_time)
      #
      #   # Generates a select field for minutes that defaults to the number given.
      #   select_minute(14)
      #
      #   # Generates a select field for minutes that defaults to the minutes for the time in my_time
      #   # that is named 'moment' rather than 'minute'.
      #   select_minute(my_time, field_name: 'moment')
      #
      #   # Generates a select field for minutes with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_minute(14, prompt: 'Choose minutes')
      def select_minute(datetime, options = {}, html_options = {})
        DateTimeSelector.new(datetime, options, html_options).select_minute
      end

      # Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
      # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
      # Override the field name using the <tt>:field_name</tt> option, 'hour' by default.
      #
      #   my_time = Time.now + 6.hours
      #
      #   # Generates a select field for hours that defaults to the hour for the time in my_time.
      #   select_hour(my_time)
      #
      #   # Generates a select field for hours that defaults to the number given.
      #   select_hour(13)
      #
      #   # Generates a select field for hours that defaults to the hour for the time in my_time
      #   # that is named 'stride' rather than 'hour'.
      #   select_hour(my_time, field_name: 'stride')
      #
      #   # Generates a select field for hours with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_hour(13, prompt: 'Choose hour')
      #
      #   # Generate a select field for hours in the AM/PM format
      #   select_hour(my_time, ampm: true)
      #
      #   # Generates a select field that includes options for hours from 2 to 14.
      #   select_hour(my_time, start_hour: 2, end_hour: 14)
      def select_hour(datetime, options = {}, html_options = {})
        DateTimeSelector.new(datetime, options, html_options).select_hour
      end

      # Returns a select tag with options for each of the days 1 through 31 with the current day selected.
      # The <tt>date</tt> can also be substituted for a day number.
      # If you want to display days with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
      # Override the field name using the <tt>:field_name</tt> option, 'day' by default.
      #
      #   my_date = Time.now + 2.days
      #
      #   # Generates a select field for days that defaults to the day for the date in my_date.
      #   select_day(my_time)
      #
      #   # Generates a select field for days that defaults to the number given.
      #   select_day(5)
      #
      #   # Generates a select field for days that defaults to the number given, but displays it with two digits.
      #   select_day(5, use_two_digit_numbers: true)
      #
      #   # Generates a select field for days that defaults to the day for the date in my_date
      #   # that is named 'due' rather than 'day'.
      #   select_day(my_time, field_name: 'due')
      #
      #   # Generates a select field for days with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_day(5, prompt: 'Choose day')
      def select_day(date, options = {}, html_options = {})
        DateTimeSelector.new(date, options, html_options).select_day
      end

      # Returns a select tag with options for each of the months January through December with the current month
      # selected. The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are
      # used as values (what's submitted to the server). It's also possible to use month numbers for the presentation
      # instead of names -- set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you
      # want both numbers and names, set the <tt>:add_month_numbers</tt> key in +options+ to true. If you would prefer
      # to show month names as abbreviations, set the <tt>:use_short_month</tt> key in +options+ to true. If you want
      # to use your own month names, set the <tt>:use_month_names</tt> key in +options+ to an array of 12 month names.
      # If you want to display months with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
      # Override the field name using the <tt>:field_name</tt> option, 'month' by default.
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys like "January", "March".
      #   select_month(Date.today)
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # is named "start" rather than "month".
      #   select_month(Date.today, field_name: 'start')
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys like "1", "3".
      #   select_month(Date.today, use_month_numbers: true)
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys like "1 - January", "3 - March".
      #   select_month(Date.today, add_month_numbers: true)
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys like "Jan", "Mar".
      #   select_month(Date.today, use_short_month: true)
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys like "Januar", "Marts."
      #   select_month(Date.today, use_month_names: %w(Januar Februar Marts ...))
      #
      #   # Generates a select field for months that defaults to the current month that
      #   # will use keys with two digit numbers like "01", "03".
      #   select_month(Date.today, use_two_digit_numbers: true)
      #
      #   # Generates a select field for months with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_month(14, prompt: 'Choose month')
      def select_month(date, options = {}, html_options = {})
        DateTimeSelector.new(date, options, html_options).select_month
      end

      # Returns a select tag with options for each of the five years on each side of the current, which is selected.
      # The five year radius can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the
      # +options+. Both ascending and descending year lists are supported by making <tt>:start_year</tt> less than or
      # greater than <tt>:end_year</tt>. The <tt>date</tt> can also be substituted for a year given as a number.
      # Override the field name using the <tt>:field_name</tt> option, 'year' by default.
      #
      #   # Generates a select field for years that defaults to the current year that
      #   # has ascending year values.
      #   select_year(Date.today, start_year: 1992, end_year: 2007)
      #
      #   # Generates a select field for years that defaults to the current year that
      #   # is named 'birth' rather than 'year'.
      #   select_year(Date.today, field_name: 'birth')
      #
      #   # Generates a select field for years that defaults to the current year that
      #   # has descending year values.
      #   select_year(Date.today, start_year: 2005, end_year: 1900)
      #
      #   # Generates a select field for years that defaults to the year 2006 that
      #   # has ascending year values.
      #   select_year(2006, start_year: 2000, end_year: 2010)
      #
      #   # Generates a select field for years with a custom prompt. Use <tt>prompt: true</tt> for a
      #   # generic prompt.
      #   select_year(14, prompt: 'Choose year')
      def select_year(date, options = {}, html_options = {})
        DateTimeSelector.new(date, options, html_options).select_year
      end

      # Returns an html time tag for the given date or time.
      #
      #   time_tag Date.today  # =>
      #     <time datetime="2010-11-04">November 04, 2010</time>
      #   time_tag Time.now  # =>
      #     <time datetime="2010-11-04T17:55:45+01:00">November 04, 2010 17:55</time>
      #   time_tag Date.yesterday, 'Yesterday'  # =>
      #     <time datetime="2010-11-03">Yesterday</time>
      #   time_tag Date.today, pubdate: true  # =>
      #     <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time>
      #
      #   <%= time_tag Time.now do %>
      #     <span>Right now</span>
      #   <% end %>
      #   # => <time datetime="2010-11-04T17:55:45+01:00"><span>Right now</span></time>
      def time_tag(date_or_time, *args, &block)
        options  = args.extract_options!
        format   = options.delete(:format) || :long
        content  = args.first || I18n.l(date_or_time, :format => format)
        datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.rfc3339

        content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block)
      end
    end

    class DateTimeSelector #:nodoc:
      include ActionView::Helpers::TagHelper

      DEFAULT_PREFIX = 'date'.freeze
      POSITION = {
        :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
      }.freeze

      AMPM_TRANSLATION = Hash[
        [[0, "12 AM"], [1, "01 AM"], [2, "02 AM"], [3, "03 AM"],
         [4, "04 AM"], [5, "05 AM"], [6, "06 AM"], [7, "07 AM"],
         [8, "08 AM"], [9, "09 AM"], [10, "10 AM"], [11, "11 AM"],
         [12, "12 PM"], [13, "01 PM"], [14, "02 PM"], [15, "03 PM"],
         [16, "04 PM"], [17, "05 PM"], [18, "06 PM"], [19, "07 PM"],
         [20, "08 PM"], [21, "09 PM"], [22, "10 PM"], [23, "11 PM"]]
      ].freeze

      def initialize(datetime, options = {}, html_options = {})
        @options      = options.dup
        @html_options = html_options.dup
        @datetime     = datetime
        @options[:datetime_separator] ||= ' &mdash; '
        @options[:time_separator]     ||= ' : '
      end

      def select_datetime
        order = date_order.dup
        order -= [:hour, :minute, :second]
        @options[:discard_year]   ||= true unless order.include?(:year)
        @options[:discard_month]  ||= true unless order.include?(:month)
        @options[:discard_day]    ||= true if @options[:discard_month] || !order.include?(:day)
        @options[:discard_minute] ||= true if @options[:discard_hour]
        @options[:discard_second] ||= true unless @options[:include_seconds] && !@options[:discard_minute]

        set_day_if_discarded

        if @options[:tag] && @options[:ignore_date]
          select_time
        else
          [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }
          order += [:hour, :minute, :second] unless @options[:discard_hour]

          build_selects_from_types(order)
        end
      end

      def select_date
        order = date_order.dup

        @options[:discard_hour]     = true
        @options[:discard_minute]   = true
        @options[:discard_second]   = true

        @options[:discard_year]   ||= true unless order.include?(:year)
        @options[:discard_month]  ||= true unless order.include?(:month)
        @options[:discard_day]    ||= true if @options[:discard_month] || !order.include?(:day)

        set_day_if_discarded

        [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }

        build_selects_from_types(order)
      end

      def select_time
        order = []

        @options[:discard_month]    = true
        @options[:discard_year]     = true
        @options[:discard_day]      = true
        @options[:discard_second] ||= true unless @options[:include_seconds]

        order += [:year, :month, :day] unless @options[:ignore_date]

        order += [:hour, :minute]
        order << :second if @options[:include_seconds]

        build_selects_from_types(order)
      end

      def select_second
        if @options[:use_hidden] || @options[:discard_second]
          build_hidden(:second, sec) if @options[:include_seconds]
        else
          build_options_and_select(:second, sec)
        end
      end

      def select_minute
        if @options[:use_hidden] || @options[:discard_minute]
          build_hidden(:minute, min)
        else
          build_options_and_select(:minute, min, :step => @options[:minute_step])
        end
      end

      def select_hour
        if @options[:use_hidden] || @options[:discard_hour]
          build_hidden(:hour, hour)
        else
          options         = {}
          options[:ampm]  = @options[:ampm] || false
          options[:start] = @options[:start_hour] || 0
          options[:end]   = @options[:end_hour] || 23
          build_options_and_select(:hour, hour, options)
        end
      end

      def select_day
        if @options[:use_hidden] || @options[:discard_day]
          build_hidden(:day, day || 1)
        else
          build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers])
        end
      end

      def select_month
        if @options[:use_hidden] || @options[:discard_month]
          build_hidden(:month, month || 1)
        else
          month_options = []
          1.upto(12) do |month_number|
            options = { :value => month_number }
            options[:selected] = "selected" if month == month_number
            month_options << content_tag(:option, month_name(month_number), options) + "\n"
          end
          build_select(:month, month_options.join)
        end
      end

      def select_year
        if !@datetime || @datetime == 0
          val = '1'
          middle_year = Date.today.year
        else
          val = middle_year = year
        end

        if @options[:use_hidden] || @options[:discard_year]
          build_hidden(:year, val)
        else
          options                     = {}
          options[:start]             = @options[:start_year] || middle_year - 5
          options[:end]               = @options[:end_year] || middle_year + 5
          options[:step]              = options[:start] < options[:end] ? 1 : -1
          options[:leading_zeros]     = false
          options[:max_years_allowed] = @options[:max_years_allowed] || 1000

          if (options[:end] - options[:start]).abs > options[:max_years_allowed]
            raise ArgumentError,  "There're too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter"
          end

          build_options_and_select(:year, val, options)
        end
      end

      private
        %w( sec min hour day month year ).each do |method|
          define_method(method) do
            @datetime.kind_of?(Numeric) ? @datetime : @datetime.send(method) if @datetime
          end
        end

        # If the day is hidden, the day should be set to the 1st so all month and year choices are
        # valid. Otherwise, February 31st or February 29th, 2011 can be selected, which are invalid.
        def set_day_if_discarded
          if @datetime && @options[:discard_day]
            @datetime = @datetime.change(:day => 1)
          end
        end

        # Returns translated month names, but also ensures that a custom month
        # name array has a leading nil element.
        def month_names
          @month_names ||= begin
            month_names = @options[:use_month_names] || translated_month_names
            month_names.unshift(nil) if month_names.size < 13
            month_names
          end
        end

        # Returns translated month names.
        #  => [nil, "January", "February", "March",
        #           "April", "May", "June", "July",
        #           "August", "September", "October",
        #           "November", "December"]
        #
        # If <tt>:use_short_month</tt> option is set
        #  => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        #           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        def translated_month_names
          key = @options[:use_short_month] ? :'date.abbr_month_names' : :'date.month_names'
          I18n.translate(key, :locale => @options[:locale])
        end

        # Lookup month name for number.
        #  month_name(1) => "January"
        #
        # If <tt>:use_month_numbers</tt> option is passed
        #  month_name(1) => 1
        #
        # If <tt>:use_two_month_numbers</tt> option is passed
        #  month_name(1) => '01'
        #
        # If <tt>:add_month_numbers</tt> option is passed
        #  month_name(1) => "1 - January"
        def month_name(number)
          if @options[:use_month_numbers]
            number
          elsif @options[:use_two_digit_numbers]
            sprintf "%02d", number
          elsif @options[:add_month_numbers]
            "#{number} - #{month_names[number]}"
          else
            month_names[number]
          end
        end

        def date_order
          @date_order ||= @options[:order] || translated_date_order
        end

        def translated_date_order
          date_order = I18n.translate(:'date.order', :locale => @options[:locale], :default => [])
          date_order = date_order.map { |element| element.to_sym }

          forbidden_elements = date_order - [:year, :month, :day]
          if forbidden_elements.any?
            raise StandardError,
              "#{@options[:locale]}.date.order only accepts :year, :month and :day"
          end

          date_order
        end

        # Build full select tag from date type and options.
        def build_options_and_select(type, selected, options = {})
          build_select(type, build_options(selected, options))
        end

        # Build select option html from date value and options.
        #  build_options(15, start: 1, end: 31)
        #  => "<option value="1">1</option>
        #      <option value="2">2</option>
        #      <option value="3">3</option>..."
        #
        # If <tt>use_two_digit_numbers: true</tt> option is passed
        #  build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
        #  => "<option value="1">01</option>
        #      <option value="2">02</option>
        #      <option value="3">03</option>..."
        #
        # If <tt>:step</tt> options is passed
        #  build_options(15, start: 1, end: 31, step: 2)
        #  => "<option value="1">1</option>
        #      <option value="3">3</option>
        #      <option value="5">5</option>..."
        def build_options(selected, options = {})
          options = {
            leading_zeros: true, ampm: false, use_two_digit_numbers: false
          }.merge!(options)

          start         = options.delete(:start) || 0
          stop          = options.delete(:end) || 59
          step          = options.delete(:step) || 1
          leading_zeros = options.delete(:leading_zeros)

          select_options = []
          start.step(stop, step) do |i|
            value = leading_zeros ? sprintf("%02d", i) : i
            tag_options = { :value => value }
            tag_options[:selected] = "selected" if selected == i
            text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value
            text = options[:ampm] ? AMPM_TRANSLATION[i] : text
            select_options << content_tag(:option, text, tag_options)
          end

          (select_options.join("\n") + "\n").html_safe
        end

        # Builds select tag from date type and html select options.
        #  build_select(:month, "<option value="1">January</option>...")
        #  => "<select id="post_written_on_2i" name="post[written_on(2i)]">
        #        <option value="1">January</option>...
        #      </select>"
        def build_select(type, select_options_as_html)
          select_options = {
            :id => input_id_from_type(type),
            :name => input_name_from_type(type)
          }.merge!(@html_options)
          select_options[:disabled] = 'disabled' if @options[:disabled]
          select_options[:class] = type if @options[:with_css_classes]

          select_html = "\n"
          select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank]
          select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
          select_html << select_options_as_html

          (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe
        end

        # Builds a prompt option tag with supplied options or from default options.
        #  prompt_option_tag(:month, prompt: 'Select month')
        #  => "<option value="">Select month</option>"
        def prompt_option_tag(type, options)
          prompt = case options
            when Hash
              default_options = {:year => false, :month => false, :day => false, :hour => false, :minute => false, :second => false}
              default_options.merge!(options)[type.to_sym]
            when String
              options
            else
              I18n.translate(:"datetime.prompts.#{type}", :locale => @options[:locale])
          end

          prompt ? content_tag(:option, prompt, :value => '') : ''
        end

        # Builds hidden input tag for date part and value.
        #  build_hidden(:year, 2008)
        #  => "<input id="post_written_on_1i" name="post[written_on(1i)]" type="hidden" value="2008" />"
        def build_hidden(type, value)
          select_options = {
            :type => "hidden",
            :id => input_id_from_type(type),
            :name => input_name_from_type(type),
            :value => value
          }.merge!(@html_options.slice(:disabled))
          select_options[:disabled] = 'disabled' if @options[:disabled]

          tag(:input, select_options) + "\n".html_safe
        end

        # Returns the name attribute for the input tag.
        #  => post[written_on(1i)]
        def input_name_from_type(type)
          prefix = @options[:prefix] || ActionView::Helpers::DateTimeSelector::DEFAULT_PREFIX
          prefix += "[#{@options[:index]}]" if @options.has_key?(:index)

          field_name = @options[:field_name] || type
          if @options[:include_position]
            field_name += "(#{ActionView::Helpers::DateTimeSelector::POSITION[type]}i)"
          end

          @options[:discard_type] ? prefix : "#{prefix}[#{field_name}]"
        end

        # Returns the id attribute for the input tag.
        #  => "post_written_on_1i"
        def input_id_from_type(type)
          id = input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
          id = @options[:namespace] + '_' + id if @options[:namespace]

          id
        end

        # Given an ordering of datetime components, create the selection HTML
        # and join them with their appropriate separators.
        def build_selects_from_types(order)
          select = ''
          first_visible = order.find { |type| !@options[:"discard_#{type}"] }
          order.reverse.each do |type|
            separator = separator(type) unless type == first_visible # don't add before first visible field
            select.insert(0, separator.to_s + send("select_#{type}").to_s)
          end
          select.html_safe
        end

        # Returns the separator for a given datetime component.
        def separator(type)
          return "" if @options[:use_hidden]

          case type
            when :year, :month, :day
              @options[:"discard_#{type}"] ? "" : @options[:date_separator]
            when :hour
              (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator]
            when :minute, :second
              @options[:"discard_#{type}"] ? "" : @options[:time_separator]
          end
        end
    end

    class FormBuilder
      # Wraps ActionView::Helpers::DateHelper#date_select for form builders:
      #
      #   <%= form_for @person do |f| %>
      #     <%= f.date_select :birth_date %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def date_select(method, options = {}, html_options = {})
        @template.date_select(@object_name, method, objectify_options(options), html_options)
      end

      # Wraps ActionView::Helpers::DateHelper#time_select for form builders:
      #
      #   <%= form_for @race do |f| %>
      #     <%= f.time_select :average_lap %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def time_select(method, options = {}, html_options = {})
        @template.time_select(@object_name, method, objectify_options(options), html_options)
      end

      # Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
      #
      #   <%= form_for @person do |f| %>
      #     <%= f.time_select :last_request_at %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def datetime_select(method, options = {}, html_options = {})
        @template.datetime_select(@object_name, method, objectify_options(options), html_options)
      end
    end
  end
end
module ActionView
  # = Action View Debug Helper
  #
  # Provides a set of methods for making it easier to debug Rails objects.
  module Helpers
    module DebugHelper

      include TagHelper

      # Returns a YAML representation of +object+ wrapped with <pre> and </pre>.
      # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead.
      # Useful for inspecting an object at the time of rendering.
      #
      #   @user = User.new({ username: 'testing', password: 'xyz', age: 42}) %>
      #   debug(@user)
      #   # =>
      #   <pre class='debug_dump'>--- !ruby/object:User
      #   attributes:
      #   &nbsp; updated_at:
      #   &nbsp; username: testing
      #
      #   &nbsp; age: 42
      #   &nbsp; password: xyz
      #   &nbsp; created_at:
      #   attributes_cache: {}
      #
      #   new_record: true
      #   </pre>
      def debug(object)
        Marshal::dump(object)
        object = ERB::Util.html_escape(object.to_yaml).gsub("  ", "&nbsp; ").html_safe
        content_tag(:pre, object, :class => "debug_dump")
      rescue Exception  # errors from Marshal or YAML
        # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback
        content_tag(:code, object.to_yaml, :class => "debug_dump")
      end
    end
  end
end
require 'cgi'
require 'action_view/helpers/date_helper'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/form_tag_helper'
require 'action_view/helpers/active_model_helper'
require 'action_view/helpers/tags'
require 'action_view/model_naming'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/string/inflections'

module ActionView
  # = Action View Form Helpers
  module Helpers
    # Form helpers are designed to make working with resources much easier
    # compared to using vanilla HTML.
    #
    # Typically, a form designed to create or update a resource reflects the
    # identity of the resource in several ways: (i) the url that the form is
    # sent to (the form element's +action+ attribute) should result in a request
    # being routed to the appropriate controller action (with the appropriate <tt>:id</tt>
    # parameter in the case of an existing resource), (ii) input fields should
    # be named in such a way that in the controller their values appear in the
    # appropriate places within the +params+ hash, and (iii) for an existing record,
    # when the form is initially displayed, input fields corresponding to attributes
    # of the resource should show the current values of those attributes.
    #
    # In Rails, this is usually achieved by creating the form using +form_for+ and
    # a number of related helper methods. +form_for+ generates an appropriate <tt>form</tt>
    # tag and yields a form builder object that knows the model the form is about.
    # Input fields are created by calling methods defined on the form builder, which
    # means they are able to generate the appropriate names and default values
    # corresponding to the model attributes, as well as convenient IDs, etc.
    # Conventions in the generated field names allow controllers to receive form data
    # nicely structured in +params+ with no effort on your side.
    #
    # For example, to create a new person you typically set up a new instance of
    # +Person+ in the <tt>PeopleController#new</tt> action, <tt>@person</tt>, and
    # in the view template pass that object to +form_for+:
    #
    #   <%= form_for @person do |f| %>
    #     <%= f.label :first_name %>:
    #     <%= f.text_field :first_name %><br />
    #
    #     <%= f.label :last_name %>:
    #     <%= f.text_field :last_name %><br />
    #
    #     <%= f.submit %>
    #   <% end %>
    #
    # The HTML generated for this would be (modulus formatting):
    #
    #   <form action="/people" class="new_person" id="new_person" method="post">
    #     <div style="margin:0;padding:0;display:inline">
    #       <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
    #     </div>
    #     <label for="person_first_name">First name</label>:
    #     <input id="person_first_name" name="person[first_name]" type="text" /><br />
    #
    #     <label for="person_last_name">Last name</label>:
    #     <input id="person_last_name" name="person[last_name]" type="text" /><br />
    #
    #     <input name="commit" type="submit" value="Create Person" />
    #   </form>
    #
    # As you see, the HTML reflects knowledge about the resource in several spots,
    # like the path the form should be submitted to, or the names of the input fields.
    #
    # In particular, thanks to the conventions followed in the generated field names, the
    # controller gets a nested hash <tt>params[:person]</tt> with the person attributes
    # set in the form. That hash is ready to be passed to <tt>Person.create</tt>:
    #
    #   if @person = Person.create(params[:person])
    #     # success
    #   else
    #     # error handling
    #   end
    #
    # Interestingly, the exact same view code in the previous example can be used to edit
    # a person. If <tt>@person</tt> is an existing record with name "John Smith" and ID 256,
    # the code above as is would yield instead:
    #
    #   <form action="/people/256" class="edit_person" id="edit_person_256" method="post">
    #     <div style="margin:0;padding:0;display:inline">
    #       <input name="_method" type="hidden" value="patch" />
    #       <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
    #     </div>
    #     <label for="person_first_name">First name</label>:
    #     <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br />
    #
    #     <label for="person_last_name">Last name</label>:
    #     <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br />
    #
    #     <input name="commit" type="submit" value="Update Person" />
    #   </form>
    #
    # Note that the endpoint, default values, and submit button label are tailored for <tt>@person</tt>.
    # That works that way because the involved helpers know whether the resource is a new record or not,
    # and generate HTML accordingly.
    #
    # The controller would receive the form data again in <tt>params[:person]</tt>, ready to be
    # passed to <tt>Person#update</tt>:
    #
    #   if @person.update(params[:person])
    #     # success
    #   else
    #     # error handling
    #   end
    #
    # That's how you typically work with resources.
    module FormHelper
      extend ActiveSupport::Concern

      include FormTagHelper
      include UrlHelper
      include ModelNaming

      # Creates a form that allows the user to create or update the attributes
      # of a specific model object.
      #
      # The method can be used in several slightly different ways, depending on
      # how much you wish to rely on Rails to infer automatically from the model
      # how the form should be constructed. For a generic model object, a form
      # can be created by passing +form_for+ a string or symbol representing
      # the object we are concerned with:
      #
      #   <%= form_for :person do |f| %>
      #     First name: <%= f.text_field :first_name %><br />
      #     Last name : <%= f.text_field :last_name %><br />
      #     Biography : <%= f.text_area :biography %><br />
      #     Admin?    : <%= f.check_box :admin %><br />
      #     <%= f.submit %>
      #   <% end %>
      #
      # The variable +f+ yielded to the block is a FormBuilder object that
      # incorporates the knowledge about the model object represented by
      # <tt>:person</tt> passed to +form_for+. Methods defined on the FormBuilder
      # are used to generate fields bound to this model. Thus, for example,
      #
      #   <%= f.text_field :first_name %>
      #
      # will get expanded to
      #
      #   <%= text_field :person, :first_name %>
      # which results in an html <tt><input></tt> tag whose +name+ attribute is
      # <tt>person[first_name]</tt>. This means that when the form is submitted,
      # the value entered by the user will be available in the controller as
      # <tt>params[:person][:first_name]</tt>.
      #
      # For fields generated in this way using the FormBuilder,
      # if <tt>:person</tt> also happens to be the name of an instance variable
      # <tt>@person</tt>, the default value of the field shown when the form is
      # initially displayed (e.g. in the situation where you are editing an
      # existing record) will be the value of the corresponding attribute of
      # <tt>@person</tt>.
      #
      # The rightmost argument to +form_for+ is an
      # optional hash of options -
      #
      # * <tt>:url</tt> - The URL the form is to be submitted to. This may be
      #   represented in the same way as values passed to +url_for+ or +link_to+.
      #   So for example you may use a named route directly. When the model is
      #   represented by a string or symbol, as in the example above, if the
      #   <tt>:url</tt> option is not specified, by default the form will be
      #   sent back to the current url (We will describe below an alternative
      #   resource-oriented usage of +form_for+ in which the URL does not need
      #   to be specified explicitly).
      # * <tt>:namespace</tt> - A namespace for your form to ensure uniqueness of
      #   id attributes on form elements. The namespace attribute will be prefixed
      #   with underscore on the generated HTML id.
      # * <tt>:html</tt> - Optional HTML attributes for the form tag.
      #
      # Also note that +form_for+ doesn't create an exclusive scope. It's still
      # possible to use both the stand-alone FormHelper methods and methods
      # from FormTagHelper. For example:
      #
      #   <%= form_for :person do |f| %>
      #     First name: <%= f.text_field :first_name %>
      #     Last name : <%= f.text_field :last_name %>
      #     Biography : <%= text_area :person, :biography %>
      #     Admin?    : <%= check_box_tag "person[admin]", "1", @person.company.admin? %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # This also works for the methods in FormOptionHelper and DateHelper that
      # are designed to work with an object as base, like
      # FormOptionHelper#collection_select and DateHelper#datetime_select.
      #
      # === #form_for with a model object
      #
      # In the examples above, the object to be created or edited was
      # represented by a symbol passed to +form_for+, and we noted that
      # a string can also be used equivalently. It is also possible, however,
      # to pass a model object itself to +form_for+. For example, if <tt>@post</tt>
      # is an existing record you wish to edit, you can create the form using
      #
      #   <%= form_for @post do |f| %>
      #     ...
      #   <% end %>
      #
      # This behaves in almost the same way as outlined previously, with a
      # couple of small exceptions. First, the prefix used to name the input
      # elements within the form (hence the key that denotes them in the +params+
      # hash) is actually derived from the object's _class_, e.g. <tt>params[:post]</tt>
      # if the object's class is +Post+. However, this can be overwritten using
      # the <tt>:as</tt> option, e.g. -
      #
      #   <%= form_for(@person, as: :client) do |f| %>
      #     ...
      #   <% end %>
      #
      # would result in <tt>params[:client]</tt>.
      #
      # Secondly, the field values shown when the form is initially displayed
      # are taken from the attributes of the object passed to +form_for+,
      # regardless of whether the object is an instance
      # variable. So, for example, if we had a _local_ variable +post+
      # representing an existing record,
      #
      #   <%= form_for post do |f| %>
      #     ...
      #   <% end %>
      #
      # would produce a form with fields whose initial state reflect the current
      # values of the attributes of +post+.
      #
      # === Resource-oriented style
      #
      # In the examples just shown, although not indicated explicitly, we still
      # need to use the <tt>:url</tt> option in order to specify where the
      # form is going to be sent. However, further simplification is possible
      # if the record passed to +form_for+ is a _resource_, i.e. it corresponds
      # to a set of RESTful routes, e.g. defined using the +resources+ method
      # in <tt>config/routes.rb</tt>. In this case Rails will simply infer the
      # appropriate URL from the record itself. For example,
      #
      #   <%= form_for @post do |f| %>
      #     ...
      #   <% end %>
      #
      # is then equivalent to something like:
      #
      #   <%= form_for @post, as: :post, url: post_path(@post), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>
      #     ...
      #   <% end %>
      #
      # And for a new record
      #
      #   <%= form_for(Post.new) do |f| %>
      #     ...
      #   <% end %>
      #
      # is equivalent to something like:
      #
      #   <%= form_for @post, as: :post, url: posts_path, html: { class: "new_post", id: "new_post" } do |f| %>
      #     ...
      #   <% end %>
      #
      # However you can still overwrite individual conventions, such as:
      #
      #   <%= form_for(@post, url: super_posts_path) do |f| %>
      #     ...
      #   <% end %>
      #
      # You can also set the answer format, like this:
      #
      #   <%= form_for(@post, format: :json) do |f| %>
      #     ...
      #   <% end %>
      #
      # For namespaced routes, like +admin_post_url+:
      #
      #   <%= form_for([:admin, @post]) do |f| %>
      #    ...
      #   <% end %>
      #
      # If your resource has associations defined, for example, you want to add comments
      # to the document given that the routes are set correctly:
      #
      #   <%= form_for([@document, @comment]) do |f| %>
      #    ...
      #   <% end %>
      #
      # Where <tt>@document = Document.find(params[:id])</tt> and
      # <tt>@comment = Comment.new</tt>.
      #
      # === Setting the method
      #
      # You can force the form to use the full array of HTTP verbs by setting
      #
      #    method: (:get|:post|:patch|:put|:delete)
      #
      # in the options hash. If the verb is not GET or POST, which are natively
      # supported by HTML forms, the form will be set to POST and a hidden input
      # called _method will carry the intended verb for the server to interpret.
      #
      # === Unobtrusive JavaScript
      #
      # Specifying:
      #
      #    remote: true
      #
      # in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
      # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
      # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
      # Even though it's using JavaScript to serialize the form elements, the form submission will work just like
      # a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
      #
      # Example:
      #
      #   <%= form_for(@post, remote: true) do |f| %>
      #     ...
      #   <% end %>
      #
      # The HTML generated for this would be:
      #
      #   <form action='http://www.example.com' method='post' data-remote='true'>
      #     <div style='margin:0;padding:0;display:inline'>
      #       <input name='_method' type='hidden' value='patch' />
      #     </div>
      #     ...
      #   </form>
      #
      # === Setting HTML options
      #
      # You can set data attributes directly by passing in a data hash, but all other HTML options must be wrapped in
      # the HTML key. Example:
      #
      #   <%= form_for(@post, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
      #     ...
      #   <% end %>
      #
      # The HTML generated for this would be:
      #
      #   <form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
      #     <div style='margin:0;padding:0;display:inline'>
      #       <input name='_method' type='hidden' value='patch' />
      #     </div>
      #     ...
      #   </form>
      #
      # === Removing hidden model id's
      #
      # The form_for method automatically includes the model id as a hidden field in the form.
      # This is used to maintain the correlation between the form data and its associated model.
      # Some ORM systems do not use IDs on nested models so in this case you want to be able
      # to disable the hidden id.
      #
      # In the following example the Post model has many Comments stored within it in a NoSQL database,
      # thus there is no primary key for comments.
      #
      # Example:
      #
      #   <%= form_for(@post) do |f| %>
      #     <%= f.fields_for(:comments, include_id: false) do |cf| %>
      #       ...
      #     <% end %>
      #   <% end %>
      #
      # === Customized form builders
      #
      # You can also build forms using a customized FormBuilder class. Subclass
      # FormBuilder and override or define some more helpers, then use your
      # custom builder. For example, let's say you made a helper to
      # automatically add labels to form inputs.
      #
      #   <%= form_for @person, url: { action: "create" }, builder: LabellingFormBuilder do |f| %>
      #     <%= f.text_field :first_name %>
      #     <%= f.text_field :last_name %>
      #     <%= f.text_area :biography %>
      #     <%= f.check_box :admin %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # In this case, if you use this:
      #
      #   <%= render f %>
      #
      # The rendered template is <tt>people/_labelling_form</tt> and the local
      # variable referencing the form builder is called
      # <tt>labelling_form</tt>.
      #
      # The custom FormBuilder class is automatically merged with the options
      # of a nested fields_for call, unless it's explicitly set.
      #
      # In many cases you will want to wrap the above in another helper, so you
      # could do something like the following:
      #
      #   def labelled_form_for(record_or_name_or_array, *args, &block)
      #     options = args.extract_options!
      #     form_for(record_or_name_or_array, *(args << options.merge(builder: LabellingFormBuilder)), &block)
      #   end
      #
      # If you don't need to attach a form to a model instance, then check out
      # FormTagHelper#form_tag.
      #
      # === Form to external resources
      #
      # When you build forms to external resources sometimes you need to set an authenticity token or just render a form
      # without it, for example when you submit data to a payment gateway number and types of fields could be limited.
      #
      # To set an authenticity token you need to pass an <tt>:authenticity_token</tt> parameter
      #
      #   <%= form_for @invoice, url: external_url, authenticity_token: 'external_token' do |f|
      #     ...
      #   <% end %>
      #
      # If you don't want to an authenticity token field be rendered at all just pass <tt>false</tt>:
      #
      #   <%= form_for @invoice, url: external_url, authenticity_token: false do |f|
      #     ...
      #   <% end %>
      def form_for(record, options = {}, &block)
        raise ArgumentError, "Missing block" unless block_given?
        html_options = options[:html] ||= {}

        case record
        when String, Symbol
          object_name = record
          object      = nil
        else
          object      = record.is_a?(Array) ? record.last : record
          raise ArgumentError, "First argument in form cannot contain nil or be empty" unless object
          object_name = options[:as] || model_name_from_record_or_class(object).param_key
          apply_form_for_options!(record, object, options)
        end

        html_options[:data]   = options.delete(:data)   if options.has_key?(:data)
        html_options[:remote] = options.delete(:remote) if options.has_key?(:remote)
        html_options[:method] = options.delete(:method) if options.has_key?(:method)
        html_options[:authenticity_token] = options.delete(:authenticity_token)

        builder = instantiate_builder(object_name, object, options)
        output  = capture(builder, &block)
        html_options[:multipart] = builder.multipart?

        form_tag(options[:url] || {}, html_options) { output }
      end

      def apply_form_for_options!(record, object, options) #:nodoc:
        object = convert_to_model(object)

        as = options[:as]
        action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :patch] : [:new, :post]
        options[:html].reverse_merge!(
          class:  as ? "#{action}_#{as}" : dom_class(object, action),
          id:     as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence,
          method: method
        )

        options[:url] ||= polymorphic_path(record, format: options.delete(:format))
      end
      private :apply_form_for_options!

      # Creates a scope around a specific model object like form_for, but
      # doesn't create the form tags themselves. This makes fields_for suitable
      # for specifying additional model objects in the same form.
      #
      # Although the usage and purpose of +field_for+ is similar to +form_for+'s,
      # its method signature is slightly different. Like +form_for+, it yields
      # a FormBuilder object associated with a particular model object to a block,
      # and within the block allows methods to be called on the builder to
      # generate fields associated with the model object. Fields may reflect
      # a model object in two ways - how they are named (hence how submitted
      # values appear within the +params+ hash in the controller) and what
      # default values are shown when the form the fields appear in is first
      # displayed. In order for both of these features to be specified independently,
      # both an object name (represented by either a symbol or string) and the
      # object itself can be passed to the method separately -
      #
      #   <%= form_for @person do |person_form| %>
      #     First name: <%= person_form.text_field :first_name %>
      #     Last name : <%= person_form.text_field :last_name %>
      #
      #     <%= fields_for :permission, @person.permission do |permission_fields| %>
      #       Admin?  : <%= permission_fields.check_box :admin %>
      #     <% end %>
      #
      #     <%= f.submit %>
      #   <% end %>
      #
      # In this case, the checkbox field will be represented by an HTML +input+
      # tag with the +name+ attribute <tt>permission[admin]</tt>, and the submitted
      # value will appear in the controller as <tt>params[:permission][:admin]</tt>.
      # If <tt>@person.permission</tt> is an existing record with an attribute
      # +admin+, the initial state of the checkbox when first displayed will
      # reflect the value of <tt>@person.permission.admin</tt>.
      #
      # Often this can be simplified by passing just the name of the model
      # object to +fields_for+ -
      #
      #   <%= fields_for :permission do |permission_fields| %>
      #     Admin?: <%= permission_fields.check_box :admin %>
      #   <% end %>
      #
      # ...in which case, if <tt>:permission</tt> also happens to be the name of an
      # instance variable <tt>@permission</tt>, the initial state of the input
      # field will reflect the value of that variable's attribute <tt>@permission.admin</tt>.
      #
      # Alternatively, you can pass just the model object itself (if the first
      # argument isn't a string or symbol +fields_for+ will realize that the
      # name has been omitted) -
      #
      #   <%= fields_for @person.permission do |permission_fields| %>
      #     Admin?: <%= permission_fields.check_box :admin %>
      #   <% end %>
      #
      # and +fields_for+ will derive the required name of the field from the
      # _class_ of the model object, e.g. if <tt>@person.permission</tt>, is
      # of class +Permission+, the field will still be named <tt>permission[admin]</tt>.
      #
      # Note: This also works for the methods in FormOptionHelper and
      # DateHelper that are designed to work with an object as base, like
      # FormOptionHelper#collection_select and DateHelper#datetime_select.
      #
      # === Nested Attributes Examples
      #
      # When the object belonging to the current scope has a nested attribute
      # writer for a certain attribute, fields_for will yield a new scope
      # for that attribute. This allows you to create forms that set or change
      # the attributes of a parent object and its associations in one go.
      #
      # Nested attribute writers are normal setter methods named after an
      # association. The most common way of defining these writers is either
      # with +accepts_nested_attributes_for+ in a model definition or by
      # defining a method with the proper name. For example: the attribute
      # writer for the association <tt>:address</tt> is called
      # <tt>address_attributes=</tt>.
      #
      # Whether a one-to-one or one-to-many style form builder will be yielded
      # depends on whether the normal reader method returns a _single_ object
      # or an _array_ of objects.
      #
      # ==== One-to-one
      #
      # Consider a Person class which returns a _single_ Address from the
      # <tt>address</tt> reader method and responds to the
      # <tt>address_attributes=</tt> writer method:
      #
      #   class Person
      #     def address
      #       @address
      #     end
      #
      #     def address_attributes=(attributes)
      #       # Process the attributes hash
      #     end
      #   end
      #
      # This model can now be used with a nested fields_for, like so:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :address do |address_fields| %>
      #       Street  : <%= address_fields.text_field :street %>
      #       Zip code: <%= address_fields.text_field :zip_code %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When address is already an association on a Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_one :address
      #     accepts_nested_attributes_for :address
      #   end
      #
      # If you want to destroy the associated model through the form, you have
      # to enable it first using the <tt>:allow_destroy</tt> option for
      # +accepts_nested_attributes_for+:
      #
      #   class Person < ActiveRecord::Base
      #     has_one :address
      #     accepts_nested_attributes_for :address, allow_destroy: true
      #   end
      #
      # Now, when you use a form element with the <tt>_destroy</tt> parameter,
      # with a value that evaluates to +true+, you will destroy the associated
      # model (eg. 1, '1', true, or 'true'):
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :address do |address_fields| %>
      #       ...
      #       Delete: <%= address_fields.check_box :_destroy %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # ==== One-to-many
      #
      # Consider a Person class which returns an _array_ of Project instances
      # from the <tt>projects</tt> reader method and responds to the
      # <tt>projects_attributes=</tt> writer method:
      #
      #   class Person
      #     def projects
      #       [@project1, @project2]
      #     end
      #
      #     def projects_attributes=(attributes)
      #       # Process the attributes hash
      #     end
      #   end
      #
      # Note that the <tt>projects_attributes=</tt> writer method is in fact
      # required for fields_for to correctly identify <tt>:projects</tt> as a
      # collection, and the correct indices to be set in the form markup.
      #
      # When projects is already an association on Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects
      #   end
      #
      # This model can now be used with a nested fields_for. The block given to
      # the nested fields_for call will be repeated for each instance in the
      # collection:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       <% if project_fields.object.active? %>
      #         Name: <%= project_fields.text_field :name %>
      #       <% end %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # It's also possible to specify the instance to be used:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <% @person.projects.each do |project| %>
      #       <% if project.active? %>
      #         <%= person_form.fields_for :projects, project do |project_fields| %>
      #           Name: <%= project_fields.text_field :name %>
      #         <% end %>
      #       <% end %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # Or a collection to be used:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
      #       Name: <%= project_fields.text_field :name %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When projects is already an association on Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects
      #   end
      #
      # If you want to destroy any of the associated models through the
      # form, you have to enable it first using the <tt>:allow_destroy</tt>
      # option for +accepts_nested_attributes_for+:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects, allow_destroy: true
      #   end
      #
      # This will allow you to specify which models to destroy in the
      # attributes hash by adding a form element for the <tt>_destroy</tt>
      # parameter with a value that evaluates to +true+
      # (eg. 1, '1', true, or 'true'):
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       Delete: <%= project_fields.check_box :_destroy %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When a collection is used you might want to know the index of each
      # object into the array. For this purpose, the <tt>index</tt> method
      # is available in the FormBuilder object.
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       Project #<%= project_fields.index %>
      #       ...
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # Note that fields_for will automatically generate a hidden field
      # to store the ID of the record. There are circumstances where this
      # hidden field is not needed and you can pass <tt>hidden_field_id: false</tt>
      # to prevent fields_for from rendering it automatically.
      def fields_for(record_name, record_object = nil, options = {}, &block)
        builder = instantiate_builder(record_name, record_object, options)
        capture(builder, &block)
      end

      # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation
      # is found in the current I18n locale (through helpers.label.<modelname>.<attribute>) or you specify it explicitly.
      # Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
      # onto the HTML as an HTML element attribute as in the example shown, except for the <tt>:value</tt> option, which is designed to
      # target labels for radio_button tags (where the value is used in the ID of the input tag).
      #
      # ==== Examples
      #   label(:post, :title)
      #   # => <label for="post_title">Title</label>
      #
      # You can localize your labels based on model and attribute names.
      # For example you can define the following in your locale (e.g. en.yml)
      #
      #   helpers:
      #     label:
      #       post:
      #         body: "Write your entire text here"
      #
      # Which then will result in
      #
      #   label(:post, :body)
      #   # => <label for="post_body">Write your entire text here</label>
      #
      # Localization can also be based purely on the translation of the attribute-name
      # (if you are using ActiveRecord):
      #
      #   activerecord:
      #     attributes:
      #       post:
      #         cost: "Total cost"
      #
      #   label(:post, :cost)
      #   # => <label for="post_cost">Total cost</label>
      #
      #   label(:post, :title, "A short title")
      #   # => <label for="post_title">A short title</label>
      #
      #   label(:post, :title, "A short title", class: "title_label")
      #   # => <label for="post_title" class="title_label">A short title</label>
      #
      #   label(:post, :privacy, "Public Post", value: "public")
      #   # => <label for="post_privacy_public">Public Post</label>
      #
      #   label(:post, :terms) do
      #     'Accept <a href="/terms">Terms</a>.'.html_safe
      #   end
      def label(object_name, method, content_or_options = nil, options = nil, &block)
        Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
      end

      # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown.
      #
      # ==== Examples
      #   text_field(:post, :title, size: 20)
      #   # => <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" />
      #
      #   text_field(:post, :title, class: "create_input")
      #   # => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />
      #
      #   text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }")
      #   # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }"/>
      #
      #   text_field(:snippet, :code, size: 20, class: 'code_input')
      #   # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
      def text_field(object_name, method, options = {})
        Tags::TextField.new(object_name, method, self, options).render
      end

      # Returns an input tag of the "password" type tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown. For security reasons this field is blank by default; pass in a value via +options+ if this is not desired.
      #
      # ==== Examples
      #   password_field(:login, :pass, size: 20)
      #   # => <input type="password" id="login_pass" name="login[pass]" size="20" />
      #
      #   password_field(:account, :secret, class: "form_input", value: @account.secret)
      #   # => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
      #
      #   password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
      #   # => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
      #
      #   password_field(:account, :pin, size: 20, class: 'form_input')
      #   # => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
      def password_field(object_name, method, options = {})
        Tags::PasswordField.new(object_name, method, self, options).render
      end

      # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown.
      #
      # ==== Examples
      #   hidden_field(:signup, :pass_confirm)
      #   # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
      #
      #   hidden_field(:post, :tag_list)
      #   # => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.tag_list}" />
      #
      #   hidden_field(:user, :token)
      #   # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
      def hidden_field(object_name, method, options = {})
        Tags::HiddenField.new(object_name, method, self, options).render
      end

      # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown.
      #
      # Using this method inside a +form_for+ block will set the enclosing form's encoding to <tt>multipart/form-data</tt>.
      #
      # ==== Options
      # * Creates standard HTML attributes for the tag.
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:multiple</tt> - If set to true, *in most updated browsers* the user will be allowed to select multiple files.
      # * <tt>:accept</tt> - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
      #
      # ==== Examples
      #   file_field(:user, :avatar)
      #   # => <input type="file" id="user_avatar" name="user[avatar]" />
      #
      #   file_field(:post, :image, :multiple => true)
      #   # => <input type="file" id="post_image" name="post[image]" multiple="true" />
      #
      #   file_field(:post, :attached, accept: 'text/html')
      #   # => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
      #
      #   file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
      #   # => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />
      #
      #   file_field(:attachment, :file, class: 'file_input')
      #   # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
      def file_field(object_name, method, options = {})
        Tags::FileField.new(object_name, method, self, options).render
      end

      # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+)
      # on an object assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+.
      #
      # ==== Examples
      #   text_area(:post, :body, cols: 20, rows: 40)
      #   # => <textarea cols="20" rows="40" id="post_body" name="post[body]">
      #   #      #{@post.body}
      #   #    </textarea>
      #
      #   text_area(:comment, :text, size: "20x30")
      #   # => <textarea cols="20" rows="30" id="comment_text" name="comment[text]">
      #   #      #{@comment.text}
      #   #    </textarea>
      #
      #   text_area(:application, :notes, cols: 40, rows: 15, class: 'app_input')
      #   # => <textarea cols="40" rows="15" id="application_notes" name="application[notes]" class="app_input">
      #   #      #{@application.notes}
      #   #    </textarea>
      #
      #   text_area(:entry, :body, size: "20x20", disabled: 'disabled')
      #   # => <textarea cols="20" rows="20" id="entry_body" name="entry[body]" disabled="disabled">
      #   #      #{@entry.body}
      #   #    </textarea>
      def text_area(object_name, method, options = {})
        Tags::TextArea.new(object_name, method, self, options).render
      end

      # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object.
      # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
      # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
      # while the default +unchecked_value+ is set to 0 which is convenient for boolean values.
      #
      # ==== Gotcha
      #
      # The HTML specification says unchecked check boxes are not successful, and
      # thus web browsers do not send them. Unfortunately this introduces a gotcha:
      # if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid
      # invoice the user unchecks its check box, no +paid+ parameter is sent. So,
      # any mass-assignment idiom like
      #
      #   @invoice.update(params[:invoice])
      #
      # wouldn't update the flag.
      #
      # To prevent this the helper generates an auxiliary hidden field before
      # the very check box. The hidden field has the same name and its
      # attributes mimic an unchecked check box.
      #
      # This way, the client either sends only the hidden field (representing
      # the check box is unchecked), or both fields. Since the HTML specification
      # says key/value pairs have to be sent in the same order they appear in the
      # form, and parameters extraction gets the last occurrence of any repeated
      # key in the query string, that works for ordinary forms.
      #
      # Unfortunately that workaround does not work when the check box goes
      # within an array-like parameter, as in
      #
      #   <%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
      #     <%= form.check_box :paid %>
      #     ...
      #   <% end %>
      #
      # because parameter name repetition is precisely what Rails seeks to distinguish
      # the elements of the array. For each item with a checked check box you
      # get an extra ghost item with only that attribute, assigned to "0".
      #
      # In that case it is preferable to either use +check_box_tag+ or to use
      # hashes instead of arrays.
      #
      #   # Let's say that @post.validated? is 1:
      #   check_box("post", "validated")
      #   # => <input name="post[validated]" type="hidden" value="0" />
      #   #    <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
      #
      #   # Let's say that @puppy.gooddog is "no":
      #   check_box("puppy", "gooddog", {}, "yes", "no")
      #   # => <input name="puppy[gooddog]" type="hidden" value="no" />
      #   #    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
      #
      #   check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
      #   # => <input name="eula[accepted]" type="hidden" value="no" />
      #   #    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
      def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
        Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
      end

      # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
      # radio button will be checked.
      #
      # To force the radio button to be checked pass <tt>checked: true</tt> in the
      # +options+ hash. You may pass HTML options there as well.
      #
      #   # Let's say that @post.category returns "rails":
      #   radio_button("post", "category", "rails")
      #   radio_button("post", "category", "java")
      #   # => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
      #   #    <input type="radio" id="post_category_java" name="post[category]" value="java" />
      #
      #   radio_button("user", "receive_newsletter", "yes")
      #   radio_button("user", "receive_newsletter", "no")
      #   # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
      #   #    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
      def radio_button(object_name, method, tag_value, options = {})
        Tags::RadioButton.new(object_name, method, self, tag_value, options).render
      end

      # Returns a text_field of type "color".
      #
      #   color_field("car", "color")
      #   # => <input id="car_color" name="car[color]" type="color" value="#000000" />
      def color_field(object_name, method, options = {})
        Tags::ColorField.new(object_name, method, self, options).render
      end

      # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
      # some browsers.
      #
      #   search_field(:user, :name)
      #   # => <input id="user_name" name="user[name]" type="search" />
      #   search_field(:user, :name, autosave: false)
      #   # => <input autosave="false" id="user_name" name="user[name]" type="search" />
      #   search_field(:user, :name, results: 3)
      #   # => <input id="user_name" name="user[name]" results="3" type="search" />
      #   #  Assume request.host returns "www.example.com"
      #   search_field(:user, :name, autosave: true)
      #   # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" />
      #   search_field(:user, :name, onsearch: true)
      #   # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
      #   search_field(:user, :name, autosave: false, onsearch: true)
      #   # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
      #   search_field(:user, :name, autosave: true, onsearch: true)
      #   # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
      def search_field(object_name, method, options = {})
        Tags::SearchField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "tel".
      #
      #   telephone_field("user", "phone")
      #   # => <input id="user_phone" name="user[phone]" type="tel" />
      #
      def telephone_field(object_name, method, options = {})
        Tags::TelField.new(object_name, method, self, options).render
      end
      # aliases telephone_field
      alias phone_field telephone_field

      # Returns a text_field of type "date".
      #
      #   date_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="date" />
      #
      # The default value is generated by trying to call "to_date"
      # on the object's value, which makes it behave as expected for instances
      # of DateTime and ActiveSupport::TimeWithZone. You can still override that
      # by passing the "value" option explicitly, e.g.
      #
      #   @user.born_on = Date.new(1984, 1, 27)
      #   date_field("user", "born_on", value: "1984-05-12")
      #   # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
      #
      def date_field(object_name, method, options = {})
        Tags::DateField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "time".
      #
      # The default value is generated by trying to call +strftime+ with "%T.%L"
      # on the objects's value. It is still possible to override that
      # by passing the "value" option.
      #
      # === Options
      # * Accepts same options as time_field_tag
      #
      # === Example
      #   time_field("task", "started_at")
      #   # => <input id="task_started_at" name="task[started_at]" type="time" />
      #
      def time_field(object_name, method, options = {})
        Tags::TimeField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "datetime".
      #
      #   datetime_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="datetime" />
      #
      # The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T.%L%z"
      # on the object's value, which makes it behave as expected for instances
      # of DateTime and ActiveSupport::TimeWithZone.
      #
      #   @user.born_on = Date.new(1984, 1, 12)
      #   datetime_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="datetime" value="1984-01-12T00:00:00.000+0000" />
      #
      def datetime_field(object_name, method, options = {})
        Tags::DatetimeField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "datetime-local".
      #
      #   datetime_local_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
      #
      # The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T"
      # on the object's value, which makes it behave as expected for instances
      # of DateTime and ActiveSupport::TimeWithZone.
      #
      #   @user.born_on = Date.new(1984, 1, 12)
      #   datetime_local_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
      #
      def datetime_local_field(object_name, method, options = {})
        Tags::DatetimeLocalField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "month".
      #
      #   month_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="month" />
      #
      # The default value is generated by trying to call +strftime+ with "%Y-%m"
      # on the object's value, which makes it behave as expected for instances
      # of DateTime and ActiveSupport::TimeWithZone.
      #
      #   @user.born_on = Date.new(1984, 1, 27)
      #   month_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
      #
      def month_field(object_name, method, options = {})
        Tags::MonthField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "week".
      #
      #   week_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="week" />
      #
      # The default value is generated by trying to call +strftime+ with "%Y-W%W"
      # on the object's value, which makes it behave as expected for instances
      # of DateTime and ActiveSupport::TimeWithZone.
      #
      #   @user.born_on = Date.new(1984, 5, 12)
      #   week_field("user", "born_on")
      #   # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />
      #
      def week_field(object_name, method, options = {})
        Tags::WeekField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "url".
      #
      #   url_field("user", "homepage")
      #   # => <input id="user_homepage" name="user[homepage]" type="url" />
      #
      def url_field(object_name, method, options = {})
        Tags::UrlField.new(object_name, method, self, options).render
      end

      # Returns a text_field of type "email".
      #
      #   email_field("user", "address")
      #   # => <input id="user_address" name="user[address]" type="email" />
      #
      def email_field(object_name, method, options = {})
        Tags::EmailField.new(object_name, method, self, options).render
      end

      # Returns an input tag of type "number".
      #
      # ==== Options
      # * Accepts same options as number_field_tag
      def number_field(object_name, method, options = {})
        Tags::NumberField.new(object_name, method, self, options).render
      end

      # Returns an input tag of type "range".
      #
      # ==== Options
      # * Accepts same options as range_field_tag
      def range_field(object_name, method, options = {})
        Tags::RangeField.new(object_name, method, self, options).render
      end

      private

        def instantiate_builder(record_name, record_object, options)
          case record_name
          when String, Symbol
            object = record_object
            object_name = record_name
          else
            object = record_name
            object_name = model_name_from_record_or_class(object).param_key
          end

          builder = options[:builder] || default_form_builder
          builder.new(object_name, object, self, options)
        end

        def default_form_builder
          builder = ActionView::Base.default_form_builder
          builder.respond_to?(:constantize) ? builder.constantize : builder
        end
    end

    class FormBuilder
      include ModelNaming

      # The methods which wrap a form helper call.
      class_attribute :field_helpers
      self.field_helpers = FormHelper.instance_methods - [:form_for, :convert_to_model, :model_name_from_record_or_class]

      attr_accessor :object_name, :object, :options

      attr_reader :multipart, :index
      alias :multipart? :multipart

      def multipart=(multipart)
        @multipart = multipart

        if parent_builder = @options[:parent_builder]
          parent_builder.multipart = multipart
        end
      end

      def self._to_partial_path
        @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, '')
      end

      def to_partial_path
        self.class._to_partial_path
      end

      def to_model
        self
      end

      def initialize(object_name, object, template, options, block=nil)
        if block
          ActiveSupport::Deprecation.warn "Giving a block to FormBuilder is deprecated and has no effect anymore."
        end

        @nested_child_index = {}
        @object_name, @object, @template, @options = object_name, object, template, options
        @default_options = @options ? @options.slice(:index, :namespace) : {}
        if @object_name.to_s.match(/\[\]$/)
          if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
            @auto_index = object.to_param
          else
            raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
          end
        end
        @multipart = nil
        @index = options[:index] || options[:child_index]
      end

      (field_helpers - [:label, :check_box, :radio_button, :fields_for, :hidden_field, :file_field]).each do |selector|
        class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
          def #{selector}(method, options = {})  # def text_field(method, options = {})
            @template.send(                      #   @template.send(
              #{selector.inspect},               #     "text_field",
              @object_name,                      #     @object_name,
              method,                            #     method,
              objectify_options(options))        #     objectify_options(options))
          end                                    # end
        RUBY_EVAL
      end

      # Creates a scope around a specific model object like form_for, but
      # doesn't create the form tags themselves. This makes fields_for suitable
      # for specifying additional model objects in the same form.
      #
      # Although the usage and purpose of +field_for+ is similar to +form_for+'s,
      # its method signature is slightly different. Like +form_for+, it yields
      # a FormBuilder object associated with a particular model object to a block,
      # and within the block allows methods to be called on the builder to
      # generate fields associated with the model object. Fields may reflect
      # a model object in two ways - how they are named (hence how submitted
      # values appear within the +params+ hash in the controller) and what
      # default values are shown when the form the fields appear in is first
      # displayed. In order for both of these features to be specified independently,
      # both an object name (represented by either a symbol or string) and the
      # object itself can be passed to the method separately -
      #
      #   <%= form_for @person do |person_form| %>
      #     First name: <%= person_form.text_field :first_name %>
      #     Last name : <%= person_form.text_field :last_name %>
      #
      #     <%= fields_for :permission, @person.permission do |permission_fields| %>
      #       Admin?  : <%= permission_fields.check_box :admin %>
      #     <% end %>
      #
      #     <%= f.submit %>
      #   <% end %>
      #
      # In this case, the checkbox field will be represented by an HTML +input+
      # tag with the +name+ attribute <tt>permission[admin]</tt>, and the submitted
      # value will appear in the controller as <tt>params[:permission][:admin]</tt>.
      # If <tt>@person.permission</tt> is an existing record with an attribute
      # +admin+, the initial state of the checkbox when first displayed will
      # reflect the value of <tt>@person.permission.admin</tt>.
      #
      # Often this can be simplified by passing just the name of the model
      # object to +fields_for+ -
      #
      #   <%= fields_for :permission do |permission_fields| %>
      #     Admin?: <%= permission_fields.check_box :admin %>
      #   <% end %>
      #
      # ...in which case, if <tt>:permission</tt> also happens to be the name of an
      # instance variable <tt>@permission</tt>, the initial state of the input
      # field will reflect the value of that variable's attribute <tt>@permission.admin</tt>.
      #
      # Alternatively, you can pass just the model object itself (if the first
      # argument isn't a string or symbol +fields_for+ will realize that the
      # name has been omitted) -
      #
      #   <%= fields_for @person.permission do |permission_fields| %>
      #     Admin?: <%= permission_fields.check_box :admin %>
      #   <% end %>
      #
      # and +fields_for+ will derive the required name of the field from the
      # _class_ of the model object, e.g. if <tt>@person.permission</tt>, is
      # of class +Permission+, the field will still be named <tt>permission[admin]</tt>.
      #
      # Note: This also works for the methods in FormOptionHelper and
      # DateHelper that are designed to work with an object as base, like
      # FormOptionHelper#collection_select and DateHelper#datetime_select.
      #
      # === Nested Attributes Examples
      #
      # When the object belonging to the current scope has a nested attribute
      # writer for a certain attribute, fields_for will yield a new scope
      # for that attribute. This allows you to create forms that set or change
      # the attributes of a parent object and its associations in one go.
      #
      # Nested attribute writers are normal setter methods named after an
      # association. The most common way of defining these writers is either
      # with +accepts_nested_attributes_for+ in a model definition or by
      # defining a method with the proper name. For example: the attribute
      # writer for the association <tt>:address</tt> is called
      # <tt>address_attributes=</tt>.
      #
      # Whether a one-to-one or one-to-many style form builder will be yielded
      # depends on whether the normal reader method returns a _single_ object
      # or an _array_ of objects.
      #
      # ==== One-to-one
      #
      # Consider a Person class which returns a _single_ Address from the
      # <tt>address</tt> reader method and responds to the
      # <tt>address_attributes=</tt> writer method:
      #
      #   class Person
      #     def address
      #       @address
      #     end
      #
      #     def address_attributes=(attributes)
      #       # Process the attributes hash
      #     end
      #   end
      #
      # This model can now be used with a nested fields_for, like so:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :address do |address_fields| %>
      #       Street  : <%= address_fields.text_field :street %>
      #       Zip code: <%= address_fields.text_field :zip_code %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When address is already an association on a Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_one :address
      #     accepts_nested_attributes_for :address
      #   end
      #
      # If you want to destroy the associated model through the form, you have
      # to enable it first using the <tt>:allow_destroy</tt> option for
      # +accepts_nested_attributes_for+:
      #
      #   class Person < ActiveRecord::Base
      #     has_one :address
      #     accepts_nested_attributes_for :address, allow_destroy: true
      #   end
      #
      # Now, when you use a form element with the <tt>_destroy</tt> parameter,
      # with a value that evaluates to +true+, you will destroy the associated
      # model (eg. 1, '1', true, or 'true'):
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :address do |address_fields| %>
      #       ...
      #       Delete: <%= address_fields.check_box :_destroy %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # ==== One-to-many
      #
      # Consider a Person class which returns an _array_ of Project instances
      # from the <tt>projects</tt> reader method and responds to the
      # <tt>projects_attributes=</tt> writer method:
      #
      #   class Person
      #     def projects
      #       [@project1, @project2]
      #     end
      #
      #     def projects_attributes=(attributes)
      #       # Process the attributes hash
      #     end
      #   end
      #
      # Note that the <tt>projects_attributes=</tt> writer method is in fact
      # required for fields_for to correctly identify <tt>:projects</tt> as a
      # collection, and the correct indices to be set in the form markup.
      #
      # When projects is already an association on Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects
      #   end
      #
      # This model can now be used with a nested fields_for. The block given to
      # the nested fields_for call will be repeated for each instance in the
      # collection:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       <% if project_fields.object.active? %>
      #         Name: <%= project_fields.text_field :name %>
      #       <% end %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # It's also possible to specify the instance to be used:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <% @person.projects.each do |project| %>
      #       <% if project.active? %>
      #         <%= person_form.fields_for :projects, project do |project_fields| %>
      #           Name: <%= project_fields.text_field :name %>
      #         <% end %>
      #       <% end %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # Or a collection to be used:
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
      #       Name: <%= project_fields.text_field :name %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When projects is already an association on Person you can use
      # +accepts_nested_attributes_for+ to define the writer method for you:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects
      #   end
      #
      # If you want to destroy any of the associated models through the
      # form, you have to enable it first using the <tt>:allow_destroy</tt>
      # option for +accepts_nested_attributes_for+:
      #
      #   class Person < ActiveRecord::Base
      #     has_many :projects
      #     accepts_nested_attributes_for :projects, allow_destroy: true
      #   end
      #
      # This will allow you to specify which models to destroy in the
      # attributes hash by adding a form element for the <tt>_destroy</tt>
      # parameter with a value that evaluates to +true+
      # (eg. 1, '1', true, or 'true'):
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       Delete: <%= project_fields.check_box :_destroy %>
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # When a collection is used you might want to know the index of each
      # object into the array. For this purpose, the <tt>index</tt> method
      # is available in the FormBuilder object.
      #
      #   <%= form_for @person do |person_form| %>
      #     ...
      #     <%= person_form.fields_for :projects do |project_fields| %>
      #       Project #<%= project_fields.index %>
      #       ...
      #     <% end %>
      #     ...
      #   <% end %>
      #
      # Note that fields_for will automatically generate a hidden field
      # to store the ID of the record. There are circumstances where this
      # hidden field is not needed and you can pass <tt>hidden_field_id: false</tt>
      # to prevent fields_for from rendering it automatically.
      def fields_for(record_name, record_object = nil, fields_options = {}, &block)
        fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
        fields_options[:builder] ||= options[:builder]
        fields_options[:namespace] = options[:namespace]
        fields_options[:parent_builder] = self

        case record_name
        when String, Symbol
          if nested_attributes_association?(record_name)
            return fields_for_with_nested_attributes(record_name, record_object, fields_options, block)
          end
        else
          record_object = record_name.is_a?(Array) ? record_name.last : record_name
          record_name   = model_name_from_record_or_class(record_object).param_key
        end

        index = if options.has_key?(:index)
          options[:index]
        elsif defined?(@auto_index)
          self.object_name = @object_name.to_s.sub(/\[\]$/,"")
          @auto_index
        end

        record_name = index ? "#{object_name}[#{index}][#{record_name}]" : "#{object_name}[#{record_name}]"
        fields_options[:child_index] = index

        @template.fields_for(record_name, record_object, fields_options, &block)
      end

      # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). The text of label will default to the attribute name unless a translation
      # is found in the current I18n locale (through helpers.label.<modelname>.<attribute>) or you specify it explicitly.
      # Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
      # onto the HTML as an HTML element attribute as in the example shown, except for the <tt>:value</tt> option, which is designed to
      # target labels for radio_button tags (where the value is used in the ID of the input tag).
      #
      # ==== Examples
      #   label(:post, :title)
      #   # => <label for="post_title">Title</label>
      #
      # You can localize your labels based on model and attribute names.
      # For example you can define the following in your locale (e.g. en.yml)
      #
      #   helpers:
      #     label:
      #       post:
      #         body: "Write your entire text here"
      #
      # Which then will result in
      #
      #   label(:post, :body)
      #   # => <label for="post_body">Write your entire text here</label>
      #
      # Localization can also be based purely on the translation of the attribute-name
      # (if you are using ActiveRecord):
      #
      #   activerecord:
      #     attributes:
      #       post:
      #         cost: "Total cost"
      #
      #   label(:post, :cost)
      #   # => <label for="post_cost">Total cost</label>
      #
      #   label(:post, :title, "A short title")
      #   # => <label for="post_title">A short title</label>
      #
      #   label(:post, :title, "A short title", class: "title_label")
      #   # => <label for="post_title" class="title_label">A short title</label>
      #
      #   label(:post, :privacy, "Public Post", value: "public")
      #   # => <label for="post_privacy_public">Public Post</label>
      #
      #   label(:post, :terms) do
      #     'Accept <a href="/terms">Terms</a>.'.html_safe
      #   end
      def label(method, text = nil, options = {}, &block)
        @template.label(@object_name, method, text, objectify_options(options), &block)
      end

      # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). This object must be an instance object (@object) and not a local object.
      # It's intended that +method+ returns an integer and if that integer is above zero, then the checkbox is checked.
      # Additional options on the input tag can be passed as a hash with +options+. The +checked_value+ defaults to 1
      # while the default +unchecked_value+ is set to 0 which is convenient for boolean values.
      #
      # ==== Gotcha
      #
      # The HTML specification says unchecked check boxes are not successful, and
      # thus web browsers do not send them. Unfortunately this introduces a gotcha:
      # if an +Invoice+ model has a +paid+ flag, and in the form that edits a paid
      # invoice the user unchecks its check box, no +paid+ parameter is sent. So,
      # any mass-assignment idiom like
      #
      #   @invoice.update(params[:invoice])
      #
      # wouldn't update the flag.
      #
      # To prevent this the helper generates an auxiliary hidden field before
      # the very check box. The hidden field has the same name and its
      # attributes mimic an unchecked check box.
      #
      # This way, the client either sends only the hidden field (representing
      # the check box is unchecked), or both fields. Since the HTML specification
      # says key/value pairs have to be sent in the same order they appear in the
      # form, and parameters extraction gets the last occurrence of any repeated
      # key in the query string, that works for ordinary forms.
      #
      # Unfortunately that workaround does not work when the check box goes
      # within an array-like parameter, as in
      #
      #   <%= fields_for "project[invoice_attributes][]", invoice, index: nil do |form| %>
      #     <%= form.check_box :paid %>
      #     ...
      #   <% end %>
      #
      # because parameter name repetition is precisely what Rails seeks to distinguish
      # the elements of the array. For each item with a checked check box you
      # get an extra ghost item with only that attribute, assigned to "0".
      #
      # In that case it is preferable to either use +check_box_tag+ or to use
      # hashes instead of arrays.
      #
      #   # Let's say that @post.validated? is 1:
      #   check_box("post", "validated")
      #   # => <input name="post[validated]" type="hidden" value="0" />
      #   #    <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
      #
      #   # Let's say that @puppy.gooddog is "no":
      #   check_box("puppy", "gooddog", {}, "yes", "no")
      #   # => <input name="puppy[gooddog]" type="hidden" value="no" />
      #   #    <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
      #
      #   check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
      #   # => <input name="eula[accepted]" type="hidden" value="no" />
      #   #    <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
      def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
        @template.check_box(@object_name, method, objectify_options(options), checked_value, unchecked_value)
      end

      # Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
      # radio button will be checked.
      #
      # To force the radio button to be checked pass <tt>checked: true</tt> in the
      # +options+ hash. You may pass HTML options there as well.
      #
      #   # Let's say that @post.category returns "rails":
      #   radio_button("post", "category", "rails")
      #   radio_button("post", "category", "java")
      #   # => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
      #   #    <input type="radio" id="post_category_java" name="post[category]" value="java" />
      #
      #   radio_button("user", "receive_newsletter", "yes")
      #   radio_button("user", "receive_newsletter", "no")
      #   # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
      #   #    <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
      def radio_button(method, tag_value, options = {})
        @template.radio_button(@object_name, method, tag_value, objectify_options(options))
      end

      # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown.
      #
      # ==== Examples
      #   hidden_field(:signup, :pass_confirm)
      #   # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
      #
      #   hidden_field(:post, :tag_list)
      #   # => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.tag_list}" />
      #
      #   hidden_field(:user, :token)
      #   # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
      #
      def hidden_field(method, options = {})
        @emitted_hidden_id = true if method == :id
        @template.hidden_field(@object_name, method, objectify_options(options))
      end

      # Returns a file upload input tag tailored for accessing a specified attribute (identified by +method+) on an object
      # assigned to the template (identified by +object+). Additional options on the input tag can be passed as a
      # hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
      # shown.
      #
      # Using this method inside a +form_for+ block will set the enclosing form's encoding to <tt>multipart/form-data</tt>.
      #
      # ==== Options
      # * Creates standard HTML attributes for the tag.
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:multiple</tt> - If set to true, *in most updated browsers* the user will be allowed to select multiple files.
      # * <tt>:accept</tt> - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
      #
      # ==== Examples
      #   file_field(:user, :avatar)
      #   # => <input type="file" id="user_avatar" name="user[avatar]" />
      #
      #   file_field(:post, :image, :multiple => true)
      #   # => <input type="file" id="post_image" name="post[image]" multiple="true" />
      #
      #   file_field(:post, :attached, accept: 'text/html')
      #   # => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
      #
      #   file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
      #   # => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />
      #
      #   file_field(:attachment, :file, class: 'file_input')
      #   # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
      def file_field(method, options = {})
        self.multipart = true
        @template.file_field(@object_name, method, objectify_options(options))
      end

      # Add the submit button for the given form. When no value is given, it checks
      # if the object is a new resource or not to create the proper label:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # In the example above, if @post is a new record, it will use "Create Post" as
      # submit button label, otherwise, it uses "Update Post".
      #
      # Those labels can be customized using I18n, under the helpers.submit key and accept
      # the %{model} as translation interpolation:
      #
      #   en:
      #     helpers:
      #       submit:
      #         create: "Create a %{model}"
      #         update: "Confirm changes to %{model}"
      #
      # It also searches for a key specific for the given object:
      #
      #   en:
      #     helpers:
      #       submit:
      #         post:
      #           create: "Add %{model}"
      #
      def submit(value=nil, options={})
        value, options = nil, value if value.is_a?(Hash)
        value ||= submit_default_value
        @template.submit_tag(value, options)
      end

      # Add the submit button for the given form. When no value is given, it checks
      # if the object is a new resource or not to create the proper label:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.button %>
      #   <% end %>
      #
      # In the example above, if @post is a new record, it will use "Create Post" as
      # button label, otherwise, it uses "Update Post".
      #
      # Those labels can be customized using I18n, under the helpers.submit key
      # (the same as submit helper) and accept the %{model} as translation interpolation:
      #
      #   en:
      #     helpers:
      #       submit:
      #         create: "Create a %{model}"
      #         update: "Confirm changes to %{model}"
      #
      # It also searches for a key specific for the given object:
      #
      #   en:
      #     helpers:
      #       submit:
      #         post:
      #           create: "Add %{model}"
      #
      # ==== Examples
      #   button("Create a post")
      #   # => <button name='button' type='submit'>Create post</button>
      #
      #   button do
      #     content_tag(:strong, 'Ask me!')
      #   end
      #   # => <button name='button' type='submit'>
      #   #      <strong>Ask me!</strong>
      #   #    </button>
      #
      def button(value = nil, options = {}, &block)
        value, options = nil, value if value.is_a?(Hash)
        value ||= submit_default_value
        @template.button_tag(value, options, &block)
      end

      def emitted_hidden_id?
        @emitted_hidden_id ||= nil
      end

      private
        def objectify_options(options)
          @default_options.merge(options.merge(object: @object))
        end

        def submit_default_value
          object = convert_to_model(@object)
          key    = object ? (object.persisted? ? :update : :create) : :submit

          model = if object.class.respond_to?(:model_name)
            object.class.model_name.human
          else
            @object_name.to_s.humanize
          end

          defaults = []
          defaults << :"helpers.submit.#{object_name}.#{key}"
          defaults << :"helpers.submit.#{key}"
          defaults << "#{key.to_s.humanize} #{model}"

          I18n.t(defaults.shift, model: model, default: defaults)
        end

        def nested_attributes_association?(association_name)
          @object.respond_to?("#{association_name}_attributes=")
        end

        def fields_for_with_nested_attributes(association_name, association, options, block)
          name = "#{object_name}[#{association_name}_attributes]"
          association = convert_to_model(association)

          if association.respond_to?(:persisted?)
            association = [association] if @object.send(association_name).respond_to?(:to_ary)
          elsif !association.respond_to?(:to_ary)
            association = @object.send(association_name)
          end

          if association.respond_to?(:to_ary)
            explicit_child_index = options[:child_index]
            output = ActiveSupport::SafeBuffer.new
            association.each do |child|
              options[:child_index] = nested_child_index(name) unless explicit_child_index
              output << fields_for_nested_model("#{name}[#{options[:child_index]}]", child, options, block)
            end
            output
          elsif association
            fields_for_nested_model(name, association, options, block)
          end
        end

        def fields_for_nested_model(name, object, fields_options, block)
          object = convert_to_model(object)
          emit_hidden_id = object.persisted? && fields_options.fetch(:include_id) {
            options.fetch(:include_id, true)
          }

          @template.fields_for(name, object, fields_options) do |f|
            output = @template.capture(f, &block)
            output.concat f.hidden_field(:id) if output && emit_hidden_id && !f.emitted_hidden_id?
            output
          end
        end

        def nested_child_index(name)
          @nested_child_index[name] ||= -1
          @nested_child_index[name] += 1
        end
    end
  end

  ActiveSupport.on_load(:action_view) do
    cattr_accessor(:default_form_builder) { ::ActionView::Helpers::FormBuilder }
  end
end
require 'cgi'
require 'erb'
require 'action_view/helpers/form_helper'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/array/wrap'

module ActionView
  # = Action View Form Option Helpers
  module Helpers
    # Provides a number of methods for turning different kinds of containers into a set of option tags.
    #
    # The <tt>collection_select</tt>, <tt>select</tt> and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter, a hash:
    #
    # * <tt>:include_blank</tt> - set to true or a prompt string if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.
    #
    #   select("post", "category", Post::CATEGORIES, {include_blank: true})
    #
    # could become:
    #
    #   <select name="post[category]">
    #     <option></option>
    #     <option>joke</option>
    #     <option>poem</option>
    #   </select>
    #
    # Another common case is a select tag for a <tt>belongs_to</tt>-associated object.
    #
    # Example with @post.person_id => 2:
    #
    #   select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {include_blank: 'None'})
    #
    # could become:
    #
    #   <select name="post[person_id]">
    #     <option value="">None</option>
    #     <option value="1">David</option>
    #     <option value="2" selected="selected">Sam</option>
    #     <option value="3">Tobias</option>
    #   </select>
    #
    # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string.
    #
    #   select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, {prompt: 'Select Person'})
    #
    # could become:
    #
    #   <select name="post[person_id]">
    #     <option value="">Select Person</option>
    #     <option value="1">David</option>
    #     <option value="2">Sam</option>
    #     <option value="3">Tobias</option>
    #   </select>
    #
    # Like the other form helpers, +select+ can accept an <tt>:index</tt> option to manually set the ID used in the resulting output. Unlike other helpers, +select+ expects this
    # option to be in the +html_options+ parameter.
    #
    #   select("album[]", "genre", %w[rap rock country], {}, { index: nil })
    #
    # becomes:
    #
    #   <select name="album[][genre]" id="album__genre">
    #     <option value="rap">rap</option>
    #     <option value="rock">rock</option>
    #     <option value="country">country</option>
    #   </select>
    #
    # * <tt>:disabled</tt> - can be a single value or an array of values that will be disabled options in the final output.
    #
    #   select("post", "category", Post::CATEGORIES, {disabled: 'restricted'})
    #
    # could become:
    #
    #   <select name="post[category]">
    #     <option></option>
    #     <option>joke</option>
    #     <option>poem</option>
    #     <option disabled="disabled">restricted</option>
    #   </select>
    #
    # When used with the <tt>collection_select</tt> helper, <tt>:disabled</tt> can also be a Proc that identifies those options that should be disabled.
    #
    #   collection_select(:post, :category_id, Category.all, :id, :name, {disabled: lambda{|category| category.archived? }})
    #
    # If the categories "2008 stuff" and "Christmas" return true when the method <tt>archived?</tt> is called, this would return:
    #   <select name="post[category_id]">
    #     <option value="1" disabled="disabled">2008 stuff</option>
    #     <option value="2" disabled="disabled">Christmas</option>
    #     <option value="3">Jokes</option>
    #     <option value="4">Poems</option>
    #   </select>
    #
    module FormOptionsHelper
      # ERB::Util can mask some helpers like textilize. Make sure to include them.
      include TextHelper

      # Create a select tag and a series of contained option tags for the provided object and method.
      # The option currently held by the object will be selected, provided that the object is available.
      #
      # There are two possible formats for the choices parameter, corresponding to other helpers' output:
      #   * A flat collection: see options_for_select
      #   * A nested collection: see grouped_options_for_select
      #
      # Example with @post.person_id => 1:
      #   select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true })
      #
      # could become:
      #
      #   <select name="post[person_id]">
      #     <option value=""></option>
      #     <option value="1" selected="selected">David</option>
      #     <option value="2">Sam</option>
      #     <option value="3">Tobias</option>
      #   </select>
      #
      # This can be used to provide a default set of options in the standard way: before rendering the create form, a
      # new model instance is assigned the default options and bound to @model_name. Usually this model is not saved
      # to the database. Instead, a second model object is created when the create request is received.
      # This allows the user to submit a form page more than once with the expected results of creating multiple records.
      # In addition, this allows a single partial to be used to generate form inputs for both edit and create forms.
      #
      # By default, <tt>post.person_id</tt> is the selected option. Specify <tt>selected: value</tt> to use a different selection
      # or <tt>selected: nil</tt> to leave all options unselected. Similarly, you can specify values to be disabled in the option
      # tags by specifying the <tt>:disabled</tt> option. This can either be a single value or an array of values to be disabled.
      #
      # ==== Gotcha
      #
      # The HTML specification says when +multiple+ parameter passed to select and all options got deselected
      # web browsers do not send any value to server. Unfortunately this introduces a gotcha:
      # if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
      # the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
      # any mass-assignment idiom like
      #
      #   @user.update(params[:user])
      #
      # wouldn't update roles.
      #
      # To prevent this the helper generates an auxiliary hidden field before
      # every multiple select. The hidden field has the same name as multiple select and blank value.
      #
      # This way, the client either sends only the hidden field (representing
      # the deselected multiple select box), or both fields. Since the HTML specification
      # says key/value pairs have to be sent in the same order they appear in the
      # form, and parameters extraction gets the last occurrence of any repeated
      # key in the query string, that works for ordinary forms.
      #
      # In case if you don't want the helper to generate this hidden field you can specify
      # <tt>include_hidden: false</tt> option.
      #
      def select(object, method, choices, options = {}, html_options = {})
        Tags::Select.new(object, method, self, choices, options, html_options).render
      end

      # Returns <tt><select></tt> and <tt><option></tt> tags for the collection of existing return values of
      # +method+ for +object+'s class. The value returned from calling +method+ on the instance +object+ will
      # be selected. If calling +method+ returns +nil+, no selection is made without including <tt>:prompt</tt>
      # or <tt>:include_blank</tt> in the +options+ hash.
      #
      # The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are methods to be called on each member
      # of +collection+. The return values are used as the +value+ attribute and contents of each
      # <tt><option></tt> tag, respectively. They can also be any object that responds to +call+, such
      # as a +proc+, that will be called for each member of the +collection+ to
      # retrieve the value/text.
      #
      # Example object structure for use with this method:
      #
      #   class Post < ActiveRecord::Base
      #     belongs_to :author
      #   end
      #
      #   class Author < ActiveRecord::Base
      #     has_many :posts
      #     def name_with_initial
      #       "#{first_name.first}. #{last_name}"
      #     end
      #   end
      #
      # Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
      #
      #   collection_select(:post, :author_id, Author.all, :id, :name_with_initial, prompt: true)
      #
      # If <tt>@post.author_id</tt> is already <tt>1</tt>, this would return:
      #   <select name="post[author_id]">
      #     <option value="">Please select</option>
      #     <option value="1" selected="selected">D. Heinemeier Hansson</option>
      #     <option value="2">D. Thomas</option>
      #     <option value="3">M. Clark</option>
      #   </select>
      def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
        Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render
      end

      # Returns <tt><select></tt>, <tt><optgroup></tt> and <tt><option></tt> tags for the collection of existing return values of
      # +method+ for +object+'s class. The value returned from calling +method+ on the instance +object+ will
      # be selected. If calling +method+ returns +nil+, no selection is made without including <tt>:prompt</tt>
      # or <tt>:include_blank</tt> in the +options+ hash.
      #
      # Parameters:
      # * +object+ - The instance of the class to be used for the select tag
      # * +method+ - The attribute of +object+ corresponding to the select tag
      # * +collection+ - An array of objects representing the <tt><optgroup></tt> tags.
      # * +group_method+ - The name of a method which, when called on a member of +collection+, returns an
      #   array of child objects representing the <tt><option></tt> tags.
      # * +group_label_method+ - The name of a method which, when called on a member of +collection+, returns a
      #   string to be used as the +label+ attribute for its <tt><optgroup></tt> tag.
      # * +option_key_method+ - The name of a method which, when called on a child object of a member of
      #   +collection+, returns a value to be used as the +value+ attribute for its <tt><option></tt> tag.
      # * +option_value_method+ - The name of a method which, when called on a child object of a member of
      #   +collection+, returns a value to be used as the contents of its <tt><option></tt> tag.
      #
      # Example object structure for use with this method:
      #
      #   class Continent < ActiveRecord::Base
      #     has_many :countries
      #     # attribs: id, name
      #   end
      #
      #   class Country < ActiveRecord::Base
      #     belongs_to :continent
      #     # attribs: id, name, continent_id
      #   end
      #
      #   class City < ActiveRecord::Base
      #     belongs_to :country
      #     # attribs: id, name, country_id
      #   end
      #
      # Sample usage:
      #
      #   grouped_collection_select(:city, :country_id, @continents, :countries, :name, :id, :name)
      #
      # Possible output:
      #
      #   <select name="city[country_id]">
      #     <optgroup label="Africa">
      #       <option value="1">South Africa</option>
      #       <option value="3">Somalia</option>
      #     </optgroup>
      #     <optgroup label="Europe">
      #       <option value="7" selected="selected">Denmark</option>
      #       <option value="2">Ireland</option>
      #     </optgroup>
      #   </select>
      #
      def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
        Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
      end

      # Return select and option tags for the given object and method, using
      # #time_zone_options_for_select to generate the list of option tags.
      #
      # In addition to the <tt>:include_blank</tt> option documented above,
      # this method also supports a <tt>:model</tt> option, which defaults
      # to ActiveSupport::TimeZone. This may be used by users to specify a
      # different time zone model object. (See +time_zone_options_for_select+
      # for more information.)
      #
      # You can also supply an array of ActiveSupport::TimeZone objects
      # as +priority_zones+, so that they will be listed above the rest of the
      # (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
      # for obtaining a list of the US time zones, or a Regexp to select the zones
      # of your choice)
      #
      # Finally, this method supports a <tt>:default</tt> option, which selects
      # a default ActiveSupport::TimeZone if the object's time zone is +nil+.
      #
      #   time_zone_select( "user", "time_zone", nil, include_blank: true)
      #
      #   time_zone_select( "user", "time_zone", nil, default: "Pacific Time (US & Canada)" )
      #
      #   time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, default: "Pacific Time (US & Canada)")
      #
      #   time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
      #
      #   time_zone_select( "user", 'time_zone', /Australia/)
      #
      #   time_zone_select( "user", "time_zone", ActiveSupport::TimeZone.all.sort, model: ActiveSupport::TimeZone)
      def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
        Tags::TimeZoneSelect.new(object, method, self, priority_zones, options, html_options).render
      end

      # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
      # where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
      # the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values
      # become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +selected+
      # may also be an array of values to be selected when using a multiple select.
      #
      #   options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
      #   # => <option value="$">Dollar</option>
      #   # => <option value="DKK">Kroner</option>
      #
      #   options_for_select([ "VISA", "MasterCard" ], "MasterCard")
      #   # => <option>VISA</option>
      #   # => <option selected="selected">MasterCard</option>
      #
      #   options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
      #   # => <option value="$20">Basic</option>
      #   # => <option value="$40" selected="selected">Plus</option>
      #
      #   options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
      #   # => <option selected="selected">VISA</option>
      #   # => <option>MasterCard</option>
      #   # => <option selected="selected">Discover</option>
      #
      # You can optionally provide html attributes as the last element of the array.
      #
      #   options_for_select([ "Denmark", ["USA", {class: 'bold'}], "Sweden" ], ["USA", "Sweden"])
      #   # => <option value="Denmark">Denmark</option>
      #   # => <option value="USA" class="bold" selected="selected">USA</option>
      #   # => <option value="Sweden" selected="selected">Sweden</option>
      #
      #   options_for_select([["Dollar", "$", {class: "bold"}], ["Kroner", "DKK", {onclick: "alert('HI');"}]])
      #   # => <option value="$" class="bold">Dollar</option>
      #   # => <option value="DKK" onclick="alert('HI');">Kroner</option>
      #
      # If you wish to specify disabled option tags, set +selected+ to be a hash, with <tt>:disabled</tt> being either a value
      # or array of values to be disabled. In this case, you can use <tt>:selected</tt> to specify selected option tags.
      #
      #   options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: "Super Platinum")
      #   # => <option value="Free">Free</option>
      #   # => <option value="Basic">Basic</option>
      #   # => <option value="Advanced">Advanced</option>
      #   # => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
      #
      #   options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], disabled: ["Advanced", "Super Platinum"])
      #   # => <option value="Free">Free</option>
      #   # => <option value="Basic">Basic</option>
      #   # => <option value="Advanced" disabled="disabled">Advanced</option>
      #   # => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
      #
      #   options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], selected: "Free", disabled: "Super Platinum")
      #   # => <option value="Free" selected="selected">Free</option>
      #   # => <option value="Basic">Basic</option>
      #   # => <option value="Advanced">Advanced</option>
      #   # => <option value="Super Platinum" disabled="disabled">Super Platinum</option>
      #
      # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
      def options_for_select(container, selected = nil)
        return container if String === container

        selected, disabled = extract_selected_and_disabled(selected).map do |r|
          Array(r).map { |item| item.to_s }
        end

        container.map do |element|
          html_attributes = option_html_attributes(element)
          text, value = option_text_and_value(element).map { |item| item.to_s }

          html_attributes[:selected] = 'selected' if option_value_selected?(value, selected)
          html_attributes[:disabled] = 'disabled' if disabled && option_value_selected?(value, disabled)
          html_attributes[:value] = value

          content_tag_string(:option, text, html_attributes)
        end.join("\n").html_safe
      end

      # Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning
      # the result of a call to the +value_method+ as the option value and the +text_method+ as the option text.
      #
      #   options_from_collection_for_select(@people, 'id', 'name')
      #   # => <option value="#{person.id}">#{person.name}</option>
      #
      # This is more often than not used inside a #select_tag like this example:
      #
      #   select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')
      #
      # If +selected+ is specified as a value or array of values, the element(s) returning a match on +value_method+
      # will be selected option tag(s).
      #
      # If +selected+ is specified as a Proc, those members of the collection that return true for the anonymous
      # function are the selected values.
      #
      # +selected+ can also be a hash, specifying both <tt>:selected</tt> and/or <tt>:disabled</tt> values as required.
      #
      # Be sure to specify the same class as the +value_method+ when specifying selected or disabled options.
      # Failure to do this will produce undesired results. Example:
      #   options_from_collection_for_select(@people, 'id', 'name', '1')
      # Will not select a person with the id of 1 because 1 (an Integer) is not the same as '1' (a string)
      #   options_from_collection_for_select(@people, 'id', 'name', 1)
      # should produce the desired results.
      def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
        options = collection.map do |element|
          [value_for_collection(element, text_method), value_for_collection(element, value_method)]
        end
        selected, disabled = extract_selected_and_disabled(selected)
        select_deselect = {
          :selected => extract_values_from_collection(collection, value_method, selected),
          :disabled => extract_values_from_collection(collection, value_method, disabled)
        }

        options_for_select(options, select_deselect)
      end

      # Returns a string of <tt><option></tt> tags, like <tt>options_from_collection_for_select</tt>, but
      # groups them by <tt><optgroup></tt> tags based on the object relationships of the arguments.
      #
      # Parameters:
      # * +collection+ - An array of objects representing the <tt><optgroup></tt> tags.
      # * +group_method+ - The name of a method which, when called on a member of +collection+, returns an
      #   array of child objects representing the <tt><option></tt> tags.
      # * group_label_method+ - The name of a method which, when called on a member of +collection+, returns a
      #   string to be used as the +label+ attribute for its <tt><optgroup></tt> tag.
      # * +option_key_method+ - The name of a method which, when called on a child object of a member of
      #   +collection+, returns a value to be used as the +value+ attribute for its <tt><option></tt> tag.
      # * +option_value_method+ - The name of a method which, when called on a child object of a member of
      #   +collection+, returns a value to be used as the contents of its <tt><option></tt> tag.
      # * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
      #   which will have the +selected+ attribute set. Corresponds to the return value of one of the calls
      #   to +option_key_method+. If +nil+, no selection is made. Can also be a hash if disabled values are
      #   to be specified.
      #
      # Example object structure for use with this method:
      #
      #   class Continent < ActiveRecord::Base
      #     has_many :countries
      #     # attribs: id, name
      #   end
      #
      #   class Country < ActiveRecord::Base
      #     belongs_to :continent
      #     # attribs: id, name, continent_id
      #   end
      #
      # Sample usage:
      #   option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
      #
      # Possible output:
      #   <optgroup label="Africa">
      #     <option value="1">Egypt</option>
      #     <option value="4">Rwanda</option>
      #     ...
      #   </optgroup>
      #   <optgroup label="Asia">
      #     <option value="3" selected="selected">China</option>
      #     <option value="12">India</option>
      #     <option value="5">Japan</option>
      #     ...
      #   </optgroup>
      #
      # <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
      # wrap the output in an appropriate <tt><select></tt> tag.
      def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
        collection.map do |group|
          option_tags = options_from_collection_for_select(
            group.send(group_method), option_key_method, option_value_method, selected_key)

          content_tag(:optgroup, option_tags, :label => group.send(group_label_method))
        end.join.html_safe
      end

      # Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
      # wraps them with <tt><optgroup></tt> tags.
      #
      # Parameters:
      # * +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
      #   <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
      #   nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
      #    Ex. ["North America",[["United States","US"],["Canada","CA"]]]
      # * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
      #   which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
      #   as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
      #
      # Options:
      # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this
      #   prepends an option with a generic prompt - "Please select" - or the given prompt string.
      # * <tt>:divider</tt> - the divider for the options groups.
      #
      #   grouped_options = [
      #    ['North America',
      #      [['United States','US'],'Canada']],
      #    ['Europe',
      #      ['Denmark','Germany','France']]
      #   ]
      #   grouped_options_for_select(grouped_options)
      #
      #   grouped_options = {
      #     'North America' => [['United States','US'], 'Canada'],
      #     'Europe' => ['Denmark','Germany','France']
      #   }
      #   grouped_options_for_select(grouped_options)
      #
      # Possible output:
      #   <optgroup label="North America">
      #     <option value="US">United States</option>
      #     <option value="Canada">Canada</option>
      #   </optgroup>
      #   <optgroup label="Europe">
      #     <option value="Denmark">Denmark</option>
      #     <option value="Germany">Germany</option>
      #     <option value="France">France</option>
      #   </optgroup>
      #
      #   grouped_options = [
      #     [['United States','US'], 'Canada'],
      #     ['Denmark','Germany','France']
      #   ]
      #   grouped_options_for_select(grouped_options, nil, divider: '---------')
      #
      # Possible output:
      #   <optgroup label="---------">
      #     <option value="US">United States</option>
      #     <option value="Canada">Canada</option>
      #   </optgroup>
      #   <optgroup label="---------">
      #     <option value="Denmark">Denmark</option>
      #     <option value="Germany">Germany</option>
      #     <option value="France">France</option>
      #   </optgroup>
      #
      # <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
      # wrap the output in an appropriate <tt><select></tt> tag.
      def grouped_options_for_select(grouped_options, selected_key = nil, options = {})
        if options.is_a?(Hash)
          prompt  = options[:prompt]
          divider = options[:divider]
        else
          prompt  = options
          options = {}
          message = "Passing the prompt to grouped_options_for_select as an argument is deprecated. " \
                    "Please use an options hash like `{ prompt: #{prompt.inspect} }`."
          ActiveSupport::Deprecation.warn message
        end

        body = "".html_safe

        if prompt
          body.safe_concat content_tag(:option, prompt_text(prompt), :value => "")
        end

        grouped_options.each do |container|
          if divider
            label = divider
          else
            label, container = container
          end
          body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), :label => label)
        end

        body
      end

      # Returns a string of option tags for pretty much any time zone in the
      # world. Supply a ActiveSupport::TimeZone name as +selected+ to have it
      # marked as the selected option tag. You can also supply an array of
      # ActiveSupport::TimeZone objects as +priority_zones+, so that they will
      # be listed above the rest of the (long) list. (You can use
      # ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list
      # of the US time zones, or a Regexp to select the zones of your choice)
      #
      # The +selected+ parameter must be either +nil+, or a string that names
      # a ActiveSupport::TimeZone.
      #
      # By default, +model+ is the ActiveSupport::TimeZone constant (which can
      # be obtained in Active Record as a value object). The only requirement
      # is that the +model+ parameter be an object that responds to +all+, and
      # returns an array of objects that represent time zones.
      #
      # NOTE: Only the option tags are returned, you have to wrap this call in
      # a regular HTML select tag.
      def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
        zone_options = "".html_safe

        zones = model.all
        convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }

        if priority_zones
          if priority_zones.is_a?(Regexp)
            priority_zones = zones.select { |z| z =~ priority_zones }
          end

          zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
          zone_options.safe_concat content_tag(:option, '-------------', :value => '', :disabled => 'disabled')
          zone_options.safe_concat "\n"

          zones.reject! { |z| priority_zones.include?(z) }
        end

        zone_options.safe_concat options_for_select(convert_zones[zones], selected)
      end

      # Returns radio button tags for the collection of existing return values
      # of +method+ for +object+'s class. The value returned from calling
      # +method+ on the instance +object+ will be selected. If calling +method+
      # returns +nil+, no selection is made.
      #
      # The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are
      # methods to be called on each member of +collection+. The return values
      # are used as the +value+ attribute and contents of each radio button tag,
      # respectively. They can also be any object that responds to +call+, such
      # as a +proc+, that will be called for each member of the +collection+ to
      # retrieve the value/text.
      #
      # Example object structure for use with this method:
      #   class Post < ActiveRecord::Base
      #     belongs_to :author
      #   end
      #   class Author < ActiveRecord::Base
      #     has_many :posts
      #     def name_with_initial
      #       "#{first_name.first}. #{last_name}"
      #     end
      #   end
      #
      # Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
      #   collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)
      #
      # If <tt>@post.author_id</tt> is already <tt>1</tt>, this would return:
      #   <input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
      #   <label for="post_author_id_1">D. Heinemeier Hansson</label>
      #   <input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
      #   <label for="post_author_id_2">D. Thomas</label>
      #   <input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
      #   <label for="post_author_id_3">M. Clark</label>
      #
      # It is also possible to customize the way the elements will be shown by
      # giving a block to the method:
      #   collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
      #     b.label { b.radio_button }
      #   end
      #
      # The argument passed to the block is a special kind of builder for this
      # collection, which has the ability to generate the label and radio button
      # for the current item in the collection, with proper text and value.
      # Using it, you can change the label and radio button display order or
      # even use the label as wrapper, as in the example above.
      #
      # The builder methods <tt>label</tt> and <tt>radio_button</tt> also accept
      # extra html options:
      #   collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
      #     b.label(class: "radio_button") { b.radio_button(class: "radio_button") }
      #   end
      #
      # There are also three special methods available: <tt>object</tt>, <tt>text</tt> and
      # <tt>value</tt>, which are the current item being rendered, its text and value methods,
      # respectively. You can use them like this:
      #   collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
      #      b.label(:"data-value" => b.value) { b.radio_button + b.text }
      #   end
      def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
        Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
      end

      # Returns check box tags for the collection of existing return values of
      # +method+ for +object+'s class. The value returned from calling +method+
      # on the instance +object+ will be selected. If calling +method+ returns
      # +nil+, no selection is made.
      #
      # The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are
      # methods to be called on each member of +collection+. The return values
      # are used as the +value+ attribute and contents of each check box tag,
      # respectively. They can also be any object that responds to +call+, such
      # as a +proc+, that will be called for each member of the +collection+ to
      # retrieve the value/text.
      #
      # Example object structure for use with this method:
      #   class Post < ActiveRecord::Base
      #     has_and_belongs_to_many :author
      #   end
      #   class Author < ActiveRecord::Base
      #     has_and_belongs_to_many :posts
      #     def name_with_initial
      #       "#{first_name.first}. #{last_name}"
      #     end
      #   end
      #
      # Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
      #   collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
      #
      # If <tt>@post.author_ids</tt> is already <tt>[1]</tt>, this would return:
      #   <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
      #   <label for="post_author_ids_1">D. Heinemeier Hansson</label>
      #   <input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
      #   <label for="post_author_ids_2">D. Thomas</label>
      #   <input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
      #   <label for="post_author_ids_3">M. Clark</label>
      #   <input name="post[author_ids][]" type="hidden" value="" />
      #
      # It is also possible to customize the way the elements will be shown by
      # giving a block to the method:
      #   collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
      #     b.label { b.check_box }
      #   end
      #
      # The argument passed to the block is a special kind of builder for this
      # collection, which has the ability to generate the label and check box
      # for the current item in the collection, with proper text and value.
      # Using it, you can change the label and check box display order or even
      # use the label as wrapper, as in the example above.
      #
      # The builder methods <tt>label</tt> and <tt>check_box</tt> also accept
      # extra html options:
      #   collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
      #     b.label(class: "check_box") { b.check_box(class: "check_box") }
      #   end
      #
      # There are also three special methods available: <tt>object</tt>, <tt>text</tt> and
      # <tt>value</tt>, which are the current item being rendered, its text and value methods,
      # respectively. You can use them like this:
      #   collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
      #      b.label(:"data-value" => b.value) { b.check_box + b.text }
      #   end
      def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
        Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
      end

      private
        def option_html_attributes(element)
          if Array === element
            element.select { |e| Hash === e }.reduce({}, :merge!)
          else
            {}
          end
        end

        def option_text_and_value(option)
          # Options are [text, value] pairs or strings used for both.
          if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
            option = option.reject { |e| Hash === e } if Array === option
            [option.first, option.last]
          else
            [option, option]
          end
        end

        def option_value_selected?(value, selected)
          Array(selected).include? value
        end

        def extract_selected_and_disabled(selected)
          if selected.is_a?(Proc)
            [selected, nil]
          else
            selected = Array.wrap(selected)
            options = selected.extract_options!.symbolize_keys
            selected_items = options.fetch(:selected, selected)
            [selected_items, options[:disabled]]
          end
        end

        def extract_values_from_collection(collection, value_method, selected)
          if selected.is_a?(Proc)
            collection.map do |element|
              element.send(value_method) if selected.call(element)
            end.compact
          else
            selected
          end
        end

        def value_for_collection(item, value)
          value.respond_to?(:call) ? value.call(item) : item.send(value)
        end

        def prompt_text(prompt)
          prompt = prompt.kind_of?(String) ? prompt : I18n.translate('helpers.select.prompt', :default => 'Please select')
        end
    end

    class FormBuilder
      # Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.select :person_id, Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true }) %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def select(method, choices, options = {}, html_options = {})
        @template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options))
      end

      # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
        @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options))
      end

      # Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders:
      #
      #   <%= form_for @city do |f| %>
      #     <%= f.grouped_collection_select :country_id, :country_id, @continents, :countries, :name, :id, :name %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
        @template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_options.merge(html_options))
      end

      # Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders:
      #
      #   <%= form_for @user do |f| %>
      #     <%= f.time_zone_select :time_zone, nil, include_blank: true %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
        @template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_options.merge(html_options))
      end

      # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
        @template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
      end

      # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
      #
      #   <%= form_for @post do |f| %>
      #     <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
      #     <%= f.submit %>
      #   <% end %>
      #
      # Please refer to the documentation of the base helper for details.
      def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
        @template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
      end
    end
  end
end
require 'cgi'
require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/module/attribute_accessors'

module ActionView
  # = Action View Form Tag Helpers
  module Helpers
    # Provides a number of methods for creating form tags that don't rely on an Active Record object assigned to the template like
    # FormHelper does. Instead, you provide the names and values manually.
    #
    # NOTE: The HTML options <tt>disabled</tt>, <tt>readonly</tt>, and <tt>multiple</tt> can all be treated as booleans. So specifying
    # <tt>disabled: true</tt> will give <tt>disabled="disabled"</tt>.
    module FormTagHelper
      extend ActiveSupport::Concern

      include UrlHelper
      include TextHelper

      mattr_accessor :embed_authenticity_token_in_remote_forms
      self.embed_authenticity_token_in_remote_forms = false

      # Starts a form tag that points the action to an url configured with <tt>url_for_options</tt> just like
      # ActionController::Base#url_for. The method for the form defaults to POST.
      #
      # ==== Options
      # * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
      # * <tt>:method</tt> - The method to use when submitting the form, usually either "get" or "post".
      #   If "patch", "put", "delete", or another verb is used, a hidden input with name <tt>_method</tt>
      #   is added to simulate the verb over post.
      # * <tt>:authenticity_token</tt> - Authenticity token to use in the form. Use only if you need to
      #   pass custom authenticity token string, or to not add authenticity_token field at all
      #   (by passing <tt>false</tt>).  Remote forms may omit the embedded authenticity token
      #   by setting <tt>config.action_view.embed_authenticity_token_in_remote_forms = false</tt>.
      #   This is helpful when you're fragment-caching the form. Remote forms get the
      #   authenticity from the <tt>meta</tt> tag, so embedding is unnecessary unless you
      #   support browsers without JavaScript.
      # * A list of parameters to feed to the URL the form will be posted to.
      # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
      #   submit behavior. By default this behavior is an ajax submit.
      #
      # ==== Examples
      #   form_tag('/posts')
      #   # => <form action="/posts" method="post">
      #
      #   form_tag('/posts/1', method: :put)
      #   # => <form action="/posts/1" method="post"> ... <input name="_method" type="hidden" value="put" /> ...
      #
      #   form_tag('/upload', multipart: true)
      #   # => <form action="/upload" method="post" enctype="multipart/form-data">
      #
      #   <%= form_tag('/posts') do -%>
      #     <div><%= submit_tag 'Save' %></div>
      #   <% end -%>
      #   # => <form action="/posts" method="post"><div><input type="submit" name="commit" value="Save" /></div></form>
      #
      #   <%= form_tag('/posts', remote: true) %>
      #   # => <form action="/posts" method="post" data-remote="true">
      #
      #   form_tag('http://far.away.com/form', authenticity_token: false)
      #   # form without authenticity token
      #
      #   form_tag('http://far.away.com/form', authenticity_token: "cf50faa3fe97702ca1ae")
      #   # form with custom authenticity token
      #
      def form_tag(url_for_options = {}, options = {}, &block)
        html_options = html_options_for_form(url_for_options, options)
        if block_given?
          form_tag_in_block(html_options, &block)
        else
          form_tag_html(html_options)
        end
      end

      # Creates a dropdown selection box, or if the <tt>:multiple</tt> option is set to true, a multiple
      # choice selection box.
      #
      # Helpers::FormOptions can be used to create common select boxes such as countries, time zones, or
      # associated records. <tt>option_tags</tt> is a string containing the option tags for the select box.
      #
      # ==== Options
      # * <tt>:multiple</tt> - If set to true the selection will allow multiple choices.
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:include_blank</tt> - If set to true, an empty option will be create
      # * <tt>:prompt</tt> - Create a prompt option with blank value and the text asking user to select something
      # * Any other key creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   select_tag "people", options_from_collection_for_select(@people, "id", "name")
      #   # <select id="people" name="people"><option value="1">David</option></select>
      #
      #   select_tag "people", "<option>David</option>".html_safe
      #   # => <select id="people" name="people"><option>David</option></select>
      #
      #   select_tag "count", "<option>1</option><option>2</option><option>3</option><option>4</option>".html_safe
      #   # => <select id="count" name="count"><option>1</option><option>2</option>
      #   #    <option>3</option><option>4</option></select>
      #
      #   select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>".html_safe, multiple: true
      #   # => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
      #   #    <option>Green</option><option>Blue</option></select>
      #
      #   select_tag "locations", "<option>Home</option><option selected='selected'>Work</option><option>Out</option>".html_safe
      #   # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
      #   #    <option>Out</option></select>
      #
      #   select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, class: 'form_input'
      #   # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
      #   #    <option>Write</option></select>
      #
      #   select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true
      #   # => <select id="people" name="people"><option value=""></option><option value="1">David</option></select>
      #
      #   select_tag "people", options_from_collection_for_select(@people, "id", "name"), prompt: "Select something"
      #   # => <select id="people" name="people"><option value="">Select something</option><option value="1">David</option></select>
      #
      #   select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>".html_safe, disabled: true
      #   # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
      #   #    <option>Paris</option><option>Rome</option></select>
      #
      #   select_tag "credit_card", options_for_select([ "VISA", "MasterCard" ], "MasterCard")
      #   # => <select id="credit_card" name="credit_card"><option>VISA</option>
      #   #    <option selected="selected">MasterCard</option></select>
      def select_tag(name, option_tags = nil, options = {})
        option_tags ||= ""
        html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name

        if options.delete(:include_blank)
          option_tags = content_tag(:option, '', :value => '').safe_concat(option_tags)
        end

        if prompt = options.delete(:prompt)
          option_tags = content_tag(:option, prompt, :value => '').safe_concat(option_tags)
        end

        content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
      end

      # Creates a standard text field; use these text fields to input smaller chunks of text like a username
      # or a search query.
      #
      # ==== Options
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:size</tt> - The number of visible characters that will fit in the input.
      # * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
      # * <tt>:placeholder</tt> - The text contained in the field by default which is removed when the field receives focus.
      # * Any other key creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   text_field_tag 'name'
      #   # => <input id="name" name="name" type="text" />
      #
      #   text_field_tag 'query', 'Enter your search query here'
      #   # => <input id="query" name="query" type="text" value="Enter your search query here" />
      #
      #   text_field_tag 'search', nil, placeholder: 'Enter search term...'
      #   # => <input id="search" name="search" placeholder="Enter search term..." type="text" />
      #
      #   text_field_tag 'request', nil, class: 'special_input'
      #   # => <input class="special_input" id="request" name="request" type="text" />
      #
      #   text_field_tag 'address', '', size: 75
      #   # => <input id="address" name="address" size="75" type="text" value="" />
      #
      #   text_field_tag 'zip', nil, maxlength: 5
      #   # => <input id="zip" maxlength="5" name="zip" type="text" />
      #
      #   text_field_tag 'payment_amount', '$0.00', disabled: true
      #   # => <input disabled="disabled" id="payment_amount" name="payment_amount" type="text" value="$0.00" />
      #
      #   text_field_tag 'ip', '0.0.0.0', maxlength: 15, size: 20, class: "ip-input"
      #   # => <input class="ip-input" id="ip" maxlength="15" name="ip" size="20" type="text" value="0.0.0.0" />
      def text_field_tag(name, value = nil, options = {})
        tag :input, { "type" => "text", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
      end

      # Creates a label element. Accepts a block.
      #
      # ==== Options
      # * Creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   label_tag 'name'
      #   # => <label for="name">Name</label>
      #
      #   label_tag 'name', 'Your name'
      #   # => <label for="name">Your name</label>
      #
      #   label_tag 'name', nil, class: 'small_label'
      #   # => <label for="name" class="small_label">Name</label>
      def label_tag(name = nil, content_or_options = nil, options = nil, &block)
        if block_given? && content_or_options.is_a?(Hash)
          options = content_or_options = content_or_options.stringify_keys
        else
          options ||= {}
          options = options.stringify_keys
        end
        options["for"] = sanitize_to_id(name) unless name.blank? || options.has_key?("for")
        content_tag :label, content_or_options || name.to_s.humanize, options, &block
      end

      # Creates a hidden form input field used to transmit data that would be lost due to HTTP's statelessness or
      # data that should be hidden from the user.
      #
      # ==== Options
      # * Creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   hidden_field_tag 'tags_list'
      #   # => <input id="tags_list" name="tags_list" type="hidden" />
      #
      #   hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
      #   # => <input id="token" name="token" type="hidden" value="VUBJKB23UIVI1UU1VOBVI@" />
      #
      #   hidden_field_tag 'collected_input', '', onchange: "alert('Input collected!')"
      #   # => <input id="collected_input" name="collected_input" onchange="alert('Input collected!')"
      #   #    type="hidden" value="" />
      def hidden_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
      end

      # Creates a file upload field. If you are using file uploads then you will also need
      # to set the multipart option for the form tag:
      #
      #   <%= form_tag '/upload', multipart: true do %>
      #     <label for="file">File to Upload</label> <%= file_field_tag "file" %>
      #     <%= submit_tag %>
      #   <% end %>
      #
      # The specified URL will then be passed a File object containing the selected file, or if the field
      # was left blank, a StringIO object.
      #
      # ==== Options
      # * Creates standard HTML attributes for the tag.
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:multiple</tt> - If set to true, *in most updated browsers* the user will be allowed to select multiple files.
      # * <tt>:accept</tt> - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
      #
      # ==== Examples
      #   file_field_tag 'attachment'
      #   # => <input id="attachment" name="attachment" type="file" />
      #
      #   file_field_tag 'avatar', class: 'profile_input'
      #   # => <input class="profile_input" id="avatar" name="avatar" type="file" />
      #
      #   file_field_tag 'picture', disabled: true
      #   # => <input disabled="disabled" id="picture" name="picture" type="file" />
      #
      #   file_field_tag 'resume', value: '~/resume.doc'
      #   # => <input id="resume" name="resume" type="file" value="~/resume.doc" />
      #
      #   file_field_tag 'user_pic', accept: 'image/png,image/gif,image/jpeg'
      #   # => <input accept="image/png,image/gif,image/jpeg" id="user_pic" name="user_pic" type="file" />
      #
      #   file_field_tag 'file', accept: 'text/html', class: 'upload', value: 'index.html'
      #   # => <input accept="text/html" class="upload" id="file" name="file" type="file" value="index.html" />
      def file_field_tag(name, options = {})
        text_field_tag(name, nil, options.update("type" => "file"))
      end

      # Creates a password field, a masked text field that will hide the users input behind a mask character.
      #
      # ==== Options
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:size</tt> - The number of visible characters that will fit in the input.
      # * <tt>:maxlength</tt> - The maximum number of characters that the browser will allow the user to enter.
      # * Any other key creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   password_field_tag 'pass'
      #   # => <input id="pass" name="pass" type="password" />
      #
      #   password_field_tag 'secret', 'Your secret here'
      #   # => <input id="secret" name="secret" type="password" value="Your secret here" />
      #
      #   password_field_tag 'masked', nil, class: 'masked_input_field'
      #   # => <input class="masked_input_field" id="masked" name="masked" type="password" />
      #
      #   password_field_tag 'token', '', size: 15
      #   # => <input id="token" name="token" size="15" type="password" value="" />
      #
      #   password_field_tag 'key', nil, maxlength: 16
      #   # => <input id="key" maxlength="16" name="key" type="password" />
      #
      #   password_field_tag 'confirm_pass', nil, disabled: true
      #   # => <input disabled="disabled" id="confirm_pass" name="confirm_pass" type="password" />
      #
      #   password_field_tag 'pin', '1234', maxlength: 4, size: 6, class: "pin_input"
      #   # => <input class="pin_input" id="pin" maxlength="4" name="pin" size="6" type="password" value="1234" />
      def password_field_tag(name = "password", value = nil, options = {})
        text_field_tag(name, value, options.update("type" => "password"))
      end

      # Creates a text input area; use a textarea for longer text inputs such as blog posts or descriptions.
      #
      # ==== Options
      # * <tt>:size</tt> - A string specifying the dimensions (columns by rows) of the textarea (e.g., "25x10").
      # * <tt>:rows</tt> - Specify the number of rows in the textarea
      # * <tt>:cols</tt> - Specify the number of columns in the textarea
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * <tt>:escape</tt> - By default, the contents of the text input are HTML escaped.
      #   If you need unescaped contents, set this to false.
      # * Any other key creates standard HTML attributes for the tag.
      #
      # ==== Examples
      #   text_area_tag 'post'
      #   # => <textarea id="post" name="post"></textarea>
      #
      #   text_area_tag 'bio', @user.bio
      #   # => <textarea id="bio" name="bio">This is my biography.</textarea>
      #
      #   text_area_tag 'body', nil, rows: 10, cols: 25
      #   # => <textarea cols="25" id="body" name="body" rows="10"></textarea>
      #
      #   text_area_tag 'body', nil, size: "25x10"
      #   # => <textarea name="body" id="body" cols="25" rows="10"></textarea>
      #
      #   text_area_tag 'description', "Description goes here.", disabled: true
      #   # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
      #
      #   text_area_tag 'comment', nil, class: 'comment_input'
      #   # => <textarea class="comment_input" id="comment" name="comment"></textarea>
      def text_area_tag(name, content = nil, options = {})
        options = options.stringify_keys

        if size = options.delete("size")
          options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
        end

        escape = options.delete("escape") { true }
        content = ERB::Util.html_escape(content) if escape

        content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
      end

      # Creates a check box form input tag.
      #
      # ==== Options
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * Any other key creates standard HTML options for the tag.
      #
      # ==== Examples
      #   check_box_tag 'accept'
      #   # => <input id="accept" name="accept" type="checkbox" value="1" />
      #
      #   check_box_tag 'rock', 'rock music'
      #   # => <input id="rock" name="rock" type="checkbox" value="rock music" />
      #
      #   check_box_tag 'receive_email', 'yes', true
      #   # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
      #
      #   check_box_tag 'tos', 'yes', false, class: 'accept_tos'
      #   # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
      #
      #   check_box_tag 'eula', 'accepted', false, disabled: true
      #   # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
      def check_box_tag(name, value = "1", checked = false, options = {})
        html_options = { "type" => "checkbox", "name" => name, "id" => sanitize_to_id(name), "value" => value }.update(options.stringify_keys)
        html_options["checked"] = "checked" if checked
        tag :input, html_options
      end

      # Creates a radio button; use groups of radio buttons named the same to allow users to
      # select from a group of options.
      #
      # ==== Options
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * Any other key creates standard HTML options for the tag.
      #
      # ==== Examples
      #   radio_button_tag 'gender', 'male'
      #   # => <input id="gender_male" name="gender" type="radio" value="male" />
      #
      #   radio_button_tag 'receive_updates', 'no', true
      #   # => <input checked="checked" id="receive_updates_no" name="receive_updates" type="radio" value="no" />
      #
      #   radio_button_tag 'time_slot', "3:00 p.m.", false, disabled: true
      #   # => <input disabled="disabled" id="time_slot_300_pm" name="time_slot" type="radio" value="3:00 p.m." />
      #
      #   radio_button_tag 'color', "green", true, class: "color_input"
      #   # => <input checked="checked" class="color_input" id="color_green" name="color" type="radio" value="green" />
      def radio_button_tag(name, value, checked = false, options = {})
        html_options = { "type" => "radio", "name" => name, "id" => "#{sanitize_to_id(name)}_#{sanitize_to_id(value)}", "value" => value }.update(options.stringify_keys)
        html_options["checked"] = "checked" if checked
        tag :input, html_options
      end

      # Creates a submit button with the text <tt>value</tt> as the caption.
      #
      # ==== Options
      # * <tt>:data</tt> - This option can be used to add custom data attributes.
      # * <tt>:disabled</tt> - If true, the user will not be able to use this input.
      # * Any other key creates standard HTML options for the tag.
      #
      # ==== Data attributes
      #
      # * <tt>confirm: 'question?'</tt> - If present the unobtrusive JavaScript
      #   drivers will provide a prompt with the question specified. If the user accepts,
      #   the form is processed normally, otherwise no action is taken.
      # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
      #   disabled version of the submit button when the form is submitted. This feature is
      #   provided by the unobtrusive JavaScript driver.
      #
      # ==== Examples
      #   submit_tag
      #   # => <input name="commit" type="submit" value="Save changes" />
      #
      #   submit_tag "Edit this article"
      #   # => <input name="commit" type="submit" value="Edit this article" />
      #
      #   submit_tag "Save edits", disabled: true
      #   # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
      #
      #   submit_tag "Complete sale", data: { disable_with: "Please wait..." }
      #   # => <input name="commit" data-disable-with="Please wait..." type="submit" value="Complete sale" />
      #
      #   submit_tag nil, class: "form_submit"
      #   # => <input class="form_submit" name="commit" type="submit" />
      #
      #   submit_tag "Edit", class: "edit_button"
      #   # => <input class="edit_button" name="commit" type="submit" value="Edit" />
      #
      #   submit_tag "Save", data: { confirm: "Are you sure?" }
      #   # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
      #
      def submit_tag(value = "Save changes", options = {})
        options = options.stringify_keys

        if disable_with = options.delete("disable_with")
          message = ":disable_with option is deprecated and will be removed from Rails 4.1. " \
                    "Use 'data: { disable_with: \'Text\' }' instead."
          ActiveSupport::Deprecation.warn message

          options["data-disable-with"] = disable_with
        end

        if confirm = options.delete("confirm")
          message = ":confirm option is deprecated and will be removed from Rails 4.1. " \
                    "Use 'data: { confirm: \'Text\' }' instead'."
          ActiveSupport::Deprecation.warn message

          options["data-confirm"] = confirm
        end

        tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options)
      end

      # Creates a button element that defines a <tt>submit</tt> button,
      # <tt>reset</tt>button or a generic button which can be used in
      # JavaScript, for example. You can use the button tag as a regular
      # submit tag but it isn't supported in legacy browsers. However,
      # the button tag allows richer labels such as images and emphasis,
      # so this helper will also accept a block.
      #
      # ==== Options
      # * <tt>:data</tt> - This option can be used to add custom data attributes.
      # * <tt>:disabled</tt> - If true, the user will not be able to
      #   use this input.
      # * Any other key creates standard HTML options for the tag.
      #
      # ==== Data attributes
      #
      # * <tt>confirm: 'question?'</tt> - If present, the
      #   unobtrusive JavaScript drivers will provide a prompt with
      #   the question specified. If the user accepts, the form is
      #   processed normally, otherwise no action is taken.
      # * <tt>:disable_with</tt> - Value of this parameter will be
      #   used as the value for a disabled version of the submit
      #   button when the form is submitted. This feature is provided
      #   by the unobtrusive JavaScript driver.
      #
      # ==== Examples
      #   button_tag
      #   # => <button name="button" type="submit">Button</button>
      #
      #   button_tag(type: 'button') do
      #     content_tag(:strong, 'Ask me!')
      #   end
      #   # => <button name="button" type="button">
      #   #     <strong>Ask me!</strong>
      #   #    </button>
      #
      #   button_tag "Checkout", data: { disable_with => "Please wait..." }
      #   # => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
      #
      def button_tag(content_or_options = nil, options = nil, &block)
        options = content_or_options if block_given? && content_or_options.is_a?(Hash)
        options ||= {}
        options = options.stringify_keys

        if disable_with = options.delete("disable_with")
          message = ":disable_with option is deprecated and will be removed from Rails 4.1. " \
                    "Use 'data: { disable_with: \'Text\' }' instead."
          ActiveSupport::Deprecation.warn message

          options["data-disable-with"] = disable_with
        end

        if confirm = options.delete("confirm")
          message = ":confirm option is deprecated and will be removed from Rails 4.1. " \
                    "Use 'data: { confirm: \'Text\' }' instead'."
          ActiveSupport::Deprecation.warn message

          options["data-confirm"] = confirm
        end

        options.reverse_merge! 'name' => 'button', 'type' => 'submit'

        content_tag :button, content_or_options || 'Button', options, &block
      end

      # Displays an image which when clicked will submit the form.
      #
      # <tt>source</tt> is passed to AssetTagHelper#path_to_image
      #
      # ==== Options
      # * <tt>:data</tt> - This option can be used to add custom data attributes.
      # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
      # * Any other key creates standard HTML options for the tag.
      #
      # ==== Data attributes
      #
      # * <tt>confirm: 'question?'</tt> - This will add a JavaScript confirm
      #   prompt with the question specified. If the user accepts, the form is
      #   processed normally, otherwise no action is taken.
      #
      # ==== Examples
      #   image_submit_tag("login.png")
      #   # => <input alt="Login" src="/images/login.png" type="image" />
      #
      #   image_submit_tag("purchase.png", disabled: true)
      #   # => <input alt="Purchase" disabled="disabled" src="/images/purchase.png" type="image" />
      #
      #   image_submit_tag("search.png", class: 'search_button', alt: 'Find')
      #   # => <input alt="Find" class="search_button" src="/images/search.png" type="image" />
      #
      #   image_submit_tag("agree.png", disabled: true, class: "agree_disagree_button")
      #   # => <input alt="Agree" class="agree_disagree_button" disabled="disabled" src="/images/agree.png" type="image" />
      #
      #   image_submit_tag("save.png", data: { confirm: "Are you sure?" })
      #   # => <input alt="Save" src="/images/save.png" data-confirm="Are you sure?" type="image" />
      def image_submit_tag(source, options = {})
        options = options.stringify_keys

        if confirm = options.delete("confirm")
          message = ":confirm option is deprecated and will be removed from Rails 4.1. " \
                    "Use 'data: { confirm: \'Text\' }' instead'."
          ActiveSupport::Deprecation.warn message

          options["data-confirm"] = confirm
        end

        tag :input, { "alt" => image_alt(source), "type" => "image", "src" => path_to_image(source) }.update(options)
      end

      # Creates a field set for grouping HTML form elements.
      #
      # <tt>legend</tt> will become the fieldset's title (optional as per W3C).
      # <tt>options</tt> accept the same values as tag.
      #
      # ==== Examples
      #   <%= field_set_tag do %>
      #     <p><%= text_field_tag 'name' %></p>
      #   <% end %>
      #   # => <fieldset><p><input id="name" name="name" type="text" /></p></fieldset>
      #
      #   <%= field_set_tag 'Your details' do %>
      #     <p><%= text_field_tag 'name' %></p>
      #   <% end %>
      #   # => <fieldset><legend>Your details</legend><p><input id="name" name="name" type="text" /></p></fieldset>
      #
      #   <%= field_set_tag nil, class: 'format' do %>
      #     <p><%= text_field_tag 'name' %></p>
      #   <% end %>
      #   # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>
      def field_set_tag(legend = nil, options = nil, &block)
        output = tag(:fieldset, options, true)
        output.safe_concat(content_tag(:legend, legend)) unless legend.blank?
        output.concat(capture(&block)) if block_given?
        output.safe_concat("</fieldset>")
      end

      # Creates a text field of type "color".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def color_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "color"))
      end

      # Creates a text field of type "search".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def search_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "search"))
      end

      # Creates a text field of type "tel".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def telephone_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
      end
      alias phone_field_tag telephone_field_tag

      # Creates a text field of type "date".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def date_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "date"))
      end

      # Creates a text field of type "time".
      #
      # === Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      def time_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "time"))
      end

      # Creates a text field of type "datetime".
      #
      # === Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      def datetime_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "datetime"))
      end

      # Creates a text field of type "datetime-local".
      #
      # === Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      def datetime_local_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "datetime-local"))
      end

      # Creates a text field of type "month".
      #
      # === Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      def month_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "month"))
      end

      # Creates a text field of type "week".
      #
      # === Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      def week_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "week"))
      end

      # Creates a text field of type "url".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def url_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
      end

      # Creates a text field of type "email".
      #
      # ==== Options
      # * Accepts the same options as text_field_tag.
      def email_field_tag(name, value = nil, options = {})
        text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
      end

      # Creates a number field.
      #
      # ==== Options
      # * <tt>:min</tt> - The minimum acceptable value.
      # * <tt>:max</tt> - The maximum acceptable value.
      # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
      #   <tt>:max</tt> values.
      # * <tt>:step</tt> - The acceptable value granularity.
      # * Otherwise accepts the same options as text_field_tag.
      #
      # ==== Examples
      #   number_field_tag 'quantity', nil, in: 1...10
      #   # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
      def number_field_tag(name, value = nil, options = {})
        options = options.stringify_keys
        options["type"] ||= "number"
        if range = options.delete("in") || options.delete("within")
          options.update("min" => range.min, "max" => range.max)
        end
        text_field_tag(name, value, options)
      end

      # Creates a range form element.
      #
      # ==== Options
      # * Accepts the same options as number_field_tag.
      def range_field_tag(name, value = nil, options = {})
        number_field_tag(name, value, options.stringify_keys.update("type" => "range"))
      end

      # Creates the hidden UTF8 enforcer tag. Override this method in a helper
      # to customize the tag.
      def utf8_enforcer_tag
        tag(:input, :type => "hidden", :name => "utf8", :value => "&#x2713;".html_safe)
      end

      private
        def html_options_for_form(url_for_options, options)
          options.stringify_keys.tap do |html_options|
            html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
            # The following URL is unescaped, this is just a hash of options, and it is the
            # responsibility of the caller to escape all the values.
            html_options["action"]  = url_for(url_for_options)
            html_options["accept-charset"] = "UTF-8"

            html_options["data-remote"] = true if html_options.delete("remote")

            if html_options["data-remote"] &&
               !embed_authenticity_token_in_remote_forms &&
               html_options["authenticity_token"].blank?
              # The authenticity token is taken from the meta tag in this case
              html_options["authenticity_token"] = false
            elsif html_options["authenticity_token"] == true
              # Include the default authenticity_token, which is only generated when its set to nil,
              # but we needed the true value to override the default of no authenticity_token on data-remote.
              html_options["authenticity_token"] = nil
            end
          end
        end

        def extra_tags_for_form(html_options)
          authenticity_token = html_options.delete("authenticity_token")
          method = html_options.delete("method").to_s

          method_tag = case method
            when /^get$/i # must be case-insensitive, but can't use downcase as might be nil
              html_options["method"] = "get"
              ''
            when /^post$/i, "", nil
              html_options["method"] = "post"
              token_tag(authenticity_token)
            else
              html_options["method"] = "post"
              method_tag(method) + token_tag(authenticity_token)
          end

          tags = utf8_enforcer_tag << method_tag
          content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
        end

        def form_tag_html(html_options)
          extra_tags = extra_tags_for_form(html_options)
          tag(:form, html_options, true) + extra_tags
        end

        def form_tag_in_block(html_options, &block)
          content = capture(&block)
          output = form_tag_html(html_options)
          output << content
          output.safe_concat("</form>")
        end

        # see http://www.w3.org/TR/html4/types.html#type-name
        def sanitize_to_id(name)
          name.to_s.gsub(']','').gsub(/[^-a-zA-Z0-9:.]/, "_")
        end
    end
  end
end
require 'action_view/helpers/tag_helper'

module ActionView
  module Helpers
    module JavaScriptHelper
      JS_ESCAPE_MAP = {
        '\\'    => '\\\\',
        '</'    => '<\/',
        "\r\n"  => '\n',
        "\n"    => '\n',
        "\r"    => '\n',
        '"'     => '\\"',
        "'"     => "\\'"
      }

      JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '&#x2028;'
      JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '&#x2029;'

      # Escapes carriage returns and single and double quotes for JavaScript segments.
      #
      # Also available through the alias j(). This is particularly helpful in JavaScript
      # responses, like:
      #
      #   $('some_element').replaceWith('<%=j render 'some/element_template' %>');
      def escape_javascript(javascript)
        if javascript
          result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
          javascript.html_safe? ? result.html_safe : result
        else
          ''
        end
      end

      alias_method :j, :escape_javascript

      # Returns a JavaScript tag with the +content+ inside. Example:
      #   javascript_tag "alert('All is good')"
      #
      # Returns:
      #   <script>
      #   //<![CDATA[
      #   alert('All is good')
      #   //]]>
      #   </script>
      #
      # +html_options+ may be a hash of attributes for the <tt>\<script></tt>
      # tag.
      #
      #   javascript_tag "alert('All is good')", defer: 'defer'
      #   # => <script defer="defer">alert('All is good')</script>
      #
      # Instead of passing the content as an argument, you can also use a block
      # in which case, you pass your +html_options+ as the first parameter.
      #
      #   <%= javascript_tag defer: 'defer' do -%>
      #     alert('All is good')
      #   <% end -%>
      def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
        content =
          if block_given?
            html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
            capture(&block)
          else
            content_or_options_with_block
          end

        content_tag(:script, javascript_cdata_section(content), html_options)
      end

      def javascript_cdata_section(content) #:nodoc:
        "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
      end

      # Returns a button whose +onclick+ handler triggers the passed JavaScript.
      #
      # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
      # name is used as button label and the JavaScript code goes into its +onclick+ attribute.
      # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+.
      #
      #   button_to_function "Greeting", "alert('Hello world!')", class: "ok"
      #   # => <input class="ok" onclick="alert('Hello world!');" type="button" value="Greeting" />
      #
      def button_to_function(name, function=nil, html_options={})
        message = "button_to_function is deprecated and will be removed from Rails 4.1. We recomend to use Unobtrusive JavaScript instead. " +
          "See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
        ActiveSupport::Deprecation.warn message

        onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"

        tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
      end

      # Returns a link whose +onclick+ handler triggers the passed JavaScript.
      #
      # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
      # name is used as the link text and the JavaScript code goes into the +onclick+ attribute.
      # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+. Once all
      # the JavaScript is set, the helper appends "; return false;".
      #
      # The +href+ attribute of the tag is set to "#" unless +html_options+ has one.
      #
      #   link_to_function "Greeting", "alert('Hello world!')", class: "nav_link"
      #   # => <a class="nav_link" href="#" onclick="alert('Hello world!'); return false;">Greeting</a>
      #
      def link_to_function(name, function, html_options={})
        message = "link_to_function is deprecated and will be removed from Rails 4.1. We recomend to use Unobtrusive JavaScript instead. " +
          "See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
        ActiveSupport::Deprecation.warn message

        onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
        href = html_options[:href] || '#'

        content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
      end
    end
  end
end
# encoding: utf-8

require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/string/output_safety'
require 'active_support/number_helper'

module ActionView
  # = Action View Number Helpers
  module Helpers #:nodoc:

    # Provides methods for converting numbers into formatted strings.
    # Methods are provided for phone numbers, currency, percentage,
    # precision, positional notation, file size and pretty printing.
    #
    # Most methods expect a +number+ argument, and will return it
    # unchanged if can't be converted into a valid number.
    module NumberHelper

      # Raised when argument +number+ param given to the helpers is invalid and
      # the option :raise is set to  +true+.
      class InvalidNumberError < StandardError
        attr_accessor :number
        def initialize(number)
          @number = number
        end
      end

      # Formats a +number+ into a US phone number (e.g., (555)
      # 123-9876). You can customize the format in the +options+ hash.
      #
      # * <tt>:area_code</tt> - Adds parentheses around the area code.
      # * <tt>:delimiter</tt> - Specifies the delimiter to use
      #   (defaults to "-").
      # * <tt>:extension</tt> - Specifies an extension to add to the
      #   end of the generated number.
      # * <tt>:country_code</tt> - Sets the country code for the phone
      #   number.
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_to_phone(5551234)                                           # => 555-1234
      #   number_to_phone("5551234")                                         # => 555-1234
      #   number_to_phone(1235551234)                                        # => 123-555-1234
      #   number_to_phone(1235551234, area_code: true)                       # => (123) 555-1234
      #   number_to_phone(1235551234, delimiter: " ")                        # => 123 555 1234
      #   number_to_phone(1235551234, area_code: true, extension: 555)       # => (123) 555-1234 x 555
      #   number_to_phone(1235551234, country_code: 1)                       # => +1-123-555-1234
      #   number_to_phone("123a456")                                         # => 123a456
      #   number_to_phone("1234a567", raise: true)                           # => InvalidNumberError
      #
      #   number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".")
      #   # => +1.123.555.1234 x 1343
      def number_to_phone(number, options = {})
        return unless number
        options = options.symbolize_keys

        parse_float(number, true) if options.delete(:raise)
        ERB::Util.html_escape(ActiveSupport::NumberHelper.number_to_phone(number, options))
      end

      # Formats a +number+ into a currency string (e.g., $13.65). You
      # can customize the format in the +options+ hash.
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:precision</tt> - Sets the level of precision (defaults
      #   to 2).
      # * <tt>:unit</tt> - Sets the denomination of the currency
      #   (defaults to "$").
      # * <tt>:separator</tt> - Sets the separator between the units
      #   (defaults to ".").
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to ",").
      # * <tt>:format</tt> - Sets the format for non-negative numbers
      #   (defaults to "%u%n").  Fields are <tt>%u</tt> for the
      #   currency, and <tt>%n</tt> for the number.
      # * <tt>:negative_format</tt> - Sets the format for negative
      #   numbers (defaults to prepending an hyphen to the formatted
      #   number given by <tt>:format</tt>).  Accepts the same fields
      #   than <tt>:format</tt>, except <tt>%n</tt> is here the
      #   absolute value of the number.
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_to_currency(1234567890.50)                    # => $1,234,567,890.50
      #   number_to_currency(1234567890.506)                   # => $1,234,567,890.51
      #   number_to_currency(1234567890.506, precision: 3)     # => $1,234,567,890.506
      #   number_to_currency(1234567890.506, locale: :fr)      # => 1 234 567 890,51 €
      #   number_to_currency("123a456")                        # => $123a456
      #
      #   number_to_currency("123a456", raise: true)           # => InvalidNumberError
      #
      #   number_to_currency(-1234567890.50, negative_format: "(%u%n)")
      #   # => ($1,234,567,890.50)
      #   number_to_currency(1234567890.50, unit: "&pound;", separator: ",", delimiter: "")
      #   # => &pound;1234567890,50
      #   number_to_currency(1234567890.50, unit: "&pound;", separator: ",", delimiter: "", format: "%n %u")
      #   # => 1234567890,50 &pound;
      def number_to_currency(number, options = {})
        return unless number
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_currency(number, options)
        }
      end

      # Formats a +number+ as a percentage string (e.g., 65%). You can
      # customize the format in the +options+ hash.
      #
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:precision</tt> - Sets the precision of the number
      #   (defaults to 3).
      # * <tt>:significant</tt> - If +true+, precision will be the #
      #   of significant_digits. If +false+, the # of fractional
      #   digits (defaults to +false+).
      # * <tt>:separator</tt> - Sets the separator between the
      #   fractional and integer digits (defaults to ".").
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to "").
      # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
      #   insignificant zeros after the decimal separator (defaults to
      #   +false+).
      # * <tt>:format</tt> - Specifies the format of the percentage
      #   string The number field is <tt>%n</tt> (defaults to "%n%").
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_to_percentage(100)                                        # => 100.000%
      #   number_to_percentage("98")                                       # => 98.000%
      #   number_to_percentage(100, precision: 0)                          # => 100%
      #   number_to_percentage(1000, delimiter: '.', separator: ',')       # => 1.000,000%
      #   number_to_percentage(302.24398923423, precision: 5)              # => 302.24399%
      #   number_to_percentage(1000, locale: :fr)                          # => 1 000,000%
      #   number_to_percentage("98a")                                      # => 98a%
      #   number_to_percentage(100, format: "%n  %")                       # => 100  %
      #
      #   number_to_percentage("98a", raise: true)                         # => InvalidNumberError
      def number_to_percentage(number, options = {})
        return unless number
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_percentage(number, options)
        }
      end

      # Formats a +number+ with grouped thousands using +delimiter+
      # (e.g., 12,324). You can customize the format in the +options+
      # hash.
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to ",").
      # * <tt>:separator</tt> - Sets the separator between the
      #   fractional and integer digits (defaults to ".").
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_with_delimiter(12345678)                        # => 12,345,678
      #   number_with_delimiter("123456")                        # => 123,456
      #   number_with_delimiter(12345678.05)                     # => 12,345,678.05
      #   number_with_delimiter(12345678, delimiter: ".")        # => 12.345.678
      #   number_with_delimiter(12345678, delimiter: ",")        # => 12,345,678
      #   number_with_delimiter(12345678.05, separator: " ")     # => 12,345,678 05
      #   number_with_delimiter(12345678.05, locale: :fr)        # => 12 345 678,05
      #   number_with_delimiter("112a")                          # => 112a
      #   number_with_delimiter(98765432.98, delimiter: " ", separator: ",")
      #   # => 98 765 432,98
      #
      #  number_with_delimiter("112a", raise: true)              # => raise InvalidNumberError
      def number_with_delimiter(number, options = {})
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_delimited(number, options)
        }
      end

      # Formats a +number+ with the specified level of
      # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
      # +:significant+ is +false+, and 5 if +:significant+ is +true+).
      # You can customize the format in the +options+ hash.
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:precision</tt> - Sets the precision of the number
      #   (defaults to 3).
      # * <tt>:significant</tt> - If +true+, precision will be the #
      #   of significant_digits. If +false+, the # of fractional
      #   digits (defaults to +false+).
      # * <tt>:separator</tt> - Sets the separator between the
      #   fractional and integer digits (defaults to ".").
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to "").
      # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
      #   insignificant zeros after the decimal separator (defaults to
      #   +false+).
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_with_precision(111.2345)                                         # => 111.235
      #   number_with_precision(111.2345, precision: 2)                           # => 111.23
      #   number_with_precision(13, precision: 5)                                 # => 13.00000
      #   number_with_precision(389.32314, precision: 0)                          # => 389
      #   number_with_precision(111.2345, significant: true)                      # => 111
      #   number_with_precision(111.2345, precision: 1, significant: true)        # => 100
      #   number_with_precision(13, precision: 5, significant: true)              # => 13.000
      #   number_with_precision(111.234, locale: :fr)                             # => 111,234
      #
      #   number_with_precision(13, precision: 5, significant: true, strip_insignificant_zeros: true)
      #   # => 13
      #
      #   number_with_precision(389.32314, precision: 4, significant: true)       # => 389.3
      #   number_with_precision(1111.2345, precision: 2, separator: ',', delimiter: '.')
      #   # => 1.111,23
      def number_with_precision(number, options = {})
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_rounded(number, options)
        }
      end

      # Formats the bytes in +number+ into a more understandable
      # representation (e.g., giving it 1500 yields 1.5 KB). This
      # method is useful for reporting file sizes to users. You can
      # customize the format in the +options+ hash.
      #
      # See <tt>number_to_human</tt> if you want to pretty-print a
      # generic number.
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:precision</tt> - Sets the precision of the number
      #   (defaults to 3).
      # * <tt>:significant</tt> - If +true+, precision will be the #
      #   of significant_digits. If +false+, the # of fractional
      #   digits (defaults to +true+)
      # * <tt>:separator</tt> - Sets the separator between the
      #   fractional and integer digits (defaults to ".").
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to "").
      # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
      #   insignificant zeros after the decimal separator (defaults to
      #   +true+)
      # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
      #   prefix (defaults to :binary)
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_to_human_size(123)                                          # => 123 Bytes
      #   number_to_human_size(1234)                                         # => 1.21 KB
      #   number_to_human_size(12345)                                        # => 12.1 KB
      #   number_to_human_size(1234567)                                      # => 1.18 MB
      #   number_to_human_size(1234567890)                                   # => 1.15 GB
      #   number_to_human_size(1234567890123)                                # => 1.12 TB
      #   number_to_human_size(1234567, precision: 2)                        # => 1.2 MB
      #   number_to_human_size(483989, precision: 2)                         # => 470 KB
      #   number_to_human_size(1234567, precision: 2, separator: ',')        # => 1,2 MB
      #
      # Non-significant zeros after the fractional separator are
      # stripped out by default (set
      # <tt>:strip_insignificant_zeros</tt> to +false+ to change
      # that):
      #
      #   number_to_human_size(1234567890123, precision: 5)        # => "1.1229 TB"
      #   number_to_human_size(524288000, precision: 5)            # => "500 MB"
      def number_to_human_size(number, options = {})
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_human_size(number, options)
        }
      end

      # Pretty prints (formats and approximates) a number in a way it
      # is more readable by humans (eg.: 1200000000 becomes "1.2
      # Billion"). This is useful for numbers that can get very large
      # (and too hard to read).
      #
      # See <tt>number_to_human_size</tt> if you want to print a file
      # size.
      #
      # You can also define you own unit-quantifier names if you want
      # to use other decimal units (eg.: 1500 becomes "1.5
      # kilometers", 0.150 becomes "150 milliliters", etc). You may
      # define a wide range of unit quantifiers, even fractional ones
      # (centi, deci, mili, etc).
      #
      # ==== Options
      #
      # * <tt>:locale</tt> - Sets the locale to be used for formatting
      #   (defaults to current locale).
      # * <tt>:precision</tt> - Sets the precision of the number
      #   (defaults to 3).
      # * <tt>:significant</tt> - If +true+, precision will be the #
      #   of significant_digits. If +false+, the # of fractional
      #   digits (defaults to +true+)
      # * <tt>:separator</tt> - Sets the separator between the
      #   fractional and integer digits (defaults to ".").
      # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
      #   to "").
      # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
      #   insignificant zeros after the decimal separator (defaults to
      #   +true+)
      # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
      #   string containing an i18n scope where to find this hash. It
      #   might have the following keys:
      #   * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
      #     *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
      #     *<tt>:billion</tt>, <tt>:trillion</tt>,
      #     *<tt>:quadrillion</tt>
      #   * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
      #     *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
      #     *<tt>:pico</tt>, <tt>:femto</tt>
      # * <tt>:format</tt> - Sets the format of the output string
      #   (defaults to "%n %u"). The field types are:
      #   * %u - The quantifier (ex.: 'thousand')
      #   * %n - The number
      # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
      #   the argument is invalid.
      #
      #   number_to_human(123)                                          # => "123"
      #   number_to_human(1234)                                         # => "1.23 Thousand"
      #   number_to_human(12345)                                        # => "12.3 Thousand"
      #   number_to_human(1234567)                                      # => "1.23 Million"
      #   number_to_human(1234567890)                                   # => "1.23 Billion"
      #   number_to_human(1234567890123)                                # => "1.23 Trillion"
      #   number_to_human(1234567890123456)                             # => "1.23 Quadrillion"
      #   number_to_human(1234567890123456789)                          # => "1230 Quadrillion"
      #   number_to_human(489939, precision: 2)                         # => "490 Thousand"
      #   number_to_human(489939, precision: 4)                         # => "489.9 Thousand"
      #   number_to_human(1234567, precision: 4,
      #                           significant: false)                   # => "1.2346 Million"
      #   number_to_human(1234567, precision: 1,
      #                           separator: ',',
      #                           significant: false)                   # => "1,2 Million"
      #
      # Non-significant zeros after the decimal separator are stripped
      # out by default (set <tt>:strip_insignificant_zeros</tt> to
      # +false+ to change that):
      #   number_to_human(12345012345, significant_digits: 6)       # => "12.345 Billion"
      #   number_to_human(500000000, precision: 5)                  # => "500 Million"
      #
      # ==== Custom Unit Quantifiers
      #
      # You can also use your own custom unit quantifiers:
      #  number_to_human(500000, units: {unit: "ml", thousand: "lt"})  # => "500 lt"
      #
      # If in your I18n locale you have:
      #   distance:
      #     centi:
      #       one: "centimeter"
      #       other: "centimeters"
      #     unit:
      #       one: "meter"
      #       other: "meters"
      #     thousand:
      #       one: "kilometer"
      #       other: "kilometers"
      #     billion: "gazillion-distance"
      #
      # Then you could do:
      #
      #  number_to_human(543934, units: :distance)              # => "544 kilometers"
      #  number_to_human(54393498, units: :distance)            # => "54400 kilometers"
      #  number_to_human(54393498000, units: :distance)         # => "54.4 gazillion-distance"
      #  number_to_human(343, units: :distance, precision: 1)   # => "300 meters"
      #  number_to_human(1, units: :distance)                   # => "1 meter"
      #  number_to_human(0.34, units: :distance)                # => "34 centimeters"
      #
      def number_to_human(number, options = {})
        options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)

        wrap_with_output_safety_handling(number, options.delete(:raise)) {
          ActiveSupport::NumberHelper.number_to_human(number, options)
        }
      end

      private

      def escape_unsafe_delimiters_and_separators(options)
        options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] && !options[:separator].html_safe?
        options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] && !options[:delimiter].html_safe?
        options
      end

      def wrap_with_output_safety_handling(number, raise_on_invalid, &block)
        valid_float = valid_float?(number)
        raise InvalidNumberError, number if raise_on_invalid && !valid_float

        formatted_number = yield

        if valid_float || number.html_safe?
          formatted_number.html_safe
        else
          formatted_number
        end
      end

      def valid_float?(number)
        !parse_float(number, false).nil?
      end

      def parse_float(number, raise_error)
        Float(number)
      rescue ArgumentError, TypeError
        raise InvalidNumberError, number if raise_error
      end
    end
  end
end
require 'active_support/core_ext/string/output_safety'

module ActionView #:nodoc:
  # = Action View Raw Output Helper
  module Helpers #:nodoc:
    module OutputSafetyHelper
      # This method outputs without escaping a string. Since escaping tags is
      # now default, this can be used when you don't want Rails to automatically
      # escape tags. This is not recommended if the data is coming from the user's
      # input.
      #
      # For example:
      #
      #  raw @user.name
      #  # => 'Jimmy <alert>Tables</alert>'
      def raw(stringish)
        stringish.to_s.html_safe
      end

      # This method returns a html safe string similar to what <tt>Array#join</tt>
      # would return. All items in the array, including the supplied separator, are
      # html escaped unless they are html safe, and the returned string is marked
      # as html safe.
      #
      #   safe_join(["<p>foo</p>".html_safe, "<p>bar</p>"], "<br />")
      #   # => "<p>foo</p>&lt;br /&gt;&lt;p&gt;bar&lt;/p&gt;"
      #
      #   safe_join(["<p>foo</p>".html_safe, "<p>bar</p>".html_safe], "<br />".html_safe)
      #   # => "<p>foo</p><br /><p>bar</p>"
      #
      def safe_join(array, sep=$,)
        sep = ERB::Util.html_escape(sep)

        array.map { |i| ERB::Util.html_escape(i) }.join(sep).html_safe
      end
    end
  end
end
module ActionView
  # = Action View Record Tag Helpers
  module Helpers
    module RecordTagHelper
      include ActionView::RecordIdentifier

      # Produces a wrapper DIV element with id and class parameters that
      # relate to the specified Active Record object. Usage example:
      #
      #    <%= div_for(@person, class: "foo") do %>
      #       <%= @person.name %>
      #    <% end %>
      #
      # produces:
      #
      #    <div id="person_123" class="person foo"> Joe Bloggs </div>
      #
      # You can also pass an array of Active Record objects, which will then
      # get iterated over and yield each record as an argument for the block.
      # For example:
      #
      #    <%= div_for(@people, class: "foo") do |person| %>
      #      <%= person.name %>
      #    <% end %>
      #
      # produces:
      #
      #    <div id="person_123" class="person foo"> Joe Bloggs </div>
      #    <div id="person_124" class="person foo"> Jane Bloggs </div>
      #
      def div_for(record, *args, &block)
        content_tag_for(:div, record, *args, &block)
      end

      # content_tag_for creates an HTML element with id and class parameters
      # that relate to the specified Active Record object. For example:
      #
      #    <%= content_tag_for(:tr, @person) do %>
      #      <td><%= @person.first_name %></td>
      #      <td><%= @person.last_name %></td>
      #    <% end %>
      #
      # would produce the following HTML (assuming @person is an instance of
      # a Person object, with an id value of 123):
      #
      #    <tr id="person_123" class="person">....</tr>
      #
      # If you require the HTML id attribute to have a prefix, you can specify it:
      #
      #    <%= content_tag_for(:tr, @person, :foo) do %> ...
      #
      # produces:
      #
      #    <tr id="foo_person_123" class="person">...
      #
      # You can also pass an array of objects which this method will loop through
      # and yield the current object to the supplied block, reducing the need for
      # having to iterate through the object (using <tt>each</tt>) beforehand.
      # For example (assuming @people is an array of Person objects):
      #
      #    <%= content_tag_for(:tr, @people) do |person| %>
      #      <td><%= person.first_name %></td>
      #      <td><%= person.last_name %></td>
      #    <% end %>
      #
      # produces:
      #
      #    <tr id="person_123" class="person">...</tr>
      #    <tr id="person_124" class="person">...</tr>
      #
      # content_tag_for also accepts a hash of options, which will be converted to
      # additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
      # with the default class name for your object. For example:
      #
      #    <%= content_tag_for(:li, @person, class: "bar") %>...
      #
      # produces:
      #
      #    <li id="person_123" class="person bar">...
      #
      def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
        options, prefix = prefix, nil if prefix.is_a?(Hash)

        Array(single_or_multiple_records).map do |single_record|
          content_tag_for_single_record(tag_name, single_record, prefix, options, &block)
        end.join("\n").html_safe
      end

      private

        # Called by <tt>content_tag_for</tt> internally to render a content tag
        # for each record.
        def content_tag_for_single_record(tag_name, record, prefix, options, &block)
          options = options ? options.dup : {}
          options[:class] = [ dom_class(record, prefix), options[:class] ].compact
          options[:id]    = dom_id(record, prefix)

          if block_given?
            content_tag(tag_name, capture(record, &block), options)
          else
            content_tag(tag_name, "", options)
          end
        end
    end
  end
end
module ActionView
  module Helpers
    # = Action View Rendering
    #
    # Implements methods that allow rendering from a view context.
    # In order to use this module, all you need is to implement
    # view_renderer that returns an ActionView::Renderer object.
    module RenderingHelper
      # Returns the result of a render that's dictated by the options hash. The primary options are:
      #
      # * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt>.
      # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
      # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
      # * <tt>:text</tt> - Renders the text passed in out.
      #
      # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
      # as the locals hash.
      def render(options = {}, locals = {}, &block)
        case options
        when Hash
          if block_given?
            view_renderer.render_partial(self, options.merge(:partial => options[:layout]), &block)
          else
            view_renderer.render(self, options)
          end
        else
          view_renderer.render_partial(self, :partial => options, :locals => locals)
        end
      end

      # Overwrites _layout_for in the context object so it supports the case a block is
      # passed to a partial. Returns the contents that are yielded to a layout, given a
      # name or a block.
      #
      # You can think of a layout as a method that is called with a block. If the user calls
      # <tt>yield :some_name</tt>, the block, by default, returns <tt>content_for(:some_name)</tt>.
      # If the user calls simply +yield+, the default block returns <tt>content_for(:layout)</tt>.
      #
      # The user can override this default by passing a block to the layout:
      #
      #   # The template
      #   <%= render layout: "my_layout" do %>
      #     Content
      #   <% end %>
      #
      #   # The layout
      #   <html>
      #     <%= yield %>
      #   </html>
      #
      # In this case, instead of the default block, which would return <tt>content_for(:layout)</tt>,
      # this method returns the block that was passed in to <tt>render :layout</tt>, and the response
      # would be
      #
      #   <html>
      #     Content
      #   </html>
      #
      # Finally, the block can take block arguments, which can be passed in by +yield+:
      #
      #   # The template
      #   <%= render layout: "my_layout" do |customer| %>
      #     Hello <%= customer.name %>
      #   <% end %>
      #
      #   # The layout
      #   <html>
      #     <%= yield Struct.new(:name).new("David") %>
      #   </html>
      #
      # In this case, the layout would receive the block passed into <tt>render :layout</tt>,
      # and the struct specified would be passed into the block as an argument. The result
      # would be
      #
      #   <html>
      #     Hello David
      #   </html>
      #
      def _layout_for(*args, &block)
        name = args.first

        if block && !name.is_a?(Symbol)
          capture(*args, &block)
        else
          super
        end
      end
    end
  end
end
require 'active_support/core_ext/object/try'
require 'action_view/vendor/html-scanner'

module ActionView
  # = Action View Sanitize Helpers
  module Helpers
    # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements.
    # These helper methods extend Action View making them callable within your template files.
    module SanitizeHelper
      extend ActiveSupport::Concern
      # This +sanitize+ helper will html encode all tags and strip all attributes that
      # aren't specifically allowed.
      #
      # It also strips href/src tags with invalid protocols, like javascript: especially.
      # It does its best to counter any  tricks that hackers may use, like throwing in
      # unicode/ascii/hex values to get past the javascript: filters. Check out
      # the extensive test suite.
      #
      #   <%= sanitize @article.body %>
      #
      # You can add or remove tags/attributes if you want to customize it a bit.
      # See ActionView::Base for full docs on the available options. You can add
      # tags/attributes for single uses of +sanitize+ by passing either the
      # <tt>:attributes</tt> or <tt>:tags</tt> options:
      #
      # Normal Use
      #
      #   <%= sanitize @article.body %>
      #
      # Custom Use (only the mentioned tags and attributes are allowed, nothing else)
      #
      #   <%= sanitize @article.body, tags: %w(table tr td), attributes: %w(id class style) %>
      #
      # Add table tags to the default allowed tags
      #
      #   class Application < Rails::Application
      #     config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
      #   end
      #
      # Remove tags to the default allowed tags
      #
      #   class Application < Rails::Application
      #     config.after_initialize do
      #       ActionView::Base.sanitized_allowed_tags.delete 'div'
      #     end
      #   end
      #
      # Change allowed default attributes
      #
      #   class Application < Rails::Application
      #     config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style'
      #   end
      #
      # Please note that sanitizing user-provided text does not guarantee that the
      # resulting markup is valid (conforming to a document type) or even well-formed.
      # The output may still contain e.g. unescaped '<', '>', '&' characters and
      # confuse browsers.
      #
      def sanitize(html, options = {})
        self.class.white_list_sanitizer.sanitize(html, options).try(:html_safe)
      end

      # Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
      def sanitize_css(style)
        self.class.white_list_sanitizer.sanitize_css(style)
      end

      # Strips all HTML tags from the +html+, including comments. This uses the
      # html-scanner tokenizer and so its HTML parsing ability is limited by
      # that of html-scanner.
      #
      #   strip_tags("Strip <i>these</i> tags!")
      #   # => Strip these tags!
      #
      #   strip_tags("<b>Bold</b> no more!  <a href='more.html'>See more here</a>...")
      #   # => Bold no more!  See more here...
      #
      #   strip_tags("<div id='top-bar'>Welcome to my website!</div>")
      #   # => Welcome to my website!
      def strip_tags(html)
        self.class.full_sanitizer.sanitize(html)
      end

      # Strips all link tags from +text+ leaving just the link text.
      #
      #   strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
      #   # => Ruby on Rails
      #
      #   strip_links('Please e-mail me at <a href="mailto:me@email.com">me@email.com</a>.')
      #   # => Please e-mail me at me@email.com.
      #
      #   strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
      #   # => Blog: Visit.
      def strip_links(html)
        self.class.link_sanitizer.sanitize(html)
      end

      module ClassMethods #:nodoc:
        attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer

        def sanitized_protocol_separator
          white_list_sanitizer.protocol_separator
        end

        def sanitized_uri_attributes
          white_list_sanitizer.uri_attributes
        end

        def sanitized_bad_tags
          white_list_sanitizer.bad_tags
        end

        def sanitized_allowed_tags
          white_list_sanitizer.allowed_tags
        end

        def sanitized_allowed_attributes
          white_list_sanitizer.allowed_attributes
        end

        def sanitized_allowed_css_properties
          white_list_sanitizer.allowed_css_properties
        end

        def sanitized_allowed_css_keywords
          white_list_sanitizer.allowed_css_keywords
        end

        def sanitized_shorthand_css_properties
          white_list_sanitizer.shorthand_css_properties
        end

        def sanitized_allowed_protocols
          white_list_sanitizer.allowed_protocols
        end

        def sanitized_protocol_separator=(value)
          white_list_sanitizer.protocol_separator = value
        end

        # Gets the HTML::FullSanitizer instance used by +strip_tags+. Replace with
        # any object that responds to +sanitize+.
        #
        #   class Application < Rails::Application
        #     config.action_view.full_sanitizer = MySpecialSanitizer.new
        #   end
        #
        def full_sanitizer
          @full_sanitizer ||= HTML::FullSanitizer.new
        end

        # Gets the HTML::LinkSanitizer instance used by +strip_links+. Replace with
        # any object that responds to +sanitize+.
        #
        #   class Application < Rails::Application
        #     config.action_view.link_sanitizer = MySpecialSanitizer.new
        #   end
        #
        def link_sanitizer
          @link_sanitizer ||= HTML::LinkSanitizer.new
        end

        # Gets the HTML::WhiteListSanitizer instance used by sanitize and +sanitize_css+.
        # Replace with any object that responds to +sanitize+.
        #
        #   class Application < Rails::Application
        #     config.action_view.white_list_sanitizer = MySpecialSanitizer.new
        #   end
        #
        def white_list_sanitizer
          @white_list_sanitizer ||= HTML::WhiteListSanitizer.new
        end

        # Adds valid HTML attributes that the +sanitize+ helper checks for URIs.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_uri_attributes = 'lowsrc', 'target'
        #   end
        #
        def sanitized_uri_attributes=(attributes)
          HTML::WhiteListSanitizer.uri_attributes.merge(attributes)
        end

        # Adds to the Set of 'bad' tags for the +sanitize+ helper.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_bad_tags = 'embed', 'object'
        #   end
        #
        def sanitized_bad_tags=(attributes)
          HTML::WhiteListSanitizer.bad_tags.merge(attributes)
        end

        # Adds to the Set of allowed tags for the +sanitize+ helper.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td'
        #   end
        #
        def sanitized_allowed_tags=(attributes)
          HTML::WhiteListSanitizer.allowed_tags.merge(attributes)
        end

        # Adds to the Set of allowed HTML attributes for the +sanitize+ helper.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_allowed_attributes = 'onclick', 'longdesc'
        #   end
        #
        def sanitized_allowed_attributes=(attributes)
          HTML::WhiteListSanitizer.allowed_attributes.merge(attributes)
        end

        # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ helpers.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_allowed_css_properties = 'expression'
        #   end
        #
        def sanitized_allowed_css_properties=(attributes)
          HTML::WhiteListSanitizer.allowed_css_properties.merge(attributes)
        end

        # Adds to the Set of allowed CSS keywords for the +sanitize+ and +sanitize_css+ helpers.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_allowed_css_keywords = 'expression'
        #   end
        #
        def sanitized_allowed_css_keywords=(attributes)
          HTML::WhiteListSanitizer.allowed_css_keywords.merge(attributes)
        end

        # Adds to the Set of allowed shorthand CSS properties for the +sanitize+ and +sanitize_css+ helpers.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_shorthand_css_properties = 'expression'
        #   end
        #
        def sanitized_shorthand_css_properties=(attributes)
          HTML::WhiteListSanitizer.shorthand_css_properties.merge(attributes)
        end

        # Adds to the Set of allowed protocols for the +sanitize+ helper.
        #
        #   class Application < Rails::Application
        #     config.action_view.sanitized_allowed_protocols = 'ssh', 'feed'
        #   end
        #
        def sanitized_allowed_protocols=(attributes)
          HTML::WhiteListSanitizer.allowed_protocols.merge(attributes)
        end
      end
    end
  end
end
require 'active_support/core_ext/string/output_safety'
require 'set'

module ActionView
  # = Action View Tag Helpers
  module Helpers #:nodoc:
    # Provides methods to generate HTML tags programmatically when you can't use
    # a Builder. By default, they output XHTML compliant tags.
    module TagHelper
      extend ActiveSupport::Concern
      include CaptureHelper

      BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
                           autoplay controls loop selected hidden scoped async
                           defer reversed ismap seemless muted required
                           autofocus novalidate formnovalidate open pubdate itemscope).to_set
      BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })

      PRE_CONTENT_STRINGS = {
        :textarea => "\n"
      }

      # Returns an empty HTML tag of type +name+ which by default is XHTML
      # compliant. Set +open+ to true to create an open tag compatible
      # with HTML 4.0 and below. Add HTML attributes by passing an attributes
      # hash to +options+. Set +escape+ to false to disable attribute value
      # escaping.
      #
      # ==== Options
      # You can use symbols or strings for the attribute names.
      #
      # Use +true+ with boolean attributes that can render with no value, like
      # +disabled+ and +readonly+.
      #
      # HTML5 <tt>data-*</tt> attributes can be set with a single +data+ key
      # pointing to a hash of sub-attributes.
      #
      # To play nicely with JavaScript conventions sub-attributes are dasherized.
      # For example, a key +user_id+ would render as <tt>data-user-id</tt> and
      # thus accessed as <tt>dataset.userId</tt>.
      #
      # Values are encoded to JSON, with the exception of strings and symbols.
      # This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
      # from 1.4.3.
      #
      # ==== Examples
      #   tag("br")
      #   # => <br />
      #
      #   tag("br", nil, true)
      #   # => <br>
      #
      #   tag("input", type: 'text', disabled: true)
      #   # => <input type="text" disabled="disabled" />
      #
      #   tag("img", src: "open & shut.png")
      #   # => <img src="open &amp; shut.png" />
      #
      #   tag("img", {src: "open &amp; shut.png"}, false, false)
      #   # => <img src="open &amp; shut.png" />
      #
      #   tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
      #   # => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
      def tag(name, options = nil, open = false, escape = true)
        "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
      end

      # Returns an HTML block tag of type +name+ surrounding the +content+. Add
      # HTML attributes by passing an attributes hash to +options+.
      # Instead of passing the content as an argument, you can also use a block
      # in which case, you pass your +options+ as the second parameter.
      # Set escape to false to disable attribute value escaping.
      #
      # ==== Options
      # The +options+ hash is used with attributes with no value like (<tt>disabled</tt> and
      # <tt>readonly</tt>), which you can give a value of true in the +options+ hash. You can use
      # symbols or strings for the attribute names.
      #
      # ==== Examples
      #   content_tag(:p, "Hello world!")
      #    # => <p>Hello world!</p>
      #   content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
      #    # => <div class="strong"><p>Hello world!</p></div>
      #   content_tag("select", options, multiple: true)
      #    # => <select multiple="multiple">...options...</select>
      #
      #   <%= content_tag :div, class: "strong" do -%>
      #     Hello world!
      #   <% end -%>
      #    # => <div class="strong">Hello world!</div>
      def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
        if block_given?
          options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
          content_tag_string(name, capture(&block), options, escape)
        else
          content_tag_string(name, content_or_options_with_block, options, escape)
        end
      end

      # Returns a CDATA section with the given +content+. CDATA sections
      # are used to escape blocks of text containing characters which would
      # otherwise be recognized as markup. CDATA sections begin with the string
      # <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
      #
      #   cdata_section("<hello world>")
      #   # => <![CDATA[<hello world>]]>
      #
      #   cdata_section(File.read("hello_world.txt"))
      #   # => <![CDATA[<hello from a text file]]>
      #
      #   cdata_section("hello]]>world")
      #   # => <![CDATA[hello]]]]><![CDATA[>world]]>
      def cdata_section(content)
        splitted = content.gsub(']]>', ']]]]><![CDATA[>')
        "<![CDATA[#{splitted}]]>".html_safe
      end

      # Returns an escaped version of +html+ without affecting existing escaped entities.
      #
      #   escape_once("1 < 2 &amp; 3")
      #   # => "1 &lt; 2 &amp; 3"
      #
      #   escape_once("&lt;&lt; Accept & Checkout")
      #   # => "&lt;&lt; Accept &amp; Checkout"
      def escape_once(html)
        ERB::Util.html_escape_once(html)
      end

      private

        def content_tag_string(name, content, options, escape = true)
          tag_options = tag_options(options, escape) if options
          content     = ERB::Util.h(content) if escape
          "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
        end

        def tag_options(options, escape = true)
          return if options.blank?
          attrs = []
          options.each_pair do |key, value|
            if key.to_s == 'data' && value.is_a?(Hash)
              value.each_pair do |k, v|
                attrs << data_tag_option(k, v, escape)
              end
            elsif BOOLEAN_ATTRIBUTES.include?(key)
              attrs << boolean_tag_option(key) if value
            elsif !value.nil?
              attrs << tag_option(key, value, escape)
            end
          end
          " #{attrs.sort * ' '}".html_safe unless attrs.empty?
        end

        def data_tag_option(key, value, escape)
          key   = "data-#{key.to_s.dasherize}"
          unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
            value = value.to_json
          end
          tag_option(key, value, escape)
        end

        def boolean_tag_option(key)
          %(#{key}="#{key}")
        end

        def tag_option(key, value, escape)
          value = value.join(" ") if value.is_a?(Array)
          value = ERB::Util.h(value) if escape
          %(#{key}="#{value}")
        end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class Base #:nodoc:
        include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
        include FormOptionsHelper

        attr_reader :object

        def initialize(object_name, method_name, template_object, options = {})
          @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
          @template_object = template_object

          @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
          @object = retrieve_object(options.delete(:object))
          @options = options
          @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
        end

        # This is what child classes implement.
        def render
          raise NotImplementedError, "Subclasses must implement a render method"
        end

        private

        def value(object)
          object.send @method_name if object
        end

        def value_before_type_cast(object)
          unless object.nil?
            method_before_type_cast = @method_name + "_before_type_cast"

            object.respond_to?(method_before_type_cast) ?
              object.send(method_before_type_cast) :
              value(object)
          end
        end

        def retrieve_object(object)
          if object
            object
          elsif @template_object.instance_variable_defined?("@#{@object_name}")
            @template_object.instance_variable_get("@#{@object_name}")
          end
        rescue NameError
          # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
          nil
        end

        def retrieve_autoindex(pre_match)
          object = self.object || @template_object.instance_variable_get("@#{pre_match}")
          if object && object.respond_to?(:to_param)
            object.to_param
          else
            raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
          end
        end

        def add_default_name_and_id_for_value(tag_value, options)
          if tag_value.nil?
            add_default_name_and_id(options)
          else
            specified_id = options["id"]
            add_default_name_and_id(options)

            if specified_id.blank? && options["id"].present?
              options["id"] += "_#{sanitized_value(tag_value)}"
            end
          end
        end

        def add_default_name_and_id(options)
          if options.has_key?("index")
            options["name"] ||= options.fetch("name"){ tag_name_with_index(options["index"]) }
            options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
            options.delete("index")
          elsif defined?(@auto_index)
            options["name"] ||= options.fetch("name"){ tag_name_with_index(@auto_index) }
            options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
          else
            options["name"] ||= options.fetch("name"){ tag_name }
            options["id"] = options.fetch("id"){ tag_id }
          end

          options["name"] += "[]" if options["multiple"]
          options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
        end

        def tag_name
          "#{@object_name}[#{sanitized_method_name}]"
        end

        def tag_name_with_index(index)
          "#{@object_name}[#{index}][#{sanitized_method_name}]"
        end

        def tag_id
          "#{sanitized_object_name}_#{sanitized_method_name}"
        end

        def tag_id_with_index(index)
          "#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
        end

        def sanitized_object_name
          @sanitized_object_name ||= @object_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
        end

        def sanitized_method_name
          @sanitized_method_name ||= @method_name.sub(/\?$/,"")
        end

        def sanitized_value(value)
          value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
        end

        def select_content_tag(option_tags, options, html_options)
          html_options = html_options.stringify_keys
          add_default_name_and_id(html_options)
          options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
          select = content_tag("select", add_options(option_tags, options, value(object)), html_options)

          if html_options["multiple"] && options.fetch(:include_hidden, true)
            tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
          else
            select
          end
        end

        def select_not_required?(html_options)
          !html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1
        end

        def add_options(option_tags, options, value = nil)
          if options[:include_blank]
            option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
          end
          if value.blank? && options[:prompt]
            option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
          end
          option_tags
        end
      end
    end
  end
end
require 'action_view/helpers/tags/checkable'

module ActionView
  module Helpers
    module Tags
      class CheckBox < Base #:nodoc:
        include Checkable

        def initialize(object_name, method_name, template_object, checked_value, unchecked_value, options)
          @checked_value   = checked_value
          @unchecked_value = unchecked_value
          super(object_name, method_name, template_object, options)
        end

        def render
          options = @options.stringify_keys
          options["type"]     = "checkbox"
          options["value"]    = @checked_value
          options["checked"] = "checked" if input_checked?(object, options)

          if options["multiple"]
            add_default_name_and_id_for_value(@checked_value, options)
            options.delete("multiple")
          else
            add_default_name_and_id(options)
          end

          include_hidden = options.delete("include_hidden") { true }
          checkbox = tag("input", options)

          if include_hidden
            hidden = hidden_field_for_checkbox(options)
            hidden + checkbox
          else
            checkbox
          end
        end

        private

        def checked?(value)
          case value
          when TrueClass, FalseClass
            value == !!@checked_value
          when NilClass
            false
          when String
            value == @checked_value
          else
            if value.respond_to?(:include?)
              value.include?(@checked_value)
            else
              value.to_i == @checked_value.to_i
            end
          end
        end

        def hidden_field_for_checkbox(options)
          @unchecked_value ? tag("input", options.slice("name", "disabled", "form").merge!("type" => "hidden", "value" => @unchecked_value)) : "".html_safe
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      module Checkable
        def input_checked?(object, options)
          if options.has_key?("checked")
            checked = options.delete "checked"
            checked == true || checked == "checked"
          else
            checked?(value(object))
          end
        end
      end
    end
  end
end
require 'action_view/helpers/tags/collection_helpers'

module ActionView
  module Helpers
    module Tags
      class CollectionCheckBoxes < Base
        include CollectionHelpers

        class CheckBoxBuilder < Builder
          def check_box(extra_html_options={})
            html_options = extra_html_options.merge(@input_html_options)
            @template_object.check_box(@object_name, @method_name, html_options, @value, nil)
          end
        end

        def render(&block)
          rendered_collection = render_collection do |item, value, text, default_html_options|
            default_html_options[:multiple] = true
            builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)

            if block_given?
              @template_object.capture(builder, &block)
            else
              render_component(builder)
            end
          end

          # Append a hidden field to make sure something will be sent back to the
          # server if all check boxes are unchecked.
          hidden = @template_object.hidden_field_tag("#{tag_name}[]", "", :id => nil)

          rendered_collection + hidden
        end

        private

        def render_component(builder)
          builder.check_box + builder.label
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      module CollectionHelpers
        class Builder
          attr_reader :object, :text, :value

          def initialize(template_object, object_name, method_name, object,
                         sanitized_attribute_name, text, value, input_html_options)
            @template_object = template_object
            @object_name = object_name
            @method_name = method_name
            @object = object
            @sanitized_attribute_name = sanitized_attribute_name
            @text = text
            @value = value
            @input_html_options = input_html_options
          end

          def label(label_html_options={}, &block)
            @template_object.label(@object_name, @sanitized_attribute_name, @text, label_html_options, &block)
          end
        end

        def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
          @collection   = collection
          @value_method = value_method
          @text_method  = text_method
          @html_options = html_options

          super(object_name, method_name, template_object, options)
        end

        private

        def instantiate_builder(builder_class, item, value, text, html_options)
          builder_class.new(@template_object, @object_name, @method_name, item,
                            sanitize_attribute_name(value), text, value, html_options)
        end

        # Generate default options for collection helpers, such as :checked and
        # :disabled.
        def default_html_options_for_collection(item, value) #:nodoc:
          html_options = @html_options.dup

          [:checked, :selected, :disabled].each do |option|
            current_value = @options[option]
            next if current_value.nil?

            accept = if current_value.respond_to?(:call)
              current_value.call(item)
            else
              Array(current_value).map(&:to_s).include?(value.to_s)
            end

            if accept
              html_options[option] = true
            elsif option == :checked
              html_options[option] = false
            end
          end

          html_options[:object] = @object
          html_options
        end

        def sanitize_attribute_name(value) #:nodoc:
          "#{sanitized_method_name}_#{sanitized_value(value)}"
        end

        def render_collection #:nodoc:
          @collection.map do |item|
            value = value_for_collection(item, @value_method)
            text  = value_for_collection(item, @text_method)
            default_html_options = default_html_options_for_collection(item, value)

            yield item, value, text, default_html_options
          end.join.html_safe
        end
      end
    end
  end
end
require 'action_view/helpers/tags/collection_helpers'

module ActionView
  module Helpers
    module Tags
      class CollectionRadioButtons < Base
        include CollectionHelpers

        class RadioButtonBuilder < Builder
          def radio_button(extra_html_options={})
            html_options = extra_html_options.merge(@input_html_options)
            @template_object.radio_button(@object_name, @method_name, @value, html_options)
          end
        end

        def render(&block)
          render_collection do |item, value, text, default_html_options|
            builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)

            if block_given?
              @template_object.capture(builder, &block)
            else
              render_component(builder)
            end
          end
        end

        private

          def render_component(builder)
            builder.radio_button + builder.label
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class CollectionSelect < Base #:nodoc:
        def initialize(object_name, method_name, template_object, collection, value_method, text_method, options, html_options)
          @collection   = collection
          @value_method = value_method
          @text_method  = text_method
          @html_options = html_options

          super(object_name, method_name, template_object, options)
        end

        def render
          option_tags_options = {
            :selected => @options.fetch(:selected) { value(@object) },
            :disabled => @options[:disabled]
          }

          select_content_tag(
            options_from_collection_for_select(@collection, @value_method, @text_method, option_tags_options),
            @options, @html_options
          )
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class ColorField < TextField #:nodoc:
        def render
          options = @options.stringify_keys
          options["value"] = @options.fetch("value") { validate_color_string(value(object)) }
          @options = options
          super
        end

        private

          def validate_color_string(string)
            regex = /#[0-9a-fA-F]{6}/
            if regex.match(string)
              string.downcase
            else
              "#000000"
            end
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class DateField < DatetimeField #:nodoc:
        private

          def format_date(value)
            value.try(:strftime, "%Y-%m-%d")
          end
      end
    end
  end
end
require 'active_support/core_ext/time/calculations'

module ActionView
  module Helpers
    module Tags
      class DateSelect < Base #:nodoc:
        def initialize(object_name, method_name, template_object, options, html_options)
          @html_options = html_options

          super(object_name, method_name, template_object, options)
        end

        def render
          error_wrapping(datetime_selector(@options, @html_options).send("select_#{select_type}").html_safe)
        end

        class << self
          def select_type
            @select_type ||= self.name.split("::").last.sub("Select", "").downcase
          end
        end

        private

        def select_type
          self.class.select_type
        end

        def datetime_selector(options, html_options)
          datetime = options.fetch(:selected) { value(object) || default_datetime(options) }
          @auto_index ||= nil

          options = options.dup
          options[:field_name]           = @method_name
          options[:include_position]     = true
          options[:prefix]             ||= @object_name
          options[:index]                = @auto_index if @auto_index && !options.has_key?(:index)

          DateTimeSelector.new(datetime, options, html_options)
        end

        def default_datetime(options)
          return if options[:include_blank] || options[:prompt]

          case options[:default]
          when nil
            Time.current
          when Date, Time
            options[:default]
          else
            default = options[:default].dup

            # Rename :minute and :second to :min and :sec
            default[:min] ||= default[:minute]
            default[:sec] ||= default[:second]

            time = Time.current

            [:year, :month, :day, :hour, :min, :sec].each do |key|
              default[key] ||= time.send(key)
            end

            Time.utc(
              default[:year], default[:month], default[:day],
              default[:hour], default[:min], default[:sec]
            )
          end
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class DatetimeField < TextField #:nodoc:
        def render
          options = @options.stringify_keys
          options["value"] = @options.fetch("value") { format_date(value(object)) }
          options["min"] = format_date(options["min"])
          options["max"] = format_date(options["max"])
          @options = options
          super
        end

        private

          def format_date(value)
            value.try(:strftime, "%Y-%m-%dT%T.%L%z")
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class DatetimeLocalField < DatetimeField #:nodoc:
        class << self
          def field_type
            @field_type ||= "datetime-local"
          end
        end

        private

          def format_date(value)
            value.try(:strftime, "%Y-%m-%dT%T")
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class DatetimeSelect < DateSelect #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class EmailField < TextField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class FileField < TextField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class GroupedCollectionSelect < Base #:nodoc:
        def initialize(object_name, method_name, template_object, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
          @collection          = collection
          @group_method        = group_method
          @group_label_method  = group_label_method
          @option_key_method   = option_key_method
          @option_value_method = option_value_method
          @html_options        = html_options

          super(object_name, method_name, template_object, options)
        end

        def render
          option_tags_options = {
            :selected => @options.fetch(:selected) { value(@object) },
            :disabled => @options[:disabled]
          }

          select_content_tag(
            option_groups_from_collection_for_select(@collection, @group_method, @group_label_method, @option_key_method, @option_value_method, option_tags_options), @options, @html_options
          )
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class HiddenField < TextField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class Label < Base #:nodoc:
        def initialize(object_name, method_name, template_object, content_or_options = nil, options = nil)
          options ||= {}

          content_is_options = content_or_options.is_a?(Hash)
          if content_is_options
            options.merge! content_or_options
            @content = nil
          else
            @content = content_or_options
          end

          super(object_name, method_name, template_object, options)
        end

        def render(&block)
          options = @options.stringify_keys
          tag_value = options.delete("value")
          name_and_id = options.dup

          if name_and_id["for"]
            name_and_id["id"] = name_and_id["for"]
          else
            name_and_id.delete("id")
          end

          add_default_name_and_id_for_value(tag_value, name_and_id)
          options.delete("index")
          options.delete("namespace")
          options["for"] = name_and_id["id"] unless options.key?("for")

          if block_given?
            content = @template_object.capture(&block)
          else
            content = if @content.blank?
                        @object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1')
                        method_and_value = tag_value.present? ? "#{@method_name}.#{tag_value}" : @method_name

                        if object.respond_to?(:to_model)
                          key = object.class.model_name.i18n_key
                          i18n_default = ["#{key}.#{method_and_value}".to_sym, ""]
                        end

                        i18n_default ||= ""
                        I18n.t("#{@object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence
                      else
                        @content.to_s
                      end

            content ||= if object && object.class.respond_to?(:human_attribute_name)
                          object.class.human_attribute_name(@method_name)
                        end

            content ||= @method_name.humanize
          end

          label_tag(name_and_id["id"], content, options)
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class MonthField < DatetimeField #:nodoc:
        private

          def format_date(value)
            value.try(:strftime, "%Y-%m")
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class NumberField < TextField #:nodoc:
        def render
          options = @options.stringify_keys

          if range = options.delete("in") || options.delete("within")
            options.update("min" => range.min, "max" => range.max)
          end

          @options = options
          super
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class PasswordField < TextField #:nodoc:
        def render
          @options = {:value => nil}.merge!(@options)
          super
        end
      end
    end
  end
end
require 'action_view/helpers/tags/checkable'

module ActionView
  module Helpers
    module Tags
      class RadioButton < Base #:nodoc:
        include Checkable

        def initialize(object_name, method_name, template_object, tag_value, options)
          @tag_value = tag_value
          super(object_name, method_name, template_object, options)
        end

        def render
          options = @options.stringify_keys
          options["type"]     = "radio"
          options["value"]    = @tag_value
          options["checked"] = "checked" if input_checked?(object, options)
          add_default_name_and_id_for_value(@tag_value, options)
          tag("input", options)
        end

        private

        def checked?(value)
          value.to_s == @tag_value.to_s
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class RangeField < NumberField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class SearchField < TextField #:nodoc:
        def render
          options = @options.stringify_keys

          if options["autosave"]
            if options["autosave"] == true
              options["autosave"] = request.host.split(".").reverse.join(".")
            end
            options["results"] ||= 10
          end

          if options["onsearch"]
            options["incremental"] = true unless options.has_key?("incremental")
          end

          super
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class Select < Base #:nodoc:
        def initialize(object_name, method_name, template_object, choices, options, html_options)
          @choices = choices
          @choices = @choices.to_a if @choices.is_a?(Range)
          @html_options = html_options

          super(object_name, method_name, template_object, options)
        end

        def render
          option_tags_options = {
            :selected => @options.fetch(:selected) { value(@object) },
            :disabled => @options[:disabled]
          }

          option_tags = if grouped_choices?
            grouped_options_for_select(@choices, option_tags_options)
          else
            options_for_select(@choices, option_tags_options)
          end

          select_content_tag(option_tags, @options, @html_options)
        end

        private

        # Grouped choices look like this:
        #
        #   [nil, []]
        #   { nil => [] }
        #
        def grouped_choices?
          !@choices.empty? && @choices.first.respond_to?(:last) && Array === @choices.first.last
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TelField < TextField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TextArea < Base #:nodoc:
        def render
          options = @options.stringify_keys
          add_default_name_and_id(options)

          if size = options.delete("size")
            options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
          end

          content_tag("textarea", options.delete('value') || value_before_type_cast(object), options)
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TextField < Base #:nodoc:
        def render
          options = @options.stringify_keys
          options["size"] = options["maxlength"] unless options.key?("size")
          options["type"]  ||= field_type
          options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file"
          options["value"] &&= ERB::Util.html_escape(options["value"])
          add_default_name_and_id(options)
          tag("input", options)
        end

        class << self
          def field_type
            @field_type ||= self.name.split("::").last.sub("Field", "").downcase
          end
        end

        private

        def field_type
          self.class.field_type
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TimeField < DatetimeField #:nodoc:
        private

          def format_date(value)
            value.try(:strftime, "%T.%L")
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TimeSelect < DateSelect #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class TimeZoneSelect < Base #:nodoc:
        def initialize(object_name, method_name, template_object, priority_zones, options, html_options)
          @priority_zones = priority_zones
          @html_options   = html_options

          super(object_name, method_name, template_object, options)
        end

        def render
          select_content_tag(
            time_zone_options_for_select(value(@object) || @options[:default], @priority_zones, @options[:model] || ActiveSupport::TimeZone), @options, @html_options
          )
        end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class UrlField < TextField #:nodoc:
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags
      class WeekField < DatetimeField #:nodoc:
        private

          def format_date(value)
            value.try(:strftime, "%Y-W%W")
          end
      end
    end
  end
end
module ActionView
  module Helpers
    module Tags #:nodoc:
      extend ActiveSupport::Autoload

      autoload :Base
      autoload :CheckBox
      autoload :CollectionCheckBoxes
      autoload :CollectionRadioButtons
      autoload :CollectionSelect
      autoload :ColorField
      autoload :DateField
      autoload :DateSelect
      autoload :DatetimeField
      autoload :DatetimeLocalField
      autoload :DatetimeSelect
      autoload :EmailField
      autoload :FileField
      autoload :GroupedCollectionSelect
      autoload :HiddenField
      autoload :Label
      autoload :MonthField
      autoload :NumberField
      autoload :PasswordField
      autoload :RadioButton
      autoload :RangeField
      autoload :SearchField
      autoload :Select
      autoload :TelField
      autoload :TextArea
      autoload :TextField
      autoload :TimeField
      autoload :TimeSelect
      autoload :TimeZoneSelect
      autoload :UrlField
      autoload :WeekField
    end
  end
end
require 'active_support/core_ext/string/filters'
require 'active_support/core_ext/array/extract_options'

module ActionView
  # = Action View Text Helpers
  module Helpers #:nodoc:
    # The TextHelper module provides a set of methods for filtering, formatting
    # and transforming strings, which can reduce the amount of inline Ruby code in
    # your views. These helper methods extend Action View making them callable
    # within your template files.
    #
    # ==== Sanitization
    #
    # Most text helpers by default sanitize the given content, but do not escape it.
    # This means HTML tags will appear in the page but all malicious code will be removed.
    # Let's look at some examples using the +simple_format+ method:
    #
    #   simple_format('<a href="http://example.com/">Example</a>')
    #   # => "<p><a href=\"http://example.com/\">Example</a></p>"
    #
    #   simple_format('<a href="javascript:alert(\'no!\')">Example</a>')
    #   # => "<p><a>Example</a></p>"
    #
    # If you want to escape all content, you should invoke the +h+ method before
    # calling the text helper.
    #
    #   simple_format h('<a href="http://example.com/">Example</a>')
    #   # => "<p>&lt;a href=\"http://example.com/\"&gt;Example&lt;/a&gt;</p>"
    module TextHelper
      extend ActiveSupport::Concern

      include SanitizeHelper
      include TagHelper
      # The preferred method of outputting text in your views is to use the
      # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
      # do not operate as expected in an eRuby code block. If you absolutely must
      # output text within a non-output code block (i.e., <% %>), you can use the concat method.
      #
      #   <%
      #       concat "hello"
      #       # is the equivalent of <%= "hello" %>
      #
      #       if logged_in
      #         concat "Logged in!"
      #       else
      #         concat link_to('login', action: :login)
      #       end
      #       # will either display "Logged in!" or a login link
      #   %>
      def concat(string)
        output_buffer << string
      end

      def safe_concat(string)
        output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
      end

      # Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
      # (defaults to 30). The last characters will be replaced with the <tt>:omission</tt> (defaults to "...")
      # for a total length not exceeding <tt>:length</tt>.
      #
      # Pass a <tt>:separator</tt> to truncate +text+ at a natural break.
      #
      # Pass a block if you want to show extra content when the text is truncated.
      #
      # The result is marked as HTML-safe, but it is escaped by default, unless <tt>:escape</tt> is
      # +false+. Care should be taken if +text+ contains HTML tags or entities, because truncation
      # may produce invalid HTML (such as unbalanced or incomplete tags).
      #
      #   truncate("Once upon a time in a world far far away")
      #   # => "Once upon a time in a world..."
      #
      #   truncate("Once upon a time in a world far far away", length: 17)
      #   # => "Once upon a ti..."
      #
      #   truncate("Once upon a time in a world far far away", length: 17, separator: ' ')
      #   # => "Once upon a..."
      #
      #   truncate("And they found that many people were sleeping better.", length: 25, omission: '... (continued)')
      #   # => "And they f... (continued)"
      #
      #   truncate("<p>Once upon a time in a world far far away</p>")
      #   # => "<p>Once upon a time in a wo..."
      #
      #   truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
      #   # => "Once upon a time in a wo...<a href="#">Continue</a>"
      def truncate(text, options = {}, &block)
        if text
          length  = options.fetch(:length, 30)

          content = text.truncate(length, options)
          content = options[:escape] == false ? content.html_safe : ERB::Util.html_escape(content)
          content << capture(&block) if block_given? && text.length > length
          content
        end
      end

      # Highlights one or more +phrases+ everywhere in +text+ by inserting it into
      # a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt>
      # as a single-quoted string with <tt>\1</tt> where the phrase is to be inserted (defaults to
      # '<mark>\1</mark>')
      #
      #   highlight('You searched for: rails', 'rails')
      #   # => You searched for: <mark>rails</mark>
      #
      #   highlight('You searched for: ruby, rails, dhh', 'actionpack')
      #   # => You searched for: ruby, rails, dhh
      #
      #   highlight('You searched for: rails', ['for', 'rails'], highlighter: '<em>\1</em>')
      #   # => You searched <em>for</em>: <em>rails</em>
      #
      #   highlight('You searched for: rails', 'rails', highlighter: '<a href="search?q=\1">\1</a>')
      #   # => You searched for: <a href="search?q=rails">rails</a>
      def highlight(text, phrases, options = {})
        text = sanitize(text) if options.fetch(:sanitize, true)

        if text.blank? || phrases.blank?
          text
        else
          highlighter = options.fetch(:highlighter, '<mark>\1</mark>')
          match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
          text.gsub(/(#{match})(?![^<]*?>)/i, highlighter)
        end.html_safe
      end

      # Extracts an excerpt from +text+ that matches the first instance of +phrase+.
      # The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
      # defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
      # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The
      # <tt>:separator</tt> enable to choose the delimation. The resulting string will be stripped in any case. If the +phrase+
      # isn't found, nil is returned.
      #
      #   excerpt('This is an example', 'an', radius: 5)
      #   # => ...s is an exam...
      #
      #   excerpt('This is an example', 'is', radius: 5)
      #   # => This is a...
      #
      #   excerpt('This is an example', 'is')
      #   # => This is an example
      #
      #   excerpt('This next thing is an example', 'ex', radius: 2)
      #   # => ...next...
      #
      #   excerpt('This is also an example', 'an', radius: 8, omission: '<chop> ')
      #   # => <chop> is also an example
      #
      #   excerpt('This is a very beautiful morning', 'very', separator:  ' ', radius: 1)
      #   # => ...a very beautiful...
      def excerpt(text, phrase, options = {})
        return unless text && phrase

        separator = options.fetch(:separator, "")
        phrase    = Regexp.escape(phrase)
        regex     = /#{phrase}/i

        return unless matches = text.match(regex)
        phrase = matches[0]

        text.split(separator).each do |value|
          if value.match(regex)
            regex = phrase = value
            break
          end
        end

        first_part, second_part = text.split(regex, 2)

        prefix, first_part   = cut_excerpt_part(:first, first_part, separator, options)
        postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)

        prefix + (first_part + separator + phrase + separator + second_part).strip + postfix
      end

      # Attempts to pluralize the +singular+ word unless +count+ is 1. If
      # +plural+ is supplied, it will use that when count is > 1, otherwise
      # it will use the Inflector to determine the plural form.
      #
      #   pluralize(1, 'person')
      #   # => 1 person
      #
      #   pluralize(2, 'person')
      #   # => 2 people
      #
      #   pluralize(3, 'person', 'users')
      #   # => 3 users
      #
      #   pluralize(0, 'person')
      #   # => 0 people
      def pluralize(count, singular, plural = nil)
        word = if (count == 1 || count =~ /^1(\.0+)?$/)
          singular
        else
          plural || singular.pluralize
        end

        "#{count || 0} #{word}"
      end

      # Wraps the +text+ into lines no longer than +line_width+ width. This method
      # breaks on the first whitespace character that does not exceed +line_width+
      # (which is 80 by default).
      #
      #   word_wrap('Once upon a time')
      #   # => Once upon a time
      #
      #   word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
      #   # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
      #
      #   word_wrap('Once upon a time', line_width: 8)
      #   # => Once\nupon a\ntime
      #
      #   word_wrap('Once upon a time', line_width: 1)
      #   # => Once\nupon\na\ntime
      def word_wrap(text, options = {})
        line_width = options.fetch(:line_width, 80)

        text.split("\n").collect do |line|
          line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
        end * "\n"
      end

      # Returns +text+ transformed into HTML using simple formatting rules.
      # Two or more consecutive newlines(<tt>\n\n</tt>) are considered as a
      # paragraph and wrapped in <tt><p></tt> tags. One newline (<tt>\n</tt>) is
      # considered as a linebreak and a <tt><br /></tt> tag is appended. This
      # method does not remove the newlines from the +text+.
      #
      # You can pass any HTML attributes into <tt>html_options</tt>. These
      # will be added to all created paragraphs.
      #
      # ==== Options
      # * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
      # * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt>
      #
      # ==== Examples
      #   my_text = "Here is some basic text...\n...with a line break."
      #
      #   simple_format(my_text)
      #   # => "<p>Here is some basic text...\n<br />...with a line break.</p>"
      #
      #   simple_format(my_text, {}, wrapper_tag: "div")
      #   # => "<div>Here is some basic text...\n<br />...with a line break.</div>"
      #
      #   more_text = "We want to put a paragraph...\n\n...right there."
      #
      #   simple_format(more_text)
      #   # => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
      #
      #   simple_format("Look ma! A class!", class: 'description')
      #   # => "<p class='description'>Look ma! A class!</p>"
      #
      #   simple_format("<span>I'm allowed!</span> It's true.", {}, sanitize: false)
      #   # => "<p><span>I'm allowed!</span> It's true.</p>"
      def simple_format(text, html_options = {}, options = {})
        wrapper_tag = options.fetch(:wrapper_tag, :p)

        text = sanitize(text) if options.fetch(:sanitize, true)
        paragraphs = split_paragraphs(text)

        if paragraphs.empty?
          content_tag(wrapper_tag, nil, html_options)
        else
          paragraphs.map { |paragraph|
            content_tag(wrapper_tag, paragraph, html_options, options[:sanitize])
          }.join("\n\n").html_safe
        end
      end

      # Creates a Cycle object whose _to_s_ method cycles through elements of an
      # array every time it is called. This can be used for example, to alternate
      # classes for table rows. You can use named cycles to allow nesting in loops.
      # Passing a Hash as the last parameter with a <tt>:name</tt> key will create a
      # named cycle. The default name for a cycle without a +:name+ key is
      # <tt>"default"</tt>. You can manually reset a cycle by calling reset_cycle
      # and passing the name of the cycle. The current cycle string can be obtained
      # anytime using the current_cycle method.
      #
      #   # Alternate CSS classes for even and odd numbers...
      #   @items = [1,2,3,4]
      #   <table>
      #   <% @items.each do |item| %>
      #     <tr class="<%= cycle("odd", "even") -%>">
      #       <td>item</td>
      #     </tr>
      #   <% end %>
      #   </table>
      #
      #
      #   # Cycle CSS classes for rows, and text colors for values within each row
      #   @items = x = [{first: 'Robert', middle: 'Daniel', last: 'James'},
      #                {first: 'Emily', middle: 'Shannon', maiden: 'Pike', last: 'Hicks'},
      #               {first: 'June', middle: 'Dae', last: 'Jones'}]
      #   <% @items.each do |item| %>
      #     <tr class="<%= cycle("odd", "even", name: "row_class") -%>">
      #       <td>
      #         <% item.values.each do |value| %>
      #           <%# Create a named cycle "colors" %>
      #           <span style="color:<%= cycle("red", "green", "blue", name: "colors") -%>">
      #             <%= value %>
      #           </span>
      #         <% end %>
      #         <% reset_cycle("colors") %>
      #       </td>
      #    </tr>
      #  <% end %>
      def cycle(first_value, *values)
        options = values.extract_options!
        name = options.fetch(:name, 'default')

        values.unshift(first_value)

        cycle = get_cycle(name)
        unless cycle && cycle.values == values
          cycle = set_cycle(name, Cycle.new(*values))
        end
        cycle.to_s
      end

      # Returns the current cycle string after a cycle has been started. Useful
      # for complex table highlighting or any other design need which requires
      # the current cycle string in more than one place.
      #
      #   # Alternate background colors
      #   @items = [1,2,3,4]
      #   <% @items.each do |item| %>
      #     <div style="background-color:<%= cycle("red","white","blue") %>">
      #       <span style="background-color:<%= current_cycle %>"><%= item %></span>
      #     </div>
      #   <% end %>
      def current_cycle(name = "default")
        cycle = get_cycle(name)
        cycle.current_value if cycle
      end

      # Resets a cycle so that it starts from the first element the next time
      # it is called. Pass in +name+ to reset a named cycle.
      #
      #   # Alternate CSS classes for even and odd numbers...
      #   @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
      #   <table>
      #   <% @items.each do |item| %>
      #     <tr class="<%= cycle("even", "odd") -%>">
      #         <% item.each do |value| %>
      #           <span style="color:<%= cycle("#333", "#666", "#999", name: "colors") -%>">
      #             <%= value %>
      #           </span>
      #         <% end %>
      #
      #         <% reset_cycle("colors") %>
      #     </tr>
      #   <% end %>
      #   </table>
      def reset_cycle(name = "default")
        cycle = get_cycle(name)
        cycle.reset if cycle
      end

      class Cycle #:nodoc:
        attr_reader :values

        def initialize(first_value, *values)
          @values = values.unshift(first_value)
          reset
        end

        def reset
          @index = 0
        end

        def current_value
          @values[previous_index].to_s
        end

        def to_s
          value = @values[@index].to_s
          @index = next_index
          return value
        end

        private

        def next_index
          step_index(1)
        end

        def previous_index
          step_index(-1)
        end

        def step_index(n)
          (@index + n) % @values.size
        end
      end

      private
        # The cycle helpers need to store the cycles in a place that is
        # guaranteed to be reset every time a page is rendered, so it
        # uses an instance variable of ActionView::Base.
        def get_cycle(name)
          @_cycles = Hash.new unless defined?(@_cycles)
          return @_cycles[name]
        end

        def set_cycle(name, cycle_object)
          @_cycles = Hash.new unless defined?(@_cycles)
          @_cycles[name] = cycle_object
        end

        def split_paragraphs(text)
          return [] if text.blank?

          text.to_str.gsub(/\r\n?/, "\n").split(/\n\n+/).map! do |t|
            t.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') || t
          end
        end

        def cut_excerpt_part(part_position, part, separator, options)
          return "", "" unless part

          radius   = options.fetch(:radius, 100)
          omission = options.fetch(:omission, "...")

          part = part.split(separator)
          part.delete("")
          affix = part.size > radius ? omission : ""

          part = if part_position == :first
            drop_index = [part.length - radius, 0].max
            part.drop(drop_index)
          else
            part.first(radius)
          end

          return affix, part.join(separator)
        end
    end
  end
end
require 'action_view/helpers/tag_helper'
require 'i18n/exceptions'

module I18n
  class ExceptionHandler
    include Module.new {
      def call(exception, locale, key, options)
        exception.is_a?(MissingTranslation) && options[:rescue_format] == :html ? super.html_safe : super
      end
    }
  end
end

module ActionView
  # = Action View Translation Helpers
  module Helpers
    module TranslationHelper
      # Delegates to <tt>I18n#translate</tt> but also performs three additional functions.
      #
      # First, it'll pass the <tt>rescue_format: :html</tt> option to I18n so that any
      # thrown +MissingTranslation+ messages will be turned into inline spans that
      #
      #   * have a "translation-missing" class set,
      #   * contain the missing key as a title attribute and
      #   * a titleized version of the last key segment as a text.
      #
      # E.g. the value returned for a missing translation key :"blog.post.title" will be
      # <span class="translation_missing" title="translation missing: en.blog.post.title">Title</span>.
      # This way your views will display rather reasonable strings but it will still
      # be easy to spot missing translations.
      #
      # Second, it'll scope the key by the current partial if the key starts
      # with a period. So if you call <tt>translate(".foo")</tt> from the
      # <tt>people/index.html.erb</tt> template, you'll actually be calling
      # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
      # to translate many keys within the same partials and gives you a simple framework
      # for scoping them consistently. If you don't prepend the key with a period,
      # nothing is converted.
      #
      # Third, it'll mark the translation as safe HTML if the key has the suffix
      # "_html" or the last element of the key is the word "html". For example,
      # calling translate("footer_html") or translate("footer.html") will return
      # a safe HTML string that won't be escaped by other HTML helper methods. This
      # naming convention helps to identify translations that include HTML tags so that
      # you know what kind of output to expect when you call translate in a template.
      def translate(key, options = {})
        options.merge!(:rescue_format => :html) unless options.key?(:rescue_format)
        options[:default] = wrap_translate_defaults(options[:default]) if options[:default]
        if html_safe_translation_key?(key)
          html_safe_options = options.dup
          options.except(*I18n::RESERVED_KEYS).each do |name, value|
            unless name == :count && value.is_a?(Numeric)
              html_safe_options[name] = ERB::Util.html_escape(value.to_s)
            end
          end
          translation = I18n.translate(scope_key_by_partial(key), html_safe_options)

          translation.respond_to?(:html_safe) ? translation.html_safe : translation
        else
          I18n.translate(scope_key_by_partial(key), options)
        end
      end
      alias :t :translate

      # Delegates to <tt>I18n.localize</tt> with no additional functionality.
      #
      # See http://rubydoc.info/github/svenfuchs/i18n/master/I18n/Backend/Base:localize
      # for more information.
      def localize(*args)
        I18n.localize(*args)
      end
      alias :l :localize

      private
        def scope_key_by_partial(key)
          if key.to_s.first == "."
            if @virtual_path
              @virtual_path.gsub(%r{/_?}, ".") + key.to_s
            else
              raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
            end
          else
            key
          end
        end

        def html_safe_translation_key?(key)
          key.to_s =~ /(\b|_|\.)html$/
        end

        def wrap_translate_defaults(defaults)
          new_defaults = []
          defaults     = Array(defaults)
          while key = defaults.shift
            if key.is_a?(Symbol)
              new_defaults << lambda { |_, options| translate key, options.merge(:default => defaults) }
              break
            else
              new_defaults << key
            end
          end

          new_defaults
        end
    end
  end
end
require 'action_view/helpers/javascript_helper'
require 'active_support/core_ext/array/access'
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/string/output_safety'

module ActionView
  # = Action View URL Helpers
  module Helpers #:nodoc:
    # Provides a set of methods for making links and getting URLs that
    # depend on the routing subsystem (see ActionDispatch::Routing).
    # This allows you to use the same format for links in views
    # and controllers.
    module UrlHelper
      # This helper may be included in any class that includes the
      # URL helpers of a routes (routes.url_helpers). Some methods
      # provided here will only work in the context of a request
      # (link_to_unless_current, for instance), which must be provided
      # as a method called #request on the context.

      extend ActiveSupport::Concern

      include TagHelper

      module ClassMethods
        def _url_for_modules
          ActionView::RoutingUrlFor
        end
      end

      # Basic implementation of url_for to allow use helpers without routes existence
      def url_for(options = nil) # :nodoc:
        case options
        when String
          options
        when :back
          _back_url
        else
          raise ArgumentError, "arguments passed to url_for can't be handled. Please require " +
                               "routes or provide your own implementation"
        end
      end

      def _back_url # :nodoc:
        referrer = controller.respond_to?(:request) && controller.request.env["HTTP_REFERER"]
        referrer || 'javascript:history.back()'
      end
      protected :_back_url

      # Creates a link tag of the given +name+ using a URL created by the set of +options+.
      # See the valid options in the documentation for +url_for+. It's also possible to
      # pass a String instead of an options hash, which generates a link tag that uses the
      # value of the String as the href for the link. Using a <tt>:back</tt> Symbol instead
      # of an options hash will generate a link to the referrer (a JavaScript back link
      # will be used in place of a referrer if none exists). If +nil+ is passed as the name
      # the value of the link itself will become the name.
      #
      # ==== Signatures
      #
      #   link_to(body, url, html_options = {})
      #     # url is a String; you can use URL helpers like
      #     # posts_path
      #
      #   link_to(body, url_options = {}, html_options = {})
      #     # url_options, except :method, is passed to url_for
      #
      #   link_to(options = {}, html_options = {}) do
      #     # name
      #   end
      #
      #   link_to(url, html_options = {}) do
      #     # name
      #   end
      #
      # ==== Options
      # * <tt>:data</tt> - This option can be used to add custom data attributes.
      # * <tt>method: symbol of HTTP verb</tt> - This modifier will dynamically
      #   create an HTML form and immediately submit the form for processing using
      #   the HTTP verb specified. Useful for having links perform a POST operation
      #   in dangerous actions like deleting a record (which search bots can follow
      #   while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>.
      #   Note that if the user has JavaScript disabled, the request will fall back
      #   to using GET. If <tt>href: '#'</tt> is used and the user has JavaScript
      #   disabled clicking the link will have no effect. If you are relying on the
      #   POST behavior, you should check for it in your controller's action by using
      #   the request object's methods for <tt>post?</tt>, <tt>delete?</tt>, <tt>:patch</tt>, or <tt>put?</tt>.
      # * <tt>remote: true</tt> - This will allow the unobtrusive JavaScript
      #   driver to make an Ajax request to the URL in question instead of following
      #   the link. The drivers each provide mechanisms for listening for the
      #   completion of the Ajax request and performing JavaScript operations once
      #   they're complete
      #
      # ==== Data attributes
      #
      # * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript
      #   driver to prompt with the question specified. If the user accepts, the link is
      #   processed normally, otherwise no action is taken.
      # * <tt>:disable_with</tt> - Value of this parameter will be
      #   used as the value for a disabled version of the submit
      #   button when the form is submitted. This feature is provided
      #   by the unobtrusive JavaScript driver.
      #
      # ==== Examples
      # Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
      # and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
      # your application on resources and use
      #
      #   link_to "Profile", profile_path(@profile)
      #   # => <a href="/profiles/1">Profile</a>
      #
      # or the even pithier
      #
      #   link_to "Profile", @profile
      #   # => <a href="/profiles/1">Profile</a>
      #
      # in place of the older more verbose, non-resource-oriented
      #
      #   link_to "Profile", controller: "profiles", action: "show", id: @profile
      #   # => <a href="/profiles/show/1">Profile</a>
      #
      # Similarly,
      #
      #   link_to "Profiles", profiles_path
      #   # => <a href="/profiles">Profiles</a>
      #
      # is better than
      #
      #   link_to "Profiles", controller: "profiles"
      #   # => <a href="/profiles">Profiles</a>
      #
      # You can use a block as well if your link target is hard to fit into the name parameter. ERB example:
      #
      #   <%= link_to(@profile) do %>
      #     <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
      #   <% end %>
      #   # => <a href="/profiles/1">
      #          <strong>David</strong> -- <span>Check it out!</span>
      #        </a>
      #
      # Classes and ids for CSS are easy to produce:
      #
      #   link_to "Articles", articles_path, id: "news", class: "article"
      #   # => <a href="/articles" class="article" id="news">Articles</a>
      #
      # Be careful when using the older argument style, as an extra literal hash is needed:
      #
      #   link_to "Articles", { controller: "articles" }, id: "news", class: "article"
      #   # => <a href="/articles" class="article" id="news">Articles</a>
      #
      # Leaving the hash off gives the wrong link:
      #
      #   link_to "WRONG!", controller: "articles", id: "news", class: "article"
      #   # => <a href="/articles/index/news?class=article">WRONG!</a>
      #
      # +link_to+ can also produce links with anchors or query strings:
      #
      #   link_to "Comment wall", profile_path(@profile, anchor: "wall")
      #   # => <a href="/profiles/1#wall">Comment wall</a>
      #
      #   link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails"
      #   # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a>
      #
      #   link_to "Nonsense search", searches_path(foo: "bar", baz: "quux")
      #   # => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>
      #
      # The only option specific to +link_to+ (<tt>:method</tt>) is used as follows:
      #
      #   link_to("Destroy", "http://www.example.com", method: :delete)
      #   # => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
      #
      # You can also use custom data attributes using the <tt>:data</tt> option:
      #
      #   link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
      #   # => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
      def link_to(name = nil, options = nil, html_options = nil, &block)
        html_options, options = options, name if block_given?
        options ||= {}

        html_options = convert_options_to_data_attributes(options, html_options)

        url = url_for(options)
        html_options['href'] ||= url

        content_tag(:a, name || url, html_options, &block)
      end

      # Generates a form containing a single button that submits to the URL created
      # by the set of +options+. This is the safest method to ensure links that
      # cause changes to your data are not triggered by search bots or accelerators.
      # If the HTML button does not work with your layout, you can also consider
      # using the +link_to+ method with the <tt>:method</tt> modifier as described in
      # the +link_to+ documentation.
      #
      # By default, the generated form element has a class name of <tt>button_to</tt>
      # to allow styling of the form itself and its children. This can be changed
      # using the <tt>:form_class</tt> modifier within +html_options+. You can control
      # the form submission and input element behavior using +html_options+.
      # This method accepts the <tt>:method</tt> modifier described in the +link_to+ documentation.
      # If no <tt>:method</tt> modifier is given, it will default to performing a POST operation.
      # You can also disable the button by passing <tt>disabled: true</tt> in +html_options+.
      # If you are using RESTful routes, you can pass the <tt>:method</tt>
      # to change the HTTP verb used to submit the form.
      #
      # ==== Options
      # The +options+ hash accepts the same options as +url_for+.
      #
      # There are a few special +html_options+:
      # * <tt>:method</tt> - Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
      #   <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
      # * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
      # * <tt>:data</tt> - This option can be used to add custom data attributes.
      # * <tt>:remote</tt> -  If set to true, will allow the Unobtrusive JavaScript drivers to control the
      #   submit behavior. By default this behavior is an ajax submit.
      # * <tt>:form</tt> - This hash will be form attributes
      # * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
      #   be placed
      #
      # ==== Data attributes
      #
      # * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
      #   prompt with the question specified. If the user accepts, the link is
      #   processed normally, otherwise no action is taken.
      # * <tt>:disable_with</tt> - Value of this parameter will be
      #   used as the value for a disabled version of the submit
      #   button when the form is submitted. This feature is provided
      #   by the unobtrusive JavaScript driver.
      #
      # ==== Examples
      #   <%= button_to "New", action: "new" %>
      #   # => "<form method="post" action="/controller/new" class="button_to">
      #   #      <div><input value="New" type="submit" /></div>
      #   #    </form>"
      #
      #   <%= button_to [:make_happy, @user] do %>
      #     Make happy <strong><%= @user.name %></strong>
      #   <% end %>
      #   # => "<form method="post" action="/users/1/make_happy" class="button_to">
      #   #      <div>
      #   #        <button type="submit">
      #   #          Make happy <strong><%= @user.name %></strong>
      #   #        </button>
      #   #      </div>
      #   #    </form>"
      #
      #   <%= button_to "New", { action: "new" }, form_class: "new-thing" %>
      #   # => "<form method="post" action="/controller/new" class="new-thing">
      #   #      <div><input value="New" type="submit" /></div>
      #   #    </form>"
      #
      #
      #   <%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
      #   # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
      #   #      <div>
      #   #        <input value="Create" type="submit" />
      #   #        <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
      #   #      </div>
      #   #    </form>"
      #
      #
      #   <%= button_to "Delete Image", { action: "delete", id: @image.id },
      #                                   method: :delete, data: { confirm: "Are you sure?" } %>
      #   # => "<form method="post" action="/images/delete/1" class="button_to">
      #   #      <div>
      #   #        <input type="hidden" name="_method" value="delete" />
      #   #        <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
      #   #        <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
      #   #      </div>
      #   #    </form>"
      #
      #
      #   <%= button_to('Destroy', 'http://www.example.com',
      #             method: "delete", remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
      #   # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
      #   #       <div>
      #   #         <input name='_method' value='delete' type='hidden' />
      #   #         <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
      #   #         <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
      #   #       </div>
      #   #     </form>"
      #   #
      def button_to(name = nil, options = nil, html_options = nil, &block)
        html_options, options = options, name if block_given?
        options      ||= {}
        html_options ||= {}

        html_options = html_options.stringify_keys
        convert_boolean_attributes!(html_options, %w(disabled))

        url    = options.is_a?(String) ? options : url_for(options)
        remote = html_options.delete('remote')

        method     = html_options.delete('method').to_s
        method_tag = %w{patch put delete}.include?(method) ? method_tag(method) : ''.html_safe

        form_method  = method == 'get' ? 'get' : 'post'
        form_options = html_options.delete('form') || {}
        form_options[:class] ||= html_options.delete('form_class') || 'button_to'
        form_options.merge!(method: form_method, action: url)
        form_options.merge!("data-remote" => "true") if remote

        request_token_tag = form_method == 'post' ? token_tag : ''

        html_options = convert_options_to_data_attributes(options, html_options)
        html_options['type'] = 'submit'

        button = if block_given?
          content_tag('button', html_options, &block)
        else
          html_options['value'] = name || url
          tag('input', html_options)
        end

        inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
        content_tag('form', content_tag('div', inner_tags), form_options)
      end

      # Creates a link tag of the given +name+ using a URL created by the set of
      # +options+ unless the current request URI is the same as the links, in
      # which case only the name is returned (or the given block is yielded, if
      # one exists). You can give +link_to_unless_current+ a block which will
      # specialize the default behavior (e.g., show a "Start Here" link rather
      # than the link's text).
      #
      # ==== Examples
      # Let's say you have a navigation menu...
      #
      #   <ul id="navbar">
      #     <li><%= link_to_unless_current("Home", { action: "index" }) %></li>
      #     <li><%= link_to_unless_current("About Us", { action: "about" }) %></li>
      #   </ul>
      #
      # If in the "about" action, it will render...
      #
      #   <ul id="navbar">
      #     <li><a href="/controller/index">Home</a></li>
      #     <li>About Us</li>
      #   </ul>
      #
      # ...but if in the "index" action, it will render:
      #
      #   <ul id="navbar">
      #     <li>Home</li>
      #     <li><a href="/controller/about">About Us</a></li>
      #   </ul>
      #
      # The implicit block given to +link_to_unless_current+ is evaluated if the current
      # action is the action given. So, if we had a comments page and wanted to render a
      # "Go Back" link instead of a link to the comments page, we could do something like this...
      #
      #    <%=
      #        link_to_unless_current("Comment", { controller: "comments", action: "new" }) do
      #           link_to("Go back", { controller: "posts", action: "index" })
      #        end
      #     %>
      def link_to_unless_current(name, options = {}, html_options = {}, &block)
        link_to_unless current_page?(options), name, options, html_options, &block
      end

      # Creates a link tag of the given +name+ using a URL created by the set of
      # +options+ unless +condition+ is true, in which case only the name is
      # returned. To specialize the default behavior (i.e., show a login link rather
      # than just the plaintext link text), you can pass a block that
      # accepts the name or the full argument list for +link_to_unless+.
      #
      # ==== Examples
      #   <%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %>
      #   # If the user is logged in...
      #   # => <a href="/controller/reply/">Reply</a>
      #
      #   <%=
      #      link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name|
      #        link_to(name, { controller: "accounts", action: "signup" })
      #      end
      #   %>
      #   # If the user is logged in...
      #   # => <a href="/controller/reply/">Reply</a>
      #   # If not...
      #   # => <a href="/accounts/signup">Reply</a>
      def link_to_unless(condition, name, options = {}, html_options = {}, &block)
        if condition
          if block_given?
            block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
          else
            name
          end
        else
          link_to(name, options, html_options)
        end
      end

      # Creates a link tag of the given +name+ using a URL created by the set of
      # +options+ if +condition+ is true, otherwise only the name is
      # returned. To specialize the default behavior, you can pass a block that
      # accepts the name or the full argument list for +link_to_unless+ (see the examples
      # in +link_to_unless+).
      #
      # ==== Examples
      #   <%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
      #   # If the user isn't logged in...
      #   # => <a href="/sessions/new/">Login</a>
      #
      #   <%=
      #      link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
      #        link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
      #      end
      #   %>
      #   # If the user isn't logged in...
      #   # => <a href="/sessions/new/">Login</a>
      #   # If they are logged in...
      #   # => <a href="/accounts/show/3">my_username</a>
      def link_to_if(condition, name, options = {}, html_options = {}, &block)
        link_to_unless !condition, name, options, html_options, &block
      end

      # Creates a mailto link tag to the specified +email_address+, which is
      # also used as the name of the link unless +name+ is specified. Additional
      # HTML attributes for the link can be passed in +html_options+.
      #
      # +mail_to+ has several methods for customizing the email itself by
      # passing special keys to +html_options+.
      #
      # ==== Options
      # * <tt>:subject</tt> - Preset the subject line of the email.
      # * <tt>:body</tt> - Preset the body of the email.
      # * <tt>:cc</tt> - Carbon Copy additional recipients on the email.
      # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
      #
      # ==== Obfuscation
      # Prior to Rails 4.0, +mail_to+ provided options for encoding the address 
      # in order to hinder email harvesters.  To take advantage of these options, 
      # install the +actionview-encoded_mail_to+ gem.
      #
      # ==== Examples
      #   mail_to "me@domain.com"
      #   # => <a href="mailto:me@domain.com">me@domain.com</a>
      #
      #   mail_to "me@domain.com", "My email"
      #   # => <a href="mailto:me@domain.com">My email</a>
      #
      #   mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
      #            subject: "This is an example email"
      #   # => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
      def mail_to(email_address, name = nil, html_options = {})
        email_address = ERB::Util.html_escape(email_address)

        html_options.stringify_keys!

        extras = %w{ cc bcc body subject }.map { |item|
          option = html_options.delete(item) || next
          "#{item}=#{Rack::Utils.escape_path(option)}"
        }.compact
        extras = extras.empty? ? '' : '?' + ERB::Util.html_escape(extras.join('&'))
        
        content_tag "a", name || email_address.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)
      end

      # True if the current request URI was generated by the given +options+.
      #
      # ==== Examples
      # Let's say we're in the <tt>http://www.example.com/shop/checkout?order=desc</tt> action.
      #
      #   current_page?(action: 'process')
      #   # => false
      #
      #   current_page?(controller: 'shop', action: 'checkout')
      #   # => true
      #
      #   current_page?(controller: 'shop', action: 'checkout', order: 'asc')
      #   # => false
      #
      #   current_page?(action: 'checkout')
      #   # => true
      #
      #   current_page?(controller: 'library', action: 'checkout')
      #   # => false
      #
      #   current_page?('http://www.example.com/shop/checkout')
      #   # => true
      #
      #   current_page?('/shop/checkout')
      #   # => true
      #
      # Let's say we're in the <tt>http://www.example.com/shop/checkout?order=desc&page=1</tt> action.
      #
      #   current_page?(action: 'process')
      #   # => false
      #
      #   current_page?(controller: 'shop', action: 'checkout')
      #   # => true
      #
      #   current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
      #   # => true
      #
      #   current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
      #   # => false
      #
      #   current_page?(controller: 'shop', action: 'checkout', order: 'desc')
      #   # => false
      #
      #   current_page?(action: 'checkout')
      #   # => true
      #
      #   current_page?(controller: 'library', action: 'checkout')
      #   # => false
      #
      # Let's say we're in the <tt>http://www.example.com/products</tt> action with method POST in case of invalid product.
      #
      #   current_page?(controller: 'product', action: 'index')
      #   # => false
      #
      def current_page?(options)
        unless request
          raise "You cannot use helpers that need to determine the current " \
                "page unless your view context provides a Request object " \
                "in a #request method"
        end

        return false unless request.get? || request.head?

        url_string = url_for(options)

        # We ignore any extra parameters in the request_uri if the
        # submitted url doesn't have any either. This lets the function
        # work with things like ?order=asc
        request_uri = url_string.index("?") ? request.fullpath : request.path

        if url_string =~ /^\w+:\/\//
          url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
        else
          url_string == request_uri
        end
      end

      private
        def convert_options_to_data_attributes(options, html_options)
          if html_options
            html_options = html_options.stringify_keys
            html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)

            disable_with = html_options.delete("disable_with")
            confirm = html_options.delete('confirm')
            method  = html_options.delete('method')

            if confirm
              message = ":confirm option is deprecated and will be removed from Rails 4.1. " \
                        "Use 'data: { confirm: \'Text\' }' instead."
              ActiveSupport::Deprecation.warn message

              html_options["data-confirm"] = confirm
            end

            add_method_to_attributes!(html_options, method) if method

            if disable_with
              message = ":disable_with option is deprecated and will be removed from Rails 4.1. " \
                        "Use 'data: { disable_with: \'Text\' }' instead."
              ActiveSupport::Deprecation.warn message

              html_options["data-disable-with"] = disable_with
            end

            html_options
          else
            link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
          end
        end

        def link_to_remote_options?(options)
          if options.is_a?(Hash)
            options.delete('remote') || options.delete(:remote)
          end
        end

        def add_method_to_attributes!(html_options, method)
          if method && method.to_s.downcase != "get" && html_options["rel"] !~ /nofollow/
            html_options["rel"] = "#{html_options["rel"]} nofollow".lstrip
          end
          html_options["data-method"] = method
        end

        # Processes the +html_options+ hash, converting the boolean
        # attributes from true/false form into the form required by
        # HTML/XHTML. (An attribute is considered to be boolean if
        # its name is listed in the given +bool_attrs+ array.)
        #
        # More specifically, for each boolean attribute in +html_options+
        # given as:
        #
        #   "attr" => bool_value
        #
        # if the associated +bool_value+ evaluates to true, it is
        # replaced with the attribute's name; otherwise the attribute is
        # removed from the +html_options+ hash. (See the XHTML 1.0 spec,
        # section 4.5 "Attribute Minimization" for more:
        # http://www.w3.org/TR/xhtml1/#h-4.5)
        #
        # Returns the updated +html_options+ hash, which is also modified
        # in place.
        #
        # Example:
        #
        #   convert_boolean_attributes!( html_options,
        #                                %w( checked disabled readonly ) )
        def convert_boolean_attributes!(html_options, bool_attrs)
          bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
          html_options
        end

        def token_tag(token=nil)
          if token != false && protect_against_forgery?
            token ||= form_authenticity_token
            tag(:input, type: "hidden", name: request_forgery_protection_token.to_s, value: token)
          else
            ''
          end
        end

        def method_tag(method)
          tag('input', type: 'hidden', name: '_method', value: method.to_s)
        end
    end
  end
end
require 'active_support/benchmarkable'

module ActionView #:nodoc:
  module Helpers #:nodoc:
    extend ActiveSupport::Autoload

    autoload :ActiveModelHelper
    autoload :AssetTagHelper
    autoload :AssetUrlHelper
    autoload :AtomFeedHelper
    autoload :CacheHelper
    autoload :CaptureHelper
    autoload :ControllerHelper
    autoload :CsrfHelper
    autoload :DateHelper
    autoload :DebugHelper
    autoload :FormHelper
    autoload :FormOptionsHelper
    autoload :FormTagHelper
    autoload :JavaScriptHelper, "action_view/helpers/javascript_helper"
    autoload :NumberHelper
    autoload :OutputSafetyHelper
    autoload :RecordTagHelper
    autoload :RenderingHelper
    autoload :SanitizeHelper
    autoload :TagHelper
    autoload :TextHelper
    autoload :TranslationHelper
    autoload :UrlHelper

    extend ActiveSupport::Concern

    include ActiveSupport::Benchmarkable
    include ActiveModelHelper
    include AssetTagHelper
    include AssetUrlHelper
    include AtomFeedHelper
    include CacheHelper
    include CaptureHelper
    include ControllerHelper
    include CsrfHelper
    include DateHelper
    include DebugHelper
    include FormHelper
    include FormOptionsHelper
    include FormTagHelper
    include JavaScriptHelper
    include NumberHelper
    include OutputSafetyHelper
    include RecordTagHelper
    include RenderingHelper
    include SanitizeHelper
    include TagHelper
    include TextHelper
    include TranslationHelper
    include UrlHelper
  end
end
module ActionView
  # = Action View Log Subscriber
  #
  # Provides functionality so that Rails can output logs from Action View.
  class LogSubscriber < ActiveSupport::LogSubscriber
    VIEWS_PATTERN = /^app\/views\//.freeze

    def render_template(event)
      return unless logger.info?
      message = "  Rendered #{from_rails_root(event.payload[:identifier])}"
      message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
      message << " (#{event.duration.round(1)}ms)"
      info(message)
    end
    alias :render_partial :render_template
    alias :render_collection :render_template

    def logger
      ActionView::Base.logger
    end

  protected

    def from_rails_root(string)
      string.sub("#{Rails.root}/", "").sub(VIEWS_PATTERN, "")
    end
  end
end

ActionView::LogSubscriber.attach_to :action_view
require 'thread_safe'
require 'active_support/core_ext/module/remove_method'

module ActionView
  # = Action View Lookup Context
  #
  # LookupContext is the object responsible to hold all information required to lookup
  # templates, i.e. view paths and details. The LookupContext is also responsible to
  # generate a key, given to view paths, used in the resolver cache lookup. Since
  # this key is generated just once during the request, it speeds up all cache accesses.
  class LookupContext #:nodoc:
    attr_accessor :prefixes, :rendered_format

    mattr_accessor :fallbacks
    @@fallbacks = FallbackFileSystemResolver.instances

    mattr_accessor :registered_details
    self.registered_details = []

    def self.register_detail(name, options = {}, &block)
      self.registered_details << name
      initialize = registered_details.map { |n| "@details[:#{n}] = details[:#{n}] || default_#{n}" }

      Accessors.send :define_method, :"default_#{name}", &block
      Accessors.module_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{name}
          @details.fetch(:#{name}, [])
        end

        def #{name}=(value)
          value = value.present? ? Array(value) : default_#{name}
          _set_detail(:#{name}, value) if value != @details[:#{name}]
        end

        remove_possible_method :initialize_details
        def initialize_details(details)
          #{initialize.join("\n")}
        end
      METHOD
    end

    # Holds accessors for the registered details.
    module Accessors #:nodoc:
    end

    register_detail(:locale)  { [I18n.locale, I18n.default_locale].uniq }
    register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css,  :xml, :json] }
    register_detail(:handlers){ Template::Handlers.extensions }

    class DetailsKey #:nodoc:
      alias :eql? :equal?
      alias :object_hash :hash

      attr_reader :hash
      @details_keys = ThreadSafe::Cache.new

      def self.get(details)
        @details_keys[details] ||= new
      end

      def self.clear
        @details_keys.clear
      end

      def initialize
        @hash = object_hash
      end
    end

    # Add caching behavior on top of Details.
    module DetailsCache
      attr_accessor :cache

      # Calculate the details key. Remove the handlers from calculation to improve performance
      # since the user cannot modify it explicitly.
      def details_key #:nodoc:
        @details_key ||= DetailsKey.get(@details) if @cache
      end

      # Temporary skip passing the details_key forward.
      def disable_cache
        old_value, @cache = @cache, false
        yield
      ensure
        @cache = old_value
      end

    protected

      def _set_detail(key, value)
        @details = @details.dup if @details_key
        @details_key = nil
        @details[key] = value
      end
    end

    # Helpers related to template lookup using the lookup context information.
    module ViewPaths
      attr_reader :view_paths, :html_fallback_for_js

      # Whenever setting view paths, makes a copy so we can manipulate then in
      # instance objects as we wish.
      def view_paths=(paths)
        @view_paths = ActionView::PathSet.new(Array(paths))
      end

      def find(name, prefixes = [], partial = false, keys = [], options = {})
        @view_paths.find(*args_for_lookup(name, prefixes, partial, keys, options))
      end
      alias :find_template :find

      def find_all(name, prefixes = [], partial = false, keys = [], options = {})
        @view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys, options))
      end

      def exists?(name, prefixes = [], partial = false, keys = [], options = {})
        @view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys, options))
      end
      alias :template_exists? :exists?

      # Add fallbacks to the view paths. Useful in cases you are rendering a :file.
      def with_fallbacks
        added_resolvers = 0
        self.class.fallbacks.each do |resolver|
          next if view_paths.include?(resolver)
          view_paths.push(resolver)
          added_resolvers += 1
        end
        yield
      ensure
        added_resolvers.times { view_paths.pop }
      end

    protected

      def args_for_lookup(name, prefixes, partial, keys, details_options) #:nodoc:
        name, prefixes = normalize_name(name, prefixes)
        details, details_key = detail_args_for(details_options)
        [name, prefixes, partial || false, details, details_key, keys]
      end

      # Compute details hash and key according to user options (e.g. passed from #render).
      def detail_args_for(options)
        return @details, details_key if options.empty? # most common path.
        user_details = @details.merge(options)
        [user_details, DetailsKey.get(user_details)]
      end

      # Support legacy foo.erb names even though we now ignore .erb
      # as well as incorrectly putting part of the path in the template
      # name instead of the prefix.
      def normalize_name(name, prefixes) #:nodoc:
        prefixes = prefixes.presence
        parts    = name.to_s.split('/')
        parts.shift if parts.first.empty?
        name     = parts.pop

        return name, prefixes || [""] if parts.empty?

        parts    = parts.join('/')
        prefixes = prefixes ? prefixes.map { |p| "#{p}/#{parts}" } : [parts]

        return name, prefixes
      end
    end

    include Accessors
    include DetailsCache
    include ViewPaths

    def initialize(view_paths, details = {}, prefixes = [])
      @details, @details_key = {}, nil
      @skip_default_locale = false
      @cache = true
      @prefixes = prefixes
      @rendered_format = nil

      self.view_paths = view_paths
      initialize_details(details)
    end

    # Override formats= to expand ["*/*"] values and automatically
    # add :html as fallback to :js.
    def formats=(values)
      if values
        values.concat(default_formats) if values.delete "*/*"
        if values == [:js]
          values << :html
          @html_fallback_for_js = true
        end
      end
      super(values)
    end

    # Do not use the default locale on template lookup.
    def skip_default_locale!
      @skip_default_locale = true
      self.locale = nil
    end

    # Override locale to return a symbol instead of array.
    def locale
      @details[:locale].first
    end

    # Overload locale= to also set the I18n.locale. If the current I18n.config object responds
    # to original_config, it means that it's has a copy of the original I18n configuration and it's
    # acting as proxy, which we need to skip.
    def locale=(value)
      if value
        config = I18n.config.respond_to?(:original_config) ? I18n.config.original_config : I18n.config
        config.locale = value
      end

      super(@skip_default_locale ? I18n.locale : default_locale)
    end

    # A method which only uses the first format in the formats array for layout lookup.
    def with_layout_format
      if formats.size == 1
        yield
      else
        old_formats = formats
        _set_detail(:formats, formats[0,1])

        begin
          yield
        ensure
          _set_detail(:formats, old_formats)
        end
      end
    end
  end
end
module ActionView
  module ModelNaming
    # Converts the given object to an ActiveModel compliant one.
    def convert_to_model(object)
      object.respond_to?(:to_model) ? object.to_model : object
    end

    def model_name_from_record_or_class(record_or_class)
      (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name
    end
  end
end
module ActionView #:nodoc:
  # = Action View PathSet
  class PathSet #:nodoc:
    include Enumerable

    attr_reader :paths

    delegate :[], :include?, :pop, :size, :each, to: :paths

    def initialize(paths = [])
      @paths = typecast paths
    end

    def initialize_copy(other)
      @paths = other.paths.dup
      self
    end

    def to_ary
      paths.dup
    end

    def compact
      PathSet.new paths.compact
    end

    def +(array)
      PathSet.new(paths + array)
    end

    %w(<< concat push insert unshift).each do |method|
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{method}(*args)
          paths.#{method}(*typecast(args))
        end
      METHOD
    end

    def find(*args)
      find_all(*args).first || raise(MissingTemplate.new(self, *args))
    end

    def find_all(path, prefixes = [], *args)
      prefixes = [prefixes] if String === prefixes
      prefixes.each do |prefix|
        paths.each do |resolver|
          templates = resolver.find_all(path, prefix, *args)
          return templates unless templates.empty?
        end
      end
      []
    end

    def exists?(path, prefixes, *args)
      find_all(path, prefixes, *args).any?
    end

    private

    def typecast(paths)
      paths.map do |path|
        case path
        when Pathname, String
          OptimizedFileSystemResolver.new path.to_s
        else
          path
        end
      end
    end
  end
end
require "action_view"
require "rails"

module ActionView
  # = Action View Railtie
  class Railtie < Rails::Railtie # :nodoc:
    config.action_view = ActiveSupport::OrderedOptions.new
    config.action_view.embed_authenticity_token_in_remote_forms = false

    config.eager_load_namespaces << ActionView

    initializer "action_view.embed_authenticity_token_in_remote_forms" do |app|
      ActiveSupport.on_load(:action_view) do
        ActionView::Helpers::FormTagHelper.embed_authenticity_token_in_remote_forms =
          app.config.action_view.delete(:embed_authenticity_token_in_remote_forms)
      end
    end

    initializer "action_view.logger" do
      ActiveSupport.on_load(:action_view) { self.logger ||= Rails.logger }
    end

    initializer "action_view.set_configs" do |app|
      ActiveSupport.on_load(:action_view) do
        app.config.action_view.each do |k,v|
          send "#{k}=", v
        end
      end
    end

    initializer "action_view.caching" do |app|
      ActiveSupport.on_load(:action_view) do
        if app.config.action_view.cache_template_loading.nil?
          ActionView::Resolver.caching = app.config.cache_classes
        end
      end
    end
  end
end
require 'active_support/core_ext/module'
require 'action_view/model_naming'

module ActionView
  # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or
  # pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to
  # a higher logical level.
  #
  #   # routes
  #   resources :posts
  #
  #   # view
  #   <%= div_for(post) do %>    <div id="post_45" class="post">
  #     <%= post.body %>           What a wonderful world!
  #   <% end %>                  </div>
  #
  #   # controller
  #   def update
  #     post = Post.find(params[:id])
  #     post.update(params[:post])
  #
  #     redirect_to(post) # Calls polymorphic_url(post) which in turn calls post_url(post)
  #   end
  #
  # As the example above shows, you can stop caring to a large extent what the actual id of the post is.
  # You just know that one is being assigned and that the subsequent calls in redirect_to expect that
  # same naming convention and allows you to write less code if you follow it.
  module RecordIdentifier
    extend self
    extend ModelNaming

    include ModelNaming

    JOIN = '_'.freeze
    NEW = 'new'.freeze

    # The DOM class convention is to use the singular form of an object or class.
    #
    #   dom_class(post)   # => "post"
    #   dom_class(Person) # => "person"
    #
    # If you need to address multiple instances of the same class in the same view, you can prefix the dom_class:
    #
    #   dom_class(post, :edit)   # => "edit_post"
    #   dom_class(Person, :edit) # => "edit_person"
    def dom_class(record_or_class, prefix = nil)
      singular = model_name_from_record_or_class(record_or_class).param_key
      prefix ? "#{prefix}#{JOIN}#{singular}" : singular
    end

    # The DOM id convention is to use the singular form of an object or class with the id following an underscore.
    # If no id is found, prefix with "new_" instead.
    #
    #   dom_id(Post.find(45))       # => "post_45"
    #   dom_id(Post.new)            # => "new_post"
    #
    # If you need to address multiple instances of the same class in the same view, you can prefix the dom_id:
    #
    #   dom_id(Post.find(45), :edit) # => "edit_post_45"
    #   dom_id(Post.new, :custom)    # => "custom_post"
    def dom_id(record, prefix = nil)
      if record_id = record_key_for_dom_id(record)
        "#{dom_class(record, prefix)}#{JOIN}#{record_id}"
      else
        dom_class(record, prefix || NEW)
      end
    end

  protected

    # Returns a string representation of the key attribute(s) that is suitable for use in an HTML DOM id.
    # This can be overwritten to customize the default generated string representation if desired.
    # If you need to read back a key from a dom_id in order to query for the underlying database record,
    # you should write a helper like 'person_record_from_dom_id' that will extract the key either based
    # on the default implementation (which just joins all key attributes with '_') or on your own
    # overwritten version of the method. By default, this implementation passes the key string through a
    # method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
    # make sure yourself that your dom ids are valid, in case you overwrite this method.
    def record_key_for_dom_id(record)
      key = convert_to_model(record).to_key
      key ? key.join('_') : key
    end
  end
end
module ActionView
  class AbstractRenderer #:nodoc:
    delegate :find_template, :template_exists?, :with_fallbacks, :with_layout_format, :formats, :to => :@lookup_context

    def initialize(lookup_context)
      @lookup_context = lookup_context
    end

    def render
      raise NotImplementedError
    end

    protected

    def extract_details(options)
      @lookup_context.registered_details.each_with_object({}) do |key, details|
        next unless value = options[key]
        details[key] = Array(value)
      end
    end

    def instrument(name, options={})
      ActiveSupport::Notifications.instrument("render_#{name}.action_view", options){ yield }
    end

    def prepend_formats(formats)
      formats = Array(formats)
      return if formats.empty? || @lookup_context.html_fallback_for_js
      @lookup_context.formats = formats | @lookup_context.formats
    end
  end
end
require 'thread_safe'

module ActionView
  # = Action View Partials
  #
  # There's also a convenience method for rendering sub templates within the current controller that depends on a
  # single object (we call this kind of sub templates for partials). It relies on the fact that partials should
  # follow the naming convention of being prefixed with an underscore -- as to separate them from regular
  # templates that could be rendered on their own.
  #
  # In a template for Advertiser#account:
  #
  #  <%= render partial: "account" %>
  #
  # This would render "advertiser/_account.html.erb".
  #
  # In another template for Advertiser#buy, we could have:
  #
  #   <%= render partial: "account", locals: { account: @buyer } %>
  #
  #   <% @advertisements.each do |ad| %>
  #     <%= render partial: "ad", locals: { ad: ad } %>
  #   <% end %>
  #
  # This would first render "advertiser/_account.html.erb" with @buyer passed in as the local variable +account+, then
  # render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display.
  #
  # == The :as and :object options
  #
  # By default <tt>ActionView::PartialRenderer</tt> doesn't have any local variables.
  # The <tt>:object</tt> option can be used to pass an object to the partial. For instance:
  #
  #   <%= render partial: "account", object: @buyer %>
  #
  # would provide the <tt>@buyer</tt> object to the partial, available under the local variable +account+ and is
  # equivalent to:
  #
  #   <%= render partial: "account", locals: { account: @buyer } %>
  #
  # With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we
  # wanted it to be +user+ instead of +account+ we'd do:
  #
  #   <%= render partial: "account", object: @buyer, as: 'user' %>
  #
  # This is equivalent to
  #
  #   <%= render partial: "account", locals: { user: @buyer } %>
  #
  # == Rendering a collection of partials
  #
  # The example of partial use describes a familiar pattern where a template needs to iterate over an array and
  # render a sub template for each of the elements. This pattern has been implemented as a single method that
  # accepts an array and renders a partial by the same name as the elements contained within. So the three-lined
  # example in "Using partials" can be rewritten with a single line:
  #
  #   <%= render partial: "ad", collection: @advertisements %>
  #
  # This will render "advertiser/_ad.html.erb" and pass the local variable +ad+ to the template for display. An
  # iteration counter will automatically be made available to the template with a name of the form
  # +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+.
  #
  # The <tt>:as</tt> option may be used when rendering partials.
  #
  # You can specify a partial to be rendered between elements via the <tt>:spacer_template</tt> option.
  # The following example will render <tt>advertiser/_ad_divider.html.erb</tt> between each ad partial:
  #
  #   <%= render partial: "ad", collection: @advertisements, spacer_template: "ad_divider" %>
  #
  # If the given <tt>:collection</tt> is nil or empty, <tt>render</tt> will return nil. This will allow you
  # to specify a text which will displayed instead by using this form:
  #
  #   <%= render(partial: "ad", collection: @advertisements) || "There's no ad to be displayed" %>
  #
  # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also
  # just keep domain objects, like Active Records, in there.
  #
  # == Rendering shared partials
  #
  # Two controllers can share a set of partials and render them like this:
  #
  #   <%= render partial: "advertisement/ad", locals: { ad: @advertisement } %>
  #
  # This will render the partial "advertisement/_ad.html.erb" regardless of which controller this is being called from.
  #
  # == Rendering objects that respond to `to_partial_path`
  #
  # Instead of explicitly naming the location of a partial, you can also let PartialRenderer do the work
  # and pick the proper path by checking `to_partial_path` method.
  #
  #  # @account.to_partial_path returns 'accounts/account', so it can be used to replace:
  #  # <%= render partial: "accounts/account", locals: { account: @account} %>
  #  <%= render partial: @account %>
  #
  #  # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
  #  # that's why we can replace:
  #  # <%= render partial: "posts/post", collection: @posts %>
  #  <%= render partial: @posts %>
  #
  # == Rendering the default case
  #
  # If you're not going to be using any of the options like collections or layouts, you can also use the short-hand
  # defaults of render to render partials. Examples:
  #
  #  # Instead of <%= render partial: "account" %>
  #  <%= render "account" %>
  #
  #  # Instead of <%= render partial: "account", locals: { account: @buyer } %>
  #  <%= render "account", account: @buyer %>
  #
  #  # @account.to_partial_path returns 'accounts/account', so it can be used to replace:
  #  # <%= render partial: "accounts/account", locals: { account: @account} %>
  #  <%= render @account %>
  #
  #  # @posts is an array of Post instances, so every post record returns 'posts/post' on `to_partial_path`,
  #  # that's why we can replace:
  #  # <%= render partial: "posts/post", collection: @posts %>
  #  <%= render @posts %>
  #
  # == Rendering partials with layouts
  #
  # Partials can have their own layouts applied to them. These layouts are different than the ones that are
  # specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types
  # of users:
  #
  #   <%# app/views/users/index.html.erb &>
  #   Here's the administrator:
  #   <%= render partial: "user", layout: "administrator", locals: { user: administrator } %>
  #
  #   Here's the editor:
  #   <%= render partial: "user", layout: "editor", locals: { user: editor } %>
  #
  #   <%# app/views/users/_user.html.erb &>
  #   Name: <%= user.name %>
  #
  #   <%# app/views/users/_administrator.html.erb &>
  #   <div id="administrator">
  #     Budget: $<%= user.budget %>
  #     <%= yield %>
  #   </div>
  #
  #   <%# app/views/users/_editor.html.erb &>
  #   <div id="editor">
  #     Deadline: <%= user.deadline %>
  #     <%= yield %>
  #   </div>
  #
  # ...this will return:
  #
  #   Here's the administrator:
  #   <div id="administrator">
  #     Budget: $<%= user.budget %>
  #     Name: <%= user.name %>
  #   </div>
  #
  #   Here's the editor:
  #   <div id="editor">
  #     Deadline: <%= user.deadline %>
  #     Name: <%= user.name %>
  #   </div>
  #
  # If a collection is given, the layout will be rendered once for each item in
  # the collection. Just think these two snippets have the same output:
  #
  #   <%# app/views/users/_user.html.erb %>
  #   Name: <%= user.name %>
  #
  #   <%# app/views/users/index.html.erb %>
  #   <%# This does not use layouts %>
  #   <ul>
  #     <% users.each do |user| -%>
  #       <li>
  #         <%= render partial: "user", locals: { user: user } %>
  #       </li>
  #     <% end -%>
  #   </ul>
  #
  #   <%# app/views/users/_li_layout.html.erb %>
  #   <li>
  #     <%= yield %>
  #   </li>
  #
  #   <%# app/views/users/index.html.erb %>
  #   <ul>
  #     <%= render partial: "user", layout: "li_layout", collection: users %>
  #   </ul>
  #
  # Given two users whose names are Alice and Bob, these snippets return:
  #
  #   <ul>
  #     <li>
  #       Name: Alice
  #     </li>
  #     <li>
  #       Name: Bob
  #     </li>
  #   </ul>
  #
  # The current object being rendered, as well as the object_counter, will be
  # available as local variables inside the layout template under the same names
  # as available in the partial.
  #
  # You can also apply a layout to a block within any template:
  #
  #   <%# app/views/users/_chief.html.erb &>
  #   <%= render(layout: "administrator", locals: { user: chief }) do %>
  #     Title: <%= chief.title %>
  #   <% end %>
  #
  # ...this will return:
  #
  #   <div id="administrator">
  #     Budget: $<%= user.budget %>
  #     Title: <%= chief.name %>
  #   </div>
  #
  # As you can see, the <tt>:locals</tt> hash is shared between both the partial and its layout.
  #
  # If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass
  # an array to layout and treat it as an enumerable.
  #
  #   <%# app/views/users/_user.html.erb &>
  #   <div class="user">
  #     Budget: $<%= user.budget %>
  #     <%= yield user %>
  #   </div>
  #
  #   <%# app/views/users/index.html.erb &>
  #   <%= render layout: @users do |user| %>
  #     Title: <%= user.title %>
  #   <% end %>
  #
  # This will render the layout for each user and yield to the block, passing the user, each time.
  #
  # You can also yield multiple times in one layout and use block arguments to differentiate the sections.
  #
  #   <%# app/views/users/_user.html.erb &>
  #   <div class="user">
  #     <%= yield user, :header %>
  #     Budget: $<%= user.budget %>
  #     <%= yield user, :footer %>
  #   </div>
  #
  #   <%# app/views/users/index.html.erb &>
  #   <%= render layout: @users do |user, section| %>
  #     <%- case section when :header -%>
  #       Title: <%= user.title %>
  #     <%- when :footer -%>
  #       Deadline: <%= user.deadline %>
  #     <%- end -%>
  #   <% end %>
  class PartialRenderer < AbstractRenderer
    PREFIXED_PARTIAL_NAMES = ThreadSafe::Cache.new do |h, k|
      h[k] = ThreadSafe::Cache.new
    end

    def initialize(*)
      super
      @context_prefix = @lookup_context.prefixes.first
    end

    def render(context, options, block)
      setup(context, options, block)
      identifier = (@template = find_partial) ? @template.identifier : @path

      @lookup_context.rendered_format ||= begin
        if @template && @template.formats.present?
          @template.formats.first
        else
          formats.first
        end
      end

      if @collection
        instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do
          render_collection
        end
      else
        instrument(:partial, :identifier => identifier) do
          render_partial
        end
      end
    end

    def render_collection
      return nil if @collection.blank?

      if @options.key?(:spacer_template)
        spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
      end

      result = @template ? collection_with_template : collection_without_template
      result.join(spacer).html_safe
    end

    def render_partial
      view, locals, block = @view, @locals, @block
      object, as = @object, @variable

      if !block && (layout = @options[:layout])
        layout = find_template(layout.to_s, @template_keys)
      end

      object ||= locals[as]
      locals[as] = object

      content = @template.render(view, locals) do |*name|
        view._layout_for(*name, &block)
      end

      content = layout.render(view, locals){ content } if layout
      content
    end

    private

    def setup(context, options, block)
      @view   = context
      partial = options[:partial]

      @options = options
      @locals  = options[:locals] || {}
      @block   = block
      @details = extract_details(options)

      prepend_formats(options[:formats])

      if String === partial
        @object     = options[:object]
        @path       = partial
        @collection = collection
      else
        @object = partial

        if @collection = collection_from_object || collection
          paths = @collection_data = @collection.map { |o| partial_path(o) }
          @path = paths.uniq.size == 1 ? paths.first : nil
        else
          @path = partial_path
        end
      end

      if as = options[:as]
        raise_invalid_identifier(as) unless as.to_s =~ /\A[a-z_]\w*\z/
        as = as.to_sym
      end

      if @path
        @variable, @variable_counter = retrieve_variable(@path, as)
        @template_keys = retrieve_template_keys
      else
        paths.map! { |path| retrieve_variable(path, as).unshift(path) }
      end

      self
    end

    def collection
      if @options.key?(:collection)
        collection = @options[:collection]
        collection.respond_to?(:to_ary) ? collection.to_ary : []
      end
    end

    def collection_from_object
      @object.to_ary if @object.respond_to?(:to_ary)
    end

    def find_partial
      if path = @path
        find_template(path, @template_keys)
      end
    end

    def find_template(path, locals)
      prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
      @lookup_context.find_template(path, prefixes, true, locals, @details)
    end

    def collection_with_template
      view, locals, template = @view, @locals, @template
      as, counter = @variable, @variable_counter

      if layout = @options[:layout]
        layout = find_template(layout, @template_keys)
      end

      index = -1
      @collection.map do |object|
        locals[as]      = object
        locals[counter] = (index += 1)

        content = template.render(view, locals)
        content = layout.render(view, locals) { content } if layout
        content
      end
    end

    def collection_without_template
      view, locals, collection_data = @view, @locals, @collection_data
      cache = {}
      keys  = @locals.keys

      index = -1
      @collection.map do |object|
        index += 1
        path, as, counter = collection_data[index]

        locals[as]      = object
        locals[counter] = index

        template = (cache[path] ||= find_template(path, keys + [as, counter]))
        template.render(view, locals)
      end
    end

    def partial_path(object = @object)
      object = object.to_model if object.respond_to?(:to_model)

      path = if object.respond_to?(:to_partial_path)
        object.to_partial_path
      else
        raise ArgumentError.new("'#{object.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.")
      end

      if @view.prefix_partial_path_with_controller_namespace
        prefixed_partial_names[path] ||= merge_prefix_into_object_path(@context_prefix, path.dup)
      else
        path
      end
    end

    def prefixed_partial_names
      @prefixed_partial_names ||= PREFIXED_PARTIAL_NAMES[@context_prefix]
    end

    def merge_prefix_into_object_path(prefix, object_path)
      if prefix.include?(?/) && object_path.include?(?/)
        prefixes = []
        prefix_array = File.dirname(prefix).split('/')
        object_path_array = object_path.split('/')[0..-3] # skip model dir & partial

        prefix_array.each_with_index do |dir, index|
          break if dir == object_path_array[index]
          prefixes << dir
        end

        (prefixes << object_path).join("/")
      else
        object_path
      end
    end

    def retrieve_template_keys
      keys = @locals.keys
      keys << @variable         if @object || @collection
      keys << @variable_counter if @collection
      keys
    end

    def retrieve_variable(path, as)
      variable = as || begin
        base = path[-1] == "/" ? "" : File.basename(path)
        raise_invalid_identifier(path) unless base =~ /\A_?([a-z]\w*)(\.\w+)*\z/
        $1.to_sym
      end
      variable_counter = :"#{variable}_counter" if @collection
      [variable, variable_counter]
    end

    IDENTIFIER_ERROR_MESSAGE = "The partial name (%s) is not a valid Ruby identifier; " +
                               "make sure your partial name starts with a lowercase letter or underscore, " +
                               "and is followed by any combination of letters, numbers and underscores."

    def raise_invalid_identifier(path)
      raise ArgumentError.new(IDENTIFIER_ERROR_MESSAGE % (path))
    end
  end
end
module ActionView
  # This is the main entry point for rendering. It basically delegates
  # to other objects like TemplateRenderer and PartialRenderer which
  # actually renders the template.
  class Renderer
    attr_accessor :lookup_context

    def initialize(lookup_context)
      @lookup_context = lookup_context
    end

    # Main render entry point shared by AV and AC.
    def render(context, options)
      if options.key?(:partial)
        render_partial(context, options)
      else
        render_template(context, options)
      end
    end

    # Render but returns a valid Rack body. If fibers are defined, we return
    # a streaming body that renders the template piece by piece.
    #
    # Note that partials are not supported to be rendered with streaming,
    # so in such cases, we just wrap them in an array.
    def render_body(context, options)
      if options.key?(:partial)
        [render_partial(context, options)]
      else
        StreamingTemplateRenderer.new(@lookup_context).render(context, options)
      end
    end

    # Direct accessor to template rendering.
    def render_template(context, options) #:nodoc:
      TemplateRenderer.new(@lookup_context).render(context, options)
    end

    # Direct access to partial rendering.
    def render_partial(context, options, &block) #:nodoc:
      PartialRenderer.new(@lookup_context).render(context, options, block)
    end
  end
end
require 'fiber'

module ActionView
  # == TODO
  #
  # * Support streaming from child templates, partials and so on.
  # * Integrate exceptions with exceptron
  # * Rack::Cache needs to support streaming bodies
  class StreamingTemplateRenderer < TemplateRenderer #:nodoc:
    # A valid Rack::Body (i.e. it responds to each).
    # It is initialized with a block that, when called, starts
    # rendering the template.
    class Body #:nodoc:
      def initialize(&start)
        @start = start
      end

      def each(&block)
        begin
          @start.call(block)
        rescue Exception => exception
          log_error(exception)
          block.call ActionView::Base.streaming_completion_on_exception
        end
        self
      end

      private

      # This is the same logging logic as in ShowExceptions middleware.
      # TODO Once "exceptron" is in, refactor this piece to simply re-use exceptron.
      def log_error(exception) #:nodoc:
        logger = ActionView::Base.logger
        return unless logger

        message = "\n#{exception.class} (#{exception.message}):\n"
        message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
        message << "  " << exception.backtrace.join("\n  ")
        logger.fatal("#{message}\n\n")
      end
    end

    # For streaming, instead of rendering a given a template, we return a Body
    # object that responds to each. This object is initialized with a block
    # that knows how to render the template.
    def render_template(template, layout_name = nil, locals = {}) #:nodoc:
      return [super] unless layout_name && template.supports_streaming?

      locals ||= {}
      layout   = layout_name && find_layout(layout_name, locals.keys)

      Body.new do |buffer|
        delayed_render(buffer, template, layout, @view, locals)
      end
    end

    private

    def delayed_render(buffer, template, layout, view, locals)
      # Wrap the given buffer in the StreamingBuffer and pass it to the
      # underlying template handler. Now, everytime something is concatenated
      # to the buffer, it is not appended to an array, but streamed straight
      # to the client.
      output  = ActionView::StreamingBuffer.new(buffer)
      yielder = lambda { |*name| view._layout_for(*name) }

      instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
        fiber = Fiber.new do
          if layout
            layout.render(view, locals, output, &yielder)
          else
            # If you don't have a layout, just render the thing
            # and concatenate the final result. This is the same
            # as a layout with just <%= yield %>
            output.safe_concat view._layout_for
          end
        end

        # Set the view flow to support streaming. It will be aware
        # when to stop rendering the layout because it needs to search
        # something in the template and vice-versa.
        view.view_flow = StreamingFlow.new(view, fiber)

        # Yo! Start the fiber!
        fiber.resume

        # If the fiber is still alive, it means we need something
        # from the template, so start rendering it. If not, it means
        # the layout exited without requiring anything from the template.
        if fiber.alive?
          content = template.render(view, locals, &yielder)

          # Once rendering the template is done, sets its content in the :layout key.
          view.view_flow.set(:layout, content)

          # In case the layout continues yielding, we need to resume
          # the fiber until all yields are handled.
          fiber.resume while fiber.alive?
        end
      end
    end
  end
end
require 'active_support/core_ext/object/try'

module ActionView
  class TemplateRenderer < AbstractRenderer #:nodoc:
    def render(context, options)
      @view    = context
      @details = extract_details(options)
      template = determine_template(options)
      context  = @lookup_context

      prepend_formats(template.formats)

      unless context.rendered_format
        context.rendered_format = template.formats.first || formats.last
      end

      render_template(template, options[:layout], options[:locals])
    end

    # Determine the template to be rendered using the given options.
    def determine_template(options) #:nodoc:
      keys = options.fetch(:locals, {}).keys

      if options.key?(:text)
        Template::Text.new(options[:text], formats.first)
      elsif options.key?(:file)
        with_fallbacks { find_template(options[:file], nil, false, keys, @details) }
      elsif options.key?(:inline)
        handler = Template.handler_for_extension(options[:type] || "erb")
        Template.new(options[:inline], "inline template", handler, :locals => keys)
      elsif options.key?(:template)
        if options[:template].respond_to?(:render)
          options[:template]
        else
          find_template(options[:template], options[:prefixes], false, keys, @details)
        end
      else
        raise ArgumentError, "You invoked render but did not give any of :partial, :template, :inline, :file or :text option."
      end
    end

    # Renders the given template. A string representing the layout can be
    # supplied as well.
    def render_template(template, layout_name = nil, locals = nil) #:nodoc:
      view, locals = @view, locals || {}

      render_with_layout(layout_name, locals) do |layout|
        instrument(:template, :identifier => template.identifier, :layout => layout.try(:virtual_path)) do
          template.render(view, locals) { |*name| view._layout_for(*name) }
        end
      end
    end

    def render_with_layout(path, locals) #:nodoc:
      layout  = path && find_layout(path, locals.keys)
      content = yield(layout)

      if layout
        view = @view
        view.view_flow.set(:layout, content)
        layout.render(view, locals){ |*name| view._layout_for(*name) }
      else
        content
      end
    end

    # This is the method which actually finds the layout using details in the lookup
    # context object. If no layout is found, it checks if at least a layout with
    # the given name exists across all details before raising the error.
    def find_layout(layout, keys)
      with_layout_format { resolve_layout(layout, keys) }
    end

    def resolve_layout(layout, keys)
      case layout
      when String
        begin
          if layout =~ /^\//
            with_fallbacks { find_template(layout, nil, false, keys, @details) }
          else
            find_template(layout, nil, false, keys, @details)
          end
        rescue ActionView::MissingTemplate
          all_details = @details.merge(:formats => @lookup_context.default_formats)
          raise unless template_exists?(layout, nil, false, keys, all_details)
        end
      when Proc
        resolve_layout(layout.call, keys)
      when FalseClass
        nil
      else
        layout
      end
    end
  end
end
module ActionView
  module RoutingUrlFor

    # Returns the URL for the set of +options+ provided. This takes the
    # same options as +url_for+ in Action Controller (see the
    # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
    # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
    # instead of the fully qualified URL like "http://example.com/controller/action".
    #
    # ==== Options
    # * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path.
    # * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified).
    # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this
    #   is currently not recommended since it breaks caching.
    # * <tt>:host</tt> - Overrides the default (current) host if provided.
    # * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
    # * <tt>:user</tt> - Inline HTTP authentication (only plucked out if <tt>:password</tt> is also present).
    # * <tt>:password</tt> - Inline HTTP authentication (only plucked out if <tt>:user</tt> is also present).
    #
    # ==== Relying on named routes
    #
    # Passing a record (like an Active Record) instead of a hash as the options parameter will
    # trigger the named route for that record. The lookup will happen on the name of the class. So passing a
    # Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
    # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
    #
    # ==== Implicit Controller Namespacing
    #
    # Controllers passed in using the +:controller+ option will retain their namespace unless it is an absolute one.
    #
    # ==== Examples
    #   <%= url_for(action: 'index') %>
    #   # => /blog/
    #
    #   <%= url_for(action: 'find', controller: 'books') %>
    #   # => /books/find
    #
    #   <%= url_for(action: 'login', controller: 'members', only_path: false, protocol: 'https') %>
    #   # => https://www.example.com/members/login/
    #
    #   <%= url_for(action: 'play', anchor: 'player') %>
    #   # => /messages/play/#player
    #
    #   <%= url_for(action: 'jump', anchor: 'tax&ship') %>
    #   # => /testing/jump/#tax&ship
    #
    #   <%= url_for(Workshop.new) %>
    #   # relies on Workshop answering a persisted? call (and in this case returning false)
    #   # => /workshops
    #
    #   <%= url_for(@workshop) %>
    #   # calls @workshop.to_param which by default returns the id
    #   # => /workshops/5
    #
    #   # to_param can be re-defined in a model to provide different URL names:
    #   # => /workshops/1-workshop-name
    #
    #   <%= url_for("http://www.example.com") %>
    #   # => http://www.example.com
    #
    #   <%= url_for(:back) %>
    #   # if request.env["HTTP_REFERER"] is set to "http://www.example.com"
    #   # => http://www.example.com
    #
    #   <%= url_for(:back) %>
    #   # if request.env["HTTP_REFERER"] is not set or is blank
    #   # => javascript:history.back()
    #
    #   <%= url_for(action: 'index', controller: 'users') %>
    #   # Assuming an "admin" namespace
    #   # => /admin/users
    #
    #   <%= url_for(action: 'index', controller: '/users') %>
    #   # Specify absolute path with beginning slash
    #   # => /users
    def url_for(options = nil)
      case options
      when String
        options
      when nil, Hash
        options ||= {}
        options = { :only_path => options[:host].nil? }.merge!(options.symbolize_keys)
        super
      when :back
        _back_url
      else
        polymorphic_path(options)
      end
    end

    def url_options #:nodoc:
      return super unless controller.respond_to?(:url_options)
      controller.url_options
    end

    def _routes_context #:nodoc:
      controller
    end
    protected :_routes_context

    def optimize_routes_generation? #:nodoc:
      controller.respond_to?(:optimize_routes_generation?, true) ?
        controller.optimize_routes_generation? : super
    end
    protected :optimize_routes_generation?
  end
end
require "active_support/core_ext/enumerable"

module ActionView
  # = Action View Errors
  class ActionViewError < StandardError #:nodoc:
  end

  class EncodingError < StandardError #:nodoc:
  end

  class MissingRequestError < StandardError #:nodoc:
  end

  class WrongEncodingError < EncodingError #:nodoc:
    def initialize(string, encoding)
      @string, @encoding = string, encoding
    end

    def message
      @string.force_encoding(Encoding::ASCII_8BIT)
      "Your template was not saved as valid #{@encoding}. Please " \
      "either specify #{@encoding} as the encoding for your template " \
      "in your text editor, or mark the template with its " \
      "encoding by inserting the following as the first line " \
      "of the template:\n\n# encoding: <name of correct encoding>.\n\n" \
      "The source of your template was:\n\n#{@string}"
    end
  end

  class MissingTemplate < ActionViewError #:nodoc:
    attr_reader :path

    def initialize(paths, path, prefixes, partial, details, *)
      @path = path
      prefixes = Array(prefixes)
      template_type = if partial
        "partial"
      elsif path =~ /layouts/i
        'layout'
      else
        'template'
      end

      searched_paths = prefixes.map { |prefix| [prefix, path].join("/") }

      out  = "Missing #{template_type} #{searched_paths.join(", ")} with #{details.inspect}. Searched in:\n"
      out += paths.compact.map { |p| "  * #{p.to_s.inspect}\n" }.join
      super out
    end
  end

  class Template
    # The Template::Error exception is raised when the compilation or rendering of the template
    # fails. This exception then gathers a bunch of intimate details and uses it to report a
    # precise exception message.
    class Error < ActionViewError #:nodoc:
      SOURCE_CODE_RADIUS = 3

      attr_reader :original_exception, :backtrace

      def initialize(template, original_exception)
        super(original_exception.message)
        @template, @original_exception = template, original_exception
        @sub_templates = nil
        @backtrace = original_exception.backtrace
      end

      def file_name
        @template.identifier
      end

      def sub_template_message
        if @sub_templates
          "Trace of template inclusion: " +
          @sub_templates.collect { |template| template.inspect }.join(", ")
        else
          ""
        end
      end

      def source_extract(indentation = 0, output = :console)
        return unless num = line_number
        num = num.to_i

        source_code = @template.source.split("\n")

        start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
        end_on_line   = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min

        indent = end_on_line.to_s.size + indentation
        return unless source_code = source_code[start_on_line..end_on_line]

        formatted_code_for(source_code, start_on_line, indent, output)
      end

      def sub_template_of(template_path)
        @sub_templates ||= []
        @sub_templates << template_path
      end

      def line_number
        @line_number ||=
          if file_name
            regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
            $1 if message =~ regexp || backtrace.find { |line| line =~ regexp }
          end
      end

      def annoted_source_code
        source_extract(4)
      end

      private

        def source_location
          if line_number
            "on line ##{line_number} of "
          else
            'in '
          end + file_name
        end

        def formatted_code_for(source_code, line_counter, indent, output)
          start_value = (output == :html) ? {} : ""
          source_code.inject(start_value) do |result, line|
            line_counter += 1
            if output == :html
              result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line])
            else
              result << "%#{indent}s: %s\n" % [line_counter, line]
            end
          end
        end
    end
  end

  TemplateError = Template::Error
end
module ActionView
  module Template::Handlers
    class Builder
      # Default format used by Builder.
      class_attribute :default_format
      self.default_format = :xml

      def call(template)
        require_engine
        "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
          "self.output_buffer = xml.target!;" +
          template.source +
          ";xml.target!;"
      end

      protected

      def require_engine
        @required ||= begin
          require "builder"
          true
        end
      end
    end
  end
end
require 'action_dispatch/http/mime_type'
require 'erubis'

module ActionView
  class Template
    module Handlers
      class Erubis < ::Erubis::Eruby
        def add_preamble(src)
          src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new;"
        end

        def add_text(src, text)
          return if text.empty?
          src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
        end

        # Erubis toggles <%= and <%== behavior when escaping is enabled.
        # We override to always treat <%== as escaped.
        def add_expr(src, code, indicator)
          case indicator
          when '=='
            add_expr_escaped(src, code)
          else
            super
          end
        end

        BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/

        def add_expr_literal(src, code)
          if code =~ BLOCK_EXPR
            src << '@output_buffer.append= ' << code
          else
            src << '@output_buffer.append= (' << code << ');'
          end
        end

        def add_expr_escaped(src, code)
          if code =~ BLOCK_EXPR
            src << "@output_buffer.safe_append= " << code
          else
            src << "@output_buffer.safe_concat((" << code << ").to_s);"
          end
        end

        def add_postamble(src)
          src << '@output_buffer.to_s'
        end
      end

      class ERB
        # Specify trim mode for the ERB compiler. Defaults to '-'.
        # See ERB documentation for suitable values.
        class_attribute :erb_trim_mode
        self.erb_trim_mode = '-'

        # Default implementation used.
        class_attribute :erb_implementation
        self.erb_implementation = Erubis

        # Do not escape templates of these mime types.
        class_attribute :escape_whitelist
        self.escape_whitelist = ["text/plain"]

        ENCODING_TAG = Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")

        def self.call(template)
          new.call(template)
        end

        def supports_streaming?
          true
        end

        def handles_encoding?
          true
        end

        def call(template)
          # First, convert to BINARY, so in case the encoding is
          # wrong, we can still find an encoding tag
          # (<%# encoding %>) inside the String using a regular
          # expression
          template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)

          erb = template_source.gsub(ENCODING_TAG, '')
          encoding = $2

          erb.force_encoding valid_encoding(template.source.dup, encoding)

          # Always make sure we return a String in the default_internal
          erb.encode!

          self.class.erb_implementation.new(
            erb,
            :escape => (self.class.escape_whitelist.include? template.type),
            :trim => (self.class.erb_trim_mode == "-")
          ).src
        end

      private

        def valid_encoding(string, encoding)
          # If a magic encoding comment was found, tag the
          # String with this encoding. This is for a case
          # where the original String was assumed to be,
          # for instance, UTF-8, but a magic comment
          # proved otherwise
          string.force_encoding(encoding) if encoding

          # If the String is valid, return the encoding we found
          return string.encoding if string.valid_encoding?

          # Otherwise, raise an exception
          raise WrongEncodingError.new(string, string.encoding)
        end
      end
    end
  end
end
module ActionView
  module Template::Handlers
    class Raw
      def call(template)
        escaped = template.source.gsub(':', '\:')

        '%q:' + escaped + ':;'
      end
    end
  end
end
module ActionView #:nodoc:
  # = Action View Template Handlers
  class Template
    module Handlers #:nodoc:
      autoload :ERB, 'action_view/template/handlers/erb'
      autoload :Builder, 'action_view/template/handlers/builder'
      autoload :Raw, 'action_view/template/handlers/raw'

      def self.extended(base)
        base.register_default_template_handler :erb, ERB.new
        base.register_template_handler :builder, Builder.new
        base.register_template_handler :raw, Raw.new
        base.register_template_handler :ruby, :source.to_proc
      end

      @@template_handlers = {}
      @@default_template_handlers = nil

      def self.extensions
        @@template_extensions ||= @@template_handlers.keys
      end

      # Register an object that knows how to handle template files with the given
      # extensions. This can be used to implement new template types.
      # The handler must respond to `:call`, which will be passed the template
      # and should return the rendered template as a String.
      def register_template_handler(*extensions, handler)
        raise(ArgumentError, "Extension is required") if extensions.empty?
        extensions.each do |extension|
          @@template_handlers[extension.to_sym] = handler
        end
        @@template_extensions = nil
      end

      def template_handler_extensions
        @@template_handlers.keys.map {|key| key.to_s }.sort
      end

      def registered_template_handler(extension)
        extension && @@template_handlers[extension.to_sym]
      end

      def register_default_template_handler(extension, klass)
        register_template_handler(extension, klass)
        @@default_template_handlers = klass
      end

      def handler_for_extension(extension)
        registered_template_handler(extension) || @@default_template_handlers
      end
    end
  end
end
require "pathname"
require "active_support/core_ext/class"
require "active_support/core_ext/class/attribute_accessors"
require "action_view/template"
require "thread"
require "thread_safe"

module ActionView
  # = Action View Resolver
  class Resolver
    # Keeps all information about view path and builds virtual path.
    class Path
      attr_reader :name, :prefix, :partial, :virtual
      alias_method :partial?, :partial

      def self.build(name, prefix, partial)
        virtual = ""
        virtual << "#{prefix}/" unless prefix.empty?
        virtual << (partial ? "_#{name}" : name)
        new name, prefix, partial, virtual
      end

      def initialize(name, prefix, partial, virtual)
        @name    = name
        @prefix  = prefix
        @partial = partial
        @virtual = virtual
      end

      def to_str
        @virtual
      end
      alias :to_s :to_str
    end

    # Threadsafe template cache
    class Cache #:nodoc:
      class SmallCache < ThreadSafe::Cache
        def initialize(options = {})
          super(options.merge(:initial_capacity => 2))
        end
      end

      # preallocate all the default blocks for performance/memory consumption reasons
      PARTIAL_BLOCK = lambda {|cache, partial| cache[partial] = SmallCache.new}
      PREFIX_BLOCK  = lambda {|cache, prefix|  cache[prefix]  = SmallCache.new(&PARTIAL_BLOCK)}
      NAME_BLOCK    = lambda {|cache, name|    cache[name]    = SmallCache.new(&PREFIX_BLOCK)}
      KEY_BLOCK     = lambda {|cache, key|     cache[key]     = SmallCache.new(&NAME_BLOCK)}

      # usually a majority of template look ups return nothing, use this canonical preallocated array to safe memory
      NO_TEMPLATES = [].freeze

      def initialize
        @data = SmallCache.new(&KEY_BLOCK)
      end

      # Cache the templates returned by the block
      def cache(key, name, prefix, partial, locals)
        if Resolver.caching?
          @data[key][name][prefix][partial][locals] ||= canonical_no_templates(yield)
        else
          fresh_templates  = yield
          cached_templates = @data[key][name][prefix][partial][locals]

          if templates_have_changed?(cached_templates, fresh_templates)
            @data[key][name][prefix][partial][locals] = canonical_no_templates(fresh_templates)
          else
            cached_templates || NO_TEMPLATES
          end
        end
      end

      def clear
        @data.clear
      end

      private

      def canonical_no_templates(templates)
        templates.empty? ? NO_TEMPLATES : templates
      end

      def templates_have_changed?(cached_templates, fresh_templates)
        # if either the old or new template list is empty, we don't need to (and can't)
        # compare modification times, and instead just check whether the lists are different
        if cached_templates.blank? || fresh_templates.blank?
          return fresh_templates.blank? != cached_templates.blank?
        end

        cached_templates_max_updated_at = cached_templates.map(&:updated_at).max

        # if a template has changed, it will be now be newer than all the cached templates
        fresh_templates.any? { |t| t.updated_at > cached_templates_max_updated_at }
      end
    end

    cattr_accessor :caching
    self.caching = true

    class << self
      alias :caching? :caching
    end

    def initialize
      @cache = Cache.new
    end

    def clear_cache
      @cache.clear
    end

    # Normalizes the arguments and passes it on to find_template.
    def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[])
      cached(key, [name, prefix, partial], details, locals) do
        find_templates(name, prefix, partial, details)
      end
    end

  private

    delegate :caching?, to: :class

    # This is what child classes implement. No defaults are needed
    # because Resolver guarantees that the arguments are present and
    # normalized.
    def find_templates(name, prefix, partial, details)
      raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details) method"
    end

    # Helpers that builds a path. Useful for building virtual paths.
    def build_path(name, prefix, partial)
      Path.build(name, prefix, partial)
    end

    # Handles templates caching. If a key is given and caching is on
    # always check the cache before hitting the resolver. Otherwise,
    # it always hits the resolver but if the key is present, check if the
    # resolver is fresher before returning it.
    def cached(key, path_info, details, locals) #:nodoc:
      name, prefix, partial = path_info
      locals = locals.map { |x| x.to_s }.sort!

      if key
        @cache.cache(key, name, prefix, partial, locals) do
          decorate(yield, path_info, details, locals)
        end
      else
        decorate(yield, path_info, details, locals)
      end
    end

    # Ensures all the resolver information is set in the template.
    def decorate(templates, path_info, details, locals) #:nodoc:
      cached = nil
      templates.each do |t|
        t.locals         = locals
        t.formats        = details[:formats] || [:html] if t.formats.empty?
        t.virtual_path ||= (cached ||= build_path(*path_info))
      end
    end
  end

  # An abstract class that implements a Resolver with path semantics.
  class PathResolver < Resolver #:nodoc:
    EXTENSIONS = [:locale, :formats, :handlers]
    DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}"

    def initialize(pattern=nil)
      @pattern = pattern || DEFAULT_PATTERN
      super()
    end

    private

    def find_templates(name, prefix, partial, details)
      path = Path.build(name, prefix, partial)
      query(path, details, details[:formats])
    end

    def query(path, details, formats)
      query = build_query(path, details)

      # deals with case-insensitive file systems.
      sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }

      template_paths = Dir[query].reject { |filename|
        File.directory?(filename) ||
          !sanitizer[File.dirname(filename)].include?(filename)
      }

      template_paths.map { |template|
        handler, format = extract_handler_and_format(template, formats)
        contents = File.binread template

        Template.new(contents, File.expand_path(template), handler,
          :virtual_path => path.virtual,
          :format       => format,
          :updated_at   => mtime(template))
      }
    end

    # Helper for building query glob string based on resolver's pattern.
    def build_query(path, details)
      query = @pattern.dup

      prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1"
      query.gsub!(/\:prefix(\/)?/, prefix)

      partial = escape_entry(path.partial? ? "_#{path.name}" : path.name)
      query.gsub!(/\:action/, partial)

      details.each do |ext, variants|
        query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}")
      end

      File.expand_path(query, @path)
    end

    def escape_entry(entry)
      entry.gsub(/[*?{}\[\]]/, '\\\\\\&')
    end

    # Returns the file mtime from the filesystem.
    def mtime(p)
      File.mtime(p)
    end

    # Extract handler and formats from path. If a format cannot be a found neither
    # from the path, or the handler, we should return the array of formats given
    # to the resolver.
    def extract_handler_and_format(path, default_formats)
      pieces = File.basename(path).split(".")
      pieces.shift

      extension = pieces.pop
      unless extension
        message = "The file #{path} did not specify a template handler. The default is currently ERB, " \
                  "but will change to RAW in the future."
        ActiveSupport::Deprecation.warn message
      end

      handler = Template.handler_for_extension(extension)
      format  = pieces.last && Template::Types[pieces.last]
      [handler, format]
    end
  end

  # A resolver that loads files from the filesystem. It allows setting your own
  # resolving pattern. Such pattern can be a glob string supported by some variables.
  #
  # ==== Examples
  #
  # Default pattern, loads views the same way as previous versions of rails, eg. when you're
  # looking for `users/new` it will produce query glob: `users/new{.{en},}{.{html,js},}{.{erb,haml},}`
  #
  #   FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}")
  #
  # This one allows you to keep files with different formats in seperated subdirectories,
  # eg. `users/new.html` will be loaded from `users/html/new.erb` or `users/new.html.erb`,
  # `users/new.js` from `users/js/new.erb` or `users/new.js.erb`, etc.
  #
  #   FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{.:handlers,}")
  #
  # If you don't specify a pattern then the default will be used.
  #
  # In order to use any of the customized resolvers above in a Rails application, you just need
  # to configure ActionController::Base.view_paths in an initializer, for example:
  #
  #   ActionController::Base.view_paths = FileSystemResolver.new(
  #     Rails.root.join("app/views"),
  #     ":prefix{/:locale}/:action{.:formats,}{.:handlers,}"
  #   )
  #
  # ==== Pattern format and variables
  #
  # Pattern has to be a valid glob string, and it allows you to use the
  # following variables:
  #
  # * <tt>:prefix</tt> - usually the controller path
  # * <tt>:action</tt> - name of the action
  # * <tt>:locale</tt> - possible locale versions
  # * <tt>:formats</tt> - possible request formats (for example html, json, xml...)
  # * <tt>:handlers</tt> - possible handlers (for example erb, haml, builder...)
  #
  class FileSystemResolver < PathResolver
    def initialize(path, pattern=nil)
      raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
      super(pattern)
      @path = File.expand_path(path)
    end

    def to_s
      @path.to_s
    end
    alias :to_path :to_s

    def eql?(resolver)
      self.class.equal?(resolver.class) && to_path == resolver.to_path
    end
    alias :== :eql?
  end

  # An Optimized resolver for Rails' most common case.
  class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
    def build_query(path, details)
      exts = EXTENSIONS.map { |ext| details[ext] }
      query = escape_entry(File.join(@path, path))

      query + exts.map { |ext|
        "{#{ext.compact.uniq.map { |e| ".#{e}," }.join}}"
      }.join
    end
  end

  # The same as FileSystemResolver but does not allow templates to store
  # a virtual path since it is invalid for such resolvers.
  class FallbackFileSystemResolver < FileSystemResolver #:nodoc:
    def self.instances
      [new(""), new("/")]
    end

    def decorate(*)
      super.each { |t| t.virtual_path = nil }
    end
  end
end
module ActionView #:nodoc:
  # = Action View Text Template
  class Template
    class Text #:nodoc:
      attr_accessor :type

      def initialize(string, type = nil)
        @string = string.to_s
        @type   = Types[type] || type if type
        @type ||= Types[:text]
      end

      def identifier
        'text template'
      end

      def inspect
        'text template'
      end

      def to_str
        @string
      end

      def render(*args)
        to_str
      end

      def formats
        [@type.to_sym]
      end
    end
  end
end
require 'set'
require 'active_support/core_ext/class/attribute_accessors'

module ActionView
  class Template
    class Types
      class Type
        cattr_accessor :types
        self.types = Set.new

        def self.register(*t)
          types.merge(t.map { |type| type.to_s })
        end

        register :html, :text, :js, :css,  :xml, :json

        def self.[](type)
          return type if type.is_a?(self)

          if type.is_a?(Symbol) || types.member?(type.to_s)
            new(type)
          end
        end

        attr_reader :symbol

        def initialize(symbol)
          @symbol = symbol.to_sym
        end

        delegate :to_s, :to_sym, :to => :symbol
        alias to_str to_s

        def ref
          to_sym || to_s
        end

        def ==(type)
          return false if type.blank?
          symbol.to_sym == type.to_sym
        end
      end

      cattr_accessor :type_klass

      def self.delegate_to(klass)
        self.type_klass = klass
      end

      delegate_to Type

      def self.[](type)
        type_klass[type]
      end
    end
  end
end
require 'active_support/core_ext/object/try'
require 'active_support/core_ext/kernel/singleton_class'
require 'thread'

module ActionView
  # = Action View Template
  class Template
    extend ActiveSupport::Autoload

    # === Encodings in ActionView::Template
    #
    # ActionView::Template is one of a few sources of potential
    # encoding issues in Rails. This is because the source for
    # templates are usually read from disk, and Ruby (like most
    # encoding-aware programming languages) assumes that the
    # String retrieved through File IO is encoded in the
    # <tt>default_external</tt> encoding. In Rails, the default
    # <tt>default_external</tt> encoding is UTF-8.
    #
    # As a result, if a user saves their template as ISO-8859-1
    # (for instance, using a non-Unicode-aware text editor),
    # and uses characters outside of the ASCII range, their
    # users will see diamonds with question marks in them in
    # the browser.
    #
    # For the rest of this documentation, when we say "UTF-8",
    # we mean "UTF-8 or whatever the default_internal encoding
    # is set to". By default, it will be UTF-8.
    #
    # To mitigate this problem, we use a few strategies:
    # 1. If the source is not valid UTF-8, we raise an exception
    #    when the template is compiled to alert the user
    #    to the problem.
    # 2. The user can specify the encoding using Ruby-style
    #    encoding comments in any template engine. If such
    #    a comment is supplied, Rails will apply that encoding
    #    to the resulting compiled source returned by the
    #    template handler.
    # 3. In all cases, we transcode the resulting String to
    #    the UTF-8.
    #
    # This means that other parts of Rails can always assume
    # that templates are encoded in UTF-8, even if the original
    # source of the template was not UTF-8.
    #
    # From a user's perspective, the easiest thing to do is
    # to save your templates as UTF-8. If you do this, you
    # do not need to do anything else for things to "just work".
    #
    # === Instructions for template handlers
    #
    # The easiest thing for you to do is to simply ignore
    # encodings. Rails will hand you the template source
    # as the default_internal (generally UTF-8), raising
    # an exception for the user before sending the template
    # to you if it could not determine the original encoding.
    #
    # For the greatest simplicity, you can support only
    # UTF-8 as the <tt>default_internal</tt>. This means
    # that from the perspective of your handler, the
    # entire pipeline is just UTF-8.
    #
    # === Advanced: Handlers with alternate metadata sources
    #
    # If you want to provide an alternate mechanism for
    # specifying encodings (like ERB does via <%# encoding: ... %>),
    # you may indicate that you will handle encodings yourself
    # by implementing <tt>self.handles_encoding?</tt>
    # on your handler.
    #
    # If you do, Rails will not try to encode the String
    # into the default_internal, passing you the unaltered
    # bytes tagged with the assumed encoding (from
    # default_external).
    #
    # In this case, make sure you return a String from
    # your handler encoded in the default_internal. Since
    # you are handling out-of-band metadata, you are
    # also responsible for alerting the user to any
    # problems with converting the user's data to
    # the <tt>default_internal</tt>.
    #
    # To do so, simply raise +WrongEncodingError+ as follows:
    #
    #     raise WrongEncodingError.new(
    #       problematic_string,
    #       expected_encoding
    #     )

    eager_autoload do
      autoload :Error
      autoload :Handlers
      autoload :Text
      autoload :Types
    end

    extend Template::Handlers

    attr_accessor :locals, :formats, :virtual_path

    attr_reader :source, :identifier, :handler, :original_encoding, :updated_at

    # This finalizer is needed (and exactly with a proc inside another proc)
    # otherwise templates leak in development.
    Finalizer = proc do |method_name, mod|
      proc do
        mod.module_eval do
          remove_possible_method method_name
        end
      end
    end

    def initialize(source, identifier, handler, details)
      format = details[:format] || (handler.default_format if handler.respond_to?(:default_format))

      @source            = source
      @identifier        = identifier
      @handler           = handler
      @compiled          = false
      @original_encoding = nil
      @locals            = details[:locals] || []
      @virtual_path      = details[:virtual_path]
      @updated_at        = details[:updated_at] || Time.now
      @formats           = Array(format).map { |f| f.respond_to?(:ref) ? f.ref : f  }
      @compile_mutex     = Mutex.new
    end

    # Returns if the underlying handler supports streaming. If so,
    # a streaming buffer *may* be passed when it start rendering.
    def supports_streaming?
      handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
    end

    # Render a template. If the template was not compiled yet, it is done
    # exactly before rendering.
    #
    # This method is instrumented as "!render_template.action_view". Notice that
    # we use a bang in this instrumentation because you don't want to
    # consume this in production. This is only slow if it's being listened to.
    def render(view, locals, buffer=nil, &block)
      ActiveSupport::Notifications.instrument("!render_template.action_view", :virtual_path => @virtual_path) do
        compile!(view)
        view.send(method_name, locals, buffer, &block)
      end
    rescue Exception => e
      handle_render_error(view, e)
    end

    def mime_type
      message = 'Template#mime_type is deprecated and will be removed in Rails 4.1. Please use type method instead.'
      ActiveSupport::Deprecation.warn message
      @mime_type ||= Mime::Type.lookup_by_extension(@formats.first.to_s) if @formats.first
    end

    def type
      @type ||= Types[@formats.first] if @formats.first
    end

    # Receives a view object and return a template similar to self by using @virtual_path.
    #
    # This method is useful if you have a template object but it does not contain its source
    # anymore since it was already compiled. In such cases, all you need to do is to call
    # refresh passing in the view object.
    #
    # Notice this method raises an error if the template to be refreshed does not have a
    # virtual path set (true just for inline templates).
    def refresh(view)
      raise "A template needs to have a virtual path in order to be refreshed" unless @virtual_path
      lookup  = view.lookup_context
      pieces  = @virtual_path.split("/")
      name    = pieces.pop
      partial = !!name.sub!(/^_/, "")
      lookup.disable_cache do
        lookup.find_template(name, [ pieces.join('/') ], partial, @locals)
      end
    end

    def inspect
      @inspect ||= defined?(Rails.root) ? identifier.sub("#{Rails.root}/", '') : identifier
    end

    # This method is responsible for properly setting the encoding of the
    # source. Until this point, we assume that the source is BINARY data.
    # If no additional information is supplied, we assume the encoding is
    # the same as <tt>Encoding.default_external</tt>.
    #
    # The user can also specify the encoding via a comment on the first
    # line of the template (# encoding: NAME-OF-ENCODING). This will work
    # with any template engine, as we process out the encoding comment
    # before passing the source on to the template engine, leaving a
    # blank line in its stead.
    def encode!
      return unless source.encoding == Encoding::BINARY

      # Look for # encoding: *. If we find one, we'll encode the
      # String in that encoding, otherwise, we'll use the
      # default external encoding.
      if source.sub!(/\A#{ENCODING_FLAG}/, '')
        encoding = magic_encoding = $1
      else
        encoding = Encoding.default_external
      end

      # Tag the source with the default external encoding
      # or the encoding specified in the file
      source.force_encoding(encoding)

      # If the user didn't specify an encoding, and the handler
      # handles encodings, we simply pass the String as is to
      # the handler (with the default_external tag)
      if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding?
        source
      # Otherwise, if the String is valid in the encoding,
      # encode immediately to default_internal. This means
      # that if a handler doesn't handle encodings, it will
      # always get Strings in the default_internal
      elsif source.valid_encoding?
        source.encode!
      # Otherwise, since the String is invalid in the encoding
      # specified, raise an exception
      else
        raise WrongEncodingError.new(source, encoding)
      end
    end

    protected

      # Compile a template. This method ensures a template is compiled
      # just once and removes the source after it is compiled.
      def compile!(view) #:nodoc:
        return if @compiled

        # Templates can be used concurrently in threaded environments
        # so compilation and any instance variable modification must
        # be synchronized
        @compile_mutex.synchronize do
          # Any thread holding this lock will be compiling the template needed
          # by the threads waiting. So re-check the @compiled flag to avoid
          # re-compilation
          return if @compiled

          if view.is_a?(ActionView::CompiledTemplates)
            mod = ActionView::CompiledTemplates
          else
            mod = view.singleton_class
          end

          compile(view, mod)

          # Just discard the source if we have a virtual path. This
          # means we can get the template back.
          @source = nil if @virtual_path
          @compiled = true
        end
      end

      # Among other things, this method is responsible for properly setting
      # the encoding of the compiled template.
      #
      # If the template engine handles encodings, we send the encoded
      # String to the engine without further processing. This allows
      # the template engine to support additional mechanisms for
      # specifying the encoding. For instance, ERB supports <%# encoding: %>
      #
      # Otherwise, after we figure out the correct encoding, we then
      # encode the source into <tt>Encoding.default_internal</tt>.
      # In general, this means that templates will be UTF-8 inside of Rails,
      # regardless of the original source encoding.
      def compile(view, mod) #:nodoc:
        encode!
        method_name = self.method_name
        code = @handler.call(self)

        # Make sure that the resulting String to be evalled is in the
        # encoding of the code
        source = <<-end_src
          def #{method_name}(local_assigns, output_buffer)
            _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code}
          ensure
            @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
          end
        end_src

        # Make sure the source is in the encoding of the returned code
        source.force_encoding(code.encoding)

        # In case we get back a String from a handler that is not in
        # BINARY or the default_internal, encode it to the default_internal
        source.encode!

        # Now, validate that the source we got back from the template
        # handler is valid in the default_internal. This is for handlers
        # that handle encoding but screw up
        unless source.valid_encoding?
          raise WrongEncodingError.new(@source, Encoding.default_internal)
        end

        begin
          mod.module_eval(source, identifier, 0)
          ObjectSpace.define_finalizer(self, Finalizer[method_name, mod])
        rescue Exception => e # errors from template code
          if logger = (view && view.logger)
            logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
            logger.debug "Function body: #{source}"
            logger.debug "Backtrace: #{e.backtrace.join("\n")}"
          end

          raise ActionView::Template::Error.new(self, e)
        end
      end

      def handle_render_error(view, e) #:nodoc:
        if e.is_a?(Template::Error)
          e.sub_template_of(self)
          raise e
        else
          template = self
          unless template.source
            template = refresh(view)
            template.encode!
          end
          raise Template::Error.new(template, e)
        end
      end

      def locals_code #:nodoc:
        @locals.map { |key| "#{key} = local_assigns[:#{key}];" }.join
      end

      def method_name #:nodoc:
        @method_name ||= "_#{identifier_method_name}__#{@identifier.hash}_#{__id__}".gsub('-', "_")
      end

      def identifier_method_name #:nodoc:
        inspect.gsub(/[^a-z_]/, '_')
      end
  end
end
require 'active_support/core_ext/module/remove_method'
require 'action_controller'
require 'action_controller/test_case'
require 'action_view'

module ActionView
  # = Action View Test Case
  class TestCase < ActiveSupport::TestCase
    class TestController < ActionController::Base
      include ActionDispatch::TestProcess

      attr_accessor :request, :response, :params

      class << self
        attr_writer :controller_path
      end

      def controller_path=(path)
        self.class.controller_path=(path)
      end

      def initialize
        super
        self.class.controller_path = ""
        @request = ActionController::TestRequest.new
        @response = ActionController::TestResponse.new

        @request.env.delete('PATH_INFO')
        @params = {}
      end
    end

    module Behavior
      extend ActiveSupport::Concern

      include ActionDispatch::Assertions, ActionDispatch::TestProcess
      include ActionController::TemplateAssertions
      include ActionView::Context

      include ActionDispatch::Routing::PolymorphicRoutes

      include AbstractController::Helpers
      include ActionView::Helpers
      include ActionView::RecordIdentifier
      include ActionView::RoutingUrlFor

      include ActiveSupport::Testing::ConstantLookup

      delegate :lookup_context, :to => :controller
      attr_accessor :controller, :output_buffer, :rendered

      module ClassMethods
        def tests(helper_class)
          case helper_class
          when String, Symbol
            self.helper_class = "#{helper_class.to_s.underscore}_helper".camelize.safe_constantize
          when Module
            self.helper_class = helper_class
          end
        end

        def determine_default_helper_class(name)
          determine_constant_from_test_name(name) do |constant|
            Module === constant && !(Class === constant)
          end
        end

        def helper_method(*methods)
          # Almost a duplicate from ActionController::Helpers
          methods.flatten.each do |method|
            _helpers.module_eval <<-end_eval
              def #{method}(*args, &block)                    # def current_user(*args, &block)
                _test_case.send(%(#{method}), *args, &block)  #   _test_case.send(%(current_user), *args, &block)
              end                                             # end
            end_eval
          end
        end

        attr_writer :helper_class

        def helper_class
          @helper_class ||= determine_default_helper_class(name)
        end

        def new(*)
          include_helper_modules!
          super
        end

      private

        def include_helper_modules!
          helper(helper_class) if helper_class
          include _helpers
        end

      end

      def setup_with_controller
        @controller = ActionView::TestCase::TestController.new
        @request = @controller.request
        @output_buffer = ActiveSupport::SafeBuffer.new
        @rendered = ''

        make_test_case_available_to_view!
        say_no_to_protect_against_forgery!
      end

      def config
        @controller.config if @controller.respond_to?(:config)
      end

      def render(options = {}, local_assigns = {}, &block)
        view.assign(view_assigns)
        @rendered << output = view.render(options, local_assigns, &block)
        output
      end

      def rendered_views
        @_rendered_views ||= RenderedViewsCollection.new
      end

      class RenderedViewsCollection
        def initialize
          @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
        end

        def add(view, locals)
          @rendered_views[view] ||= []
          @rendered_views[view] << locals
        end

        def locals_for(view)
          @rendered_views[view]
        end

        def rendered_views
          @rendered_views.keys
        end

        def view_rendered?(view, expected_locals)
          locals_for(view).any? do |actual_locals|
            expected_locals.all? {|key, value| value == actual_locals[key] }
          end
        end
      end

      included do
        setup :setup_with_controller
      end

    private

      # Support the selector assertions
      #
      # Need to experiment if this priority is the best one: rendered => output_buffer
      def response_from_page
        HTML::Document.new(@rendered.blank? ? @output_buffer : @rendered).root
      end

      def say_no_to_protect_against_forgery!
        _helpers.module_eval do
          remove_possible_method :protect_against_forgery?
          def protect_against_forgery?
            false
          end
        end
      end

      def make_test_case_available_to_view!
        test_case_instance = self
        _helpers.module_eval do
          unless private_method_defined?(:_test_case)
            define_method(:_test_case) { test_case_instance }
            private :_test_case
          end
        end
      end

      module Locals
        attr_accessor :rendered_views

        def render(options = {}, local_assigns = {})
          case options
          when Hash
            if block_given?
              rendered_views.add options[:layout], options[:locals]
            elsif options.key?(:partial)
              rendered_views.add options[:partial], options[:locals]
            end
          else
            rendered_views.add options, local_assigns
          end

          super
        end
      end

      # The instance of ActionView::Base that is used by +render+.
      def view
        @view ||= begin
          view = @controller.view_context
          view.singleton_class.send :include, _helpers
          view.extend(Locals)
          view.rendered_views = self.rendered_views
          view.output_buffer = self.output_buffer
          view
        end
      end

      alias_method :_view, :view

      INTERNAL_IVARS = [
        :@__name__,
        :@__io__,
        :@_assertion_wrapped,
        :@_assertions,
        :@_result,
        :@_routes,
        :@controller,
        :@_layouts,
        :@_rendered_views,
        :@method_name,
        :@output_buffer,
        :@_partials,
        :@passed,
        :@rendered,
        :@request,
        :@routes,
        :@tagged_logger,
        :@_templates,
        :@options,
        :@test_passed,
        :@view,
        :@view_context_class
      ]

      def _user_defined_ivars
        instance_variables - INTERNAL_IVARS
      end

      # Returns a Hash of instance variables and their values, as defined by
      # the user in the test case, which are then assigned to the view being
      # rendered. This is generally intended for internal use and extension
      # frameworks.
      def view_assigns
        Hash[_user_defined_ivars.map do |ivar|
          [ivar[1..-1].to_sym, instance_variable_get(ivar)]
        end]
      end

      def _routes
        @controller._routes if @controller.respond_to?(:_routes)
      end

      def method_missing(selector, *args)
        if @controller.respond_to?(:_routes) &&
          ( @controller._routes.named_routes.helpers.include?(selector) ||
            @controller._routes.mounted_helpers.method_defined?(selector) )
          @controller.__send__(selector, *args)
        else
          super
        end
      end
    end

    include Behavior
  end
end
require 'action_view/template/resolver'

module ActionView #:nodoc:
  # Use FixtureResolver in your tests to simulate the presence of files on the
  # file system. This is used internally by Rails' own test suite, and is
  # useful for testing extensions that have no way of knowing what the file
  # system will look like at runtime.
  class FixtureResolver < PathResolver
    attr_reader :hash

    def initialize(hash = {}, pattern=nil)
      super(pattern)
      @hash = hash
    end

    def to_s
      @hash.keys.join(', ')
    end

  private

    def query(path, exts, formats)
      query = ""
      EXTENSIONS.each do |ext|
        query << '(' << exts[ext].map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)'
      end
      query = /^(#{Regexp.escape(path)})#{query}$/

      templates = []
      @hash.each do |_path, array|
        source, updated_at = array
        next unless _path =~ query
        handler, format = extract_handler_and_format(_path, formats)
        templates << Template.new(source, _path, handler,
          :virtual_path => path.virtual, :format => format, :updated_at => updated_at)
      end

      templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
    end
  end

  class NullResolver < PathResolver
    def query(path, exts, formats)
      handler, format = extract_handler_and_format(path, formats)
      [ActionView::Template.new("Template generated by Null Resolver", path, handler, :virtual_path => path, :format => format)]
    end
  end

end

require 'html/tokenizer'
require 'html/node'
require 'html/selector'
require 'html/sanitizer'

module HTML #:nodoc:
  # A top-level HTML document. You give it a body of text, and it will parse that
  # text into a tree of nodes.
  class Document #:nodoc:

    # The root of the parsed document.
    attr_reader :root

    # Create a new Document from the given text.
    def initialize(text, strict=false, xml=false)
      tokenizer = Tokenizer.new(text)
      @root = Node.new(nil)
      node_stack = [ @root ]
      while token = tokenizer.next
        node = Node.parse(node_stack.last, tokenizer.line, tokenizer.position, token, strict)

        node_stack.last.children << node unless node.tag? && node.closing == :close
        if node.tag?
          if node_stack.length > 1 && node.closing == :close
            if node_stack.last.name == node.name
              if node_stack.last.children.empty?
                node_stack.last.children << Text.new(node_stack.last, node.line, node.position, "")
              end
              node_stack.pop
            else
              open_start = node_stack.last.position - 20
              open_start = 0 if open_start < 0
              close_start = node.position - 20
              close_start = 0 if close_start < 0
              msg = <<EOF.strip
ignoring attempt to close #{node_stack.last.name} with #{node.name}
  opened at byte #{node_stack.last.position}, line #{node_stack.last.line}
  closed at byte #{node.position}, line #{node.line}
  attributes at open: #{node_stack.last.attributes.inspect}
  text around open: #{text[open_start,40].inspect}
  text around close: #{text[close_start,40].inspect}
EOF
              strict ? raise(msg) : warn(msg)
            end
          elsif !node.childless?(xml) && node.closing != :close
            node_stack.push node
          end
        end
      end
    end

    # Search the tree for (and return) the first node that matches the given
    # conditions. The conditions are interpreted differently for different node
    # types, see HTML::Text#find and HTML::Tag#find.
    def find(conditions)
      @root.find(conditions)
    end

    # Search the tree for (and return) all nodes that match the given
    # conditions. The conditions are interpreted differently for different node
    # types, see HTML::Text#find and HTML::Tag#find.
    def find_all(conditions)
      @root.find_all(conditions)
    end

  end

end
require 'strscan'

module HTML #:nodoc:

  class Conditions < Hash #:nodoc:
    def initialize(hash)
      super()
      hash = { :content => hash } unless Hash === hash
      hash = keys_to_symbols(hash)
      hash.each do |k,v|
        case k
          when :tag, :content then
            # keys are valid, and require no further processing
          when :attributes then
            hash[k] = keys_to_strings(v)
          when :parent, :child, :ancestor, :descendant, :sibling, :before,
                  :after
            hash[k] = Conditions.new(v)
          when :children
            hash[k] = v = keys_to_symbols(v)
            v.each do |key,value|
              case key
                when :count, :greater_than, :less_than
                  # keys are valid, and require no further processing
                when :only
                  v[key] = Conditions.new(value)
                else
                  raise "illegal key #{key.inspect} => #{value.inspect}"
              end
            end
          else
            raise "illegal key #{k.inspect} => #{v.inspect}"
        end
      end
      update hash
    end

    private

      def keys_to_strings(hash)
        Hash[hash.keys.map {|k| [k.to_s, hash[k]]}]
      end

      def keys_to_symbols(hash)
        Hash[hash.keys.map do |k|
          raise "illegal key #{k.inspect}" unless k.respond_to?(:to_sym)
          [k.to_sym, hash[k]]
        end]
      end
  end

  # The base class of all nodes, textual and otherwise, in an HTML document.
  class Node #:nodoc:
    # The array of children of this node. Not all nodes have children.
    attr_reader :children

    # The parent node of this node. All nodes have a parent, except for the
    # root node.
    attr_reader :parent

    # The line number of the input where this node was begun
    attr_reader :line

    # The byte position in the input where this node was begun
    attr_reader :position

    # Create a new node as a child of the given parent.
    def initialize(parent, line=0, pos=0)
      @parent = parent
      @children = []
      @line, @position = line, pos
    end

    # Return a textual representation of the node.
    def to_s
      @children.join()
    end

    # Return false (subclasses must override this to provide specific matching
    # behavior.) +conditions+ may be of any type.
    def match(conditions)
      false
    end

    # Search the children of this node for the first node for which #find
    # returns non +nil+. Returns the result of the #find call that succeeded.
    def find(conditions)
      conditions = validate_conditions(conditions)
      @children.each do |child|
        node = child.find(conditions)
        return node if node
      end
      nil
    end

    # Search for all nodes that match the given conditions, and return them
    # as an array.
    def find_all(conditions)
      conditions = validate_conditions(conditions)

      matches = []
      matches << self if match(conditions)
      @children.each do |child|
        matches.concat child.find_all(conditions)
      end
      matches
    end

    # Returns +false+. Subclasses may override this if they define a kind of
    # tag.
    def tag?
      false
    end

    def validate_conditions(conditions)
      Conditions === conditions ? conditions : Conditions.new(conditions)
    end

    def ==(node)
      return false unless self.class == node.class && children.size == node.children.size

      equivalent = true

      children.size.times do |i|
        equivalent &&= children[i] == node.children[i]
      end

      equivalent
    end

    class <<self
      def parse(parent, line, pos, content, strict=true)
        if content !~ /^<\S/
          Text.new(parent, line, pos, content)
        else
          scanner = StringScanner.new(content)

          unless scanner.skip(/</)
            if strict
              raise "expected <"
            else
              return Text.new(parent, line, pos, content)
            end
          end

          if scanner.skip(/!\[CDATA\[/)
            unless scanner.skip_until(/\]\]>/)
              if strict
                raise "expected ]]> (got #{scanner.rest.inspect} for #{content})"
              else
                scanner.skip_until(/\Z/)
              end
            end

            return CDATA.new(parent, line, pos, scanner.pre_match.gsub(/<!\[CDATA\[/, ''))
          end

          closing = ( scanner.scan(/\//) ? :close : nil )
          return Text.new(parent, line, pos, content) unless name = scanner.scan(/[^\s!>\/]+/)
          name.downcase!

          unless closing
            scanner.skip(/\s*/)
            attributes = {}
            while attr = scanner.scan(/[-\w:]+/)
              value = true
              if scanner.scan(/\s*=\s*/)
                if delim = scanner.scan(/['"]/)
                  value = ""
                  while text = scanner.scan(/[^#{delim}\\]+|./)
                    case text
                      when "\\" then
                        value << text
                        break if scanner.eos?
                        value << scanner.getch
                      when delim
                        break
                      else value << text
                    end
                  end
                else
                  value = scanner.scan(/[^\s>\/]+/)
                end
              end
              attributes[attr.downcase] = value
              scanner.skip(/\s*/)
            end

            closing = ( scanner.scan(/\//) ? :self : nil )
          end

          unless scanner.scan(/\s*>/)
            if strict
              raise "expected > (got #{scanner.rest.inspect} for #{content}, #{attributes.inspect})"
            else
              # throw away all text until we find what we're looking for
              scanner.skip_until(/>/) or scanner.terminate
            end
          end

          Tag.new(parent, line, pos, name, attributes, closing)
        end
      end
    end
  end

  # A node that represents text, rather than markup.
  class Text < Node #:nodoc:

    attr_reader :content

    # Creates a new text node as a child of the given parent, with the given
    # content.
    def initialize(parent, line, pos, content)
      super(parent, line, pos)
      @content = content
    end

    # Returns the content of this node.
    def to_s
      @content
    end

    # Returns +self+ if this node meets the given conditions. Text nodes support
    # conditions of the following kinds:
    #
    # * if +conditions+ is a string, it must be a substring of the node's
    #   content
    # * if +conditions+ is a regular expression, it must match the node's
    #   content
    # * if +conditions+ is a hash, it must contain a <tt>:content</tt> key that
    #   is either a string or a regexp, and which is interpreted as described
    #   above.
    def find(conditions)
      match(conditions) && self
    end

    # Returns non-+nil+ if this node meets the given conditions, or +nil+
    # otherwise. See the discussion of #find for the valid conditions.
    def match(conditions)
      case conditions
        when String
          @content == conditions
        when Regexp
          @content =~ conditions
        when Hash
          conditions = validate_conditions(conditions)

          # Text nodes only have :content, :parent, :ancestor
          unless (conditions.keys - [:content, :parent, :ancestor]).empty?
            return false
          end

          match(conditions[:content])
        else
          nil
      end
    end

    def ==(node)
      return false unless super
      content == node.content
    end
  end

  # A CDATA node is simply a text node with a specialized way of displaying
  # itself.
  class CDATA < Text #:nodoc:
    def to_s
      "<![CDATA[#{super}]]>"
    end
  end

  # A Tag is any node that represents markup. It may be an opening tag, a
  # closing tag, or a self-closing tag. It has a name, and may have a hash of
  # attributes.
  class Tag < Node #:nodoc:

    # Either +nil+, <tt>:close</tt>, or <tt>:self</tt>
    attr_reader :closing

    # Either +nil+, or a hash of attributes for this node.
    attr_reader :attributes

    # The name of this tag.
    attr_reader :name

    # Create a new node as a child of the given parent, using the given content
    # to describe the node. It will be parsed and the node name, attributes and
    # closing status extracted.
    def initialize(parent, line, pos, name, attributes, closing)
      super(parent, line, pos)
      @name = name
      @attributes = attributes
      @closing = closing
    end

    # A convenience for obtaining an attribute of the node. Returns +nil+ if
    # the node has no attributes.
    def [](attr)
      @attributes ? @attributes[attr] : nil
    end

    # Returns non-+nil+ if this tag can contain child nodes.
    def childless?(xml = false)
      return false if xml && @closing.nil?
      !@closing.nil? ||
        @name =~ /^(img|br|hr|link|meta|area|base|basefont|
                    col|frame|input|isindex|param)$/ox
    end

    # Returns a textual representation of the node
    def to_s
      if @closing == :close
        "</#{@name}>"
      else
        s = "<#{@name}"
        @attributes.each do |k,v|
          s << " #{k}"
          s << "=\"#{v}\"" if String === v
        end
        s << " /" if @closing == :self
        s << ">"
        @children.each { |child| s << child.to_s }
        s << "</#{@name}>" if @closing != :self && !@children.empty?
        s
      end
    end

    # If either the node or any of its children meet the given conditions, the
    # matching node is returned. Otherwise, +nil+ is returned. (See the
    # description of the valid conditions in the +match+ method.)
    def find(conditions)
      match(conditions) && self || super
    end

    # Returns +true+, indicating that this node represents an HTML tag.
    def tag?
      true
    end

    # Returns +true+ if the node meets any of the given conditions. The
    # +conditions+ parameter must be a hash of any of the following keys
    # (all are optional):
    #
    # * <tt>:tag</tt>: the node name must match the corresponding value
    # * <tt>:attributes</tt>: a hash. The node's values must match the
    #   corresponding values in the hash.
    # * <tt>:parent</tt>: a hash. The node's parent must match the
    #   corresponding hash.
    # * <tt>:child</tt>: a hash. At least one of the node's immediate children
    #   must meet the criteria described by the hash.
    # * <tt>:ancestor</tt>: a hash. At least one of the node's ancestors must
    #   meet the criteria described by the hash.
    # * <tt>:descendant</tt>: a hash. At least one of the node's descendants
    #   must meet the criteria described by the hash.
    # * <tt>:sibling</tt>: a hash. At least one of the node's siblings must
    #   meet the criteria described by the hash.
    # * <tt>:after</tt>: a hash. The node must be after any sibling meeting
    #   the criteria described by the hash, and at least one sibling must match.
    # * <tt>:before</tt>: a hash. The node must be before any sibling meeting
    #   the criteria described by the hash, and at least one sibling must match.
    # * <tt>:children</tt>: a hash, for counting children of a node. Accepts the
    #   keys:
    # ** <tt>:count</tt>: either a number or a range which must equal (or
    #    include) the number of children that match.
    # ** <tt>:less_than</tt>: the number of matching children must be less than
    #    this number.
    # ** <tt>:greater_than</tt>: the number of matching children must be
    #    greater than this number.
    # ** <tt>:only</tt>: another hash consisting of the keys to use
    #    to match on the children, and only matching children will be
    #    counted.
    #
    # Conditions are matched using the following algorithm:
    #
    # * if the condition is a string, it must be a substring of the value.
    # * if the condition is a regexp, it must match the value.
    # * if the condition is a number, the value must match number.to_s.
    # * if the condition is +true+, the value must not be +nil+.
    # * if the condition is +false+ or +nil+, the value must be +nil+.
    #
    # Usage:
    #
    #   # test if the node is a "span" tag
    #   node.match tag: "span"
    #
    #   # test if the node's parent is a "div"
    #   node.match parent: { tag: "div" }
    #
    #   # test if any of the node's ancestors are "table" tags
    #   node.match ancestor: { tag: "table" }
    #
    #   # test if any of the node's immediate children are "em" tags
    #   node.match child: { tag: "em" }
    #
    #   # test if any of the node's descendants are "strong" tags
    #   node.match descendant: { tag: "strong" }
    #
    #   # test if the node has between 2 and 4 span tags as immediate children
    #   node.match children: { count: 2..4, only: { tag: "span" } }
    #
    #   # get funky: test to see if the node is a "div", has a "ul" ancestor
    #   # and an "li" parent (with "class" = "enum"), and whether or not it has
    #   # a "span" descendant that contains # text matching /hello world/:
    #   node.match tag: "div",
    #              ancestor: { tag: "ul" },
    #              parent: { tag: "li",
    #                           attributes: { class: "enum" } },
    #              descendant: { tag: "span",
    #                               child: /hello world/ }
    def match(conditions)
      conditions = validate_conditions(conditions)
      # check content of child nodes
      if conditions[:content]
        if children.empty?
          return false unless match_condition("", conditions[:content])
        else
          return false unless children.find { |child| child.match(conditions[:content]) }
        end
      end

      # test the name
      return false unless match_condition(@name, conditions[:tag]) if conditions[:tag]

      # test attributes
      (conditions[:attributes] || {}).each do |key, value|
        return false unless match_condition(self[key], value)
      end

      # test parent
      return false unless parent.match(conditions[:parent]) if conditions[:parent]

      # test children
      return false unless children.find { |child| child.match(conditions[:child]) } if conditions[:child]

      # test ancestors
      if conditions[:ancestor]
        return false unless catch :found do
          p = self
          throw :found, true if p.match(conditions[:ancestor]) while p = p.parent
        end
      end

      # test descendants
      if conditions[:descendant]
        return false unless children.find do |child|
          # test the child
          child.match(conditions[:descendant]) ||
          # test the child's descendants
          child.match(:descendant => conditions[:descendant])
        end
      end

      # count children
      if opts = conditions[:children]
        matches = children.select do |c|
          (c.kind_of?(HTML::Tag) and (c.closing == :self or ! c.childless?))
        end

        matches = matches.select { |c| c.match(opts[:only]) } if opts[:only]
        opts.each do |key, value|
          next if key == :only
          case key
            when :count
              if Integer === value
                return false if matches.length != value
              else
                return false unless value.include?(matches.length)
              end
            when :less_than
              return false unless matches.length < value
            when :greater_than
              return false unless matches.length > value
            else raise "unknown count condition #{key}"
          end
        end
      end

      # test siblings
      if conditions[:sibling] || conditions[:before] || conditions[:after]
        siblings = parent ? parent.children : []
        self_index = siblings.index(self)

        if conditions[:sibling]
          return false unless siblings.detect do |s|
            s != self && s.match(conditions[:sibling])
          end
        end

        if conditions[:before]
          return false unless siblings[self_index+1..-1].detect do |s|
            s != self && s.match(conditions[:before])
          end
        end

        if conditions[:after]
          return false unless siblings[0,self_index].detect do |s|
            s != self && s.match(conditions[:after])
          end
        end
      end

      true
    end

    def ==(node)
      return false unless super
      return false unless closing == node.closing && self.name == node.name
      attributes == node.attributes
    end

    private
      # Match the given value to the given condition.
      def match_condition(value, condition)
        case condition
          when String
            value && value == condition
          when Regexp
            value && value.match(condition)
          when Numeric
            value == condition.to_s
          when true
            !value.nil?
          when false, nil
            value.nil?
          else
            false
        end
      end
  end
end
require 'set'
require 'cgi'
require 'active_support/core_ext/class/attribute_accessors'

module HTML
  class Sanitizer
    def sanitize(text, options = {})
      validate_options(options)
      return text unless sanitizeable?(text)
      tokenize(text, options).join
    end

    def sanitizeable?(text)
      !(text.nil? || text.empty? || !text.index("<"))
    end

  protected
    def tokenize(text, options)
      tokenizer = HTML::Tokenizer.new(text)
      result = []
      while token = tokenizer.next
        node = Node.parse(nil, 0, 0, token, false)
        process_node node, result, options
      end
      result
    end

    def process_node(node, result, options)
      result << node.to_s
    end

    def validate_options(options)
      if options[:tags] && !options[:tags].is_a?(Enumerable)
        raise ArgumentError, "You should pass :tags as an Enumerable"
      end

      if options[:attributes] && !options[:attributes].is_a?(Enumerable)
        raise ArgumentError, "You should pass :attributes as an Enumerable"
      end
    end
  end

  class FullSanitizer < Sanitizer
    def sanitize(text, options = {})
      result = super
      # strip any comments, and if they have a newline at the end (ie. line with
      # only a comment) strip that too
      result = result.gsub(/<!--(.*?)-->[\n]?/m, "") if (result && result =~ /<!--(.*?)-->[\n]?/m)
      # Recurse - handle all dirty nested tags
      result == text ? result : sanitize(result, options)
    end

    def process_node(node, result, options)
      result << node.to_s if node.class == HTML::Text
    end
  end

  class LinkSanitizer < FullSanitizer
    cattr_accessor :included_tags, :instance_writer => false
    self.included_tags = Set.new(%w(a href))

    def sanitizeable?(text)
      !(text.nil? || text.empty? || !((text.index("<a") || text.index("<href")) && text.index(">")))
    end

  protected
    def process_node(node, result, options)
      result << node.to_s unless node.is_a?(HTML::Tag) && included_tags.include?(node.name)
    end
  end

  class WhiteListSanitizer < Sanitizer
    [:protocol_separator, :uri_attributes, :allowed_attributes, :allowed_tags, :allowed_protocols, :bad_tags,
     :allowed_css_properties, :allowed_css_keywords, :shorthand_css_properties].each do |attr|
      class_attribute attr, :instance_writer => false
    end

    # A regular expression of the valid characters used to separate protocols like
    # the ':' in 'http://foo.com'
    self.protocol_separator     = /:|(&#0*58)|(&#x70)|(%|&#37;)3A/

    # Specifies a Set of HTML attributes that can have URIs.
    self.uri_attributes         = Set.new(%w(href src cite action longdesc xlink:href lowsrc))

    # Specifies a Set of 'bad' tags that the #sanitize helper will remove completely, as opposed
    # to just escaping harmless tags like &lt;font&gt;
    self.bad_tags               = Set.new(%w(script))

    # Specifies the default Set of tags that the #sanitize helper will allow unscathed.
    self.allowed_tags           = Set.new(%w(strong em b i p code pre tt samp kbd var sub
      sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr
      acronym a img blockquote del ins))

    # Specifies the default Set of html attributes that the #sanitize helper will leave
    # in the allowed tag.
    self.allowed_attributes     = Set.new(%w(href src width height alt cite datetime title class name xml:lang abbr))

    # Specifies the default Set of acceptable css properties that #sanitize and #sanitize_css will accept.
    self.allowed_protocols      = Set.new(%w(ed2k ftp http https irc mailto news gopher nntp telnet webcal xmpp callto
      feed svn urn aim rsync tag ssh sftp rtsp afs))

    # Specifies the default Set of acceptable css properties that #sanitize and #sanitize_css will accept.
    self.allowed_css_properties = Set.new(%w(azimuth background-color border-bottom-color border-collapse
      border-color border-left-color border-right-color border-top-color clear color cursor direction display
      elevation float font font-family font-size font-style font-variant font-weight height letter-spacing line-height
      overflow pause pause-after pause-before pitch pitch-range richness speak speak-header speak-numeral speak-punctuation
      speech-rate stress text-align text-decoration text-indent unicode-bidi vertical-align voice-family volume white-space
      width))

    # Specifies the default Set of acceptable css keywords that #sanitize and #sanitize_css will accept.
    self.allowed_css_keywords   = Set.new(%w(auto aqua black block blue bold both bottom brown center
      collapse dashed dotted fuchsia gray green !important italic left lime maroon medium none navy normal
      nowrap olive pointer purple red right solid silver teal top transparent underline white yellow))

    # Specifies the default Set of allowed shorthand css properties for the #sanitize and #sanitize_css helpers.
    self.shorthand_css_properties = Set.new(%w(background border margin padding))

    # Sanitizes a block of css code. Used by #sanitize when it comes across a style attribute
    def sanitize_css(style)
      # disallow urls
      style = style.to_s.gsub(/url\s*\(\s*[^\s)]+?\s*\)\s*/, ' ')

      # gauntlet
      if style !~ /^([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*$/ ||
          style !~ /^(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*$/
        return ''
      end

      clean = []
      style.scan(/([-\w]+)\s*:\s*([^:;]*)/) do |prop,val|
        if allowed_css_properties.include?(prop.downcase)
          clean <<  prop + ': ' + val + ';'
        elsif shorthand_css_properties.include?(prop.split('-')[0].downcase)
          unless val.split().any? do |keyword|
            !allowed_css_keywords.include?(keyword) &&
              keyword !~ /^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$/
          end
            clean << prop + ': ' + val + ';'
          end
        end
      end
      clean.join(' ')
    end

  protected
    def tokenize(text, options)
      options[:parent] = []
      options[:attributes] ||= allowed_attributes
      options[:tags]       ||= allowed_tags
      super
    end

    def process_node(node, result, options)
      result << case node
        when HTML::Tag
          if node.closing == :close
            options[:parent].shift
          else
            options[:parent].unshift node.name
          end

          process_attributes_for node, options

          options[:tags].include?(node.name) ? node : nil
        else
          bad_tags.include?(options[:parent].first) ? nil : node.to_s.gsub(/</, "&lt;")
      end
    end

    def process_attributes_for(node, options)
      return unless node.attributes
      node.attributes.keys.each do |attr_name|
        value = node.attributes[attr_name].to_s

        if !options[:attributes].include?(attr_name) || contains_bad_protocols?(attr_name, value)
          node.attributes.delete(attr_name)
        else
          node.attributes[attr_name] = attr_name == 'style' ? sanitize_css(value) : CGI::escapeHTML(CGI::unescapeHTML(value))
        end
      end
    end

    def contains_bad_protocols?(attr_name, value)
      uri_attributes.include?(attr_name) &&
      (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(%|&#37;)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first.downcase.strip))
    end
  end
end
#--
# Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
# Under MIT and/or CC By license.
#++

module HTML

  # Selects HTML elements using CSS 2 selectors.
  #
  # The +Selector+ class uses CSS selector expressions to match and select
  # HTML elements.
  #
  # For example:
  #   selector = HTML::Selector.new "form.login[action=/login]"
  # creates a new selector that matches any +form+ element with the class
  # +login+ and an attribute +action+ with the value <tt>/login</tt>.
  #
  # === Matching Elements
  #
  # Use the #match method to determine if an element matches the selector.
  #
  # For simple selectors, the method returns an array with that element,
  # or +nil+ if the element does not match. For complex selectors (see below)
  # the method returns an array with all matched elements, of +nil+ if no
  # match found.
  #
  # For example:
  #   if selector.match(element)
  #     puts "Element is a login form"
  #   end
  #
  # === Selecting Elements
  #
  # Use the #select method to select all matching elements starting with
  # one element and going through all children in depth-first order.
  #
  # This method returns an array of all matching elements, an empty array
  # if no match is found
  #
  # For example:
  #   selector = HTML::Selector.new "input[type=text]"
  #   matches = selector.select(element)
  #   matches.each do |match|
  #     puts "Found text field with name #{match.attributes['name']}"
  #   end
  #
  # === Expressions
  #
  # Selectors can match elements using any of the following criteria:
  # * <tt>name</tt> -- Match an element based on its name (tag name).
  #   For example, <tt>p</tt> to match a paragraph. You can use <tt>*</tt>
  #   to match any element.
  # * <tt>#</tt><tt>id</tt> -- Match an element based on its identifier (the
  #   <tt>id</tt> attribute). For example, <tt>#</tt><tt>page</tt>.
  # * <tt>.class</tt> -- Match an element based on its class name, all
  #   class names if more than one specified.
  # * <tt>[attr]</tt> -- Match an element that has the specified attribute.
  # * <tt>[attr=value]</tt> -- Match an element that has the specified
  #   attribute and value. (More operators are supported see below)
  # * <tt>:pseudo-class</tt> -- Match an element based on a pseudo class,
  #   such as <tt>:nth-child</tt> and <tt>:empty</tt>.
  # * <tt>:not(expr)</tt> -- Match an element that does not match the
  #   negation expression.
  #
  # When using a combination of the above, the element name comes first
  # followed by identifier, class names, attributes, pseudo classes and
  # negation in any order. Do not separate these parts with spaces!
  # Space separation is used for descendant selectors.
  #
  # For example:
  #   selector = HTML::Selector.new "form.login[action=/login]"
  # The matched element must be of type +form+ and have the class +login+.
  # It may have other classes, but the class +login+ is required to match.
  # It must also have an attribute called +action+ with the value
  # <tt>/login</tt>.
  #
  # This selector will match the following element:
  #   <form class="login form" method="post" action="/login">
  # but will not match the element:
  #   <form method="post" action="/logout">
  #
  # === Attribute Values
  #
  # Several operators are supported for matching attributes:
  # * <tt>name</tt> -- The element must have an attribute with that name.
  # * <tt>name=value</tt> -- The element must have an attribute with that
  #   name and value.
  # * <tt>name^=value</tt> -- The attribute value must start with the
  #   specified value.
  # * <tt>name$=value</tt> -- The attribute value must end with the
  #   specified value.
  # * <tt>name*=value</tt> -- The attribute value must contain the
  #   specified value.
  # * <tt>name~=word</tt> -- The attribute value must contain the specified
  #   word (space separated).
  # * <tt>name|=word</tt> -- The attribute value must start with specified
  #   word.
  #
  # For example, the following two selectors match the same element:
  #   #my_id
  #   [id=my_id]
  # and so do the following two selectors:
  #   .my_class
  #   [class~=my_class]
  #
  # === Alternatives, siblings, children
  #
  # Complex selectors use a combination of expressions to match elements:
  # * <tt>expr1 expr2</tt> -- Match any element against the second expression
  #   if it has some parent element that matches the first expression.
  # * <tt>expr1 > expr2</tt> -- Match any element against the second expression
  #   if it is the child of an element that matches the first expression.
  # * <tt>expr1 + expr2</tt> -- Match any element against the second expression
  #   if it immediately follows an element that matches the first expression.
  # * <tt>expr1 ~ expr2</tt> -- Match any element against the second expression
  #   that comes after an element that matches the first expression.
  # * <tt>expr1, expr2</tt> -- Match any element against the first expression,
  #   or against the second expression.
  #
  # Since children and sibling selectors may match more than one element given
  # the first element, the #match method may return more than one match.
  #
  # === Pseudo classes
  #
  # Pseudo classes were introduced in CSS 3. They are most often used to select
  # elements in a given position:
  # * <tt>:root</tt> -- Match the element only if it is the root element
  #   (no parent element).
  # * <tt>:empty</tt> -- Match the element only if it has no child elements,
  #   and no text content.
  # * <tt>:content(string)</tt> -- Match the element only if it has <tt>string</tt>
  #   as its text content (ignoring leading and trailing whitespace).
  # * <tt>:only-child</tt> -- Match the element if it is the only child (element)
  #   of its parent element.
  # * <tt>:only-of-type</tt> -- Match the element if it is the only child (element)
  #   of its parent element and its type.
  # * <tt>:first-child</tt> -- Match the element if it is the first child (element)
  #   of its parent element.
  # * <tt>:first-of-type</tt> -- Match the element if it is the first child (element)
  #   of its parent element of its type.
  # * <tt>:last-child</tt> -- Match the element if it is the last child (element)
  #   of its parent element.
  # * <tt>:last-of-type</tt> -- Match the element if it is the last child (element)
  #   of its parent element of its type.
  # * <tt>:nth-child(b)</tt> -- Match the element if it is the b-th child (element)
  #   of its parent element. The value <tt>b</tt> specifies its index, starting with 1.
  # * <tt>:nth-child(an+b)</tt> -- Match the element if it is the b-th child (element)
  #   in each group of <tt>a</tt> child elements of its parent element.
  # * <tt>:nth-child(-an+b)</tt> -- Match the element if it is the first child (element)
  #   in each group of <tt>a</tt> child elements, up to the first <tt>b</tt> child
  #   elements of its parent element.
  # * <tt>:nth-child(odd)</tt> -- Match element in the odd position (i.e. first, third).
  #   Same as <tt>:nth-child(2n+1)</tt>.
  # * <tt>:nth-child(even)</tt> -- Match element in the even position (i.e. second,
  #   fourth). Same as <tt>:nth-child(2n+2)</tt>.
  # * <tt>:nth-of-type(..)</tt> -- As above, but only counts elements of its type.
  # * <tt>:nth-last-child(..)</tt> -- As above, but counts from the last child.
  # * <tt>:nth-last-of-type(..)</tt> -- As above, but counts from the last child and
  #   only elements of its type.
  # * <tt>:not(selector)</tt> -- Match the element only if the element does not
  #   match the simple selector.
  #
  # As you can see, <tt>:nth-child</tt> pseudo class and its variant can get quite
  # tricky and the CSS specification doesn't do a much better job explaining it.
  # But after reading the examples and trying a few combinations, it's easy to
  # figure out.
  #
  # For example:
  #   table tr:nth-child(odd)
  # Selects every second row in the table starting with the first one.
  #
  #   div p:nth-child(4)
  # Selects the fourth paragraph in the +div+, but not if the +div+ contains
  # other elements, since those are also counted.
  #
  #   div p:nth-of-type(4)
  # Selects the fourth paragraph in the +div+, counting only paragraphs, and
  # ignoring all other elements.
  #
  #   div p:nth-of-type(-n+4)
  # Selects the first four paragraphs, ignoring all others.
  #
  # And you can always select an element that matches one set of rules but
  # not another using <tt>:not</tt>. For example:
  #   p:not(.post)
  # Matches all paragraphs that do not have the class <tt>.post</tt>.
  #
  # === Substitution Values
  #
  # You can use substitution with identifiers, class names and element values.
  # A substitution takes the form of a question mark (<tt>?</tt>) and uses the
  # next value in the argument list following the CSS expression.
  #
  # The substitution value may be a string or a regular expression. All other
  # values are converted to strings.
  #
  # For example:
  #   selector = HTML::Selector.new "#?", /^\d+$/
  # matches any element whose identifier consists of one or more digits.
  #
  # See http://www.w3.org/TR/css3-selectors/
  class Selector


    # An invalid selector.
    class InvalidSelectorError < StandardError #:nodoc:
    end


    class << self

      # :call-seq:
      #   Selector.for_class(cls) => selector
      #
      # Creates a new selector for the given class name.
      def for_class(cls)
        self.new([".?", cls])
      end


      # :call-seq:
      #   Selector.for_id(id) => selector
      #
      # Creates a new selector for the given id.
      def for_id(id)
        self.new(["#?", id])
      end

    end


    # :call-seq:
    #   Selector.new(string, [values ...]) => selector
    #
    # Creates a new selector from a CSS 2 selector expression.
    #
    # The first argument is the selector expression. All other arguments
    # are used for value substitution.
    #
    # Throws InvalidSelectorError is the selector expression is invalid.
    def initialize(selector, *values)
      raise ArgumentError, "CSS expression cannot be empty" if selector.empty?
      @source = ""
      values = values[0] if values.size == 1 && values[0].is_a?(Array)

      # We need a copy to determine if we failed to parse, and also
      # preserve the original pass by-ref statement.
      statement = selector.strip.dup

      # Create a simple selector, along with negation.
      simple_selector(statement, values).each { |name, value| instance_variable_set("@#{name}", value) }

      @alternates = []
      @depends = nil

      # Alternative selector.
      if statement.sub!(/^\s*,\s*/, "")
        second = Selector.new(statement, values)
        @alternates << second
        # If there are alternate selectors, we group them in the top selector.
        if alternates = second.instance_variable_get(:@alternates)
          second.instance_variable_set(:@alternates, [])
          @alternates.concat alternates
        end
        @source << " , " << second.to_s
      # Sibling selector: create a dependency into second selector that will
      # match element immediately following this one.
      elsif statement.sub!(/^\s*\+\s*/, "")
        second = next_selector(statement, values)
        @depends = lambda do |element, first|
          if element = next_element(element)
            second.match(element, first)
          end
        end
        @source << " + " << second.to_s
      # Adjacent selector: create a dependency into second selector that will
      # match all elements following this one.
      elsif statement.sub!(/^\s*~\s*/, "")
        second = next_selector(statement, values)
        @depends = lambda do |element, first|
          matches = []
          while element = next_element(element)
            if subset = second.match(element, first)
              if first && !subset.empty?
                matches << subset.first
                break
              else
                matches.concat subset
              end
            end
          end
          matches.empty? ? nil : matches
        end
        @source << " ~ " << second.to_s
      # Child selector: create a dependency into second selector that will
      # match a child element of this one.
      elsif statement.sub!(/^\s*>\s*/, "")
        second = next_selector(statement, values)
        @depends = lambda do |element, first|
          matches = []
          element.children.each do |child|
            if child.tag? && subset = second.match(child, first)
              if first && !subset.empty?
                matches << subset.first
                break
              else
                matches.concat subset
              end
            end
          end
          matches.empty? ? nil : matches
        end
        @source << " > " << second.to_s
      # Descendant selector: create a dependency into second selector that
      # will match all descendant elements of this one. Note,
      elsif statement =~ /^\s+\S+/ && statement != selector
        second = next_selector(statement, values)
        @depends = lambda do |element, first|
          matches = []
          stack = element.children.reverse
          while node = stack.pop
            next unless node.tag?
            if subset = second.match(node, first)
              if first && !subset.empty?
                matches << subset.first
                break
              else
                matches.concat subset
              end
            elsif children = node.children
              stack.concat children.reverse
            end
          end
          matches.empty? ? nil : matches
        end
        @source << " " << second.to_s
      else
        # The last selector is where we check that we parsed
        # all the parts.
        unless statement.empty? || statement.strip.empty?
          raise ArgumentError, "Invalid selector: #{statement}"
        end
      end
    end


    # :call-seq:
    #   match(element, first?) => array or nil
    #
    # Matches an element against the selector.
    #
    # For a simple selector this method returns an array with the
    # element if the element matches, nil otherwise.
    #
    # For a complex selector (sibling and descendant) this method
    # returns an array with all matching elements, nil if no match is
    # found.
    #
    # Use +first_only=true+ if you are only interested in the first element.
    #
    # For example:
    #   if selector.match(element)
    #     puts "Element is a login form"
    #   end
    def match(element, first_only = false)
      # Match element if no element name or element name same as element name
      if matched = (!@tag_name || @tag_name == element.name)
        # No match if one of the attribute matches failed
        for attr in @attributes
          if element.attributes[attr[0]] !~ attr[1]
            matched = false
            break
          end
        end
      end

      # Pseudo class matches (nth-child, empty, etc).
      if matched
        for pseudo in @pseudo
          unless pseudo.call(element)
            matched = false
            break
          end
        end
      end

      # Negation. Same rules as above, but we fail if a match is made.
      if matched && @negation
        for negation in @negation
          if negation[:tag_name] == element.name
            matched = false
          else
            for attr in negation[:attributes]
              if element.attributes[attr[0]] =~ attr[1]
                matched = false
                break
              end
            end
          end
          if matched
            for pseudo in negation[:pseudo]
              if pseudo.call(element)
                matched = false
                break
              end
            end
          end
          break unless matched
        end
      end

      # If element matched but depends on another element (child,
      # sibling, etc), apply the dependent matches instead.
      if matched && @depends
        matches = @depends.call(element, first_only)
      else
        matches = matched ? [element] : nil
      end

      # If this selector is part of the group, try all the alternative
      # selectors (unless first_only).
      if !first_only || !matches
        @alternates.each do |alternate|
          break if matches && first_only
          if subset = alternate.match(element, first_only)
            if matches
              matches.concat subset
            else
              matches = subset
            end
          end
        end
      end

      matches
    end


    # :call-seq:
    #   select(root) => array
    #
    # Selects and returns an array with all matching elements, beginning
    # with one node and traversing through all children depth-first.
    # Returns an empty array if no match is found.
    #
    # The root node may be any element in the document, or the document
    # itself.
    #
    # For example:
    #   selector = HTML::Selector.new "input[type=text]"
    #   matches = selector.select(element)
    #   matches.each do |match|
    #     puts "Found text field with name #{match.attributes['name']}"
    #   end
    def select(root)
      matches = []
      stack = [root]
      while node = stack.pop
        if node.tag? && subset = match(node, false)
          subset.each do |match|
            matches << match unless matches.any? { |item| item.equal?(match) }
          end
        elsif children = node.children
          stack.concat children.reverse
        end
      end
      matches
    end


    # Similar to #select but returns the first matching element. Returns +nil+
    # if no element matches the selector.
    def select_first(root)
      stack = [root]
      while node = stack.pop
        if node.tag? && subset = match(node, true)
          return subset.first if !subset.empty?
        elsif children = node.children
          stack.concat children.reverse
        end
      end
      nil
    end


    def to_s #:nodoc:
      @source
    end


    # Return the next element after this one. Skips sibling text nodes.
    #
    # With the +name+ argument, returns the next element with that name,
    # skipping other sibling elements.
    def next_element(element, name = nil)
      if siblings = element.parent.children
        found = false
        siblings.each do |node|
          if node.equal?(element)
            found = true
          elsif found && node.tag?
            return node if (name.nil? || node.name == name)
          end
        end
      end
      nil
    end


  protected


    # Creates a simple selector given the statement and array of
    # substitution values.
    #
    # Returns a hash with the values +tag_name+, +attributes+,
    # +pseudo+ (classes) and +negation+.
    #
    # Called the first time with +can_negate+ true to allow
    # negation. Called a second time with false since negation
    # cannot be negated.
    def simple_selector(statement, values, can_negate = true)
      tag_name = nil
      attributes = []
      pseudo = []
      negation = []

      # Element name. (Note that in negation, this can come at
      # any order, but for simplicity we allow if only first).
      statement.sub!(/^(\*|[[:alpha:]][\w\-]*)/) do |match|
        match.strip!
        tag_name = match.downcase unless match == "*"
        @source << match
        "" # Remove
      end

      # Get identifier, class, attribute name, pseudo or negation.
      while true
        # Element identifier.
        next if statement.sub!(/^#(\?|[\w\-]+)/) do |match|
          id = $1
          if id == "?"
            id = values.shift
          end
          @source << "##{id}"
          id = Regexp.new("^#{Regexp.escape(id.to_s)}$") unless id.is_a?(Regexp)
          attributes << ["id", id]
          "" # Remove
        end

        # Class name.
        next if statement.sub!(/^\.([\w\-]+)/) do |match|
          class_name = $1
          @source << ".#{class_name}"
          class_name = Regexp.new("(^|\s)#{Regexp.escape(class_name)}($|\s)") unless class_name.is_a?(Regexp)
          attributes << ["class", class_name]
          "" # Remove
        end

        # Attribute value.
        next if statement.sub!(/^\[\s*([[:alpha:]][\w\-:]*)\s*((?:[~|^$*])?=)?\s*('[^']*'|"[^*]"|[^\]]*)\s*\]/) do |match|
          name, equality, value = $1, $2, $3
          if value == "?"
            value = values.shift
          else
            # Handle single and double quotes.
            value.strip!
            if (value[0] == ?" || value[0] == ?') && value[0] == value[-1]
              value = value[1..-2]
            end
          end
          @source << "[#{name}#{equality}'#{value}']"
          attributes << [name.downcase.strip, attribute_match(equality, value)]
          "" # Remove
        end

        # Root element only.
        next if statement.sub!(/^:root/) do |match|
          pseudo << lambda do |element|
            element.parent.nil? || !element.parent.tag?
          end
          @source << ":root"
          "" # Remove
        end

        # Nth-child including last and of-type.
        next if statement.sub!(/^:nth-(last-)?(child|of-type)\((odd|even|(\d+|\?)|(-?\d*|\?)?n([+\-]\d+|\?)?)\)/) do |match|
          reverse = $1 == "last-"
          of_type = $2 == "of-type"
          @source << ":nth-#{$1}#{$2}("
          case $3
            when "odd"
              pseudo << nth_child(2, 1, of_type, reverse)
              @source << "odd)"
            when "even"
              pseudo << nth_child(2, 2, of_type, reverse)
              @source << "even)"
            when /^(\d+|\?)$/  # b only
              b = ($1 == "?" ? values.shift : $1).to_i
              pseudo << nth_child(0, b, of_type, reverse)
              @source << "#{b})"
            when /^(-?\d*|\?)?n([+\-]\d+|\?)?$/
              a = ($1 == "?" ? values.shift :
                   $1 == "" ? 1 : $1 == "-" ? -1 : $1).to_i
              b = ($2 == "?" ? values.shift : $2).to_i
              pseudo << nth_child(a, b, of_type, reverse)
              @source << (b >= 0 ? "#{a}n+#{b})" : "#{a}n#{b})")
            else
              raise ArgumentError, "Invalid nth-child #{match}"
          end
          "" # Remove
        end
        # First/last child (of type).
        next if statement.sub!(/^:(first|last)-(child|of-type)/) do |match|
          reverse = $1 == "last"
          of_type = $2 == "of-type"
          pseudo << nth_child(0, 1, of_type, reverse)
          @source << ":#{$1}-#{$2}"
          "" # Remove
        end
        # Only child (of type).
        next if statement.sub!(/^:only-(child|of-type)/) do |match|
          of_type = $1 == "of-type"
          pseudo << only_child(of_type)
          @source << ":only-#{$1}"
          "" # Remove
        end

        # Empty: no child elements or meaningful content (whitespaces
        # are ignored).
        next if statement.sub!(/^:empty/) do |match|
          pseudo << lambda do |element|
            empty = true
            for child in element.children
              if child.tag? || !child.content.strip.empty?
                empty = false
                break
              end
            end
            empty
          end
          @source << ":empty"
          "" # Remove
        end
        # Content: match the text content of the element, stripping
        # leading and trailing spaces.
        next if statement.sub!(/^:content\(\s*(\?|'[^']*'|"[^"]*"|[^)]*)\s*\)/) do |match|
          content = $1
          if content == "?"
            content = values.shift
          elsif (content[0] == ?" || content[0] == ?') && content[0] == content[-1]
            content = content[1..-2]
          end
          @source << ":content('#{content}')"
          content = Regexp.new("^#{Regexp.escape(content.to_s)}$") unless content.is_a?(Regexp)
          pseudo << lambda do |element|
            text = ""
            for child in element.children
              unless child.tag?
                text << child.content
              end
            end
            text.strip =~ content
          end
          "" # Remove
        end

        # Negation. Create another simple selector to handle it.
        if statement.sub!(/^:not\(\s*/, "")
          raise ArgumentError, "Double negatives are not missing feature" unless can_negate
          @source << ":not("
          negation << simple_selector(statement, values, false)
          raise ArgumentError, "Negation not closed" unless statement.sub!(/^\s*\)/, "")
          @source << ")"
          next
        end

        # No match: moving on.
        break
      end

      # Return hash. The keys are mapped to instance variables.
      {:tag_name=>tag_name, :attributes=>attributes, :pseudo=>pseudo, :negation=>negation}
    end


    # Create a regular expression to match an attribute value based
    # on the equality operator (=, ^=, |=, etc).
    def attribute_match(equality, value)
      regexp = value.is_a?(Regexp) ? value : Regexp.escape(value.to_s)
      case equality
        when "=" then
          # Match the attribute value in full
          Regexp.new("^#{regexp}$")
        when "~=" then
          # Match a space-separated word within the attribute value
          Regexp.new("(^|\s)#{regexp}($|\s)")
        when "^="
          # Match the beginning of the attribute value
          Regexp.new("^#{regexp}")
        when "$="
          # Match the end of the attribute value
          Regexp.new("#{regexp}$")
        when "*="
          # Match substring of the attribute value
          regexp.is_a?(Regexp) ? regexp : Regexp.new(regexp)
        when "|=" then
          # Match the first space-separated item of the attribute value
          Regexp.new("^#{regexp}($|\s)")
        else
          raise InvalidSelectorError, "Invalid operation/value" unless value.empty?
          # Match all attributes values (existence check)
          //
      end
    end


    # Returns a lambda that can match an element against the nth-child
    # pseudo class, given the following arguments:
    # * +a+ -- Value of a part.
    # * +b+ -- Value of b part.
    # * +of_type+ -- True to test only elements of this type (of-type).
    # * +reverse+ -- True to count in reverse order (last-).
    def nth_child(a, b, of_type, reverse)
      # a = 0 means select at index b, if b = 0 nothing selected
      return lambda { |element| false } if a == 0 && b == 0
      # a < 0 and b < 0 will never match against an index
      return lambda { |element| false } if a < 0 && b < 0
      b = a + b + 1 if b < 0   # b < 0 just picks last element from each group
      b -= 1 unless b == 0  # b == 0 is same as b == 1, otherwise zero based
      lambda do |element|
        # Element must be inside parent element.
        return false unless element.parent && element.parent.tag?
        index = 0
        # Get siblings, reverse if counting from last.
        siblings = element.parent.children
        siblings = siblings.reverse if reverse
        # Match element name if of-type, otherwise ignore name.
        name = of_type ? element.name : nil
        found = false
        for child in siblings
          # Skip text nodes/comments.
          if child.tag? && (name == nil || child.name == name)
            if a == 0
              # Shortcut when a == 0 no need to go past count
              if index == b
                found = child.equal?(element)
                break
              end
            elsif a < 0
              # Only look for first b elements
              break if index > b
              if child.equal?(element)
                found = (index % a) == 0
                break
              end
            else
              # Otherwise, break if child found and count ==  an+b
              if child.equal?(element)
                found = (index % a) == b
                break
              end
            end
            index += 1
          end
        end
        found
      end
    end


    # Creates a only child lambda. Pass +of-type+ to only look at
    # elements of its type.
    def only_child(of_type)
      lambda do |element|
        # Element must be inside parent element.
        return false unless element.parent && element.parent.tag?
        name = of_type ? element.name : nil
        other = false
        for child in element.parent.children
          # Skip text nodes/comments.
          if child.tag? && (name == nil || child.name == name)
            unless child.equal?(element)
              other = true
              break
            end
          end
        end
        !other
      end
    end


    # Called to create a dependent selector (sibling, descendant, etc).
    # Passes the remainder of the statement that will be reduced to zero
    # eventually, and array of substitution values.
    #
    # This method is called from four places, so it helps to put it here
    # for reuse. The only logic deals with the need to detect comma
    # separators (alternate) and apply them to the selector group of the
    # top selector.
    def next_selector(statement, values)
      second = Selector.new(statement, values)
      # If there are alternate selectors, we group them in the top selector.
      if alternates = second.instance_variable_get(:@alternates)
        second.instance_variable_set(:@alternates, [])
        @alternates.concat alternates
      end
      second
    end

  end


  # See HTML::Selector.new
  def self.selector(statement, *values)
    Selector.new(statement, *values)
  end


  class Tag

    def select(selector, *values)
      selector = HTML::Selector.new(selector, values)
      selector.select(self)
    end

  end

end
require 'strscan'

module HTML #:nodoc:

  # A simple HTML tokenizer. It simply breaks a stream of text into tokens, where each
  # token is a string. Each string represents either "text", or an HTML element.
  #
  # This currently assumes valid XHTML, which means no free < or > characters.
  #
  # Usage:
  #
  #   tokenizer = HTML::Tokenizer.new(text)
  #   while token = tokenizer.next
  #     p token
  #   end
  class Tokenizer #:nodoc:

    # The current (byte) position in the text
    attr_reader :position

    # The current line number
    attr_reader :line

    # Create a new Tokenizer for the given text.
    def initialize(text)
      text.encode!
      @scanner = StringScanner.new(text)
      @position = 0
      @line = 0
      @current_line = 1
    end

    # Return the next token in the sequence, or +nil+ if there are no more tokens in
    # the stream.
    def next
      return nil if @scanner.eos?
      @position = @scanner.pos
      @line = @current_line
      if @scanner.check(/<\S/)
        update_current_line(scan_tag)
      else
        update_current_line(scan_text)
      end
    end

    private

      # Treat the text at the current position as a tag, and scan it. Supports
      # comments, doctype tags, and regular tags, and ignores less-than and
      # greater-than characters within quoted strings.
      def scan_tag
        tag = @scanner.getch
        if @scanner.scan(/!--/) # comment
          tag << @scanner.matched
          tag << (@scanner.scan_until(/--\s*>/) || @scanner.scan_until(/\Z/))
        elsif @scanner.scan(/!\[CDATA\[/)
          tag << @scanner.matched
          tag << (@scanner.scan_until(/\]\]>/) || @scanner.scan_until(/\Z/))
        elsif @scanner.scan(/!/) # doctype
          tag << @scanner.matched
          tag << consume_quoted_regions
        else
          tag << consume_quoted_regions
        end
        tag
      end

      # Scan all text up to the next < character and return it.
      def scan_text
        "#{@scanner.getch}#{@scanner.scan(/[^<]*/)}"
      end

      # Counts the number of newlines in the text and updates the current line
      # accordingly.
      def update_current_line(text)
        text.scan(/\r?\n/) { @current_line += 1 }
      end

      # Skips over quoted strings, so that less-than and greater-than characters
      # within the strings are ignored.
      def consume_quoted_regions
        text = ""
        loop do
          match = @scanner.scan_until(/['"<>]/) or break

          delim = @scanner.matched
          if delim == "<"
            match = match.chop
            @scanner.pos -= 1
          end

          text << match
          break if delim == "<" || delim == ">"

          # consume the quoted region
          while match = @scanner.scan_until(/[\\#{delim}]/)
            text << match
            break if @scanner.matched == delim
            break if @scanner.eos?
            text << @scanner.getch # skip the escaped character
          end
        end
        text
      end
  end

end
module HTML #:nodoc:
  module Version #:nodoc:

    MAJOR = 0
    MINOR = 5
    TINY  = 3

    STRING = [ MAJOR, MINOR, TINY ].join(".")

  end
end
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/html-scanner"

module HTML
  extend ActiveSupport::Autoload

  eager_autoload do
    autoload :CDATA, 'html/node'
    autoload :Document, 'html/document'
    autoload :FullSanitizer, 'html/sanitizer'
    autoload :LinkSanitizer, 'html/sanitizer'
    autoload :Node, 'html/node'
    autoload :Sanitizer, 'html/sanitizer'
    autoload :Selector, 'html/selector'
    autoload :Tag, 'html/node'
    autoload :Text, 'html/node'
    autoload :Tokenizer, 'html/tokenizer'
    autoload :Version, 'html/version'
    autoload :WhiteListSanitizer, 'html/sanitizer'
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'active_support'
require 'active_support/rails'
require 'action_pack'

module ActionView
  extend ActiveSupport::Autoload

  eager_autoload do
    autoload :Base
    autoload :Context
    autoload :CompiledTemplates, "action_view/context"
    autoload :Digestor
    autoload :Helpers
    autoload :LookupContext
    autoload :PathSet
    autoload :RecordIdentifier
    autoload :RoutingUrlFor
    autoload :Template

    autoload_under "renderer" do
      autoload :Renderer
      autoload :AbstractRenderer
      autoload :PartialRenderer
      autoload :TemplateRenderer
      autoload :StreamingTemplateRenderer
    end

    autoload_at "action_view/template/resolver" do
      autoload :Resolver
      autoload :PathResolver
      autoload :FileSystemResolver
      autoload :OptimizedFileSystemResolver
      autoload :FallbackFileSystemResolver
    end

    autoload_at "action_view/buffers" do
      autoload :OutputBuffer
      autoload :StreamingBuffer
    end

    autoload_at "action_view/flows" do
      autoload :OutputFlow
      autoload :StreamingFlow
    end

    autoload_at "action_view/template/error" do
      autoload :MissingTemplate
      autoload :ActionViewError
      autoload :EncodingError
      autoload :MissingRequestError
      autoload :TemplateError
      autoload :WrongEncodingError
    end
  end

  autoload :TestCase

  ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'

  def self.eager_load!
    super
    ActionView::Template.eager_load!
  end
end

require 'active_support/core_ext/string/output_safety'

ActiveSupport.on_load(:i18n) do
  I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
end
require 'active_model'

class Person
  include ActiveModel::Conversion
  include ActiveModel::Validations

  validates_presence_of :name

  attr_accessor :name

  def initialize(attributes = {})
    @name = attributes[:name]
  end

  def persist
    @persisted = true
  end

  def persisted?
    @persisted
  end
end

person1 = Person.new
p person1.valid? # => false
p person1.errors.messages # => {:name=>["can't be blank"]}

person2 = Person.new(:name => "matz")
p person2.valid? # => true
require 'thread_safe'

module ActiveModel
  # Raised when an attribute is not defined.
  #
  #   class User < ActiveRecord::Base
  #     has_many :pets
  #   end
  #
  #   user = User.first
  #   user.pets.select(:id).first.user_id
  #   # => ActiveModel::MissingAttributeError: missing attribute: user_id
  class MissingAttributeError < NoMethodError
  end
  # == Active \Model Attribute Methods
  #
  # <tt>ActiveModel::AttributeMethods</tt> provides a way to add prefixes and
  # suffixes to your methods as well as handling the creation of Active Record
  # like class methods such as +table_name+.
  #
  # The requirements to implement ActiveModel::AttributeMethods are to:
  #
  # * <tt>include ActiveModel::AttributeMethods</tt> in your object.
  # * Call each Attribute Method module method you want to add, such as
  #   +attribute_method_suffix+ or +attribute_method_prefix+.
  # * Call +define_attribute_methods+ after the other methods are called.
  # * Define the various generic +_attribute+ methods that you have declared.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #     include ActiveModel::AttributeMethods
  #
  #     attribute_method_affix  prefix: 'reset_', suffix: '_to_default!'
  #     attribute_method_suffix '_contrived?'
  #     attribute_method_prefix 'clear_'
  #     define_attribute_methods :name
  #
  #     attr_accessor :name
  #
  #     private
  #
  #     def attribute_contrived?(attr)
  #       true
  #     end
  #
  #     def clear_attribute(attr)
  #       send("#{attr}=", nil)
  #     end
  #
  #     def reset_attribute_to_default!(attr)
  #       send("#{attr}=", 'Default Name')
  #     end
  #   end
  #
  # Note that whenever you include ActiveModel::AttributeMethods in your class,
  # it requires you to implement an +attributes+ method which returns a hash
  # with each attribute name in your model as hash key and the attribute value as
  # hash value.
  #
  # Hash keys must be strings.
  module AttributeMethods
    extend ActiveSupport::Concern

    NAME_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?=]?\z/
    CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/

    included do
      class_attribute :attribute_aliases, :attribute_method_matchers, instance_writer: false
      self.attribute_aliases = {}
      self.attribute_method_matchers = [ClassMethods::AttributeMethodMatcher.new]
    end

    module ClassMethods
      # Declares a method available for all attributes with the given prefix.
      # Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
      #
      #   #{prefix}#{attr}(*args, &block)
      #
      # to
      #
      #   #{prefix}attribute(#{attr}, *args, &block)
      #
      # An instance method <tt>#{prefix}attribute</tt> must exist and accept
      # at least the +attr+ argument.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_prefix 'clear_'
      #     define_attribute_methods :name
      #
      #     private
      #
      #     def clear_attribute(attr)
      #       send("#{attr}=", nil)
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name = 'Bob'
      #   person.name          # => "Bob"
      #   person.clear_name
      #   person.name          # => nil
      def attribute_method_prefix(*prefixes)
        self.attribute_method_matchers += prefixes.map! { |prefix| AttributeMethodMatcher.new prefix: prefix }
        undefine_attribute_methods
      end

      # Declares a method available for all attributes with the given suffix.
      # Uses +method_missing+ and <tt>respond_to?</tt> to rewrite the method.
      #
      #   #{attr}#{suffix}(*args, &block)
      #
      # to
      #
      #   attribute#{suffix}(#{attr}, *args, &block)
      #
      # An <tt>attribute#{suffix}</tt> instance method must exist and accept at
      # least the +attr+ argument.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_suffix '_short?'
      #     define_attribute_methods :name
      #
      #     private
      #
      #     def attribute_short?(attr)
      #       send(attr).length < 5
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name = 'Bob'
      #   person.name          # => "Bob"
      #   person.name_short?   # => true
      def attribute_method_suffix(*suffixes)
        self.attribute_method_matchers += suffixes.map! { |suffix| AttributeMethodMatcher.new suffix: suffix }
        undefine_attribute_methods
      end

      # Declares a method available for all attributes with the given prefix
      # and suffix. Uses +method_missing+ and <tt>respond_to?</tt> to rewrite
      # the method.
      #
      #   #{prefix}#{attr}#{suffix}(*args, &block)
      #
      # to
      #
      #   #{prefix}attribute#{suffix}(#{attr}, *args, &block)
      #
      # An <tt>#{prefix}attribute#{suffix}</tt> instance method must exist and
      # accept at least the +attr+ argument.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_affix prefix: 'reset_', suffix: '_to_default!'
      #     define_attribute_methods :name
      #
      #     private
      #
      #     def reset_attribute_to_default!(attr)
      #       ...
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name                         # => 'Gem'
      #   person.reset_name_to_default!
      #   person.name                         # => 'Gemma'
      def attribute_method_affix(*affixes)
        self.attribute_method_matchers += affixes.map! { |affix| AttributeMethodMatcher.new prefix: affix[:prefix], suffix: affix[:suffix] }
        undefine_attribute_methods
      end


      # Allows you to make aliases for attributes.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_suffix '_short?'
      #     define_attribute_methods :name
      #
      #     alias_attribute :nickname, :name
      #
      #     private
      #
      #     def attribute_short?(attr)
      #       send(attr).length < 5
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name = 'Bob'
      #   person.name            # => "Bob"
      #   person.nickname        # => "Bob"
      #   person.name_short?     # => true
      #   person.nickname_short? # => true
      def alias_attribute(new_name, old_name)
        self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s)
        attribute_method_matchers.each do |matcher|
          matcher_new = matcher.method_name(new_name).to_s
          matcher_old = matcher.method_name(old_name).to_s
          define_proxy_call false, self, matcher_new, matcher_old
        end
      end

      # Declares the attributes that should be prefixed and suffixed by
      # ActiveModel::AttributeMethods.
      #
      # To use, pass attribute names (as strings or symbols), be sure to declare
      # +define_attribute_methods+ after you define any prefix, suffix or affix
      # methods, or they will not hook in.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name, :age, :address
      #     attribute_method_prefix 'clear_'
      #
      #     # Call to define_attribute_methods must appear after the
      #     # attribute_method_prefix, attribute_method_suffix or
      #     # attribute_method_affix declares.
      #     define_attribute_methods :name, :age, :address
      #
      #     private
      #
      #     def clear_attribute(attr)
      #       ...
      #     end
      #   end
      def define_attribute_methods(*attr_names)
        attr_names.flatten.each { |attr_name| define_attribute_method(attr_name) }
      end

      # Declares an attribute that should be prefixed and suffixed by
      # ActiveModel::AttributeMethods.
      #
      # To use, pass an attribute name (as string or symbol), be sure to declare
      # +define_attribute_method+ after you define any prefix, suffix or affix
      # method, or they will not hook in.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_suffix '_short?'
      #
      #     # Call to define_attribute_method must appear after the
      #     # attribute_method_prefix, attribute_method_suffix or
      #     # attribute_method_affix declares.
      #     define_attribute_method :name
      #
      #     private
      #
      #     def attribute_short?(attr)
      #       send(attr).length < 5
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name = 'Bob'
      #   person.name        # => "Bob"
      #   person.name_short? # => true
      def define_attribute_method(attr_name)
        attribute_method_matchers.each do |matcher|
          method_name = matcher.method_name(attr_name)

          unless instance_method_already_implemented?(method_name)
            generate_method = "define_method_#{matcher.method_missing_target}"

            if respond_to?(generate_method, true)
              send(generate_method, attr_name)
            else
              define_proxy_call true, generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
            end
          end
        end
        attribute_method_matchers_cache.clear
      end

      # Removes all the previously dynamically defined methods from the class.
      #
      #   class Person
      #     include ActiveModel::AttributeMethods
      #
      #     attr_accessor :name
      #     attribute_method_suffix '_short?'
      #     define_attribute_method :name
      #
      #     private
      #
      #     def attribute_short?(attr)
      #       send(attr).length < 5
      #     end
      #   end
      #
      #   person = Person.new
      #   person.name = 'Bob'
      #   person.name_short? # => true
      #
      #   Person.undefine_attribute_methods
      #
      #   person.name_short? # => NoMethodError
      def undefine_attribute_methods
        generated_attribute_methods.module_eval do
          instance_methods.each { |m| undef_method(m) }
        end
        attribute_method_matchers_cache.clear
      end

      # Returns true if the attribute methods defined have been generated.
      def generated_attribute_methods #:nodoc:
        @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
      end

      protected
        def instance_method_already_implemented?(method_name) #:nodoc:
          generated_attribute_methods.method_defined?(method_name)
        end

      private
        # The methods +method_missing+ and +respond_to?+ of this module are
        # invoked often in a typical rails, both of which invoke the method
        # +match_attribute_method?+. The latter method iterates through an
        # array doing regular expression matches, which results in a lot of
        # object creations. Most of the times it returns a +nil+ match. As the
        # match result is always the same given a +method_name+, this cache is
        # used to alleviate the GC, which ultimately also speeds up the app
        # significantly (in our case our test suite finishes 10% faster with
        # this cache).
        def attribute_method_matchers_cache #:nodoc:
          @attribute_method_matchers_cache ||= ThreadSafe::Cache.new(:initial_capacity => 4)
        end

        def attribute_method_matcher(method_name) #:nodoc:
          attribute_method_matchers_cache.compute_if_absent(method_name) do
            # Must try to match prefixes/suffixes first, or else the matcher with no prefix/suffix
            # will match every time.
            matchers = attribute_method_matchers.partition(&:plain?).reverse.flatten(1)
            match = nil
            matchers.detect { |method| match = method.match(method_name) }
            match
          end
        end

        # Define a method `name` in `mod` that dispatches to `send`
        # using the given `extra` args. This fallbacks `define_method`
        # and `send` if the given names cannot be compiled.
        def define_proxy_call(include_private, mod, name, send, *extra) #:nodoc:
          defn = if name =~ NAME_COMPILABLE_REGEXP
            "def #{name}(*args)"
          else
            "define_method(:'#{name}') do |*args|"
          end

          extra = (extra.map!(&:inspect) << "*args").join(", ")

          target = if send =~ CALL_COMPILABLE_REGEXP
            "#{"self." unless include_private}#{send}(#{extra})"
          else
            "send(:'#{send}', #{extra})"
          end

          mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
            #{defn}
              #{target}
            end
          RUBY
        end

        class AttributeMethodMatcher #:nodoc:
          attr_reader :prefix, :suffix, :method_missing_target

          AttributeMethodMatch = Struct.new(:target, :attr_name, :method_name)

          def initialize(options = {})
            if options[:prefix] == '' || options[:suffix] == ''
              message = "Specifying an empty prefix/suffix for an attribute method is no longer " \
                        "necessary. If the un-prefixed/suffixed version of the method has not been " \
                        "defined when `define_attribute_methods` is called, it will be defined " \
                        "automatically."
              ActiveSupport::Deprecation.warn message
            end

            @prefix, @suffix = options.fetch(:prefix, ''), options.fetch(:suffix, '')
            @regex = /^(?:#{Regexp.escape(@prefix)})(.*)(?:#{Regexp.escape(@suffix)})$/
            @method_missing_target = "#{@prefix}attribute#{@suffix}"
            @method_name = "#{prefix}%s#{suffix}"
          end

          def match(method_name)
            if @regex =~ method_name
              AttributeMethodMatch.new(method_missing_target, $1, method_name)
            end
          end

          def method_name(attr_name)
            @method_name % attr_name
          end

          def plain?
            prefix.empty? && suffix.empty?
          end
        end
    end

    # Allows access to the object attributes, which are held in the
    # <tt>@attributes</tt> hash, as though they were first-class methods. So a
    # Person class with a name attribute can use Person#name and Person#name=
    # and never directly use the attributes hash -- except for multiple assigns
    # with ActiveRecord#attributes=. A Milestone class can also ask
    # Milestone#completed? to test that the completed attribute is not +nil+
    # or 0.
    #
    # It's also possible to instantiate related objects, so a Client class
    # belonging to the clients table with a +master_id+ foreign key can
    # instantiate master through Client#master.
    def method_missing(method, *args, &block)
      if respond_to_without_attributes?(method, true)
        super
      else
        match = match_attribute_method?(method.to_s)
        match ? attribute_missing(match, *args, &block) : super
      end
    end

    # attribute_missing is like method_missing, but for attributes. When method_missing is
    # called we check to see if there is a matching attribute method. If so, we call
    # attribute_missing to dispatch the attribute. This method can be overloaded to
    # customize the behavior.
    def attribute_missing(match, *args, &block)
      __send__(match.target, match.attr_name, *args, &block)
    end

    # A Person object with a name attribute can ask <tt>person.respond_to?(:name)</tt>,
    # <tt>person.respond_to?(:name=)</tt>, and <tt>person.respond_to?(:name?)</tt>
    # which will all return +true+.
    alias :respond_to_without_attributes? :respond_to?
    def respond_to?(method, include_private_methods = false)
      if super
        true
      elsif !include_private_methods && super(method, true)
        # If we're here then we haven't found among non-private methods
        # but found among all methods. Which means that the given method is private.
        false
      else
        !match_attribute_method?(method.to_s).nil?
      end
    end

    protected
      def attribute_method?(attr_name) #:nodoc:
        respond_to_without_attributes?(:attributes) && attributes.include?(attr_name)
      end

    private
      # Returns a struct representing the matching attribute method.
      # The struct's attributes are prefix, base and suffix.
      def match_attribute_method?(method_name)
        match = self.class.send(:attribute_method_matcher, method_name)
        match if match && attribute_method?(match.attr_name)
      end

      def missing_attribute(attr_name, stack)
        raise ActiveModel::MissingAttributeError, "missing attribute: #{attr_name}", stack
      end
  end
end
require 'active_support/core_ext/array/extract_options'

module ActiveModel
  # == Active \Model \Callbacks
  #
  # Provides an interface for any class to have Active Record like callbacks.
  #
  # Like the Active Record methods, the callback chain is aborted as soon as
  # one of the methods in the chain returns +false+.
  #
  # First, extend ActiveModel::Callbacks from the class you are creating:
  #
  #   class MyModel
  #     extend ActiveModel::Callbacks
  #   end
  #
  # Then define a list of methods that you want callbacks attached to:
  #
  #   define_model_callbacks :create, :update
  #
  # This will provide all three standard callbacks (before, around and after)
  # for both the <tt>:create</tt> and <tt>:update</tt> methods. To implement,
  # you need to wrap the methods you want callbacks on in a block so that the
  # callbacks get a chance to fire:
  #
  #   def create
  #     run_callbacks :create do
  #       # Your create action methods here
  #     end
  #   end
  #
  # Then in your class, you can use the +before_create+, +after_create+ and
  # +around_create+ methods, just as you would in an Active Record module.
  #
  #   before_create :action_before_create
  #
  #   def action_before_create
  #     # Your code here
  #   end
  #
  # When defining an around callback remember to yield to the block, otherwise
  # it won't be executed:
  #
  #  around_create :log_status
  #
  #  def log_status
  #    puts 'going to call the block...'
  #    yield
  #    puts 'block successfully called.'
  #  end
  #
  # You can choose not to have all three callbacks by passing a hash to the
  # +define_model_callbacks+ method.
  #
  #   define_model_callbacks :create, only: [:after, :before]
  #
  # Would only create the +after_create+ and +before_create+ callback methods in
  # your class.
  module Callbacks
    def self.extended(base) #:nodoc:
      base.class_eval do
        include ActiveSupport::Callbacks
      end
    end

    # define_model_callbacks accepts the same options +define_callbacks+ does,
    # in case you want to overwrite a default. Besides that, it also accepts an
    # <tt>:only</tt> option, where you can choose if you want all types (before,
    # around or after) or just some.
    #
    #   define_model_callbacks :initializer, only: :after
    #
    # Note, the <tt>only: <type></tt> hash will apply to all callbacks defined
    # on that method call. To get around this you can call the define_model_callbacks
    # method as many times as you need.
    #
    #   define_model_callbacks :create,  only: :after
    #   define_model_callbacks :update,  only: :before
    #   define_model_callbacks :destroy, only: :around
    #
    # Would create +after_create+, +before_update+ and +around_destroy+ methods
    # only.
    #
    # You can pass in a class to before_<type>, after_<type> and around_<type>,
    # in which case the callback will call that class's <action>_<type> method
    # passing the object that the callback is being called on.
    #
    #   class MyModel
    #     extend ActiveModel::Callbacks
    #     define_model_callbacks :create
    #
    #     before_create AnotherClass
    #   end
    #
    #   class AnotherClass
    #     def self.before_create( obj )
    #       # obj is the MyModel instance that the callback is being called on
    #     end
    #   end
    def define_model_callbacks(*callbacks)
      options = callbacks.extract_options!
      options = {
        :terminator => "result == false",
        :skip_after_callbacks_if_terminated => true,
        :scope => [:kind, :name],
        :only => [:before, :around, :after]
      }.merge!(options)

      types = Array(options.delete(:only))

      callbacks.each do |callback|
        define_callbacks(callback, options)

        types.each do |type|
          send("_define_#{type}_model_callback", self, callback)
        end
      end
    end

    private

    def _define_before_model_callback(klass, callback) #:nodoc:
      klass.class_eval <<-CALLBACK, __FILE__, __LINE__ + 1
        def self.before_#{callback}(*args, &block)
          set_callback(:#{callback}, :before, *args, &block)
        end
      CALLBACK
    end

    def _define_around_model_callback(klass, callback) #:nodoc:
      klass.class_eval <<-CALLBACK, __FILE__, __LINE__ + 1
        def self.around_#{callback}(*args, &block)
          set_callback(:#{callback}, :around, *args, &block)
        end
      CALLBACK
    end

    def _define_after_model_callback(klass, callback) #:nodoc:
      klass.class_eval <<-CALLBACK, __FILE__, __LINE__ + 1
        def self.after_#{callback}(*args, &block)
          options = args.extract_options!
          options[:prepend] = true
          options[:if] = Array(options[:if]) << "value != false"
          set_callback(:#{callback}, :after, *(args << options), &block)
        end
      CALLBACK
    end
  end
end
module ActiveModel
  # == Active \Model Conversions
  #
  # Handles default conversions: to_model, to_key, to_param, and to_partial_path.
  #
  # Let's take for example this non-persisted object.
  #
  #   class ContactMessage
  #     include ActiveModel::Conversion
  #
  #     # ContactMessage are never persisted in the DB
  #     def persisted?
  #       false
  #     end
  #   end
  #
  #   cm = ContactMessage.new
  #   cm.to_model == cm  # => true
  #   cm.to_key          # => nil
  #   cm.to_param        # => nil
  #   cm.to_partial_path # => "contact_messages/contact_message"
  module Conversion
    extend ActiveSupport::Concern

    # If your object is already designed to implement all of the Active Model
    # you can use the default <tt>:to_model</tt> implementation, which simply
    # returns +self+.
    #
    #   class Person
    #     include ActiveModel::Conversion
    #   end
    #
    #   person = Person.new
    #   person.to_model == person # => true
    #
    # If your model does not act like an Active Model object, then you should
    # define <tt>:to_model</tt> yourself returning a proxy object that wraps
    # your object with Active Model compliant methods.
    def to_model
      self
    end

    # Returns an Enumerable of all key attributes if any is set, regardless if
    # the object is persisted or not. If there no key attributes, returns +nil+.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.create
    #   person.to_key # => [1]
    def to_key
      key = respond_to?(:id) && id
      key ? [key] : nil
    end

    # Returns a +string+ representing the object's key suitable for use in URLs,
    # or +nil+ if <tt>persisted?</tt> is +false+.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.create
    #   person.to_param # => "1"
    def to_param
      persisted? ? to_key.join('-') : nil
    end

    # Returns a +string+ identifying the path associated with the object.
    # ActionPack uses this to find a suitable partial to represent the object.
    #
    #   class Person
    #     include ActiveModel::Conversion
    #   end
    #
    #   person = Person.new
    #   person.to_partial_path # => "people/person"
    def to_partial_path
      self.class._to_partial_path
    end

    module ClassMethods #:nodoc:
      # Provide a class level cache for #to_partial_path. This is an
      # internal method and should not be accessed directly.
      def _to_partial_path #:nodoc:
        @_to_partial_path ||= begin
          element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self))
          collection = ActiveSupport::Inflector.tableize(self)
          "#{collection}/#{element}".freeze
        end
      end
    end
  end
end
module ActiveModel
  module DeprecatedMassAssignmentSecurity # :nodoc:
    extend ActiveSupport::Concern

     module ClassMethods # :nodoc:
       def attr_protected(*args)
         raise "`attr_protected` is extracted out of Rails into a gem. " \
           "Please use new recommended protection model for params" \
           "(strong_parameters) or add `protected_attributes` to your " \
           "Gemfile to use old one."
       end

       def attr_accessible(*args)
         raise "`attr_accessible` is extracted out of Rails into a gem. " \
           "Please use new recommended protection model for params" \
           "(strong_parameters) or add `protected_attributes` to your " \
           "Gemfile to use old one."
       end
     end
  end
end
require 'active_support/hash_with_indifferent_access'
require 'active_support/core_ext/object/duplicable'

module ActiveModel
  # == Active \Model \Dirty
  #
  # Provides a way to track changes in your object in the same way as
  # Active Record does.
  #
  # The requirements for implementing ActiveModel::Dirty are:
  #
  # * <tt>include ActiveModel::Dirty</tt> in your object.
  # * Call <tt>define_attribute_methods</tt> passing each method you want to
  #   track.
  # * Call <tt>attr_name_will_change!</tt> before each change to the tracked
  #   attribute.
  #
  # If you wish to also track previous changes on save or update, you need to
  # add:
  #
  #   @previously_changed = changes
  #
  # inside of your save or update method.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #     include ActiveModel::Dirty
  #
  #     define_attribute_methods :name
  #
  #     def name
  #       @name
  #     end
  #
  #     def name=(val)
  #       name_will_change! unless val == @name
  #       @name = val
  #     end
  #
  #     def save
  #       @previously_changed = changes
  #       @changed_attributes.clear
  #     end
  #   end
  #
  # A newly instantiated object is unchanged:
  #
  #   person = Person.find_by_name('Uncle Bob')
  #   person.changed?       # => false
  #
  # Change the name:
  #
  #   person.name = 'Bob'
  #   person.changed?       # => true
  #   person.name_changed?  # => true
  #   person.name_was       # => "Uncle Bob"
  #   person.name_change    # => ["Uncle Bob", "Bob"]
  #   person.name = 'Bill'
  #   person.name_change    # => ["Uncle Bob", "Bill"]
  #
  # Save the changes:
  #
  #   person.save
  #   person.changed?       # => false
  #   person.name_changed?  # => false
  #
  # Assigning the same value leaves the attribute unchanged:
  #
  #   person.name = 'Bill'
  #   person.name_changed?  # => false
  #   person.name_change    # => nil
  #
  # Which attributes have changed?
  #
  #   person.name = 'Bob'
  #   person.changed        # => ["name"]
  #   person.changes        # => {"name" => ["Bill", "Bob"]}
  #
  # If an attribute is modified in-place then make use of <tt>[attribute_name]_will_change!</tt>
  # to mark that the attribute is changing. Otherwise ActiveModel can't track
  # changes to in-place attributes.
  #
  #   person.name_will_change!
  #   person.name_change    # => ["Bill", "Bill"]
  #   person.name << 'y'
  #   person.name_change    # => ["Bill", "Billy"]
  module Dirty
    extend ActiveSupport::Concern
    include ActiveModel::AttributeMethods

    included do
      attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
      attribute_method_affix :prefix => 'reset_', :suffix => '!'
    end

    # Returns +true+ if any attribute have unsaved changes, +false+ otherwise.
    #
    #   person.changed? # => false
    #   person.name = 'bob'
    #   person.changed? # => true
    def changed?
      changed_attributes.present?
    end

    # Returns an array with the name of the attributes with unsaved changes.
    #
    #   person.changed # => []
    #   person.name = 'bob'
    #   person.changed # => ["name"]
    def changed
      changed_attributes.keys
    end

    # Returns a hash of changed attributes indicating their original
    # and new values like <tt>attr => [original value, new value]</tt>.
    #
    #   person.changes # => {}
    #   person.name = 'bob'
    #   person.changes # => { "name" => ["bill", "bob"] }
    def changes
      ActiveSupport::HashWithIndifferentAccess[changed.map { |attr| [attr, attribute_change(attr)] }]
    end

    # Returns a hash of attributes that were changed before the model was saved.
    #
    #   person.name # => "bob"
    #   person.name = 'robert'
    #   person.save
    #   person.previous_changes # => {"name" => ["bob", "robert"]}
    def previous_changes
      @previously_changed
    end

    # Returns a hash of the attributes with unsaved changes indicating their original
    # values like <tt>attr => original value</tt>.
    #
    #   person.name # => "bob"
    #   person.name = 'robert'
    #   person.changed_attributes # => {"name" => "bob"}
    def changed_attributes
      @changed_attributes ||= {}
    end

    private

      # Handle <tt>*_changed?</tt> for +method_missing+.
      def attribute_changed?(attr)
        changed_attributes.include?(attr)
      end

      # Handle <tt>*_change</tt> for +method_missing+.
      def attribute_change(attr)
        [changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
      end

      # Handle <tt>*_was</tt> for +method_missing+.
      def attribute_was(attr)
        attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
      end

      # Handle <tt>*_will_change!</tt> for +method_missing+.
      def attribute_will_change!(attr)
        return if attribute_changed?(attr)

        begin
          value = __send__(attr)
          value = value.duplicable? ? value.clone : value
        rescue TypeError, NoMethodError
        end

        changed_attributes[attr] = value
      end

      # Handle <tt>reset_*!</tt> for +method_missing+.
      def reset_attribute!(attr)
        if attribute_changed?(attr)
          __send__("#{attr}=", changed_attributes[attr])
          changed_attributes.delete(attr)
        end
      end
  end
end
# -*- coding: utf-8 -*-

require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/string/inflections'

module ActiveModel
  # == Active \Model \Errors
  #
  # Provides a modified +Hash+ that you can include in your object
  # for handling error messages and interacting with Action Pack helpers.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #
  #     # Required dependency for ActiveModel::Errors
  #     extend ActiveModel::Naming
  #
  #     def initialize
  #       @errors = ActiveModel::Errors.new(self)
  #     end
  #
  #     attr_accessor :name
  #     attr_reader   :errors
  #
  #     def validate!
  #       errors.add(:name, "can not be nil") if name == nil
  #     end
  #
  #     # The following methods are needed to be minimally implemented
  #
  #     def read_attribute_for_validation(attr)
  #       send(attr)
  #     end
  #
  #     def Person.human_attribute_name(attr, options = {})
  #       attr
  #     end
  #
  #     def Person.lookup_ancestors
  #       [self]
  #     end
  #
  #   end
  #
  # The last three methods are required in your object for Errors to be
  # able to generate error messages correctly and also handle multiple
  # languages. Of course, if you extend your object with ActiveModel::Translation
  # you will not need to implement the last two. Likewise, using
  # ActiveModel::Validations will handle the validation related methods
  # for you.
  #
  # The above allows you to do:
  #
  #   p = Person.new
  #   person.validate!            # => ["can not be nil"]
  #   person.errors.full_messages # => ["name can not be nil"]
  #   # etc..
  class Errors
    include Enumerable

    CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank, :strict]

    attr_reader :messages

    # Pass in the instance of the object that is using the errors object.
    #
    #   class Person
    #     def initialize
    #       @errors = ActiveModel::Errors.new(self)
    #     end
    #   end
    def initialize(base)
      @base     = base
      @messages = {}
    end

    def initialize_dup(other) # :nodoc:
      @messages = other.messages.dup
      super
    end

    # Clear the error messages.
    #
    #   person.errors.full_messages # => ["name can not be nil"]
    #   person.errors.clear
    #   person.errors.full_messages # => []
    def clear
      messages.clear
    end

    # Returns +true+ if the error messages include an error for the given key
    # +attribute+, +false+ otherwise.
    #
    #   person.errors.messages        # => {:name=>["can not be nil"]}
    #   person.errors.include?(:name) # => true
    #   person.errors.include?(:age)  # => false
    def include?(attribute)
      (v = messages[attribute]) && v.any?
    end
    # aliases include?
    alias :has_key? :include?

    # Get messages for +key+.
    #
    #   person.errors.messages   # => {:name=>["can not be nil"]}
    #   person.errors.get(:name) # => ["can not be nil"]
    #   person.errors.get(:age)  # => nil
    def get(key)
      messages[key]
    end

    # Set messages for +key+ to +value+.
    #
    #   person.errors.get(:name) # => ["can not be nil"]
    #   person.errors.set(:name, ["can't be nil"])
    #   person.errors.get(:name) # => ["can't be nil"]
    def set(key, value)
      messages[key] = value
    end

    # Delete messages for +key+. Returns the deleted messages.
    #
    #   person.errors.get(:name)    # => ["can not be nil"]
    #   person.errors.delete(:name) # => ["can not be nil"]
    #   person.errors.get(:name)    # => nil
    def delete(key)
      messages.delete(key)
    end

    # When passed a symbol or a name of a method, returns an array of errors
    # for the method.
    #
    #   person.errors[:name]  # => ["can not be nil"]
    #   person.errors['name'] # => ["can not be nil"]
    def [](attribute)
      get(attribute.to_sym) || set(attribute.to_sym, [])
    end

    # Adds to the supplied attribute the supplied error message.
    #
    #   person.errors[:name] = "must be set"
    #   person.errors[:name] # => ['must be set']
    def []=(attribute, error)
      self[attribute] << error
    end

    # Iterates through each error key, value pair in the error messages hash.
    # Yields the attribute and the error for that attribute. If the attribute
    # has more than one error message, yields once for each error message.
    #
    #   person.errors.add(:name, "can't be blank")
    #   person.errors.each do |attribute, error|
    #     # Will yield :name and "can't be blank"
    #   end
    #
    #   person.errors.add(:name, "must be specified")
    #   person.errors.each do |attribute, error|
    #     # Will yield :name and "can't be blank"
    #     # then yield :name and "must be specified"
    #   end
    def each
      messages.each_key do |attribute|
        self[attribute].each { |error| yield attribute, error }
      end
    end

    # Returns the number of error messages.
    #
    #   person.errors.add(:name, "can't be blank")
    #   person.errors.size # => 1
    #   person.errors.add(:name, "must be specified")
    #   person.errors.size # => 2
    def size
      values.flatten.size
    end

    # Returns all message values.
    #
    #   person.errors.messages # => {:name=>["can not be nil", "must be specified"]}
    #   person.errors.values   # => [["can not be nil", "must be specified"]]
    def values
      messages.values
    end

    # Returns all message keys.
    #
    #   person.errors.messages # => {:name=>["can not be nil", "must be specified"]}
    #   person.errors.keys     # => [:name]
    def keys
      messages.keys
    end

    # Returns an array of error messages, with the attribute name included.
    #
    #   person.errors.add(:name, "can't be blank")
    #   person.errors.add(:name, "must be specified")
    #   person.errors.to_a # => ["name can't be blank", "name must be specified"]
    def to_a
      full_messages
    end

    # Returns the number of error messages.
    #
    #   person.errors.add(:name, "can't be blank")
    #   person.errors.count # => 1
    #   person.errors.add(:name, "must be specified")
    #   person.errors.count # => 2
    def count
      to_a.size
    end

    # Returns +true+ if no errors are found, +false+ otherwise.
    # If the error message is a string it can be empty.
    #
    #   person.errors.full_messages # => ["name can not be nil"]
    #   person.errors.empty?        # => false
    def empty?
      all? { |k, v| v && v.empty? && !v.is_a?(String) }
    end
    # aliases empty?
    alias_method :blank?, :empty?

    # Returns an xml formatted representation of the Errors hash.
    #
    #   person.errors.add(:name, "can't be blank")
    #   person.errors.add(:name, "must be specified")
    #   person.errors.to_xml
    #   # =>
    #   #  <?xml version=\"1.0\" encoding=\"UTF-8\"?>
    #   #  <errors>
    #   #    <error>name can't be blank</error>
    #   #    <error>name must be specified</error>
    #   #  </errors>
    def to_xml(options={})
      to_a.to_xml({ :root => "errors", :skip_types => true }.merge!(options))
    end

    # Returns a Hash that can be used as the JSON representation for this
    # object. You can pass the <tt>:full_messages</tt> option. This determines
    # if the json object should contain full messages or not (false by default).
    #
    #   person.as_json                      # => {:name=>["can not be nil"]}
    #   person.as_json(full_messages: true) # => {:name=>["name can not be nil"]}
    def as_json(options=nil)
      to_hash(options && options[:full_messages])
    end

    # Returns a Hash of attributes with their error messages. If +full_messages+
    # is +true+, it will contain full messages (see +full_message+).
    #
    #   person.to_hash       # => {:name=>["can not be nil"]}
    #   person.to_hash(true) # => {:name=>["name can not be nil"]}
    def to_hash(full_messages = false)
      if full_messages
        messages = {}
        self.messages.each do |attribute, array|
          messages[attribute] = array.map { |message| full_message(attribute, message) }
        end
        messages
      else
        self.messages.dup
      end
    end

    # Adds +message+ to the error messages on +attribute+. More than one error
    # can be added to the same +attribute+. If no +message+ is supplied,
    # <tt>:invalid</tt> is assumed.
    #
    #   person.errors.add(:name)
    #   # => ["is invalid"]
    #   person.errors.add(:name, 'must be implemented')
    #   # => ["is invalid", "must be implemented"]
    #
    #   person.errors.messages
    #   # => {:name=>["must be implemented", "is invalid"]}
    #
    # If +message+ is a symbol, it will be translated using the appropriate
    # scope (see +generate_message+).
    #
    # If +message+ is a proc, it will be called, allowing for things like
    # <tt>Time.now</tt> to be used within an error.
    #
    # If the <tt>:strict</tt> option is set to true will raise
    # ActiveModel::StrictValidationFailed instead of adding the error.
    # <tt>:strict</tt> option can also be set to any other exception.
    #
    #   person.errors.add(:name, nil, strict: true)
    #   # => ActiveModel::StrictValidationFailed: name is invalid
    #   person.errors.add(:name, nil, strict: NameIsInvalid)
    #   # => NameIsInvalid: name is invalid
    #
    #   person.errors.messages # => {}
    def add(attribute, message = nil, options = {})
      message = normalize_message(attribute, message, options)
      if exception = options[:strict]
        exception = ActiveModel::StrictValidationFailed if exception == true
        raise exception, full_message(attribute, message)
      end

      self[attribute] << message
    end

    # Will add an error message to each of the attributes in +attributes+
    # that is empty.
    #
    #   person.errors.add_on_empty(:name)
    #   person.errors.messages
    #   # => {:name=>["can't be empty"]}
    def add_on_empty(attributes, options = {})
      Array(attributes).each do |attribute|
        value = @base.send(:read_attribute_for_validation, attribute)
        is_empty = value.respond_to?(:empty?) ? value.empty? : false
        add(attribute, :empty, options) if value.nil? || is_empty
      end
    end

    # Will add an error message to each of the attributes in +attributes+ that
    # is blank (using Object#blank?).
    #
    #   person.errors.add_on_blank(:name)
    #   person.errors.messages
    #   # => {:name=>["can't be blank"]}
    def add_on_blank(attributes, options = {})
      Array(attributes).each do |attribute|
        value = @base.send(:read_attribute_for_validation, attribute)
        add(attribute, :blank, options) if value.blank?
      end
    end

    # Returns +true+ if an error on the attribute with the given message is
    # present, +false+ otherwise. +message+ is treated the same as for +add+.
    #
    #   person.errors.add :name, :blank
    #   person.errors.added? :name, :blank # => true
    def added?(attribute, message = nil, options = {})
      message = normalize_message(attribute, message, options)
      self[attribute].include? message
    end

    # Returns all the full error messages in an array.
    #
    #   class Person
    #     validates_presence_of :name, :address, :email
    #     validates_length_of :name, in: 5..30
    #   end
    #
    #   person = Person.create(address: '123 First St.')
    #   person.errors.full_messages
    #   # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"]
    def full_messages
      map { |attribute, message| full_message(attribute, message) }
    end

    # Returns a full message for a given attribute.
    #
    #   person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
    def full_message(attribute, message)
      return message if attribute == :base
      attr_name = attribute.to_s.tr('.', '_').humanize
      attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
      I18n.t(:"errors.format", {
        :default   => "%{attribute} %{message}",
        :attribute => attr_name,
        :message   => message
      })
    end

    # Translates an error message in its default scope
    # (<tt>activemodel.errors.messages</tt>).
    #
    # Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>,
    # if it's not there, it's looked up in <tt>models.MODEL.MESSAGE</tt> and if
    # that is not there also, it returns the translation of the default message
    # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model
    # name, translated attribute name and the value are available for
    # interpolation.
    #
    # When using inheritance in your models, it will check all the inherited
    # models too, but only if the model itself hasn't been found. Say you have
    # <tt>class Admin < User; end</tt> and you wanted the translation for
    # the <tt>:blank</tt> error message for the <tt>title</tt> attribute,
    # it looks for these translations:
    #
    # * <tt>activemodel.errors.models.admin.attributes.title.blank</tt>
    # * <tt>activemodel.errors.models.admin.blank</tt>
    # * <tt>activemodel.errors.models.user.attributes.title.blank</tt>
    # * <tt>activemodel.errors.models.user.blank</tt>
    # * any default you provided through the +options+ hash (in the <tt>activemodel.errors</tt> scope)
    # * <tt>activemodel.errors.messages.blank</tt>
    # * <tt>errors.attributes.title.blank</tt>
    # * <tt>errors.messages.blank</tt>
    def generate_message(attribute, type = :invalid, options = {})
      type = options.delete(:message) if options[:message].is_a?(Symbol)

      if @base.class.respond_to?(:i18n_scope)
        defaults = @base.class.lookup_ancestors.map do |klass|
          [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}",
            :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ]
        end
      else
        defaults = []
      end

      defaults << options.delete(:message)
      defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" if @base.class.respond_to?(:i18n_scope)
      defaults << :"errors.attributes.#{attribute}.#{type}"
      defaults << :"errors.messages.#{type}"

      defaults.compact!
      defaults.flatten!

      key = defaults.shift
      value = (attribute != :base ? @base.send(:read_attribute_for_validation, attribute) : nil)

      options = {
        :default => defaults,
        :model => @base.class.model_name.human,
        :attribute => @base.class.human_attribute_name(attribute),
        :value => value
      }.merge!(options)

      I18n.translate(key, options)
    end

  private
    def normalize_message(attribute, message, options)
      message ||= :invalid

      case message
      when Symbol
        generate_message(attribute, message, options.except(*CALLBACKS_OPTIONS))
      when Proc
        message.call
      else
        message
      end
    end
  end

  # Raised when a validation cannot be corrected by end users and are considered
  # exceptional.
  #
  #   class Person
  #     include ActiveModel::Validations
  #
  #     attr_accessor :name
  #
  #     validates_presence_of :name, strict: true
  #   end
  #
  #   person = Person.new
  #   person.name = nil
  #   person.valid?
  #   # => ActiveModel::StrictValidationFailed: Name can't be blank
  class StrictValidationFailed < StandardError
  end
end
module ActiveModel
  # Raised when forbidden attributes are used for mass assignment.
  #
  #   class Person < ActiveRecord::Base
  #   end
  #
  #   params = ActionController::Parameters.new(name: 'Bob')
  #   Person.new(params)
  #   # => ActiveModel::ForbiddenAttributesError
  #
  #   params.permit!
  #   Person.new(params)
  #   # => #<Person id: nil, name: "Bob">
  class ForbiddenAttributesError < StandardError
  end

  module ForbiddenAttributesProtection # :nodoc:
    protected
      def sanitize_for_mass_assignment(attributes)
        if attributes.respond_to?(:permitted?) && !attributes.permitted?
          raise ActiveModel::ForbiddenAttributesError
        else
          attributes
        end
      end
  end
end
module ActiveModel
  module Lint
    # == Active \Model \Lint \Tests
    #
    # You can test whether an object is compliant with the Active \Model API by
    # including <tt>ActiveModel::Lint::Tests</tt> in your TestCase. It will
    # include tests that tell you whether your object is fully compliant,
    # or if not, which aspects of the API are not implemented.
    #
    # Note an object is not required to implement all APIs in order to work
    # with Action Pack. This module only intends to provide guidance in case
    # you want all features out of the box.
    #
    # These tests do not attempt to determine the semantic correctness of the
    # returned values. For instance, you could implement <tt>valid?</tt> to
    # always return true, and the tests would pass. It is up to you to ensure
    # that the values are semantically meaningful.
    #
    # Objects you pass in are expected to return a compliant object from a call
    # to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return
    # +self+.
    module Tests

      # == Responds to <tt>to_key</tt>
      #
      # Returns an Enumerable of all (primary) key attributes
      # or nil if <tt>model.persisted?</tt> is false. This is used by
      # <tt>dom_id</tt> to generate unique ids for the object.
      def test_to_key
        assert model.respond_to?(:to_key), "The model should respond to to_key"
        def model.persisted?() false end
        assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false"
      end

      # == Responds to <tt>to_param</tt>
      #
      # Returns a string representing the object's key suitable for use in URLs
      # or +nil+ if <tt>model.persisted?</tt> is +false+.
      #
      # Implementers can decide to either raise an exception or provide a
      # default in case the record uses a composite primary key. There are no
      # tests for this behavior in lint because it doesn't make sense to force
      # any of the possible implementation strategies on the implementer.
      # However, if the resource is not persisted?, then <tt>to_param</tt>
      # should always return +nil+.
      def test_to_param
        assert model.respond_to?(:to_param), "The model should respond to to_param"
        def model.to_key() [1] end
        def model.persisted?() false end
        assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false"
      end

      # == Responds to <tt>to_partial_path</tt>
      #
      # Returns a string giving a relative path. This is used for looking up
      # partials. For example, a BlogPost model might return "blog_posts/blog_post"
      def test_to_partial_path
        assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path"
        assert_kind_of String, model.to_partial_path
      end

      # == Responds to <tt>persisted?</tt>
      #
      # Returns a boolean that specifies whether the object has been persisted
      # yet. This is used when calculating the URL for an object. If the object
      # is not persisted, a form for that object, for instance, will route to
      # the create action. If it is persisted, a form for the object will routes
      # to the update action.
      def test_persisted?
        assert model.respond_to?(:persisted?), "The model should respond to persisted?"
        assert_boolean model.persisted?, "persisted?"
      end

      # == \Naming
      #
      # Model.model_name must return a string with some convenience methods:
      # <tt>:human</tt>, <tt>:singular</tt> and <tt>:plural</tt>. Check
      # ActiveModel::Naming for more information.
      def test_model_naming
        assert model.class.respond_to?(:model_name), "The model should respond to model_name"
        model_name = model.class.model_name
        assert model_name.respond_to?(:to_str)
        assert model_name.human.respond_to?(:to_str)
        assert model_name.singular.respond_to?(:to_str)
        assert model_name.plural.respond_to?(:to_str)
      end

      # == \Errors Testing
      #
      # Returns an object that implements [](attribute) defined which returns an
      # Array of Strings that are the errors for the attribute in question.
      # If localization is used, the Strings should be localized for the current
      # locale. If no error is present, this method should return an empty Array.
      def test_errors_aref
        assert model.respond_to?(:errors), "The model should respond to errors"
        assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array"
      end

      private
        def model
          assert @model.respond_to?(:to_model), "The object should respond_to to_model"
          @model.to_model
        end

        def assert_boolean(result, name)
          assert result == true || result == false, "#{name} should be a boolean"
        end
    end
  end
end
module ActiveModel

  # == Active \Model Basic \Model
  #
  # Includes the required interface for an object to interact with
  # <tt>ActionPack</tt>, using different <tt>ActiveModel</tt> modules.
  # It includes model name introspections, conversions, translations and
  # validations. Besides that, it allows you to initialize the object with a
  # hash of attributes, pretty much like <tt>ActiveRecord</tt> does.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #     include ActiveModel::Model
  #     attr_accessor :name, :age
  #   end
  #
  #   person = Person.new(name: 'bob', age: '18')
  #   person.name # => 'bob'
  #   person.age  # => 18
  #
  # Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt>
  # to return +false+, which is the most common case. You may want to override
  # it in your class to simulate a different scenario:
  #
  #   class Person
  #     include ActiveModel::Model
  #     attr_accessor :id, :name
  #
  #     def persisted?
  #       self.id == 1
  #     end
  #   end
  #
  #   person = Person.new(id: 1, name: 'bob')
  #   person.persisted? # => true
  #
  # Also, if for some reason you need to run code on <tt>initialize</tt>, make
  # sure you call +super+ if you want the attributes hash initialization to
  # happen.
  #
  #   class Person
  #     include ActiveModel::Model
  #     attr_accessor :id, :name, :omg
  #
  #     def initialize(attributes={})
  #       super
  #       @omg ||= true
  #     end
  #   end
  #
  #   person = Person.new(id: 1, name: 'bob')
  #   person.omg # => true
  #
  # For more detailed information on other functionalities available, please
  # refer to the specific modules included in <tt>ActiveModel::Model</tt>
  # (see below).
  module Model
    def self.included(base) #:nodoc:
      base.class_eval do
        extend  ActiveModel::Naming
        extend  ActiveModel::Translation
        include ActiveModel::Validations
        include ActiveModel::Conversion
      end
    end

    # Initializes a new model with the given +params+.
    #
    #   class Person
    #     include ActiveModel::Model
    #     attr_accessor :name, :age
    #   end
    #
    #   person = Person.new(name: 'bob', age: '18')
    #   person.name # => "bob"
    #   person.age  # => 18
    def initialize(params={})
      params.each do |attr, value|
        self.public_send("#{attr}=", value)
      end if params
    end

    # Indicates if the model is persisted. Default is +false+.
    #
    #  class Person
    #    include ActiveModel::Model
    #    attr_accessor :id, :name
    #  end
    #
    #  person = Person.new(id: 1, name: 'bob')
    #  person.persisted? # => false
    def persisted?
      false
    end
  end
end
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/introspection'

module ActiveModel
  class Name
    include Comparable

    attr_reader :singular, :plural, :element, :collection,
      :singular_route_key, :route_key, :param_key, :i18n_key,
      :name

    alias_method :cache_key, :collection

    ##
    # :method: ==
    #
    # :call-seq:
    #   ==(other)
    #
    # Equivalent to <tt>String#==</tt>. Returns +true+ if the class name and
    # +other+ are equal, otherwise +false+.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name == 'BlogPost'  # => true
    #   BlogPost.model_name == 'Blog Post' # => false

    ##
    # :method: ===
    #
    # :call-seq:
    #   ===(other)
    #
    # Equivalent to <tt>#==</tt>.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name === 'BlogPost'  # => true
    #   BlogPost.model_name === 'Blog Post' # => false

    ##
    # :method: <=>
    #
    # :call-seq:
    #   ==(other)
    #
    # Equivalent to <tt>String#<=></tt>.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name <=> 'BlogPost'  # => 0
    #   BlogPost.model_name <=> 'Blog'      # => 1
    #   BlogPost.model_name <=> 'BlogPosts' # => -1

    ##
    # :method: =~
    #
    # :call-seq:
    #   =~(regexp)
    #
    # Equivalent to <tt>String#=~</tt>. Match the class name against the given
    # regexp. Returns the position where the match starts or +nil+ if there is
    # no match.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name =~ /Post/ # => 4
    #   BlogPost.model_name =~ /\d/   # => nil

    ##
    # :method: !~
    #
    # :call-seq:
    #   !~(regexp)
    #
    # Equivalent to <tt>String#!~</tt>. Match the class name against the given
    # regexp. Returns +true+ if there is no match, otherwise +false+.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name !~ /Post/ # => false
    #   BlogPost.model_name !~ /\d/   # => true

    ##
    # :method: eql?
    #
    # :call-seq:
    #   eql?(other)
    #
    # Equivalent to <tt>String#eql?</tt>. Returns +true+ if the class name and
    # +other+ have the same length and content, otherwise +false+.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name.eql?('BlogPost')  # => true
    #   BlogPost.model_name.eql?('Blog Post') # => false

    ##
    # :method: to_s
    #
    # :call-seq:
    #   to_s()
    #
    # Returns the class name.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name.to_s # => "BlogPost"

    ##
    # :method: to_str
    #
    # :call-seq:
    #   to_str()
    #
    # Equivalent to +to_s+.
    delegate :==, :===, :<=>, :=~, :"!~", :eql?, :to_s,
             :to_str, :to => :name

    # Returns a new ActiveModel::Name instance. By default, the +namespace+
    # and +name+ option will take the namespace and name of the given class
    # respectively.
    #
    #   module Foo
    #     class Bar
    #     end
    #   end
    #
    #   ActiveModel::Name.new(Foo::Bar).to_s
    #   # => "Foo::Bar"
    def initialize(klass, namespace = nil, name = nil)
      @name = name || klass.name

      raise ArgumentError, "Class name cannot be blank. You need to supply a name argument when anonymous class given" if @name.blank?

      @unnamespaced = @name.sub(/^#{namespace.name}::/, '') if namespace
      @klass        = klass
      @singular     = _singularize(@name)
      @plural       = ActiveSupport::Inflector.pluralize(@singular)
      @element      = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(@name))
      @human        = ActiveSupport::Inflector.humanize(@element)
      @collection   = ActiveSupport::Inflector.tableize(@name)
      @param_key    = (namespace ? _singularize(@unnamespaced) : @singular)
      @i18n_key     = @name.underscore.to_sym

      @route_key          = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural.dup)
      @singular_route_key = ActiveSupport::Inflector.singularize(@route_key)
      @route_key << "_index" if @plural == @singular
    end

    # Transform the model name into a more humane format, using I18n. By default,
    # it will underscore then humanize the class name.
    #
    #   class BlogPost
    #     extend ActiveModel::Naming
    #   end
    #
    #   BlogPost.model_name.human # => "Blog post"
    #
    # Specify +options+ with additional translating options.
    def human(options={})
      return @human unless @klass.respond_to?(:lookup_ancestors) &&
                           @klass.respond_to?(:i18n_scope)

      defaults = @klass.lookup_ancestors.map do |klass|
        klass.model_name.i18n_key
      end

      defaults << options[:default] if options[:default]
      defaults << @human

      options = { :scope => [@klass.i18n_scope, :models], :count => 1, :default => defaults }.merge!(options.except(:default))
      I18n.translate(defaults.shift, options)
    end

    private

    def _singularize(string, replacement='_')
      ActiveSupport::Inflector.underscore(string).tr('/', replacement)
    end
  end

  # == Active \Model \Naming
  #
  # Creates a +model_name+ method on your object.
  #
  # To implement, just extend ActiveModel::Naming in your object:
  #
  #   class BookCover
  #     extend ActiveModel::Naming
  #   end
  #
  #   BookCover.model_name        # => "BookCover"
  #   BookCover.model_name.human  # => "Book cover"
  #
  #   BookCover.model_name.i18n_key              # => :book_cover
  #   BookModule::BookCover.model_name.i18n_key  # => :"book_module/book_cover"
  #
  # Providing the functionality that ActiveModel::Naming provides in your object
  # is required to pass the Active Model Lint test. So either extending the
  # provided method below, or rolling your own is required.
  module Naming
    # Returns an ActiveModel::Name object for module. It can be
    # used to retrieve all kinds of naming-related information
    # (See ActiveModel::Name for more information).
    #
    #   class Person < ActiveModel::Model
    #   end
    #
    #   Person.model_name          # => Person
    #   Person.model_name.class    # => ActiveModel::Name
    #   Person.model_name.singular # => "person"
    #   Person.model_name.plural   # => "people"
    def model_name
      @_model_name ||= begin
        namespace = self.parents.detect do |n|
          n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
        end
        ActiveModel::Name.new(self, namespace)
      end
    end

    # Returns the plural class name of a record or class.
    #
    #   ActiveModel::Naming.plural(post)             # => "posts"
    #   ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people"
    def self.plural(record_or_class)
      model_name_from_record_or_class(record_or_class).plural
    end

    # Returns the singular class name of a record or class.
    #
    #   ActiveModel::Naming.singular(post)             # => "post"
    #   ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person"
    def self.singular(record_or_class)
      model_name_from_record_or_class(record_or_class).singular
    end

    # Identifies whether the class name of a record or class is uncountable.
    #
    #   ActiveModel::Naming.uncountable?(Sheep) # => true
    #   ActiveModel::Naming.uncountable?(Post)  # => false
    def self.uncountable?(record_or_class)
      plural(record_or_class) == singular(record_or_class)
    end

    # Returns string to use while generating route names. It differs for
    # namespaced models regarding whether it's inside isolated engine.
    #
    #   # For isolated engine:
    #   ActiveModel::Naming.singular_route_key(Blog::Post) #=> post
    #
    #   # For shared engine:
    #   ActiveModel::Naming.singular_route_key(Blog::Post) #=> blog_post
    def self.singular_route_key(record_or_class)
      model_name_from_record_or_class(record_or_class).singular_route_key
    end

    # Returns string to use while generating route names. It differs for
    # namespaced models regarding whether it's inside isolated engine.
    #
    #   # For isolated engine:
    #   ActiveModel::Naming.route_key(Blog::Post) #=> posts
    #
    #   # For shared engine:
    #   ActiveModel::Naming.route_key(Blog::Post) #=> blog_posts
    #
    # The route key also considers if the noun is uncountable and, in
    # such cases, automatically appends _index.
    def self.route_key(record_or_class)
      model_name_from_record_or_class(record_or_class).route_key
    end

    # Returns string to use for params names. It differs for
    # namespaced models regarding whether it's inside isolated engine.
    #
    #   # For isolated engine:
    #   ActiveModel::Naming.param_key(Blog::Post) #=> post
    #
    #   # For shared engine:
    #   ActiveModel::Naming.param_key(Blog::Post) #=> blog_post
    def self.param_key(record_or_class)
      model_name_from_record_or_class(record_or_class).param_key
    end

    def self.model_name_from_record_or_class(record_or_class) #:nodoc:
      if record_or_class.respond_to?(:model_name)
        record_or_class.model_name
      elsif record_or_class.respond_to?(:to_model)
        record_or_class.to_model.class.model_name
      else
        record_or_class.class.model_name
      end
    end
    private_class_method :model_name_from_record_or_class
  end
end
require "active_model"
require "rails"

module ActiveModel
  class Railtie < Rails::Railtie # :nodoc:
    config.eager_load_namespaces << ActiveModel

    initializer "active_model.secure_password" do
      ActiveModel::SecurePassword.min_cost = Rails.env.test?
    end
  end
end
module ActiveModel
  module SecurePassword
    extend ActiveSupport::Concern

    class << self; attr_accessor :min_cost; end
    self.min_cost = false

    module ClassMethods
      # Adds methods to set and authenticate against a BCrypt password.
      # This mechanism requires you to have a password_digest attribute.
      #
      # Validations for presence of password on create, confirmation of password
      # (using a +password_confirmation+ attribute) are automatically added. If
      # you wish to turn off validations, pass <tt>validations: false</tt> as an
      # argument. You can add more validations by hand if need be.
      #
      # If you don't need the confirmation validation, just don't set any
      # value to the password_confirmation attribute and the the validation
      # will not be triggered.
      #
      # You need to add bcrypt-ruby (~> 3.0.0) to Gemfile to use #has_secure_password:
      #
      #   gem 'bcrypt-ruby', '~> 3.0.0'
      #
      # Example using Active Record (which automatically includes ActiveModel::SecurePassword):
      #
      #   # Schema: User(name:string, password_digest:string)
      #   class User < ActiveRecord::Base
      #     has_secure_password
      #   end
      #
      #   user = User.new(name: 'david', password: '', password_confirmation: 'nomatch')
      #   user.save                                                      # => false, password required
      #   user.password = 'mUc3m00RsqyRe'
      #   user.save                                                      # => false, confirmation doesn't match
      #   user.password_confirmation = 'mUc3m00RsqyRe'
      #   user.save                                                      # => true
      #   user.authenticate('notright')                                  # => false
      #   user.authenticate('mUc3m00RsqyRe')                             # => user
      #   User.find_by_name('david').try(:authenticate, 'notright')      # => false
      #   User.find_by_name('david').try(:authenticate, 'mUc3m00RsqyRe') # => user
      def has_secure_password(options = {})
        # Load bcrypt-ruby only when has_secure_password is used.
        # This is to avoid ActiveModel (and by extension the entire framework)
        # being dependent on a binary library.
        gem 'bcrypt-ruby', '~> 3.0.0'
        require 'bcrypt'

        attr_reader :password

        if options.fetch(:validations, true)
          validates_confirmation_of :password
          validates_presence_of     :password, :on => :create

          before_create { raise "Password digest missing on new record" if password_digest.blank? }
        end

        include InstanceMethodsOnActivation

        if respond_to?(:attributes_protected_by_default)
          def self.attributes_protected_by_default #:nodoc:
            super + ['password_digest']
          end
        end
      end
    end

    module InstanceMethodsOnActivation
      # Returns +self+ if the password is correct, otherwise +false+.
      #
      #   class User < ActiveRecord::Base
      #     has_secure_password validations: false
      #   end
      #
      #   user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
      #   user.save
      #   user.authenticate('notright')      # => false
      #   user.authenticate('mUc3m00RsqyRe') # => user
      def authenticate(unencrypted_password)
        BCrypt::Password.new(password_digest) == unencrypted_password && self
      end

      # Encrypts the password into the +password_digest+ attribute, only if the
      # new password is not blank.
      #
      #   class User < ActiveRecord::Base
      #     has_secure_password validations: false
      #   end
      #
      #   user = User.new
      #   user.password = nil
      #   user.password_digest # => nil
      #   user.password = 'mUc3m00RsqyRe'
      #   user.password_digest # => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."
      def password=(unencrypted_password)
        unless unencrypted_password.blank?
          @password = unencrypted_password
          cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine::DEFAULT_COST
          self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost)
        end
      end
    end
  end
end
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'

module ActiveModel
  # == Active \Model \Serialization
  #
  # Provides a basic serialization to a serializable_hash for your object.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #     include ActiveModel::Serialization
  #
  #     attr_accessor :name
  #
  #     def attributes
  #       {'name' => nil}
  #     end
  #   end
  #
  # Which would provide you with:
  #
  #   person = Person.new
  #   person.serializable_hash   # => {"name"=>nil}
  #   person.name = "Bob"
  #   person.serializable_hash   # => {"name"=>"Bob"}
  #
  # You need to declare an attributes hash which contains the attributes you
  # want to serialize. Attributes must be strings, not symbols. When called,
  # serializable hash will use instance methods that match the name of the
  # attributes hash's keys. In order to override this behavior, take a look at
  # the private method +read_attribute_for_serialization+.
  #
  # Most of the time though, you will want to include the JSON or XML
  # serializations. Both of these modules automatically include the
  # <tt>ActiveModel::Serialization</tt> module, so there is no need to
  # explicitly include it.
  #
  # A minimal implementation including XML and JSON would be:
  #
  #   class Person
  #     include ActiveModel::Serializers::JSON
  #     include ActiveModel::Serializers::Xml
  #
  #     attr_accessor :name
  #
  #     def attributes
  #       {'name' => nil}
  #     end
  #   end
  #
  # Which would provide you with:
  #
  #   person = Person.new
  #   person.serializable_hash   # => {"name"=>nil}
  #   person.as_json             # => {"name"=>nil}
  #   person.to_json             # => "{\"name\":null}"
  #   person.to_xml              # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
  #
  #   person.name = "Bob"
  #   person.serializable_hash   # => {"name"=>"Bob"}
  #   person.as_json             # => {"name"=>"Bob"}
  #   person.to_json             # => "{\"name\":\"Bob\"}"
  #   person.to_xml              # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
  #
  # Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and
  # <tt>:include</tt>. The following are all valid examples:
  #
  #   person.serializable_hash(only: 'name')
  #   person.serializable_hash(include: :address)
  #   person.serializable_hash(include: { address: { only: 'city' }})
  module Serialization
    # Returns a serialized hash of your object.
    #
    #   class Person
    #     include ActiveModel::Serialization
    #
    #     attr_accessor :name, :age
    #
    #     def attributes
    #       {'name' => nil, 'age' => nil}
    #     end
    #
    #     def capitalized_name
    #       name.capitalize
    #     end
    #   end
    #
    #   person = Person.new
    #   person.name = 'bob'
    #   person.age  = 22
    #   person.serializable_hash                # => {"name"=>"bob", "age"=>22}
    #   person.serializable_hash(only: :name)   # => {"name"=>"bob"}
    #   person.serializable_hash(except: :name) # => {"age"=>22}
    #   person.serializable_hash(methods: :capitalized_name)
    #   # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
    def serializable_hash(options = nil)
      options ||= {}

      attribute_names = attributes.keys
      if only = options[:only]
        attribute_names &= Array(only).map(&:to_s)
      elsif except = options[:except]
        attribute_names -= Array(except).map(&:to_s)
      end

      hash = {}
      attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }

      Array(options[:methods]).each { |m| hash[m.to_s] = send(m) if respond_to?(m) }

      serializable_add_includes(options) do |association, records, opts|
        hash[association.to_s] = if records.respond_to?(:to_ary)
          records.to_ary.map { |a| a.serializable_hash(opts) }
        else
          records.serializable_hash(opts)
        end
      end

      hash
    end

    private

      # Hook method defining how an attribute value should be retrieved for
      # serialization. By default this is assumed to be an instance named after
      # the attribute. Override this method in subclasses should you need to
      # retrieve the value for a given attribute differently:
      #
      #   class MyClass
      #     include ActiveModel::Validations
      #
      #     def initialize(data = {})
      #       @data = data
      #     end
      #
      #     def read_attribute_for_serialization(key)
      #       @data[key]
      #     end
      #   end
      alias :read_attribute_for_serialization :send

      # Add associations specified via the <tt>:include</tt> option.
      #
      # Expects a block that takes as arguments:
      #   +association+ - name of the association
      #   +records+     - the association record(s) to be serialized
      #   +opts+        - options for the association records
      def serializable_add_includes(options = {}) #:nodoc:
        return unless includes = options[:include]

        unless includes.is_a?(Hash)
          includes = Hash[Array(includes).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }]
        end

        includes.each do |association, opts|
          if records = send(association)
            yield association, records, opts
          end
        end
      end
  end
end
require 'active_support/json'

module ActiveModel
  module Serializers
    # == Active Model JSON Serializer
    module JSON
      extend ActiveSupport::Concern
      include ActiveModel::Serialization

      included do
        extend ActiveModel::Naming

        class_attribute :include_root_in_json
        self.include_root_in_json = false
      end

      # Returns a hash representing the model. Some configuration can be
      # passed through +options+.
      #
      # The option <tt>include_root_in_json</tt> controls the top-level behavior
      # of +as_json+. If +true+, +as_json+ will emit a single root node named
      # after the object's type. The default value for <tt>include_root_in_json</tt>
      # option is +false+.
      #
      #   user = User.find(1)
      #   user.as_json
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #     "created_at" => "2006/08/01", "awesome" => true}
      #
      #   ActiveRecord::Base.include_root_in_json = true
      #
      #   user.as_json
      #   # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #                  "created_at" => "2006/08/01", "awesome" => true } }
      #
      # This behavior can also be achieved by setting the <tt>:root</tt> option
      # to +true+ as in:
      #
      #   user = User.find(1)
      #   user.as_json(root: true)
      #   # => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #                  "created_at" => "2006/08/01", "awesome" => true } }
      #
      # Without any +options+, the returned Hash will include all the model's
      # attributes.
      #
      #   user = User.find(1)
      #   user.as_json
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #      "created_at" => "2006/08/01", "awesome" => true}
      #
      # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit
      # the attributes included, and work similar to the +attributes+ method.
      #
      #   user.as_json(only: [:id, :name])
      #   # => { "id" => 1, "name" => "Konata Izumi" }
      #
      #   user.as_json(except: [:id, :created_at, :age])
      #   # => { "name" => "Konata Izumi", "awesome" => true }
      #
      # To include the result of some method calls on the model use <tt>:methods</tt>:
      #
      #   user.as_json(methods: :permalink)
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #      "created_at" => "2006/08/01", "awesome" => true,
      #   #      "permalink" => "1-konata-izumi" }
      #
      # To include associations use <tt>:include</tt>:
      #
      #   user.as_json(include: :posts)
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #      "created_at" => "2006/08/01", "awesome" => true,
      #   #      "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
      #   #                   { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
      #
      # Second level and higher order associations work as well:
      #
      #   user.as_json(include: { posts: {
      #                              include: { comments: {
      #                                             only: :body } },
      #                              only: :title } })
      #   # => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
      #   #      "created_at" => "2006/08/01", "awesome" => true,
      #   #      "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
      #   #                     "title" => "Welcome to the weblog" },
      #   #                   { "comments" => [ { "body" => "Don't think too hard" } ],
      #   #                     "title" => "So I was thinking" } ] }
      def as_json(options = nil)
        root = if options && options.key?(:root)
          options[:root]
        else
          include_root_in_json
        end

        if root
          root = self.class.model_name.element if root == true
          { root => serializable_hash(options) }
        else
          serializable_hash(options)
        end
      end

      # Sets the model +attributes+ from a JSON string. Returns +self+.
      #
      #   class Person
      #     include ActiveModel::Serializers::JSON
      #
      #     attr_accessor :name, :age, :awesome
      #
      #     def attributes=(hash)
      #       hash.each do |key, value|
      #         instance_variable_set("@#{key}", value)
      #       end
      #     end
      #
      #     def attributes
      #       instance_values
      #     end
      #   end
      #
      #   json = { name: 'bob', age: 22, awesome:true }.to_json
      #   person = Person.new
      #   person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
      #   person.name            # => "bob"
      #   person.age             # => 22
      #   person.awesome         # => true
      #
      # The default value for +include_root+ is +false+. You can change it to
      # +true+ if the given JSON string includes a single root node.
      #
      #   json = { person: { name: 'bob', age: 22, awesome:true } }.to_json
      #   person = Person.new
      #   person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
      #   person.name            # => "bob"
      #   person.age             # => 22
      #   person.awesome         # => true
      def from_json(json, include_root=include_root_in_json)
        hash = ActiveSupport::JSON.decode(json)
        hash = hash.values.first if include_root
        self.attributes = hash
        self
      end
    end
  end
end
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/hash/conversions'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/time/acts_like'

module ActiveModel
  module Serializers
    # == Active Model XML Serializer
    module Xml
      extend ActiveSupport::Concern
      include ActiveModel::Serialization

      included do
        extend ActiveModel::Naming
      end

      class Serializer #:nodoc:
        class Attribute #:nodoc:
          attr_reader :name, :value, :type

          def initialize(name, serializable, value)
            @name, @serializable = name, serializable

            if value.acts_like?(:time) && value.respond_to?(:in_time_zone)
              value  = value.in_time_zone
            end

            @value = value
            @type  = compute_type
          end

          def decorations
            decorations = {}
            decorations[:encoding] = 'base64' if type == :binary
            decorations[:type] = (type == :string) ? nil : type
            decorations[:nil] = true if value.nil?
            decorations
          end

        protected

          def compute_type
            return if value.nil?
            type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name]
            type ||= :string if value.respond_to?(:to_str)
            type ||= :yaml
            type
          end
        end

        class MethodAttribute < Attribute #:nodoc:
        end

        attr_reader :options

        def initialize(serializable, options = nil)
          @serializable = serializable
          @options = options ? options.dup : {}
        end

        def serializable_hash
          @serializable.serializable_hash(@options.except(:include))
        end

        def serializable_collection
          methods = Array(options[:methods]).map(&:to_s)
          serializable_hash.map do |name, value|
            name = name.to_s
            if methods.include?(name)
              self.class::MethodAttribute.new(name, @serializable, value)
            else
              self.class::Attribute.new(name, @serializable, value)
            end
          end
        end

        def serialize
          require 'builder' unless defined? ::Builder

          options[:indent]  ||= 2
          options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])

          @builder = options[:builder]
          @builder.instruct! unless options[:skip_instruct]

          root = (options[:root] || @serializable.class.model_name.element).to_s
          root = ActiveSupport::XmlMini.rename_key(root, options)

          args = [root]
          args << {:xmlns => options[:namespace]} if options[:namespace]
          args << {:type => options[:type]} if options[:type] && !options[:skip_types]

          @builder.tag!(*args) do
            add_attributes_and_methods
            add_includes
            add_extra_behavior
            add_procs
            yield @builder if block_given?
          end
        end

      private

        def add_extra_behavior
        end

        def add_attributes_and_methods
          serializable_collection.each do |attribute|
            key = ActiveSupport::XmlMini.rename_key(attribute.name, options)
            ActiveSupport::XmlMini.to_tag(key, attribute.value,
              options.merge(attribute.decorations))
          end
        end

        def add_includes
          @serializable.send(:serializable_add_includes, options) do |association, records, opts|
            add_associations(association, records, opts)
          end
        end

        # TODO: This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well.
        def add_associations(association, records, opts)
          merged_options = opts.merge(options.slice(:builder, :indent))
          merged_options[:skip_instruct] = true

          [:skip_types, :dasherize, :camelize].each do |key|
            merged_options[key] = options[key] if merged_options[key].nil? && !options[key].nil?
          end

          if records.respond_to?(:to_ary)
            records = records.to_ary

            tag  = ActiveSupport::XmlMini.rename_key(association.to_s, options)
            type = options[:skip_types] ? { } : {:type => "array"}
            association_name = association.to_s.singularize
            merged_options[:root] = association_name

            if records.empty?
              @builder.tag!(tag, type)
            else
              @builder.tag!(tag, type) do
                records.each do |record|
                  if options[:skip_types]
                    record_type = {}
                  else
                    record_class = (record.class.to_s.underscore == association_name) ? nil : record.class.name
                    record_type = {:type => record_class}
                  end

                  record.to_xml merged_options.merge(record_type)
                end
              end
            end
          else
            merged_options[:root] = association.to_s

            unless records.class.to_s.underscore == association.to_s
              merged_options[:type] = records.class.name
            end

            records.to_xml merged_options
          end
        end

        def add_procs
          if procs = options.delete(:procs)
            Array(procs).each do |proc|
              if proc.arity == 1
                proc.call(options)
              else
                proc.call(options, @serializable)
              end
            end
          end
        end
      end

      # Returns XML representing the model. Configuration can be
      # passed through +options+.
      #
      # Without any +options+, the returned XML string will include all the
      # model's attributes.
      #
      #   user = User.find(1)
      #   user.to_xml
      #
      #   <?xml version="1.0" encoding="UTF-8"?>
      #   <user>
      #     <id type="integer">1</id>
      #     <name>David</name>
      #     <age type="integer">16</age>
      #     <created-at type="dateTime">2011-01-30T22:29:23Z</created-at>
      #   </user>
      #
      # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the
      # attributes included, and work similar to the +attributes+ method.
      #
      # To include the result of some method calls on the model use <tt>:methods</tt>.
      #
      # To include associations use <tt>:include</tt>.
      #
      # For further documentation, see <tt>ActiveRecord::Serialization#to_xml</tt>
      def to_xml(options = {}, &block)
        Serializer.new(self, options).serialize(&block)
      end

      # Sets the model +attributes+ from a JSON string. Returns +self+.
      #
      #   class Person
      #     include ActiveModel::Serializers::Xml
      #
      #     attr_accessor :name, :age, :awesome
      #
      #     def attributes=(hash)
      #       hash.each do |key, value|
      #         instance_variable_set("@#{key}", value)
      #       end
      #     end
      #
      #     def attributes
      #       instance_values
      #     end
      #   end
      #
      #   xml = { name: 'bob', age: 22, awesome:true }.to_xml
      #   person = Person.new
      #   person.from_xml(xml) # => #<Person:0x007fec5e3b3c40 @age=22, @awesome=true, @name="bob">
      #   person.name          # => "bob"
      #   person.age           # => 22
      #   person.awesome       # => true
      def from_xml(xml)
        self.attributes = Hash.from_xml(xml).values.first
        self
      end
    end
  end
end
module ActiveModel #:nodoc:
  class TestCase < ActiveSupport::TestCase #:nodoc:
  end
end
module ActiveModel

  # == Active \Model \Translation
  #
  # Provides integration between your object and the Rails internationalization
  # (i18n) framework.
  #
  # A minimal implementation could be:
  #
  #   class TranslatedPerson
  #     extend ActiveModel::Translation
  #   end
  #
  #   TranslatedPerson.human_attribute_name('my_attribute')
  #   # => "My attribute"
  #
  # This also provides the required class methods for hooking into the
  # Rails internationalization API, including being able to define a
  # class based +i18n_scope+ and +lookup_ancestors+ to find translations in
  # parent classes.
  module Translation
    include ActiveModel::Naming

    # Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup.
    def i18n_scope
      :activemodel
    end

    # When localizing a string, it goes through the lookup returned by this
    # method, which is used in ActiveModel::Name#human,
    # ActiveModel::Errors#full_messages and
    # ActiveModel::Translation#human_attribute_name.
    def lookup_ancestors
      self.ancestors.select { |x| x.respond_to?(:model_name) }
    end

    # Transforms attribute names into a more human format, such as "First name"
    # instead of "first_name".
    #
    #   Person.human_attribute_name("first_name") # => "First name"
    #
    # Specify +options+ with additional translating options.
    def human_attribute_name(attribute, options = {})
      options   = { :count => 1 }.merge!(options)
      parts     = attribute.to_s.split(".")
      attribute = parts.pop
      namespace = parts.join("/") unless parts.empty?
      attributes_scope = "#{self.i18n_scope}.attributes"

      if namespace
        defaults = lookup_ancestors.map do |klass|
          :"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
        end
        defaults << :"#{attributes_scope}.#{namespace}.#{attribute}"
      else
        defaults = lookup_ancestors.map do |klass|
          :"#{attributes_scope}.#{klass.model_name.i18n_key}.#{attribute}"
        end
      end

      defaults << :"attributes.#{attribute}"
      defaults << options.delete(:default) if options[:default]
      defaults << attribute.humanize

      options[:default] = defaults
      I18n.translate(defaults.shift, options)
    end
  end
end
module ActiveModel
  module Validations
    # == Active Model Absence Validator
    class AbsenceValidator < EachValidator #:nodoc:
      def validate_each(record, attr_name, value)
        record.errors.add(attr_name, :present, options) if value.present?
      end
    end

    module HelperMethods
      # Validates that the specified attributes are blank (as defined by
      # Object#blank?). Happens by default on save.
      #
      #   class Person < ActiveRecord::Base
      #     validates_absence_of :first_name
      #   end
      #
      # The first_name attribute must be in the object and it must be blank.
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "must be blank").
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_absence_of(*attr_names)
        validates_with AbsenceValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveModel

  module Validations
    class AcceptanceValidator < EachValidator # :nodoc:
      def initialize(options)
        super({ :allow_nil => true, :accept => "1" }.merge!(options))
      end

      def validate_each(record, attribute, value)
        unless value == options[:accept]
          record.errors.add(attribute, :accepted, options.except(:accept, :allow_nil))
        end
      end

      def setup(klass)
        attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
        attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
        klass.send(:attr_reader, *attr_readers)
        klass.send(:attr_writer, *attr_writers)
      end
    end

    module HelperMethods
      # Encapsulates the pattern of wanting to validate the acceptance of a
      # terms of service check box (or similar agreement).
      #
      #   class Person < ActiveRecord::Base
      #     validates_acceptance_of :terms_of_service
      #     validates_acceptance_of :eula, message: 'must be abided'
      #   end
      #
      # If the database column does not exist, the +terms_of_service+ attribute
      # is entirely virtual. This check is performed only if +terms_of_service+
      # is not +nil+ and by default on save.
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "must be
      #   accepted").
      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default
      #   is +true+).
      # * <tt>:accept</tt> - Specifies value that is considered accepted.
      #   The default value is a string "1", which makes it easy to relate to
      #   an HTML checkbox. This should be set to +true+ if you are validating
      #   a database column, since the attribute is typecast from "1" to +true+
      #   before validation.
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_acceptance_of(*attr_names)
        validates_with AcceptanceValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveModel
  module Validations
    # == Active \Model Validation Callbacks
    #
    # Provides an interface for any class to have +before_validation+ and
    # +after_validation+ callbacks.
    #
    # First, include ActiveModel::Validations::Callbacks from the class you are
    # creating:
    #
    #   class MyModel
    #     include ActiveModel::Validations::Callbacks
    #
    #     before_validation :do_stuff_before_validation
    #     after_validation  :do_stuff_after_validation
    #   end
    #
    # Like other <tt>before_*</tt> callbacks if +before_validation+ returns
    # +false+ then <tt>valid?</tt> will not be called.
    module Callbacks
      extend ActiveSupport::Concern

      included do
        include ActiveSupport::Callbacks
        define_callbacks :validation, :terminator => "result == false", :skip_after_callbacks_if_terminated => true, :scope => [:kind, :name]
      end

      module ClassMethods
        # Defines a callback that will get called right before validation
        # happens.
        #
        #   class Person
        #     include ActiveModel::Validations
        #     include ActiveModel::Validations::Callbacks
        #
        #     attr_accessor :name
        #
        #     validates_length_of :name, maximum: 6
        #
        #     before_validation :remove_whitespaces
        #
        #     private
        #
        #     def remove_whitespaces
        #       name.strip!
        #     end
        #   end
        #
        #   person = Person.new
        #   person.name = '  bob  '
        #   person.valid? # => true
        #   person.name   # => "bob"
        def before_validation(*args, &block)
          options = args.last
          if options.is_a?(Hash) && options[:on]
            options[:if] = Array(options[:if])
            options[:on] = Array(options[:on])
            options[:if].unshift("#{options[:on]}.include? self.validation_context")
          end
          set_callback(:validation, :before, *args, &block)
        end

        # Defines a callback that will get called right after validation
        # happens.
        #
        #   class Person
        #     include ActiveModel::Validations
        #     include ActiveModel::Validations::Callbacks
        #
        #     attr_accessor :name, :status
        #
        #     validates_presence_of :name
        #
        #     after_validation :set_status
        #
        #     private
        #
        #     def set_status
        #       self.status = errors.empty?
        #     end
        #   end
        #
        #   person = Person.new
        #   person.name = ''
        #   person.valid? # => false
        #   person.status # => false
        #   person.name = 'bob'
        #   person.valid? # => true
        #   person.status # => true
        def after_validation(*args, &block)
          options = args.extract_options!
          options[:prepend] = true
          options[:if] = Array(options[:if])
          if options[:on]
            options[:on] = Array(options[:on])
            options[:if].unshift("#{options[:on]}.include? self.validation_context")
          end
          set_callback(:validation, :after, *(args << options), &block)
        end
      end

    protected

      # Overwrite run validations to include callbacks.
      def run_validations! #:nodoc:
        run_callbacks(:validation) { super }
      end
    end
  end
end
require 'active_support/core_ext/range'

module ActiveModel
  module Validations
    module Clusivity #:nodoc:
      ERROR_MESSAGE = "An object with the method #include? or a proc, lambda or symbol is required, " \
                      "and must be supplied as the :in (or :within) option of the configuration hash"

      def check_validity!
        unless delimiter.respond_to?(:include?) || delimiter.respond_to?(:call) || delimiter.respond_to?(:to_sym)
          raise ArgumentError, ERROR_MESSAGE
        end
      end

    private

      def include?(record, value)
        exclusions = if delimiter.respond_to?(:call)
                       delimiter.call(record)
                     elsif delimiter.respond_to?(:to_sym)
                       record.send(delimiter)
                     else
                       delimiter
                     end

        exclusions.send(inclusion_method(exclusions), value)
      end

      def delimiter
        @delimiter ||= options[:in] || options[:within]
      end

      # In Ruby 1.9 <tt>Range#include?</tt> on non-numeric ranges checks all possible values in the
      # range for equality, so it may be slow for large ranges. The new <tt>Range#cover?</tt>
      # uses the previous logic of comparing a value with the range endpoints.
      def inclusion_method(enumerable)
        enumerable.is_a?(Range) ? :cover? : :include?
      end
    end
  end
end
module ActiveModel

  module Validations
    class ConfirmationValidator < EachValidator # :nodoc:
      def validate_each(record, attribute, value)
        if (confirmed = record.send("#{attribute}_confirmation")) && (value != confirmed)
          human_attribute_name = record.class.human_attribute_name(attribute)
          record.errors.add(:"#{attribute}_confirmation", :confirmation, options.merge(:attribute => human_attribute_name))
        end
      end

      def setup(klass)
        klass.send(:attr_accessor, *attributes.map do |attribute|
          :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation")
        end.compact)
      end
    end

    module HelperMethods
      # Encapsulates the pattern of wanting to validate a password or email
      # address field with a confirmation.
      #
      #   Model:
      #     class Person < ActiveRecord::Base
      #       validates_confirmation_of :user_name, :password
      #       validates_confirmation_of :email_address,
      #                                 message: 'should match confirmation'
      #     end
      #
      #   View:
      #     <%= password_field "person", "password" %>
      #     <%= password_field "person", "password_confirmation" %>
      #
      # The added +password_confirmation+ attribute is virtual; it exists only
      # as an in-memory attribute for validating the password. To achieve this,
      # the validation adds accessors to the model for the confirmation
      # attribute.
      #
      # NOTE: This check is performed only if +password_confirmation+ is not
      # +nil+. To require confirmation, make sure to add a presence check for
      # the confirmation attribute:
      #
      #   validates_presence_of :password_confirmation, if: :password_changed?
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "doesn't match
      #   confirmation").
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_confirmation_of(*attr_names)
        validates_with ConfirmationValidator, _merge_attributes(attr_names)
      end
    end
  end
end
require "active_model/validations/clusivity"

module ActiveModel

  module Validations
    class ExclusionValidator < EachValidator # :nodoc:
      include Clusivity

      def validate_each(record, attribute, value)
        if include?(record, value)
          record.errors.add(attribute, :exclusion, options.except(:in, :within).merge!(:value => value))
        end
      end
    end

    module HelperMethods
      # Validates that the value of the specified attribute is not in a
      # particular enumerable object.
      #
      #   class Person < ActiveRecord::Base
      #     validates_exclusion_of :username, in: %w( admin superuser ), message: "You don't belong here"
      #     validates_exclusion_of :age, in: 30..60, message: 'This site is only for under 30 and over 60'
      #     validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed"
      #     validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] },
      #                            message: 'should not be the same as your username or first name'
      #     validates_exclusion_of :karma, in: :reserved_karmas
      #   end
      #
      # Configuration options:
      # * <tt>:in</tt> - An enumerable object of items that the value shouldn't
      #   be part of. This can be supplied as a proc, lambda or symbol which returns an
      #   enumerable. If the enumerable is a range the test is performed with
      # * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
      #   <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>.
      # * <tt>:message</tt> - Specifies a custom error message (default is: "is
      #   reserved").
      # * <tt>:allow_nil</tt> - If set to true, skips this validation if the
      #   attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to true, skips this validation if the
      #   attribute is blank(default is +false+).
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_exclusion_of(*attr_names)
        validates_with ExclusionValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveModel

  module Validations
    class FormatValidator < EachValidator # :nodoc:
      def validate_each(record, attribute, value)
        if options[:with]
          regexp = option_call(record, :with)
          record_error(record, attribute, :with, value) if value.to_s !~ regexp
        elsif options[:without]
          regexp = option_call(record, :without)
          record_error(record, attribute, :without, value) if value.to_s =~ regexp
        end
      end

      def check_validity!
        unless options.include?(:with) ^ options.include?(:without)  # ^ == xor, or "exclusive or"
          raise ArgumentError, "Either :with or :without must be supplied (but not both)"
        end

        check_options_validity(options, :with)
        check_options_validity(options, :without)
      end

      private

      def option_call(record, name)
        option = options[name]
        option.respond_to?(:call) ? option.call(record) : option
      end

      def record_error(record, attribute, name, value)
        record.errors.add(attribute, :invalid, options.except(name).merge!(:value => value))
      end

      def regexp_using_multiline_anchors?(regexp)
        regexp.source.start_with?("^") ||
          (regexp.source.end_with?("$") && !regexp.source.end_with?("\\$"))
      end

      def check_options_validity(options, name)
        option = options[name]
        if option && !option.is_a?(Regexp) && !option.respond_to?(:call)
          raise ArgumentError, "A regular expression or a proc or lambda must be supplied as :#{name}"
        elsif option && option.is_a?(Regexp) &&
              regexp_using_multiline_anchors?(option) && options[:multiline] != true
          raise ArgumentError, "The provided regular expression is using multiline anchors (^ or $), " \
          "which may present a security risk. Did you mean to use \\A and \\z, or forgot to add the " \
          ":multiline => true option?"
        end
      end
    end

    module HelperMethods
      # Validates whether the value of the specified attribute is of the correct
      # form, going by the regular expression provided.You can require that the
      # attribute matches the regular expression:
      #
      #   class Person < ActiveRecord::Base
      #     validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create
      #   end
      #
      # Alternatively, you can require that the specified attribute does _not_
      # match the regular expression:
      #
      #   class Person < ActiveRecord::Base
      #     validates_format_of :email, without: /NOSPAM/
      #   end
      #
      # You can also provide a proc or lambda which will determine the regular
      # expression that will be used to validate the attribute.
      #
      #   class Person < ActiveRecord::Base
      #     # Admin can have number as a first letter in their screen name
      #     validates_format_of :screen_name,
      #                         with: ->(person) { person.admin? ? /\A[a-z0-9][a-z0-9_\-]*\z/i : /\A[a-z][a-z0-9_\-]*\z/i }
      #   end
      #
      # Note: use <tt>\A</tt> and <tt>\Z</tt> to match the start and end of the
      # string, <tt>^</tt> and <tt>$</tt> match the start/end of a line.
      #
      # Due to frequent misuse of <tt>^</tt> and <tt>$</tt>, you need to pass
      # the <tt>multiline: true</tt> option in case you use any of these two
      # anchors in the provided regular expression. In most cases, you should be
      # using <tt>\A</tt> and <tt>\z</tt>.
      #
      # You must pass either <tt>:with</tt> or <tt>:without</tt> as an option.
      # In addition, both must be a regular expression or a proc or lambda, or
      # else an exception will be raised.
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "is invalid").
      # * <tt>:allow_nil</tt> - If set to true, skips this validation if the
      #   attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to true, skips this validation if the
      #   attribute is blank (default is +false+).
      # * <tt>:with</tt> - Regular expression that if the attribute matches will
      #   result in a successful validation. This can be provided as a proc or
      #   lambda returning regular expression which will be called at runtime.
      # * <tt>:without</tt> - Regular expression that if the attribute does not
      #   match will result in a successful validation. This can be provided as
      #   a proc or lambda returning regular expression which will be called at
      #   runtime.
      # * <tt>:multiline</tt> - Set to true if your regular expression contains
      #   anchors that match the beginning or end of lines as opposed to the
      #   beginning or end of the string. These anchors are <tt>^</tt> and <tt>$</tt>.
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_format_of(*attr_names)
        validates_with FormatValidator, _merge_attributes(attr_names)
      end
    end
  end
end
require "active_model/validations/clusivity"

module ActiveModel

  module Validations
    class InclusionValidator < EachValidator # :nodoc:
      include Clusivity

      def validate_each(record, attribute, value)
        unless include?(record, value)
          record.errors.add(attribute, :inclusion, options.except(:in, :within).merge!(:value => value))
        end
      end
    end

    module HelperMethods
      # Validates whether the value of the specified attribute is available in a
      # particular enumerable object.
      #
      #   class Person < ActiveRecord::Base
      #     validates_inclusion_of :gender, in: %w( m f )
      #     validates_inclusion_of :age, in: 0..99
      #     validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
      #     validates_inclusion_of :states, in: ->(person) { STATES[person.country] }
      #     validates_inclusion_of :karma, in: :available_karmas
      #   end
      #
      # Configuration options:
      # * <tt>:in</tt> - An enumerable object of available items. This can be
      #   supplied as a proc, lambda or symbol which returns an enumerable. If the
      #   enumerable is a range the test is performed with <tt>Range#cover?</tt>,
      #   otherwise with <tt>include?</tt>.
      # * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
      # * <tt>:message</tt> - Specifies a custom error message (default is: "is
      #   not included in the list").
      # * <tt>:allow_nil</tt> - If set to +true+, skips this validation if the
      #   attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to +true+, skips this validation if the
      #   attribute is blank (default is +false+).
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_inclusion_of(*attr_names)
        validates_with InclusionValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveModel

  # == Active \Model Length \Validator
  module Validations
    class LengthValidator < EachValidator # :nodoc:
      MESSAGES  = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }.freeze
      CHECKS    = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze

      RESERVED_OPTIONS  = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]

      def initialize(options)
        if range = (options.delete(:in) || options.delete(:within))
          raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
          options[:minimum], options[:maximum] = range.min, range.max
        end

        if options[:allow_blank] == false && options[:minimum].nil? && options[:is].nil?
          options[:minimum] = 1
        end

        super
      end

      def check_validity!
        keys = CHECKS.keys & options.keys

        if keys.empty?
          raise ArgumentError, 'Range unspecified. Specify the :in, :within, :maximum, :minimum, or :is option.'
        end

        keys.each do |key|
          value = options[key]

          unless (value.is_a?(Integer) && value >= 0) || value == Float::INFINITY
            raise ArgumentError, ":#{key} must be a nonnegative Integer or Infinity"
          end
        end
      end

      def validate_each(record, attribute, value)
        value = tokenize(value)
        value_length = value.respond_to?(:length) ? value.length : value.to_s.length
        errors_options = options.except(*RESERVED_OPTIONS)

        CHECKS.each do |key, validity_check|
          next unless check_value = options[key]

          if !value.nil? || skip_nil_check?(key)
            next if value_length.send(validity_check, check_value)
          end

          errors_options[:count] = check_value

          default_message = options[MESSAGES[key]]
          errors_options[:message] ||= default_message if default_message

          record.errors.add(attribute, MESSAGES[key], errors_options)
        end
      end

      private

      def tokenize(value)
        if options[:tokenizer] && value.kind_of?(String)
          options[:tokenizer].call(value)
        end || value
      end

      def skip_nil_check?(key)
        key == :maximum && options[:allow_nil].nil? && options[:allow_blank].nil?
      end
    end

    module HelperMethods

      # Validates that the specified attribute matches the length restrictions
      # supplied. Only one option can be used at a time:
      #
      #   class Person < ActiveRecord::Base
      #     validates_length_of :first_name, maximum: 30
      #     validates_length_of :last_name, maximum: 30, message: "less than 30 if you don't mind"
      #     validates_length_of :fax, in: 7..32, allow_nil: true
      #     validates_length_of :phone, in: 7..32, allow_blank: true
      #     validates_length_of :user_name, within: 6..20, too_long: 'pick a shorter name', too_short: 'pick a longer name'
      #     validates_length_of :zip_code, minimum: 5, too_short: 'please enter at least 5 characters'
      #     validates_length_of :smurf_leader, is: 4, message: "papa is spelled with 4 characters... don't play me."
      #     validates_length_of :essay, minimum: 100, too_short: 'Your essay must be at least 100 words.',
      #                         tokenizer: ->(str) { str.scan(/\w+/) }
      #   end
      #
      # Configuration options:
      # * <tt>:minimum</tt> - The minimum size of the attribute.
      # * <tt>:maximum</tt> - The maximum size of the attribute. Allows +nil+ by
      #   default if not used with :minimum.
      # * <tt>:is</tt> - The exact size of the attribute.
      # * <tt>:within</tt> - A range specifying the minimum and maximum size of
      #   the attribute.
      # * <tt>:in</tt> - A synonym (or alias) for <tt>:within</tt>.
      # * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
      # * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
      # * <tt>:too_long</tt> - The error message if the attribute goes over the
      #   maximum (default is: "is too long (maximum is %{count} characters)").
      # * <tt>:too_short</tt> - The error message if the attribute goes under the
      #   minimum (default is: "is too short (min is %{count} characters)").
      # * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt>
      #   method and the attribute is the wrong size (default is: "is the wrong
      #   length (should be %{count} characters)").
      # * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>,
      #   <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate
      #   <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
      # * <tt>:tokenizer</tt> - Specifies how to split up the attribute string.
      #   (e.g. <tt>tokenizer: ->(str) { str.scan(/\w+/) }</tt> to count words
      #   as in above example). Defaults to <tt>->(value) { value.split(//) }</tt>
      #   which counts individual characters.
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_length_of(*attr_names)
        validates_with LengthValidator, _merge_attributes(attr_names)
      end

      alias_method :validates_size_of, :validates_length_of
    end
  end
end
module ActiveModel

  module Validations
    class NumericalityValidator < EachValidator # :nodoc:
      CHECKS = { :greater_than => :>, :greater_than_or_equal_to => :>=,
                 :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=,
                 :odd => :odd?, :even => :even?, :other_than => :!= }.freeze

      RESERVED_OPTIONS = CHECKS.keys + [:only_integer]

      def check_validity!
        keys = CHECKS.keys - [:odd, :even]
        options.slice(*keys).each do |option, value|
          next if value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
          raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
        end
      end

      def validate_each(record, attr_name, value)
        before_type_cast = :"#{attr_name}_before_type_cast"

        raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast)
        raw_value ||= value

        return if options[:allow_nil] && raw_value.nil?

        unless value = parse_raw_value_as_a_number(raw_value)
          record.errors.add(attr_name, :not_a_number, filtered_options(raw_value))
          return
        end

        if options[:only_integer]
          unless value = parse_raw_value_as_an_integer(raw_value)
            record.errors.add(attr_name, :not_an_integer, filtered_options(raw_value))
            return
          end
        end

        options.slice(*CHECKS.keys).each do |option, option_value|
          case option
          when :odd, :even
            unless value.to_i.send(CHECKS[option])
              record.errors.add(attr_name, option, filtered_options(value))
            end
          else
            option_value = option_value.call(record) if option_value.is_a?(Proc)
            option_value = record.send(option_value) if option_value.is_a?(Symbol)

            unless value.send(CHECKS[option], option_value)
              record.errors.add(attr_name, option, filtered_options(value).merge(:count => option_value))
            end
          end
        end
      end

    protected

      def parse_raw_value_as_a_number(raw_value)
        case raw_value
        when /\A0[xX]/
          nil
        else
          begin
            Kernel.Float(raw_value)
          rescue ArgumentError, TypeError
            nil
          end
        end
      end

      def parse_raw_value_as_an_integer(raw_value)
        raw_value.to_i if raw_value.to_s =~ /\A[+-]?\d+\Z/
      end

      def filtered_options(value)
        options.except(*RESERVED_OPTIONS).merge!(:value => value)
      end
    end

    module HelperMethods
      # Validates whether the value of the specified attribute is numeric by
      # trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt>
      # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\Z/</tt>
      # (if <tt>only_integer</tt> is set to +true+).
      #
      #   class Person < ActiveRecord::Base
      #     validates_numericality_of :value, on: :create
      #   end
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "is not a number").
      # * <tt>:only_integer</tt> - Specifies whether the value has to be an
      #   integer, e.g. an integral value (default is +false+).
      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+ (default is
      #   +false+). Notice that for fixnum and float columns empty strings are
      #   converted to +nil+.
      # * <tt>:greater_than</tt> - Specifies the value must be greater than the
      #   supplied value.
      # * <tt>:greater_than_or_equal_to</tt> - Specifies the value must be
      #   greater than or equal the supplied value.
      # * <tt>:equal_to</tt> - Specifies the value must be equal to the supplied
      #   value.
      # * <tt>:less_than</tt> - Specifies the value must be less than the
      #   supplied value.
      # * <tt>:less_than_or_equal_to</tt> - Specifies the value must be less
      #   than or equal the supplied value.
      # * <tt>:other_than</tt> - Specifies the value must be other than the
      #   supplied value.
      # * <tt>:odd</tt> - Specifies the value must be an odd number.
      # * <tt>:even</tt> - Specifies the value must be an even number.
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+ .
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      #
      # The following checks can also be supplied with a proc or a symbol which
      # corresponds to a method:
      #
      # * <tt>:greater_than</tt>
      # * <tt>:greater_than_or_equal_to</tt>
      # * <tt>:equal_to</tt>
      # * <tt>:less_than</tt>
      # * <tt>:less_than_or_equal_to</tt>
      #
      # For example:
      #
      #   class Person < ActiveRecord::Base
      #     validates_numericality_of :width, less_than: ->(person) { person.height }
      #     validates_numericality_of :width, greater_than: :minimum_weight
      #   end
      def validates_numericality_of(*attr_names)
        validates_with NumericalityValidator, _merge_attributes(attr_names)
      end
    end
  end
end

module ActiveModel

  module Validations
    class PresenceValidator < EachValidator # :nodoc:
      def validate_each(record, attr_name, value)
        record.errors.add(attr_name, :blank, options) if value.blank?
      end
    end

    module HelperMethods
      # Validates that the specified attributes are not blank (as defined by
      # Object#blank?). Happens by default on save.
      #
      #   class Person < ActiveRecord::Base
      #     validates_presence_of :first_name
      #   end
      #
      # The first_name attribute must be in the object and it cannot be blank.
      #
      # If you want to validate the presence of a boolean field (where the real
      # values are +true+ and +false+), you will want to use
      # <tt>validates_inclusion_of :field_name, in: [true, false]</tt>.
      #
      # This is due to the way Object#blank? handles boolean values:
      # <tt>false.blank? # => true</tt>.
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "can't be blank").
      #
      # There is also a list of default options supported by every validator:
      # +:if+, +:unless+, +:on+ and +:strict+.
      # See <tt>ActiveModel::Validation#validates</tt> for more information
      def validates_presence_of(*attr_names)
        validates_with PresenceValidator, _merge_attributes(attr_names)
      end
    end
  end
end
require 'active_support/core_ext/hash/slice'

module ActiveModel
  module Validations
    module ClassMethods
      # This method is a shortcut to all default validators and any custom
      # validator classes ending in 'Validator'. Note that Rails default
      # validators can be overridden inside specific classes by creating
      # custom validator classes in their place such as PresenceValidator.
      #
      # Examples of using the default rails validators:
      #
      #   validates :terms, acceptance: true
      #   validates :password, confirmation: true
      #   validates :username, exclusion: { in: %w(admin superuser) }
      #   validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :create }
      #   validates :age, inclusion: { in: 0..9 }
      #   validates :first_name, length: { maximum: 30 }
      #   validates :age, numericality: true
      #   validates :username, presence: true
      #   validates :username, uniqueness: true
      #
      # The power of the +validates+ method comes when using custom validators
      # and default validators in one call for a given attribute.
      #
      #   class EmailValidator < ActiveModel::EachValidator
      #     def validate_each(record, attribute, value)
      #       record.errors.add attribute, (options[:message] || "is not an email") unless
      #         value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
      #     end
      #   end
      #
      #   class Person
      #     include ActiveModel::Validations
      #     attr_accessor :name, :email
      #
      #     validates :name, presence: true, uniqueness: true, length: { maximum: 100 }
      #     validates :email, presence: true, email: true
      #   end
      #
      # Validator classes may also exist within the class being validated
      # allowing custom modules of validators to be included as needed.
      #
      #   class Film
      #     include ActiveModel::Validations
      #
      #     class TitleValidator < ActiveModel::EachValidator
      #       def validate_each(record, attribute, value)
      #         record.errors.add attribute, "must start with 'the'" unless value =~ /\Athe/i
      #       end
      #     end
      #
      #     validates :name, title: true
      #   end
      #
      # Additionally validator classes may be in another namespace and still
      # used within any class.
      #
      #   validates :name, :'film/title' => true
      #
      # The validators hash can also handle regular expressions, ranges, arrays
      # and strings in shortcut form.
      #
      #   validates :email, format: /@/
      #   validates :gender, inclusion: %w(male female)
      #   validates :password, length: 6..20
      #
      # When using shortcut form, ranges and arrays are passed to your
      # validator's initializer as <tt>options[:in]</tt> while other types
      # including regular expressions and strings are passed as <tt>options[:with]</tt>.
      #
      # There is also a list of options that could be used along with validators:
      #
      # * <tt>:on</tt> - Specifies when this validation is active. Runs in all
      #   validation contexts by default (+nil+), other options are <tt>:create</tt>
      #   and <tt>:update</tt>.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
      #   method, proc or string should return or evaluate to a +true+ or
      #   +false+ value.
      # * <tt>:strict</tt> - if the <tt>:strict</tt> option is set to true
      #   will raise ActiveModel::StrictValidationFailed instead of adding the error.
      #   <tt>:strict</tt> option can also be set to any other exception.
      #
      # Example:
      #
      #   validates :password, presence: true, confirmation: true, if: :password_required?
      #   validates :token, uniqueness: true, strict: TokenGenerationException
      #
      #
      # Finally, the options +:if+, +:unless+, +:on+, +:allow_blank+, +:allow_nil+, +:strict+
      # and +:message+ can be given to one specific validator, as a hash:
      #
      #   validates :password, presence: { if: :password_required?, message: 'is forgotten.' }, confirmation: true
      def validates(*attributes)
        defaults = attributes.extract_options!.dup
        validations = defaults.slice!(*_validates_default_keys)

        raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
        raise ArgumentError, "You need to supply at least one validation" if validations.empty?

        defaults[:attributes] = attributes

        validations.each do |key, options|
          next unless options
          key = "#{key.to_s.camelize}Validator"

          begin
            validator = key.include?('::') ? key.constantize : const_get(key)
          rescue NameError
            raise ArgumentError, "Unknown validator: '#{key}'"
          end

          validates_with(validator, defaults.merge(_parse_validates_options(options)))
        end
      end

      # This method is used to define validations that cannot be corrected by end
      # users and are considered exceptional. So each validator defined with bang
      # or <tt>:strict</tt> option set to <tt>true</tt> will always raise
      # <tt>ActiveModel::StrictValidationFailed</tt> instead of adding error
      # when validation fails. See <tt>validates</tt> for more information about
      # the validation itself.
      #
      #   class Person
      #     include ActiveModel::Validations
      #
      #     attr_accessor :name
      #     validates! :name, presence: true
      #   end
      #
      #   person = Person.new
      #   person.name = ''
      #   person.valid?
      #   # => ActiveModel::StrictValidationFailed: Name can't be blank
      def validates!(*attributes)
        options = attributes.extract_options!
        options[:strict] = true
        validates(*(attributes << options))
      end

    protected

      # When creating custom validators, it might be useful to be able to specify
      # additional default keys. This can be done by overwriting this method.
      def _validates_default_keys # :nodoc:
        [:if, :unless, :on, :allow_blank, :allow_nil , :strict]
      end

      def _parse_validates_options(options) # :nodoc:
        case options
        when TrueClass
          {}
        when Hash
          options
        when Range, Array
          { :in => options }
        else
          { :with => options }
        end
      end
    end
  end
end
module ActiveModel
  module Validations
    module HelperMethods
      private
        def _merge_attributes(attr_names)
          options = attr_names.extract_options!.symbolize_keys
          attr_names.flatten!
          options[:attributes] = attr_names
          options
        end
    end

    class WithValidator < EachValidator # :nodoc:
      def validate_each(record, attr, val)
        method_name = options[:with]

        if record.method(method_name).arity == 0
          record.send method_name
        else
          record.send method_name, attr
        end
      end
    end

    module ClassMethods
      # Passes the record off to the class or classes specified and allows them
      # to add errors based on more complex conditions.
      #
      #   class Person
      #     include ActiveModel::Validations
      #     validates_with MyValidator
      #   end
      #
      #   class MyValidator < ActiveModel::Validator
      #     def validate(record)
      #       if some_complex_logic
      #         record.errors.add :base, 'This record is invalid'
      #       end
      #     end
      #
      #     private
      #       def some_complex_logic
      #         # ...
      #       end
      #   end
      #
      # You may also pass it multiple classes, like so:
      #
      #   class Person
      #     include ActiveModel::Validations
      #     validates_with MyValidator, MyOtherValidator, on: :create
      #   end
      #
      # Configuration options:
      # * <tt>:on</tt> - Specifies when this validation is active
      #   (<tt>:create</tt> or <tt>:update</tt>.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>).
      #   The method, proc or string should return or evaluate to a +true+ or
      #   +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
      #   determine if the validation should not occur
      #   (e.g. <tt>unless: :skip_validation</tt>, or
      #   <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>).
      #   The method, proc or string should return or evaluate to a +true+ or
      #   +false+ value.
      # * <tt>:strict</tt> - Specifies whether validation should be strict.
      #   See <tt>ActiveModel::Validation#validates!</tt> for more information.
      #
      # If you pass any additional configuration options, they will be passed
      # to the class and available as +options+:
      #
      #   class Person
      #     include ActiveModel::Validations
      #     validates_with MyValidator, my_custom_key: 'my custom value'
      #   end
      #
      #   class MyValidator < ActiveModel::Validator
      #     def validate(record)
      #       options[:my_custom_key] # => "my custom value"
      #     end
      #   end
      def validates_with(*args, &block)
        options = args.extract_options!
        args.each do |klass|
          validator = klass.new(options, &block)
          validator.setup(self) if validator.respond_to?(:setup)

          if validator.respond_to?(:attributes) && !validator.attributes.empty?
            validator.attributes.each do |attribute|
              _validators[attribute.to_sym] << validator
            end
          else
            _validators[nil] << validator
          end

          validate(validator, options)
        end
      end
    end

    # Passes the record off to the class or classes specified and allows them
    # to add errors based on more complex conditions.
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     validate :instance_validations
    #
    #     def instance_validations
    #       validates_with MyValidator
    #     end
    #   end
    #
    # Please consult the class method documentation for more information on
    # creating your own validator.
    #
    # You may also pass it multiple classes, like so:
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     validate :instance_validations, on: :create
    #
    #     def instance_validations
    #       validates_with MyValidator, MyOtherValidator
    #     end
    #   end
    #
    # Standard configuration options (<tt>:on</tt>, <tt>:if</tt> and
    # <tt>:unless</tt>), which are available on the class version of
    # +validates_with+, should instead be placed on the +validates+ method
    # as these are applied and tested in the callback.
    #
    # If you pass any additional configuration options, they will be passed
    # to the class and available as +options+, please refer to the
    # class version of this method for more information.
    def validates_with(*args, &block)
      options = args.extract_options!
      args.each do |klass|
        validator = klass.new(options, &block)
        validator.validate(self)
      end
    end
  end
end
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/except'

module ActiveModel

  # == Active \Model Validations
  #
  # Provides a full validation framework to your objects.
  #
  # A minimal implementation could be:
  #
  #   class Person
  #     include ActiveModel::Validations
  #
  #     attr_accessor :first_name, :last_name
  #
  #     validates_each :first_name, :last_name do |record, attr, value|
  #       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
  #     end
  #   end
  #
  # Which provides you with the full standard validation stack that you
  # know from Active Record:
  #
  #   person = Person.new
  #   person.valid?                   # => true
  #   person.invalid?                 # => false
  #
  #   person.first_name = 'zoolander'
  #   person.valid?                   # => false
  #   person.invalid?                 # => true
  #   person.errors.messages          # => {first_name:["starts with z."]}
  #
  # Note that <tt>ActiveModel::Validations</tt> automatically adds an +errors+
  # method to your instances initialized with a new <tt>ActiveModel::Errors</tt>
  # object, so there is no need for you to do this manually.
  module Validations
    extend ActiveSupport::Concern

    included do
      extend ActiveModel::Callbacks
      extend ActiveModel::Translation

      extend  HelperMethods
      include HelperMethods

      attr_accessor :validation_context
      define_callbacks :validate, :scope => :name

      class_attribute :_validators
      self._validators = Hash.new { |h,k| h[k] = [] }
    end

    module ClassMethods
      # Validates each attribute against a block.
      #
      #   class Person
      #     include ActiveModel::Validations
      #
      #     attr_accessor :first_name, :last_name
      #
      #     validates_each :first_name, :last_name, allow_blank: true do |record, attr, value|
      #       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
      #     end
      #   end
      #
      # Options:
      # * <tt>:on</tt> - Specifies the context where this validation is active
      #   (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt>)
      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
      # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
      #   determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
      #   method, proc or string should return or evaluate to a +true+ or +false+
      #   value.
      def validates_each(*attr_names, &block)
        validates_with BlockValidator, _merge_attributes(attr_names), &block
      end

      # Adds a validation method or block to the class. This is useful when
      # overriding the +validate+ instance method becomes too unwieldy and
      # you're looking for more descriptive declaration of your validations.
      #
      # This can be done with a symbol pointing to a method:
      #
      #   class Comment
      #     include ActiveModel::Validations
      #
      #     validate :must_be_friends
      #
      #     def must_be_friends
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
      #     end
      #   end
      #
      # With a block which is passed with the current record to be validated:
      #
      #   class Comment
      #     include ActiveModel::Validations
      #
      #     validate do |comment|
      #       comment.must_be_friends
      #     end
      #
      #     def must_be_friends
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
      #     end
      #   end
      #
      # Or with a block where self points to the current record to be validated:
      #
      #   class Comment
      #     include ActiveModel::Validations
      #
      #     validate do
      #       errors.add(:base, 'Must be friends to leave a comment') unless commenter.friend_of?(commentee)
      #     end
      #   end
      #
      # Options:
      # * <tt>:on</tt> - Specifies the context where this validation is active
      #   (e.g. <tt>on: :create</tt> or <tt>on: :custom_validation_context</tt>)
      # * <tt>:allow_nil</tt> - Skip validation if attribute is +nil+.
      # * <tt>:allow_blank</tt> - Skip validation if attribute is blank.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
      #   determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
      #   method, proc or string should return or evaluate to a +true+ or +false+
      #   value.
      def validate(*args, &block)
        options = args.extract_options!
        if options.key?(:on)
          options = options.dup
          options[:if] = Array(options[:if])
          options[:if].unshift("validation_context == :#{options[:on]}")
        end
        args << options
        set_callback(:validate, *args, &block)
      end

      # List all validators that are being used to validate the model using
      # +validates_with+ method.
      #
      #   class Person
      #     include ActiveModel::Validations
      #
      #     validates_with MyValidator
      #     validates_with OtherValidator, on: :create
      #     validates_with StrictValidator, strict: true
      #   end
      #
      #   Person.validators
      #   # => [
      #   #      #<MyValidator:0x007fbff403e808 @options={}>,
      #   #      #<OtherValidator:0x007fbff403d930 @options={on: :create}>,
      #   #      #<StrictValidator:0x007fbff3204a30 @options={strict:true}>
      #   #    ]
      def validators
        _validators.values.flatten.uniq
      end

      # List all validators that are being used to validate a specific attribute.
      #
      #   class Person
      #     include ActiveModel::Validations
      #
      #     attr_accessor :name , :age
      #
      #     validates_presence_of :name
      #     validates_inclusion_of :age, in: 0..99
      #   end
      #
      #   Person.validators_on(:name)
      #   # => [
      #   #       #<ActiveModel::Validations::PresenceValidator:0x007fe604914e60 @attributes=[:name], @options={}>,
      #   #       #<ActiveModel::Validations::InclusionValidator:0x007fe603bb8780 @attributes=[:age], @options={in:0..99}>
      #   #    ]
      def validators_on(*attributes)
        attributes.flat_map do |attribute|
          _validators[attribute.to_sym]
        end
      end

      # Returns +true+ if +attribute+ is an attribute method, +false+ otherwise.
      #
      #  class Person
      #    include ActiveModel::Validations
      #
      #    attr_accessor :name
      #  end
      #
      #  User.attribute_method?(:name) # => true
      #  User.attribute_method?(:age)  # => false
      def attribute_method?(attribute)
        method_defined?(attribute)
      end

      # Copy validators on inheritance.
      def inherited(base) #:nodoc:
        dup = _validators.dup
        base._validators = dup.each { |k, v| dup[k] = v.dup }
        super
      end
    end

    # Clean the +Errors+ object if instance is duped.
    def initialize_dup(other) #:nodoc:
      @errors = nil
      super
    end

    # Returns the +Errors+ object that holds all information about attribute
    # error messages.
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     attr_accessor :name
    #     validates_presence_of :name
    #   end
    #
    #   person = Person.new
    #   person.valid? # => false
    #   person.errors # => #<ActiveModel::Errors:0x007fe603816640 @messages={name:["can't be blank"]}>
    def errors
      @errors ||= Errors.new(self)
    end

    # Runs all the specified validations and returns +true+ if no errors were
    # added otherwise +false+.
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     attr_accessor :name
    #     validates_presence_of :name
    #   end
    #
    #   person = Person.new
    #   person.name = ''
    #   person.valid? # => false
    #   person.name = 'david'
    #   person.valid? # => true
    #
    # Context can optionally be supplied to define which callbacks to test
    # against (the context is defined on the validations using <tt>:on</tt>).
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     attr_accessor :name
    #     validates_presence_of :name, on: :new
    #   end
    #
    #   person = Person.new
    #   person.valid?       # => true
    #   person.valid?(:new) # => false
    def valid?(context = nil)
      current_context, self.validation_context = validation_context, context
      errors.clear
      run_validations!
    ensure
      self.validation_context = current_context
    end

    # Performs the opposite of <tt>valid?</tt>. Returns +true+ if errors were
    # added, +false+ otherwise.
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     attr_accessor :name
    #     validates_presence_of :name
    #   end
    #
    #   person = Person.new
    #   person.name = ''
    #   person.invalid? # => true
    #   person.name = 'david'
    #   person.invalid? # => false
    #
    # Context can optionally be supplied to define which callbacks to test
    # against (the context is defined on the validations using <tt>:on</tt>).
    #
    #   class Person
    #     include ActiveModel::Validations
    #
    #     attr_accessor :name
    #     validates_presence_of :name, on: :new
    #   end
    #
    #   person = Person.new
    #   person.invalid?       # => false
    #   person.invalid?(:new) # => true
    def invalid?(context = nil)
      !valid?(context)
    end

    # Hook method defining how an attribute value should be retrieved. By default
    # this is assumed to be an instance named after the attribute. Override this
    # method in subclasses should you need to retrieve the value for a given
    # attribute differently:
    #
    #   class MyClass
    #     include ActiveModel::Validations
    #
    #     def initialize(data = {})
    #       @data = data
    #     end
    #
    #     def read_attribute_for_validation(key)
    #       @data[key]
    #     end
    #   end
    alias :read_attribute_for_validation :send

  protected

    def run_validations! #:nodoc:
      run_callbacks :validate
      errors.empty?
    end
  end
end

Dir[File.dirname(__FILE__) + "/validations/*.rb"].sort.each do |path|
  filename = File.basename(path)
  require "active_model/validations/#{filename}"
end
require "active_support/core_ext/module/anonymous"

module ActiveModel

  # == Active \Model \Validator
  #
  # A simple base class that can be used along with
  # ActiveModel::Validations::ClassMethods.validates_with
  #
  #   class Person
  #     include ActiveModel::Validations
  #     validates_with MyValidator
  #   end
  #
  #   class MyValidator < ActiveModel::Validator
  #     def validate(record)
  #       if some_complex_logic
  #         record.errors[:base] = "This record is invalid"
  #       end
  #     end
  #
  #     private
  #       def some_complex_logic
  #         # ...
  #       end
  #   end
  #
  # Any class that inherits from ActiveModel::Validator must implement a method
  # called +validate+ which accepts a +record+.
  #
  #   class Person
  #     include ActiveModel::Validations
  #     validates_with MyValidator
  #   end
  #
  #   class MyValidator < ActiveModel::Validator
  #     def validate(record)
  #       record # => The person instance being validated
  #       options # => Any non-standard options passed to validates_with
  #     end
  #   end
  #
  # To cause a validation error, you must add to the +record+'s errors directly
  # from within the validators message.
  #
  #   class MyValidator < ActiveModel::Validator
  #     def validate(record)
  #       record.errors.add :base, "This is some custom error message"
  #       record.errors.add :first_name, "This is some complex validation"
  #       # etc...
  #     end
  #   end
  #
  # To add behavior to the initialize method, use the following signature:
  #
  #   class MyValidator < ActiveModel::Validator
  #     def initialize(options)
  #       super
  #       @my_custom_field = options[:field_name] || :first_name
  #     end
  #   end
  #
  # Note that the validator is initialized only once for the whole application
  # lifecycle, and not on each validation run.
  #
  # The easiest way to add custom validators for validating individual attributes
  # is with the convenient <tt>ActiveModel::EachValidator</tt>.
  #
  #   class TitleValidator < ActiveModel::EachValidator
  #     def validate_each(record, attribute, value)
  #       record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
  #     end
  #   end
  #
  # This can now be used in combination with the +validates+ method
  # (see <tt>ActiveModel::Validations::ClassMethods.validates</tt> for more on this).
  #
  #   class Person
  #     include ActiveModel::Validations
  #     attr_accessor :title
  #
  #     validates :title, presence: true
  #   end
  #
  # Validator may also define a +setup+ instance method which will get called
  # with the class that using that validator as its argument. This can be
  # useful when there are prerequisites such as an +attr_accessor+ being present.
  #
  #   class MyValidator < ActiveModel::Validator
  #     def setup(klass)
  #       klass.send :attr_accessor, :custom_attribute
  #     end
  #   end
  #
  # This setup method is only called when used with validation macros or the
  # class level <tt>validates_with</tt> method.
  class Validator
    attr_reader :options

    # Returns the kind of the validator.
    #
    #   PresenceValidator.kind   # => :presence
    #   UniquenessValidator.kind # => :uniqueness
    def self.kind
      @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous?
    end

    # Accepts options that will be made available through the +options+ reader.
    def initialize(options = {})
      @options = options.freeze
    end

    # Return the kind for this validator.
    #
    #   PresenceValidator.new.kind   # => :presence
    #   UniquenessValidator.new.kind # => :uniqueness
    def kind
      self.class.kind
    end

    # Override this method in subclasses with validation logic, adding errors
    # to the records +errors+ array where necessary.
    def validate(record)
      raise NotImplementedError, "Subclasses must implement a validate(record) method."
    end
  end

  # +EachValidator+ is a validator which iterates through the attributes given
  # in the options hash invoking the <tt>validate_each</tt> method passing in the
  # record, attribute and value.
  #
  # All Active Model validations are built on top of this validator.
  class EachValidator < Validator #:nodoc:
    attr_reader :attributes

    # Returns a new validator instance. All options will be available via the
    # +options+ reader, however the <tt>:attributes</tt> option will be removed
    # and instead be made available through the +attributes+ reader.
    def initialize(options)
      @attributes = Array(options.delete(:attributes))
      raise ArgumentError, ":attributes cannot be blank" if @attributes.empty?
      super
      check_validity!
    end

    # Performs validation on the supplied record. By default this will call
    # +validates_each+ to determine validity therefore subclasses should
    # override +validates_each+ with validation logic.
    def validate(record)
      attributes.each do |attribute|
        value = record.read_attribute_for_validation(attribute)
        next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
        validate_each(record, attribute, value)
      end
    end

    # Override this method in subclasses with the validation logic, adding
    # errors to the records +errors+ array where necessary.
    def validate_each(record, attribute, value)
      raise NotImplementedError, "Subclasses must implement a validate_each(record, attribute, value) method"
    end

    # Hook method that gets called by the initializer allowing verification
    # that the arguments supplied are valid. You could for example raise an
    # +ArgumentError+ when invalid options are supplied.
    def check_validity!
    end
  end

  # +BlockValidator+ is a special +EachValidator+ which receives a block on initialization
  # and call this block for each attribute being validated. +validates_each+ uses this validator.
  class BlockValidator < EachValidator #:nodoc:
    def initialize(options, &block)
      @block = block
      super
    end

    private

    def validate_each(record, attribute, value)
      @block.call(record, attribute, value)
    end
  end
end
module ActiveModel
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'active_support'
require 'active_support/rails'
require 'active_model/version'

module ActiveModel
  extend ActiveSupport::Autoload

  autoload :AttributeMethods
  autoload :BlockValidator, 'active_model/validator'
  autoload :Callbacks
  autoload :Conversion
  autoload :Dirty
  autoload :EachValidator, 'active_model/validator'
  autoload :ForbiddenAttributesProtection
  autoload :Lint
  autoload :Model
  autoload :DeprecatedMassAssignmentSecurity
  autoload :Name, 'active_model/naming'
  autoload :Naming
  autoload :SecurePassword
  autoload :Serialization
  autoload :TestCase
  autoload :Translation
  autoload :Validations
  autoload :Validator

  eager_autoload do
    autoload :Errors
  end

  module Serializers
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :JSON
      autoload :Xml
    end
  end

  def eager_load!
    super
    ActiveModel::Serializer.eager_load!
  end
end

ActiveSupport.on_load(:i18n) do
  I18n.load_path << File.dirname(__FILE__) + '/active_model/locale/en.yml'
end
require File.expand_path('../../../load_paths', __FILE__)
require "active_record"
require 'benchmark/ips'

TIME    = (ENV['BENCHMARK_TIME'] || 20).to_i
RECORDS = (ENV['BENCHMARK_RECORDS'] || TIME*1000).to_i

conn = { :adapter => 'sqlite3', :database => ':memory:' }

ActiveRecord::Base.establish_connection(conn)

class User < ActiveRecord::Base
  connection.create_table :users, :force => true do |t|
    t.string :name, :email
    t.timestamps
  end

  has_many :exhibits
end

class Exhibit < ActiveRecord::Base
  connection.create_table :exhibits, :force => true do |t|
    t.belongs_to :user
    t.string :name
    t.text :notes
    t.timestamps
  end

  belongs_to :user

  def look; attributes end
  def feel; look; user.name end

  def self.with_name
    where("name IS NOT NULL")
  end

  def self.with_notes
    where("notes IS NOT NULL")
  end

  def self.look(exhibits) exhibits.each { |e| e.look } end
  def self.feel(exhibits) exhibits.each { |e| e.feel } end
end

puts 'Generating data...'

module ActiveRecord
  class Faker
    LOREM = %Q{Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non aliquet diam. Curabitur vel urna metus, quis malesuada elit.
     Integer consequat tincidunt felis. Etiam non erat dolor. Vivamus imperdiet nibh sit amet diam eleifend id posuere diam malesuada. Mauris at accumsan sem.
     Donec id lorem neque. Fusce erat lorem, ornare eu congue vitae, malesuada quis neque. Maecenas vel urna a velit pretium fermentum. Donec tortor enim,
     tempor venenatis egestas a, tempor sed ipsum. Ut arcu justo, faucibus non imperdiet ac, interdum at diam. Pellentesque ipsum enim, venenatis ut iaculis vitae,
     varius vitae sem. Sed rutrum quam ac elit euismod bibendum. Donec ultricies ultricies magna, at lacinia libero mollis aliquam. Sed ac arcu in tortor elementum
     tincidunt vel interdum sem. Curabitur eget erat arcu. Praesent eget eros leo. Nam magna enim, sollicitudin vehicula scelerisque in, vulputate ut libero.
     Praesent varius tincidunt commodo}.split

    def self.name
      LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join ' '
    end

    def self.email
      LOREM.grep(/^\w*$/).sort_by { rand }.first(2).join('@') + ".com"
    end
  end
end

# pre-compute the insert statements and fake data compilation,
# so the benchmarks below show the actual runtime for the execute
# method, minus the setup steps

# Using the same paragraph for all exhibits because it is very slow
# to generate unique paragraphs for all exhibits.
notes = ActiveRecord::Faker::LOREM.join ' '
today = Date.today

puts "Inserting #{RECORDS} users and exhibits..."
RECORDS.times do
  user = User.create(
    :created_at => today,
    :name       => ActiveRecord::Faker.name,
    :email      => ActiveRecord::Faker.email
  )

  Exhibit.create(
    :created_at => today,
    :name       => ActiveRecord::Faker.name,
    :user       => user,
    :notes      => notes
  )
end

Benchmark.ips(TIME) do |x|
  ar_obj       = Exhibit.find(1)
  attrs        = { :name => 'sam' }
  attrs_first  = { :name => 'sam' }
  attrs_second = { :name => 'tom' }
  exhibit      = {
    :name       => ActiveRecord::Faker.name,
    :notes      => notes,
    :created_at => Date.today
  }

  x.report("Model#id") do
    ar_obj.id
  end

  x.report 'Model.new (instantiation)' do
    Exhibit.new
  end

  x.report 'Model.new (setting attributes)' do
    Exhibit.new(attrs)
  end

  x.report 'Model.first' do
    Exhibit.first.look
  end

  x.report("Model.all limit(100)") do
    Exhibit.look Exhibit.limit(100)
  end

  x.report "Model.all limit(100) with relationship" do
    Exhibit.feel Exhibit.limit(100).includes(:user)
  end

  x.report "Model.all limit(10,000)" do
    Exhibit.look Exhibit.limit(10000)
  end

  x.report 'Model.named_scope' do
    Exhibit.limit(10).with_name.with_notes
  end

  x.report 'Model.create' do
    Exhibit.create(exhibit)
  end

  x.report 'Resource#attributes=' do
    e = Exhibit.new(attrs_first)
    e.attributes = attrs_second
  end

  x.report 'Resource#update' do
    Exhibit.first.update(name: 'bob')
  end

  x.report 'Resource#destroy' do
    Exhibit.first.destroy
  end

  x.report 'Model.transaction' do
    Exhibit.transaction { Exhibit.new }
  end

  x.report 'Model.find(id)' do
    User.find(1)
  end

  x.report 'Model.find_by_sql' do
    Exhibit.find_by_sql("SELECT * FROM exhibits WHERE id = #{(rand * 1000 + 1).to_i}").first
  end

  x.report "Model.log" do
    Exhibit.connection.send(:log, "hello", "world") {}
  end

  x.report "AR.execute(query)" do
    ActiveRecord::Base.connection.execute("Select * from exhibits where id = #{(rand * 1000 + 1).to_i}")
  end
end
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
require 'active_record'

class Person < ActiveRecord::Base
  establish_connection :adapter => 'sqlite3', :database => 'foobar.db'
  connection.create_table table_name, :force => true do |t|
    t.string :name
  end
end

bob = Person.create!(:name => 'bob')
puts Person.all.inspect
bob.destroy
puts Person.all.inspect
module ActiveRecord
  # = Active Record Aggregations
  module Aggregations # :nodoc:
    extend ActiveSupport::Concern

    def clear_aggregation_cache #:nodoc:
      @aggregation_cache.clear if persisted?
    end

    # Active Record implements aggregation through a macro-like class method called +composed_of+
    # for representing attributes  as value objects. It expresses relationships like "Account [is]
    # composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
    # to the macro adds a description of how the value objects are created from the attributes of
    # the entity object (when the entity is initialized either as a new object or from finding an
    # existing object) and how it can be turned back into attributes (when the entity is saved to
    # the database).
    #
    #   class Customer < ActiveRecord::Base
    #     composed_of :balance, class_name: "Money", mapping: %w(balance amount)
    #     composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
    #   end
    #
    # The customer class now has the following methods to manipulate the value objects:
    # * <tt>Customer#balance, Customer#balance=(money)</tt>
    # * <tt>Customer#address, Customer#address=(address)</tt>
    #
    # These methods will operate with value objects like the ones described below:
    #
    #  class Money
    #    include Comparable
    #    attr_reader :amount, :currency
    #    EXCHANGE_RATES = { "USD_TO_DKK" => 6 }
    #
    #    def initialize(amount, currency = "USD")
    #      @amount, @currency = amount, currency
    #    end
    #
    #    def exchange_to(other_currency)
    #      exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor
    #      Money.new(exchanged_amount, other_currency)
    #    end
    #
    #    def ==(other_money)
    #      amount == other_money.amount && currency == other_money.currency
    #    end
    #
    #    def <=>(other_money)
    #      if currency == other_money.currency
    #        amount <=> other_money.amount
    #      else
    #        amount <=> other_money.exchange_to(currency).amount
    #      end
    #    end
    #  end
    #
    #  class Address
    #    attr_reader :street, :city
    #    def initialize(street, city)
    #      @street, @city = street, city
    #    end
    #
    #    def close_to?(other_address)
    #      city == other_address.city
    #    end
    #
    #    def ==(other_address)
    #      city == other_address.city && street == other_address.street
    #    end
    #  end
    #
    # Now it's possible to access attributes from the database through the value objects instead. If
    # you choose to name the composition the same as the attribute's name, it will be the only way to
    # access that attribute. That's the case with our +balance+ attribute. You interact with the value
    # objects just like you would with any other attribute:
    #
    #   customer.balance = Money.new(20)     # sets the Money value object and the attribute
    #   customer.balance                     # => Money value object
    #   customer.balance.exchange_to("DKK")  # => Money.new(120, "DKK")
    #   customer.balance > Money.new(10)     # => true
    #   customer.balance == Money.new(20)    # => true
    #   customer.balance < Money.new(5)      # => false
    #
    # Value objects can also be composed of multiple attributes, such as the case of Address. The order
    # of the mappings will determine the order of the parameters.
    #
    #   customer.address_street = "Hyancintvej"
    #   customer.address_city   = "Copenhagen"
    #   customer.address        # => Address.new("Hyancintvej", "Copenhagen")
    #
    #   customer.address_street = "Vesterbrogade"
    #   customer.address        # => Address.new("Hyancintvej", "Copenhagen")
    #   customer.clear_aggregation_cache
    #   customer.address        # => Address.new("Vesterbrogade", "Copenhagen")
    #
    #   customer.address = Address.new("May Street", "Chicago")
    #   customer.address_street # => "May Street"
    #   customer.address_city   # => "Chicago"
    #
    # == Writing value objects
    #
    # Value objects are immutable and interchangeable objects that represent a given value, such as
    # a Money object representing $5. Two Money objects both representing $5 should be equal (through
    # methods such as <tt>==</tt> and <tt><=></tt> from Comparable if ranking makes sense). This is
    # unlike entity objects where equality is determined by identity. An entity class such as Customer can
    # easily have two different objects that both have an address on Hyancintvej. Entity identity is
    # determined by object or relational unique identifiers (such as primary keys). Normal
    # ActiveRecord::Base classes are entity objects.
    #
    # It's also important to treat the value objects as immutable. Don't allow the Money object to have
    # its amount changed after creation. Create a new Money object with the new value instead. The
    # Money#exchange_to method is an example of this. It returns a new value object instead of changing
    # its own values. Active Record won't persist value objects that have been changed through means
    # other than the writer method.
    #
    # The immutable requirement is enforced by Active Record by freezing any object assigned as a value
    # object. Attempting to change it afterwards will result in a RuntimeError.
    #
    # Read more about value objects on http://c2.com/cgi/wiki?ValueObject and on the dangers of not
    # keeping value objects immutable on http://c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
    #
    # == Custom constructors and converters
    #
    # By default value objects are initialized by calling the <tt>new</tt> constructor of the value
    # class passing each of the mapped attributes, in the order specified by the <tt>:mapping</tt>
    # option, as arguments. If the value class doesn't support this convention then +composed_of+ allows
    # a custom constructor to be specified.
    #
    # When a new value is assigned to the value object, the default assumption is that the new value
    # is an instance of the value class. Specifying a custom converter allows the new value to be automatically
    # converted to an instance of value class if necessary.
    #
    # For example, the NetworkResource model has +network_address+ and +cidr_range+ attributes that
    # should be aggregated using the NetAddr::CIDR value class (http://netaddr.rubyforge.org). The constructor
    # for the value class is called +create+ and it expects a CIDR address string as a parameter. New
    # values can be assigned to the value object using either another NetAddr::CIDR object, a string
    # or an array. The <tt>:constructor</tt> and <tt>:converter</tt> options can be used to meet
    # these requirements:
    #
    #   class NetworkResource < ActiveRecord::Base
    #     composed_of :cidr,
    #                 class_name: 'NetAddr::CIDR',
    #                 mapping: [ %w(network_address network), %w(cidr_range bits) ],
    #                 allow_nil: true,
    #                 constructor: Proc.new { |network_address, cidr_range| NetAddr::CIDR.create("#{network_address}/#{cidr_range}") },
    #                 converter: Proc.new { |value| NetAddr::CIDR.create(value.is_a?(Array) ? value.join('/') : value) }
    #   end
    #
    #   # This calls the :constructor
    #   network_resource = NetworkResource.new(network_address: '192.168.0.1', cidr_range: 24)
    #
    #   # These assignments will both use the :converter
    #   network_resource.cidr = [ '192.168.2.1', 8 ]
    #   network_resource.cidr = '192.168.0.1/24'
    #
    #   # This assignment won't use the :converter as the value is already an instance of the value class
    #   network_resource.cidr = NetAddr::CIDR.create('192.168.2.1/8')
    #
    #   # Saving and then reloading will use the :constructor on reload
    #   network_resource.save
    #   network_resource.reload
    #
    # == Finding records by a value object
    #
    # Once a +composed_of+ relationship is specified for a model, records can be loaded from the database
    # by specifying an instance of the value object in the conditions hash. The following example
    # finds all customers with +balance_amount+ equal to 20 and +balance_currency+ equal to "USD":
    #
    #   Customer.where(balance: Money.new(20, "USD"))
    #
    module ClassMethods
      # Adds reader and writer methods for manipulating a value object:
      # <tt>composed_of :address</tt> adds <tt>address</tt> and <tt>address=(new_address)</tt> methods.
      #
      # Options are:
      # * <tt>:class_name</tt> - Specifies the class name of the association. Use it only if that name
      #   can't be inferred from the part id. So <tt>composed_of :address</tt> will by default be linked
      #   to the Address class, but if the real class name is CompanyAddress, you'll have to specify it
      #   with this option.
      # * <tt>:mapping</tt> - Specifies the mapping of entity attributes to attributes of the value
      #   object. Each mapping is represented as an array where the first item is the name of the
      #   entity attribute and the second item is the name of the attribute in the value object. The
      #   order in which mappings are defined determines the order in which attributes are sent to the
      #   value class constructor.
      # * <tt>:allow_nil</tt> - Specifies that the value object will not be instantiated when all mapped
      #   attributes are +nil+. Setting the value object to +nil+ has the effect of writing +nil+ to all
      #   mapped attributes.
      #   This defaults to +false+.
      # * <tt>:constructor</tt> - A symbol specifying the name of the constructor method or a Proc that
      #   is called to initialize the value object. The constructor is passed all of the mapped attributes,
      #   in the order that they are defined in the <tt>:mapping option</tt>, as arguments and uses them
      #   to instantiate a <tt>:class_name</tt> object.
      #   The default is <tt>:new</tt>.
      # * <tt>:converter</tt> - A symbol specifying the name of a class method of <tt>:class_name</tt>
      #   or a Proc that is called when a new value is assigned to the value object. The converter is
      #   passed the single value that is used in the assignment and is only called if the new value is
      #   not an instance of <tt>:class_name</tt>. If <tt>:allow_nil</tt> is set to true, the converter
      #   can return nil to skip the assignment.
      #
      # Option examples:
      #   composed_of :temperature, mapping: %w(reading celsius)
      #   composed_of :balance, class_name: "Money", mapping: %w(balance amount),
      #                         converter: Proc.new { |balance| balance.to_money }
      #   composed_of :address, mapping: [ %w(address_street street), %w(address_city city) ]
      #   composed_of :gps_location
      #   composed_of :gps_location, allow_nil: true
      #   composed_of :ip_address,
      #               class_name: 'IPAddr',
      #               mapping: %w(ip to_i),
      #               constructor: Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
      #               converter: Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
      #
      def composed_of(part_id, options = {})
        options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)

        name        = part_id.id2name
        class_name  = options[:class_name]  || name.camelize
        mapping     = options[:mapping]     || [ name, name ]
        mapping     = [ mapping ] unless mapping.first.is_a?(Array)
        allow_nil   = options[:allow_nil]   || false
        constructor = options[:constructor] || :new
        converter   = options[:converter]

        reader_method(name, class_name, mapping, allow_nil, constructor)
        writer_method(name, class_name, mapping, allow_nil, converter)

        create_reflection(:composed_of, part_id, nil, options, self)
      end

      private
        def reader_method(name, class_name, mapping, allow_nil, constructor)
          define_method(name) do
            if @aggregation_cache[name].nil? && (!allow_nil || mapping.any? {|pair| !read_attribute(pair.first).nil? })
              attrs = mapping.collect {|pair| read_attribute(pair.first)}
              object = constructor.respond_to?(:call) ?
                constructor.call(*attrs) :
                class_name.constantize.send(constructor, *attrs)
              @aggregation_cache[name] = object
            end
            @aggregation_cache[name]
          end
        end

        def writer_method(name, class_name, mapping, allow_nil, converter)
          define_method("#{name}=") do |part|
            klass = class_name.constantize
            unless part.is_a?(klass) || converter.nil? || part.nil?
              part = converter.respond_to?(:call) ? converter.call(part) : klass.send(converter, part)
            end

            if part.nil? && allow_nil
              mapping.each { |pair| self[pair.first] = nil }
              @aggregation_cache[name] = nil
            else
              mapping.each { |pair| self[pair.first] = part.send(pair.last) }
              @aggregation_cache[name] = part.freeze
            end
          end
        end
    end
  end
end
require 'active_support/core_ext/string/conversions'

module ActiveRecord
  module Associations
    # Keeps track of table aliases for ActiveRecord::Associations::ClassMethods::JoinDependency and
    # ActiveRecord::Associations::ThroughAssociationScope
    class AliasTracker # :nodoc:
      attr_reader :aliases, :table_joins, :connection

      # table_joins is an array of arel joins which might conflict with the aliases we assign here
      def initialize(connection = Base.connection, table_joins = [])
        @aliases     = Hash.new { |h,k| h[k] = initial_count_for(k) }
        @table_joins = table_joins
        @connection  = connection
      end

      def aliased_table_for(table_name, aliased_name = nil)
        table_alias = aliased_name_for(table_name, aliased_name)

        if table_alias == table_name
          Arel::Table.new(table_name)
        else
          Arel::Table.new(table_name).alias(table_alias)
        end
      end

      def aliased_name_for(table_name, aliased_name = nil)
        aliased_name ||= table_name

        if aliases[table_name].zero?
          # If it's zero, we can have our table_name
          aliases[table_name] = 1
          table_name
        else
          # Otherwise, we need to use an alias
          aliased_name = connection.table_alias_for(aliased_name)

          # Update the count
          aliases[aliased_name] += 1

          if aliases[aliased_name] > 1
            "#{truncate(aliased_name)}_#{aliases[aliased_name]}"
          else
            aliased_name
          end
        end
      end

      private

        def initial_count_for(name)
          return 0 if Arel::Table === table_joins

          # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase
          quoted_name = connection.quote_table_name(name).downcase

          counts = table_joins.map do |join|
            if join.is_a?(Arel::Nodes::StringJoin)
              # Table names + table aliases
              join.left.downcase.scan(
                /join(?:\s+\w+)?\s+(\S+\s+)?#{quoted_name}\son/
              ).size
            else
              join.left.table_name == name ? 1 : 0
            end
          end

          counts.sum
        end

        def truncate(name)
          name.slice(0, connection.table_alias_length - 2)
        end
    end
  end
end
require 'active_support/core_ext/array/wrap'

module ActiveRecord
  module Associations
    # = Active Record Associations
    #
    # This is the root class of all associations ('+ Foo' signifies an included module Foo):
    #
    #   Association
    #     SingularAssociation
    #       HasOneAssociation
    #         HasOneThroughAssociation + ThroughAssociation
    #       BelongsToAssociation
    #         BelongsToPolymorphicAssociation
    #     CollectionAssociation
    #       HasAndBelongsToManyAssociation
    #       HasManyAssociation
    #         HasManyThroughAssociation + ThroughAssociation
    class Association #:nodoc:
      attr_reader :owner, :target, :reflection

      delegate :options, :to => :reflection

      def initialize(owner, reflection)
        reflection.check_validity!

        @owner, @reflection = owner, reflection

        reset
        reset_scope
      end

      # Returns the name of the table of the related class:
      #
      #   post.comments.aliased_table_name # => "comments"
      #
      def aliased_table_name
        klass.table_name
      end

      # Resets the \loaded flag to +false+ and sets the \target to +nil+.
      def reset
        @loaded = false
        @target = nil
        @stale_state = nil
      end

      # Reloads the \target and returns +self+ on success.
      def reload
        reset
        reset_scope
        load_target
        self unless target.nil?
      end

      # Has the \target been already \loaded?
      def loaded?
        @loaded
      end

      # Asserts the \target has been loaded setting the \loaded flag to +true+.
      def loaded!
        @loaded      = true
        @stale_state = stale_state
      end

      # The target is stale if the target no longer points to the record(s) that the
      # relevant foreign_key(s) refers to. If stale, the association accessor method
      # on the owner will reload the target. It's up to subclasses to implement the
      # state_state method if relevant.
      #
      # Note that if the target has not been loaded, it is not considered stale.
      def stale_target?
        loaded? && @stale_state != stale_state
      end

      # Sets the target of this association to <tt>\target</tt>, and the \loaded flag to +true+.
      def target=(target)
        @target = target
        loaded!
      end

      def scope
        target_scope.merge(association_scope)
      end

      def scoped
        ActiveSupport::Deprecation.warn "#scoped is deprecated. use #scope instead."
        scope
      end

      # The scope for this association.
      #
      # Note that the association_scope is merged into the target_scope only when the
      # scoped method is called. This is because at that point the call may be surrounded
      # by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
      # actually gets built.
      def association_scope
        if klass
          @association_scope ||= AssociationScope.new(self).scope
        end
      end

      def reset_scope
        @association_scope = nil
      end

      # Set the inverse association, if possible
      def set_inverse_instance(record)
        if record && invertible_for?(record)
          inverse = record.association(inverse_reflection_for(record).name)
          inverse.target = owner
        end
      end

      # This class of the target. belongs_to polymorphic overrides this to look at the
      # polymorphic_type field on the owner.
      def klass
        reflection.klass
      end

      # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
      # through association's scope)
      def target_scope
        klass.all
      end

      # Loads the \target if needed and returns it.
      #
      # This method is abstract in the sense that it relies on +find_target+,
      # which is expected to be provided by descendants.
      #
      # If the \target is already \loaded it is just returned. Thus, you can call
      # +load_target+ unconditionally to get the \target.
      #
      # ActiveRecord::RecordNotFound is rescued within the method, and it is
      # not reraised. The proxy is \reset and +nil+ is the return value.
      def load_target
        @target = find_target if (@stale_state && stale_target?) || find_target?

        loaded! unless loaded?
        target
      rescue ActiveRecord::RecordNotFound
        reset
      end

      def interpolate(sql, record = nil)
        if sql.respond_to?(:to_proc)
          owner.send(:instance_exec, record, &sql)
        else
          sql
        end
      end

      # We can't dump @reflection since it contains the scope proc
      def marshal_dump
        ivars = (instance_variables - [:@reflection]).map { |name| [name, instance_variable_get(name)] }
        [@reflection.name, ivars]
      end

      def marshal_load(data)
        reflection_name, ivars = data
        ivars.each { |name, val| instance_variable_set(name, val) }
        @reflection = @owner.class.reflect_on_association(reflection_name)
      end

      private

        def find_target?
          !loaded? && (!owner.new_record? || foreign_key_present?) && klass
        end

        def creation_attributes
          attributes = {}

          if (reflection.macro == :has_one || reflection.macro == :has_many) && !options[:through]
            attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]

            if reflection.options[:as]
              attributes[reflection.type] = owner.class.base_class.name
            end
          end

          attributes
        end

        # Sets the owner attributes on the given record
        def set_owner_attributes(record)
          creation_attributes.each { |key, value| record[key] = value }
        end

        # Should be true if there is a foreign key present on the owner which
        # references the target. This is used to determine whether we can load
        # the target if the owner is currently a new record (and therefore
        # without a key).
        #
        # Currently implemented by belongs_to (vanilla and polymorphic) and
        # has_one/has_many :through associations which go through a belongs_to
        def foreign_key_present?
          false
        end

        # Raises ActiveRecord::AssociationTypeMismatch unless +record+ is of
        # the kind of the class of the associated objects. Meant to be used as
        # a sanity check when you are about to assign an associated record.
        def raise_on_type_mismatch(record)
          unless record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize)
            message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
            raise ActiveRecord::AssociationTypeMismatch, message
          end
        end

        # Can be redefined by subclasses, notably polymorphic belongs_to
        # The record parameter is necessary to support polymorphic inverses as we must check for
        # the association in the specific class of the record.
        def inverse_reflection_for(record)
          reflection.inverse_of
        end

        # Is this association invertible? Can be redefined by subclasses.
        def invertible_for?(record)
          inverse_reflection_for(record)
        end

        # This should be implemented to return the values of the relevant key(s) on the owner,
        # so that when stale_state is different from the value stored on the last find_target,
        # the target is stale.
        #
        # This is only relevant to certain associations, which is why it returns nil by default.
        def stale_state
        end

        def build_record(attributes)
          reflection.build_association(attributes) do |record|
            skip_assign = [reflection.foreign_key, reflection.type].compact
            attributes = create_scope.except(*(record.changed - skip_assign))
            record.assign_attributes(attributes)
          end
        end
    end
  end
end
module ActiveRecord
  module Associations
    class AssociationScope #:nodoc:
      include JoinHelper

      attr_reader :association, :alias_tracker

      delegate :klass, :owner, :reflection, :interpolate, :to => :association
      delegate :chain, :scope_chain, :options, :source_options, :active_record, :to => :reflection

      def initialize(association)
        @association   = association
        @alias_tracker = AliasTracker.new klass.connection
      end

      def scope
        scope = klass.unscoped
        scope.extending! Array(options[:extend])
        add_constraints(scope)
      end

      private

      def column_for(table_name, column_name)
        columns = alias_tracker.connection.schema_cache.columns_hash[table_name]
        columns[column_name]
      end

      def bind_value(scope, column, value)
        substitute = alias_tracker.connection.substitute_at(
          column, scope.bind_values.length)
        scope.bind_values += [[column, value]]
        substitute
      end

      def bind(scope, table_name, column_name, value)
        column   = column_for table_name, column_name
        bind_value scope, column, value
      end

      def add_constraints(scope)
        tables = construct_tables

        chain.each_with_index do |reflection, i|
          table, foreign_table = tables.shift, tables.first

          if reflection.source_macro == :has_and_belongs_to_many
            join_table = tables.shift

            scope = scope.joins(join(
              join_table,
              table[reflection.association_primary_key].
                eq(join_table[reflection.association_foreign_key])
            ))

            table, foreign_table = join_table, tables.first
          end

          if reflection.source_macro == :belongs_to
            if reflection.options[:polymorphic]
              key = reflection.association_primary_key(self.klass)
            else
              key = reflection.association_primary_key
            end

            foreign_key = reflection.foreign_key
          else
            key         = reflection.foreign_key
            foreign_key = reflection.active_record_primary_key
          end

          if reflection == chain.last
            bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key]
            scope    = scope.where(table[key].eq(bind_val))

            if reflection.type
              value    = owner.class.base_class.name
              bind_val = bind scope, table.table_name, reflection.type.to_s, value
              scope    = scope.where(table[reflection.type].eq(bind_val))
            end
          else
            constraint = table[key].eq(foreign_table[foreign_key])

            if reflection.type
              type = chain[i + 1].klass.base_class.name
              constraint = constraint.and(table[reflection.type].eq(type))
            end

            scope = scope.joins(join(foreign_table, constraint))
          end

          # Exclude the scope of the association itself, because that
          # was already merged in the #scope method.
          scope_chain[i].each do |scope_chain_item|
            klass = i == 0 ? self.klass : reflection.klass
            item  = eval_scope(klass, scope_chain_item)

            if scope_chain_item == self.reflection.scope
              scope.merge! item.except(:where, :includes)
            end

            scope.includes! item.includes_values
            scope.where_values += item.where_values
          end
        end

        scope
      end

      def alias_suffix
        reflection.name
      end

      def table_name_for(reflection)
        if reflection == self.reflection
          # If this is a polymorphic belongs_to, we want to get the klass from the
          # association because it depends on the polymorphic_type attribute of
          # the owner
          klass.table_name
        else
          reflection.table_name
        end
      end

      def eval_scope(klass, scope)
        if scope.is_a?(Relation)
          scope
        else
          klass.unscoped.instance_exec(owner, &scope)
        end
      end
    end
  end
end
module ActiveRecord
  # = Active Record Belongs To Associations
  module Associations
    class BelongsToAssociation < SingularAssociation #:nodoc:

      def handle_dependency
        target.send(options[:dependent]) if load_target
      end

      def replace(record)
        raise_on_type_mismatch(record) if record

        update_counters(record)
        replace_keys(record)
        set_inverse_instance(record)

        @updated = true if record

        self.target = record
      end

      def reset
        super
        @updated = false
      end

      def updated?
        @updated
      end

      private

        def find_target?
          !loaded? && foreign_key_present? && klass
        end

        def update_counters(record)
          counter_cache_name = reflection.counter_cache_column

          if counter_cache_name && owner.persisted? && different_target?(record)
            if record
              record.class.increment_counter(counter_cache_name, record.id)
            end

            if foreign_key_present?
              klass.decrement_counter(counter_cache_name, target_id)
            end
          end
        end

        # Checks whether record is different to the current target, without loading it
        def different_target?(record)
          if record.nil? 
            owner[reflection.foreign_key] 
          else
            record.id != owner[reflection.foreign_key]
          end
        end

        def replace_keys(record)
          if record
            owner[reflection.foreign_key] = record[reflection.association_primary_key(record.class)]
          else
            owner[reflection.foreign_key] = nil
          end
        end

        def foreign_key_present?
          owner[reflection.foreign_key]
        end

        # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
        # has_one associations.
        def invertible_for?(record)
          inverse = inverse_reflection_for(record)
          inverse && inverse.macro == :has_one
        end

        def target_id
          if options[:primary_key]
            owner.send(reflection.name).try(:id)
          else
            owner[reflection.foreign_key]
          end
        end

        def stale_state
          owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s
        end
    end
  end
end
module ActiveRecord
  # = Active Record Belongs To Polymorphic Association
  module Associations
    class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
      def klass
        type = owner[reflection.foreign_type]
        type.presence && type.constantize
      end

      private

        def replace_keys(record)
          super
          owner[reflection.foreign_type] = record && record.class.base_class.name
        end

        def different_target?(record)
          super || record.class != klass
        end

        def inverse_reflection_for(record)
          reflection.polymorphic_inverse_of(record.class)
        end

        def raise_on_type_mismatch(record)
          # A polymorphic association cannot have a type mismatch, by definition
        end

        def stale_state
          foreign_key = super
          foreign_key && [foreign_key.to_s, owner[reflection.foreign_type].to_s]
        end
    end
  end
end
module ActiveRecord::Associations::Builder
  class Association #:nodoc:
    class << self
      attr_accessor :valid_options
    end

    self.valid_options = [:class_name, :foreign_key, :validate]

    attr_reader :model, :name, :scope, :options, :reflection

    def self.build(*args, &block)
      new(*args, &block).build
    end

    def initialize(model, name, scope, options)
      raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)

      @model   = model
      @name    = name

      if scope.is_a?(Hash)
        @scope   = nil
        @options = scope
      else
        @scope   = scope
        @options = options
      end

      if @scope && @scope.arity == 0
        prev_scope = @scope
        @scope = proc { instance_exec(&prev_scope) }
      end
    end

    def mixin
      @model.generated_feature_methods
    end

    include Module.new { def build; end }

    def build
      validate_options
      define_accessors
      configure_dependency if options[:dependent]
      @reflection = model.create_reflection(macro, name, scope, options, model)
      super # provides an extension point
      @reflection
    end

    def macro
      raise NotImplementedError
    end

    def valid_options
      Association.valid_options
    end

    def validate_options
      options.assert_valid_keys(valid_options)
    end

    def define_accessors
      define_readers
      define_writers
    end

    def define_readers
      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name}(*args)
          association(:#{name}).reader(*args)
        end
      CODE
    end

    def define_writers
      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name}=(value)
          association(:#{name}).writer(value)
        end
      CODE
    end

    def configure_dependency
      unless valid_dependent_options.include? options[:dependent]
        raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
      end

      if options[:dependent] == :restrict
        ActiveSupport::Deprecation.warn(
          "The :restrict option is deprecated. Please use :restrict_with_exception instead, which " \
          "provides the same functionality."
        )
      end

      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{macro}_dependent_for_#{name}
          association(:#{name}).handle_dependency
        end
      CODE

      model.before_destroy "#{macro}_dependent_for_#{name}"
    end

    def valid_dependent_options
      raise NotImplementedError
    end
  end
end
module ActiveRecord::Associations::Builder
  class BelongsTo < SingularAssociation #:nodoc:
    def macro
      :belongs_to
    end

    def valid_options
      super + [:foreign_type, :polymorphic, :touch]
    end

    def constructable?
      !options[:polymorphic]
    end

    def build
      reflection = super
      add_counter_cache_callbacks(reflection) if options[:counter_cache]
      add_touch_callbacks(reflection)         if options[:touch]
      reflection
    end

    def add_counter_cache_callbacks(reflection)
      cache_column = reflection.counter_cache_column

      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def belongs_to_counter_cache_after_create_for_#{name}
          record = #{name}
          record.class.increment_counter(:#{cache_column}, record.id) unless record.nil?
        end

        def belongs_to_counter_cache_before_destroy_for_#{name}
          unless marked_for_destruction?
            record = #{name}
            record.class.decrement_counter(:#{cache_column}, record.id) unless record.nil?
          end
        end
      CODE

      model.after_create   "belongs_to_counter_cache_after_create_for_#{name}"
      model.before_destroy "belongs_to_counter_cache_before_destroy_for_#{name}"

      klass = reflection.class_name.safe_constantize
      klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
    end

    def add_touch_callbacks(reflection)
      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def belongs_to_touch_after_save_or_destroy_for_#{name}
          record = #{name}

          unless record.nil?
            record.touch #{options[:touch].inspect if options[:touch] != true}
          end
        end
      CODE

      model.after_save    "belongs_to_touch_after_save_or_destroy_for_#{name}"
      model.after_touch   "belongs_to_touch_after_save_or_destroy_for_#{name}"
      model.after_destroy "belongs_to_touch_after_save_or_destroy_for_#{name}"
    end

    def valid_dependent_options
      [:destroy, :delete]
    end
  end
end
require 'active_record/associations'

module ActiveRecord::Associations::Builder
  class CollectionAssociation < Association #:nodoc:

    CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]

    def valid_options
      super + [:table_name, :finder_sql, :counter_sql, :before_add,
               :after_add, :before_remove, :after_remove, :extend]
    end

    attr_reader :block_extension, :extension_module

    def initialize(*args, &extension)
      super(*args)
      @block_extension = extension
    end

    def build
      show_deprecation_warnings
      wrap_block_extension
      reflection = super
      CALLBACKS.each { |callback_name| define_callback(callback_name) }
      reflection
    end

    def writable?
      true
    end

    def show_deprecation_warnings
      [:finder_sql, :counter_sql].each do |name|
        if options.include? name
          ActiveSupport::Deprecation.warn("The :#{name} association option is deprecated. Please find an alternative (such as using scopes).")
        end
      end
    end

    def wrap_block_extension
      if block_extension
        @extension_module = mod = Module.new(&block_extension)
        silence_warnings do
          model.parent.const_set(extension_module_name, mod)
        end

        prev_scope = @scope

        if prev_scope
          @scope = proc { |owner| instance_exec(owner, &prev_scope).extending(mod) }
        else
          @scope = proc { extending(mod) }
        end
      end
    end

    def extension_module_name
      @extension_module_name ||= "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
    end

    def define_callback(callback_name)
      full_callback_name = "#{callback_name}_for_#{name}"

      # TODO : why do i need method_defined? I think its because of the inheritance chain
      model.class_attribute full_callback_name.to_sym unless model.method_defined?(full_callback_name)
      model.send("#{full_callback_name}=", Array(options[callback_name.to_sym]))
    end

    def define_readers
      super

      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name.to_s.singularize}_ids
          association(:#{name}).ids_reader
        end
      CODE
    end

    def define_writers
      super

      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name.to_s.singularize}_ids=(ids)
          association(:#{name}).ids_writer(ids)
        end
      CODE
    end
  end
end
module ActiveRecord::Associations::Builder
  class HasAndBelongsToMany < CollectionAssociation #:nodoc:
    def macro
      :has_and_belongs_to_many
    end

    def valid_options
      super + [:join_table, :association_foreign_key, :delete_sql, :insert_sql]
    end

    def build
      reflection = super
      define_destroy_hook
      reflection
    end

    def show_deprecation_warnings
      super

      [:delete_sql, :insert_sql].each do |name|
        if options.include? name
          ActiveSupport::Deprecation.warn("The :#{name} association option is deprecated. Please find an alternative (such as using has_many :through).")
        end
      end
    end

    def define_destroy_hook
      name = self.name
      model.send(:include, Module.new {
        class_eval <<-RUBY, __FILE__, __LINE__ + 1
          def destroy_associations
            association(:#{name}).delete_all
            super
          end
        RUBY
      })
    end
  end
end
module ActiveRecord::Associations::Builder
  class HasMany < CollectionAssociation #:nodoc:
    def macro
      :has_many
    end

    def valid_options
      super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache]
    end

    def valid_dependent_options
      [:destroy, :delete_all, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
    end
  end
end
module ActiveRecord::Associations::Builder
  class HasOne < SingularAssociation #:nodoc:
    def macro
      :has_one
    end

    def valid_options
      valid = super + [:order, :as]
      valid += [:through, :source, :source_type] if options[:through]
      valid
    end

    def constructable?
      !options[:through]
    end

    def configure_dependency
      super unless options[:through]
    end

    def valid_dependent_options
      [:destroy, :delete, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
    end
  end
end
module ActiveRecord::Associations::Builder
  class SingularAssociation < Association #:nodoc:
    def valid_options
      super + [:remote, :dependent, :counter_cache, :primary_key, :inverse_of]
    end

    def constructable?
      true
    end

    def define_accessors
      super
      define_constructors if constructable?
    end

    def define_constructors
      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def build_#{name}(*args, &block)
          association(:#{name}).build(*args, &block)
        end

        def create_#{name}(*args, &block)
          association(:#{name}).create(*args, &block)
        end

        def create_#{name}!(*args, &block)
          association(:#{name}).create!(*args, &block)
        end
      CODE
    end
  end
end
module ActiveRecord
  module Associations
    # = Active Record Association Collection
    #
    # CollectionAssociation is an abstract class that provides common stuff to
    # ease the implementation of association proxies that represent
    # collections. See the class hierarchy in AssociationProxy.
    #
    #   CollectionAssociation:
    #     HasAndBelongsToManyAssociation => has_and_belongs_to_many
    #     HasManyAssociation => has_many
    #       HasManyThroughAssociation + ThroughAssociation => has_many :through
    #
    # CollectionAssociation class provides common methods to the collections
    # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
    # +:through association+ option.
    #
    # You need to be careful with assumptions regarding the target: The proxy
    # does not fetch records from the database until it needs them, but new
    # ones created with +build+ are added to the target. So, the target may be
    # non-empty and still lack children waiting to be read from the database.
    # If you look directly to the database you cannot assume that's the entire
    # collection because new records may have been added to the target, etc.
    #
    # If you need to work on all current children, new and existing records,
    # +load_target+ and the +loaded+ flag are your friends.
    class CollectionAssociation < Association #:nodoc:

      # Implements the reader method, e.g. foo.items for Foo.has_many :items
      def reader(force_reload = false)
        if force_reload
          klass.uncached { reload }
        elsif stale_target?
          reload
        end

        CollectionProxy.new(klass, self)
      end

      # Implements the writer method, e.g. foo.items= for Foo.has_many :items
      def writer(records)
        replace(records)
      end

      # Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
      def ids_reader
        if loaded? || options[:finder_sql]
          load_target.map do |record|
            record.send(reflection.association_primary_key)
          end
        else
          column  = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
          scope.pluck(column)
        end
      end

      # Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
      def ids_writer(ids)
        pk_column = reflection.primary_key_column
        ids = Array(ids).reject { |id| id.blank? }
        ids.map! { |i| pk_column.type_cast(i) }
        replace(klass.find(ids).index_by { |r| r.id }.values_at(*ids))
      end

      def reset
        super
        @target = []
      end

      def select(select = nil)
        if block_given?
          load_target.select.each { |e| yield e }
        else
          scope.select(select)
        end
      end

      def find(*args)
        if block_given?
          load_target.find(*args) { |*block_args| yield(*block_args) }
        else
          if options[:finder_sql]
            find_by_scan(*args)
          else
            scope.find(*args)
          end
        end
      end

      def first(*args)
        first_or_last(:first, *args)
      end

      def last(*args)
        first_or_last(:last, *args)
      end

      def build(attributes = {}, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| build(attr, &block) }
        else
          add_to_target(build_record(attributes)) do |record|
            yield(record) if block_given?
          end
        end
      end

      def create(attributes = {}, &block)
        create_record(attributes, &block)
      end

      def create!(attributes = {}, &block)
        create_record(attributes, true, &block)
      end

      # Add +records+ to this association. Returns +self+ so method calls may
      # be chained. Since << flattens its argument list and inserts each record,
      # +push+ and +concat+ behave identically.
      def concat(*records)
        load_target if owner.new_record?

        if owner.new_record?
          concat_records(records)
        else
          transaction { concat_records(records) }
        end
      end

      # Starts a transaction in the association class's database connection.
      #
      #   class Author < ActiveRecord::Base
      #     has_many :books
      #   end
      #
      #   Author.first.books.transaction do
      #     # same effect as calling Book.transaction
      #   end
      def transaction(*args)
        reflection.klass.transaction(*args) do
          yield
        end
      end

      # Remove all records from this association.
      #
      # See delete for more info.
      def delete_all
        delete(:all).tap do
          reset
          loaded!
        end
      end

      # Destroy all the records from this association.
      #
      # See destroy for more info.
      def destroy_all
        destroy(load_target).tap do
          reset
          loaded!
        end
      end

      # Count all records using SQL. If the +:counter_sql+ or +:finder_sql+ option is set for the
      # association, it will be used for the query. Otherwise, construct options and pass them with
      # scope to the target class's +count+.
      def count(column_name = nil, count_options = {})
        column_name, count_options = nil, column_name if column_name.is_a?(Hash)

        if options[:counter_sql] || options[:finder_sql]
          unless count_options.blank?
            raise ArgumentError, "If finder_sql/counter_sql is used then options cannot be passed"
          end

          reflection.klass.count_by_sql(custom_counter_sql)
        else
          if association_scope.uniq_value
            # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL.
            column_name ||= reflection.klass.primary_key
            count_options[:distinct] = true
          end

          value = scope.count(column_name, count_options)

          limit  = options[:limit]
          offset = options[:offset]

          if limit || offset
            [ [value - offset.to_i, 0].max, limit.to_i ].min
          else
            value
          end
        end
      end

      # Removes +records+ from this association calling +before_remove+ and
      # +after_remove+ callbacks.
      #
      # This method is abstract in the sense that +delete_records+ has to be
      # provided by descendants. Note this method does not imply the records
      # are actually removed from the database, that depends precisely on
      # +delete_records+. They are in any case removed from the collection.
      def delete(*records)
        dependent = options[:dependent]

        if records.first == :all
          if loaded? || dependent == :destroy
            delete_or_destroy(load_target, dependent)
          else
            delete_records(:all, dependent)
          end
        else
          records = find(records) if records.any? { |record| record.kind_of?(Fixnum) || record.kind_of?(String) }
          delete_or_destroy(records, dependent)
        end
      end

      # Destroy +records+ and remove them from this association calling
      # +before_remove+ and +after_remove+ callbacks.
      #
      # Note that this method will _always_ remove records from the database
      # ignoring the +:dependent+ option.
      def destroy(*records)
        records = find(records) if records.any? { |record| record.kind_of?(Fixnum) || record.kind_of?(String) }
        delete_or_destroy(records, :destroy)
      end

      # Returns the size of the collection by executing a SELECT COUNT(*)
      # query if the collection hasn't been loaded, and calling
      # <tt>collection.size</tt> if it has.
      #
      # If the collection has been already loaded +size+ and +length+ are
      # equivalent. If not and you are going to need the records anyway
      # +length+ will take one less query. Otherwise +size+ is more efficient.
      #
      # This method is abstract in the sense that it relies on
      # +count_records+, which is a method descendants have to provide.
      def size
        if !find_target? || loaded?
          if association_scope.uniq_value
            target.uniq.size
          else
            target.size
          end
        elsif !loaded? && !association_scope.group_values.empty?
          load_target.size
        elsif !loaded? && !association_scope.uniq_value && target.is_a?(Array)
          unsaved_records = target.select { |r| r.new_record? }
          unsaved_records.size + count_records
        else
          count_records
        end
      end

      # Returns the size of the collection calling +size+ on the target.
      #
      # If the collection has been already loaded +length+ and +size+ are
      # equivalent. If not and you are going to need the records anyway this
      # method will take one less query. Otherwise +size+ is more efficient.
      def length
        load_target.size
      end

      # Returns true if the collection is empty.
      #
      # If the collection has been loaded or the <tt>:counter_sql</tt> option
      # is provided, it is equivalent to <tt>collection.size.zero?</tt>. If the
      # collection has not been loaded, it is equivalent to
      # <tt>collection.exists?</tt>. If the collection has not already been
      # loaded and you are going to fetch the records anyway it is better to
      # check <tt>collection.length.zero?</tt>.
      def empty?
        if loaded? || options[:counter_sql]
          size.zero?
        else
          @target.blank? && !scope.exists?
        end
      end

      # Returns true if the collections is not empty.
      # Equivalent to +!collection.empty?+.
      def any?
        if block_given?
          load_target.any? { |*block_args| yield(*block_args) }
        else
          !empty?
        end
      end

      # Returns true if the collection has more than 1 record.
      # Equivalent to +collection.size > 1+.
      def many?
        if block_given?
          load_target.many? { |*block_args| yield(*block_args) }
        else
          size > 1
        end
      end

      def uniq
        seen = {}
        load_target.find_all do |record|
          seen[record.id] = true unless seen.key?(record.id)
        end
      end

      # Replace this collection with +other_array+. This will perform a diff
      # and delete/add only records that have changed.
      def replace(other_array)
        other_array.each { |val| raise_on_type_mismatch(val) }
        original_target = load_target.dup

        if owner.new_record?
          replace_records(other_array, original_target)
        else
          transaction { replace_records(other_array, original_target) }
        end
      end

      def include?(record)
        if record.is_a?(reflection.klass)
          if record.new_record?
            include_in_memory?(record)
          else
            load_target if options[:finder_sql]
            loaded? ? target.include?(record) : scope.exists?(record)
          end
        else
          false
        end
      end

      def load_target
        if find_target?
          @target = merge_target_lists(find_target, target)
        end

        loaded!
        target
      end

      def add_to_target(record)
        callback(:before_add, record)
        yield(record) if block_given?

        if association_scope.uniq_value && index = @target.index(record)
          @target[index] = record
        else
          @target << record
        end

        callback(:after_add, record)
        set_inverse_instance(record)

        record
      end

      def scope(opts = {})
        scope = super()
        scope.none! if opts.fetch(:nullify, true) && null_scope?
        scope
      end

      def null_scope?
        owner.new_record? && !foreign_key_present?
      end

      private

        def custom_counter_sql
          if options[:counter_sql]
            interpolate(options[:counter_sql])
          else
            # replace the SELECT clause with COUNT(SELECTS), preserving any hints within /* ... */
            interpolate(options[:finder_sql]).sub(/SELECT\b(\/\*.*?\*\/ )?(.*)\bFROM\b/im) do
              count_with = $2.to_s
              count_with = '*' if count_with.blank? || count_with =~ /,/ || count_with =~ /\.\*/
              "SELECT #{$1}COUNT(#{count_with}) FROM"
            end
          end
        end

        def custom_finder_sql
          interpolate(options[:finder_sql])
        end

        def find_target
          records =
            if options[:finder_sql]
              reflection.klass.find_by_sql(custom_finder_sql)
            else
              scope.to_a
            end

          records.each { |record| set_inverse_instance(record) }
          records
        end

        # We have some records loaded from the database (persisted) and some that are
        # in-memory (memory). The same record may be represented in the persisted array
        # and in the memory array.
        #
        # So the task of this method is to merge them according to the following rules:
        #
        #   * The final array must not have duplicates
        #   * The order of the persisted array is to be preserved
        #   * Any changes made to attributes on objects in the memory array are to be preserved
        #   * Otherwise, attributes should have the value found in the database
        def merge_target_lists(persisted, memory)
          return persisted if memory.empty?
          return memory    if persisted.empty?

          persisted.map! do |record|
            if mem_record = memory.delete(record)

              ((record.attribute_names & mem_record.attribute_names) - mem_record.changes.keys).each do |name|
                mem_record[name] = record[name]
              end

              mem_record
            else
              record
            end
          end

          persisted + memory
        end

        def create_record(attributes, raise = false, &block)
          unless owner.persisted?
            raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
          end

          if attributes.is_a?(Array)
            attributes.collect { |attr| create_record(attr, raise, &block) }
          else
            transaction do
              add_to_target(build_record(attributes)) do |record|
                yield(record) if block_given?
                insert_record(record, true, raise)
              end
            end
          end
        end

        # Do the relevant stuff to insert the given record into the association collection.
        def insert_record(record, validate = true, raise = false)
          raise NotImplementedError
        end

        def create_scope
          scope.scope_for_create.stringify_keys
        end

        def delete_or_destroy(records, method)
          records = records.flatten
          records.each { |record| raise_on_type_mismatch(record) }
          existing_records = records.reject { |r| r.new_record? }

          if existing_records.empty?
            remove_records(existing_records, records, method)
          else
            transaction { remove_records(existing_records, records, method) }
          end
        end

        def remove_records(existing_records, records, method)
          records.each { |record| callback(:before_remove, record) }

          delete_records(existing_records, method) if existing_records.any?
          records.each { |record| target.delete(record) }

          records.each { |record| callback(:after_remove, record) }
        end

        # Delete the given records from the association, using one of the methods :destroy,
        # :delete_all or :nullify (or nil, in which case a default is used).
        def delete_records(records, method)
          raise NotImplementedError
        end

        def replace_records(new_target, original_target)
          delete(target - new_target)

          unless concat(new_target - target)
            @target = original_target
            raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
                                  "new records could not be saved."
          end

          target
        end

        def concat_records(records)
          result = true

          records.flatten.each do |record|
            raise_on_type_mismatch(record)
            add_to_target(record) do |r|
              result &&= insert_record(record) unless owner.new_record?
            end
          end

          result && records
        end

        def callback(method, record)
          callbacks_for(method).each do |callback|
            case callback
            when Symbol
              owner.send(callback, record)
            when Proc
              callback.call(owner, record)
            else
              callback.send(method, owner, record)
            end
          end
        end

        def callbacks_for(callback_name)
          full_callback_name = "#{callback_name}_for_#{reflection.name}"
          owner.class.send(full_callback_name.to_sym) || []
        end

        # Should we deal with assoc.first or assoc.last by issuing an independent query to
        # the database, or by getting the target, and then taking the first/last item from that?
        #
        # If the args is just a non-empty options hash, go to the database.
        #
        # Otherwise, go to the database only if none of the following are true:
        #   * target already loaded
        #   * owner is new record
        #   * custom :finder_sql exists
        #   * target contains new or changed record(s)
        #   * the first arg is an integer (which indicates the number of records to be returned)
        def fetch_first_or_last_using_find?(args)
          if args.first.is_a?(Hash)
            true
          else
            !(loaded? ||
              owner.new_record? ||
              options[:finder_sql] ||
              target.any? { |record| record.new_record? || record.changed? } ||
              args.first.kind_of?(Integer))
          end
        end

        def include_in_memory?(record)
          if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
            owner.send(reflection.through_reflection.name).any? { |source|
              target = source.send(reflection.source_reflection.name)
              target.respond_to?(:include?) ? target.include?(record) : target == record
            } || target.include?(record)
          else
            target.include?(record)
          end
        end

        # If using a custom finder_sql, #find scans the entire collection.
        def find_by_scan(*args)
          expects_array = args.first.kind_of?(Array)
          ids           = args.flatten.compact.map{ |arg| arg.to_i }.uniq

          if ids.size == 1
            id = ids.first
            record = load_target.detect { |r| id == r.id }
            expects_array ? [ record ] : record
          else
            load_target.select { |r| ids.include?(r.id) }
          end
        end

        # Fetches the first/last using SQL if possible, otherwise from the target array.
        def first_or_last(type, *args)
          args.shift if args.first.is_a?(Hash) && args.first.empty?

          collection = fetch_first_or_last_using_find?(args) ? scope : load_target
          collection.send(type, *args).tap do |record|
            set_inverse_instance record if record.is_a? ActiveRecord::Base
          end
        end
    end
  end
end
module ActiveRecord
  module Associations
    # Association proxies in Active Record are middlemen between the object that
    # holds the association, known as the <tt>@owner</tt>, and the actual associated
    # object, known as the <tt>@target</tt>. The kind of association any proxy is
    # about is available in <tt>@reflection</tt>. That's an instance of the class
    # ActiveRecord::Reflection::AssociationReflection.
    #
    # For example, given
    #
    #   class Blog < ActiveRecord::Base
    #     has_many :posts
    #   end
    #
    #   blog = Blog.first
    #
    # the association proxy in <tt>blog.posts</tt> has the object in +blog+ as
    # <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
    # the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
    #
    # This class delegates unknown methods to <tt>@target</tt> via
    # <tt>method_missing</tt>.
    #
    # The <tt>@target</tt> object is not \loaded until needed. For example,
    #
    #   blog.posts.count
    #
    # is computed directly through SQL and does not trigger by itself the
    # instantiation of the actual post records.
    class CollectionProxy < Relation
      delegate(*(ActiveRecord::Calculations.public_instance_methods - [:count]), to: :scope)

      def initialize(klass, association) #:nodoc:
        @association = association
        super klass, klass.arel_table
        self.default_scoped = true
        merge! association.scope(nullify: false)
      end

      def target
        @association.target
      end

      def load_target
        @association.load_target
      end

      # Returns +true+ if the association has been loaded, otherwise +false+.
      #
      #   person.pets.loaded? # => false
      #   person.pets
      #   person.pets.loaded? # => true
      def loaded?
        @association.loaded?
      end

      # Works in two ways.
      #
      # *First:* Specify a subset of fields to be selected from the result set.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.select(:name)
      #   # => [
      #   #      #<Pet id: nil, name: "Fancy-Fancy">,
      #   #      #<Pet id: nil, name: "Spook">,
      #   #      #<Pet id: nil, name: "Choo-Choo">
      #   #    ]
      #
      #   person.pets.select([:id, :name])
      #   # => [
      #   #      #<Pet id: 1, name: "Fancy-Fancy">,
      #   #      #<Pet id: 2, name: "Spook">,
      #   #      #<Pet id: 3, name: "Choo-Choo">
      #   #    ]
      #
      # Be careful because this also means you’re initializing a model
      # object with only the fields that you’ve selected. If you attempt
      # to access a field that is not in the initialized record you’ll
      # receive:
      #
      #   person.pets.select(:name).first.person_id
      #   # => ActiveModel::MissingAttributeError: missing attribute: person_id
      #
      # *Second:* You can pass a block so it can be used just like Array#select.
      # This build an array of objects from the database for the scope,
      # converting them into an array and iterating through them using
      # Array#select.
      #
      #   person.pets.select { |pet| pet.name =~ /oo/ }
      #   # => [
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.select(:name) { |pet| pet.name =~ /oo/ }
      #   # => [
      #   #      #<Pet id: 2, name: "Spook">,
      #   #      #<Pet id: 3, name: "Choo-Choo">
      #   #    ]
      def select(select = nil, &block)
        @association.select(select, &block)
      end

      # Finds an object in the collection responding to the +id+. Uses the same
      # rules as <tt>ActiveRecord::Base.find</tt>. Returns <tt>ActiveRecord::RecordNotFound</tt>
      # error if the object can not be found.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
      #   person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=4
      #
      #   person.pets.find(2) { |pet| pet.name.downcase! }
      #   # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
      #
      #   person.pets.find(2, 3)
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def find(*args, &block)
        @association.find(*args, &block)
      end

      # Returns the first record, or the first +n+ records, from the collection.
      # If the collection is empty, the first form returns +nil+, and the second
      # form returns an empty array.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
      #
      #   person.pets.first(2)
      #   # => [
      #   #      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>
      #   #    ]
      #
      #   another_person_without.pets          # => []
      #   another_person_without.pets.first    # => nil
      #   another_person_without.pets.first(3) # => []
      def first(*args)
        @association.first(*args)
      end

      # Returns the last record, or the last +n+ records, from the collection.
      # If the collection is empty, the first form returns +nil+, and the second
      # form returns an empty array.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #
      #   person.pets.last(2)
      #   # => [
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   another_person_without.pets         # => []
      #   another_person_without.pets.last    # => nil
      #   another_person_without.pets.last(3) # => []
      def last(*args)
        @association.last(*args)
      end

      # Returns a new object of the collection type that has been instantiated
      # with +attributes+ and linked to this object, but have not yet been saved.
      # You can pass an array of attributes hashes, this will return an array
      # with the new objects.
      #
      #   class Person
      #     has_many :pets
      #   end
      #
      #   person.pets.build
      #   # => #<Pet id: nil, name: nil, person_id: 1>
      #
      #   person.pets.build(name: 'Fancy-Fancy')
      #   # => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
      #
      #   person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
      #   # => [
      #   #      #<Pet id: nil, name: "Spook", person_id: 1>,
      #   #      #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
      #   #      #<Pet id: nil, name: "Brain", person_id: 1>
      #   #    ]
      #
      #   person.pets.size  # => 5 # size of the collection
      #   person.pets.count # => 0 # count from database
      def build(attributes = {}, &block)
        @association.build(attributes, &block)
      end

      # Returns a new object of the collection type that has been instantiated with
      # attributes, linked to this object and that has already been saved (if it
      # passes the validations).
      #
      #   class Person
      #     has_many :pets
      #   end
      #
      #   person.pets.create(name: 'Fancy-Fancy')
      #   # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
      #
      #   person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
      #   # => [
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.size  # => 3
      #   person.pets.count # => 3
      #
      #   person.pets.find(1, 2, 3)
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def create(attributes = {}, &block)
        @association.create(attributes, &block)
      end

      # Like +create+, except that if the record is invalid, raises an exception.
      #
      #   class Person
      #     has_many :pets
      #   end
      #
      #   class Pet
      #     validates :name, presence: true
      #   end
      #
      #   person.pets.create!(name: nil)
      #   # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
      def create!(attributes = {}, &block)
        @association.create!(attributes, &block)
      end

      # Add one or more records to the collection by setting their foreign keys
      # to the association's primary key. Since << flattens its argument list and
      # inserts each record, +push+ and +concat+ behave identically. Returns +self+
      # so method calls may be chained.
      #
      #   class Person < ActiveRecord::Base
      #     pets :has_many
      #   end
      #
      #   person.pets.size # => 0
      #   person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
      #   person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
      #   person.pets.size # => 3
      #
      #   person.id # => 1
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
      #   person.pets.size # => 5
      def concat(*records)
        @association.concat(*records)
      end

      # Replace this collection with +other_array+. This will perform a diff
      # and delete/add only records that have changed.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
      #
      #   other_pets = [Pet.new(name: 'Puff', group: 'celebrities']
      #
      #   person.pets.replace(other_pets)
      #
      #   person.pets
      #   # => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
      #
      # If the supplied array has an incorrect association type, it raises
      # an <tt>ActiveRecord::AssociationTypeMismatch</tt> error:
      #
      #   person.pets.replace(["doo", "ggie", "gaga"])
      #   # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
      def replace(other_array)
        @association.replace(other_array)
      end

      # Deletes all the records from the collection. For +has_many+ associations,
      # the deletion is done according to the strategy specified by the <tt>:dependent</tt>
      # option. Returns an array with the deleted records.
      #
      # If no <tt>:dependent</tt> option is given, then it will follow the
      # default strategy. The default strategy is <tt>:nullify</tt>. This
      # sets the foreign keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>,
      # the default strategy is +delete_all+.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets # dependent: :nullify option by default
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete_all
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.size # => 0
      #   person.pets      # => []
      #
      #   Pet.find(1, 2, 3)
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
      #   #       #<Pet id: 2, name: "Spook", person_id: nil>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: nil>
      #   #    ]
      #
      # If it is set to <tt>:destroy</tt> all the objects from the collection
      # are removed by calling their +destroy+ method. See +destroy+ for more
      # information.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets, dependent: :destroy
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete_all
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   Pet.find(1, 2, 3)
      #   # => ActiveRecord::RecordNotFound
      #
      # If it is set to <tt>:delete_all</tt>, all the objects are deleted
      # *without* calling their +destroy+ method.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets, dependent: :delete_all
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete_all
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   Pet.find(1, 2, 3)
      #   # => ActiveRecord::RecordNotFound
      def delete_all
        @association.delete_all
      end

      # Deletes the records of the collection directly from the database.
      # This will _always_ remove the records ignoring the +:dependent+
      # option.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.destroy_all
      #
      #   person.pets.size # => 0
      #   person.pets      # => []
      #
      #   Pet.find(1) # => Couldn't find Pet with id=1
      def destroy_all
        @association.destroy_all
      end

      # Deletes the +records+ supplied and removes them from the collection. For
      # +has_many+ associations, the deletion is done according to the strategy
      # specified by the <tt>:dependent</tt> option. Returns an array with the
      # deleted records.
      #
      # If no <tt>:dependent</tt> option is given, then it will follow the default
      # strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign
      # keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
      # strategy is +delete_all+.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets # dependent: :nullify option by default
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete(Pet.find(1))
      #   # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
      #
      #   person.pets.size # => 2
      #   person.pets
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   Pet.find(1)
      #   # => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
      #
      # If it is set to <tt>:destroy</tt> all the +records+ are removed by calling
      # their +destroy+ method. See +destroy+ for more information.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets, dependent: :destroy
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete(Pet.find(1), Pet.find(3))
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.size # => 1
      #   person.pets
      #   # => [#<Pet id: 2, name: "Spook", person_id: 1>]
      #
      #   Pet.find(1, 3)
      #   # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 3)
      #
      # If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
      # *without* calling their +destroy+ method.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets, dependent: :delete_all
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete(Pet.find(1))
      #   # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
      #
      #   person.pets.size # => 2
      #   person.pets
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   Pet.find(1)
      #   # => ActiveRecord::RecordNotFound: Couldn't find Pet with id=1
      #
      # You can pass +Fixnum+ or +String+ values, it finds the records
      # responding to the +id+ and executes delete on them.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.delete("1")
      #   # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
      #
      #   person.pets.delete(2, 3)
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def delete(*records)
        @association.delete(*records)
      end

      # Destroys the +records+ supplied and removes them from the collection.
      # This method will _always_ remove record from the database ignoring
      # the +:dependent+ option. Returns an array with the removed records.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.destroy(Pet.find(1))
      #   # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
      #
      #   person.pets.size # => 2
      #   person.pets
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.destroy(Pet.find(2), Pet.find(3))
      #   # => [
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.size  # => 0
      #   person.pets       # => []
      #
      #   Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (1, 2, 3)
      #
      # You can pass +Fixnum+ or +String+ values, it finds the records
      # responding to the +id+ and then deletes them from the database.
      #
      #   person.pets.size # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 4, name: "Benny", person_id: 1>,
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      #
      #   person.pets.destroy("4")
      #   # => #<Pet id: 4, name: "Benny", person_id: 1>
      #
      #   person.pets.size # => 2
      #   person.pets
      #   # => [
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      #
      #   person.pets.destroy(5, 6)
      #   # => [
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      #
      #   person.pets.size  # => 0
      #   person.pets       # => []
      #
      #   Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with IDs (4, 5, 6)
      def destroy(*records)
        @association.destroy(*records)
      end

      # Specifies whether the records should be unique or not.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.select(:name)
      #   # => [
      #   #      #<Pet name: "Fancy-Fancy">,
      #   #      #<Pet name: "Fancy-Fancy">
      #   #    ]
      #
      #   person.pets.select(:name).uniq
      #   # => [#<Pet name: "Fancy-Fancy">]
      def uniq
        @association.uniq
      end

      # Count all records using SQL.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.count # => 3
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def count(column_name = nil, options = {})
        @association.count(column_name, options)
      end

      # Returns the size of the collection. If the collection hasn't been loaded,
      # it executes a <tt>SELECT COUNT(*)</tt> query. Else it calls <tt>collection.size</tt>.
      #
      # If the collection has been already loaded +size+ and +length+ are
      # equivalent. If not and you are going to need the records anyway
      # +length+ will take one less query. Otherwise +size+ is more efficient.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.size # => 3
      #   # executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
      #
      #   person.pets # This will execute a SELECT * FROM query
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      #
      #   person.pets.size # => 3
      #   # Because the collection is already loaded, this will behave like
      #   # collection.size and no SQL count query is executed.
      def size
        @association.size
      end

      # Returns the size of the collection calling +size+ on the target.
      # If the collection has been already loaded, +length+ and +size+ are
      # equivalent. If not and you are going to need the records anyway this
      # method will take one less query. Otherwise +size+ is more efficient.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.length # => 3
      #   # executes something like SELECT "pets".* FROM "pets" WHERE "pets"."person_id" = 1
      #
      #   # Because the collection is loaded, you can
      #   # call the collection with no additional queries:
      #   person.pets
      #   # => [
      #   #       #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #       #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #       #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def length
        @association.length
      end

      # Returns +true+ if the collection is empty. If the collection has been
      # loaded or the <tt>:counter_sql</tt> option is provided, it is equivalent
      # to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
      # it is equivalent to <tt>collection.exists?</tt>. If the collection has
      # not already been loaded and you are going to fetch the records anyway it
      # is better to check <tt>collection.length.zero?</tt>.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.count  # => 1
      #   person.pets.empty? # => false
      #
      #   person.pets.delete_all
      #
      #   person.pets.count  # => 0
      #   person.pets.empty? # => true
      def empty?
        @association.empty?
      end

      # Returns +true+ if the collection is not empty.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.count # => 0
      #   person.pets.any?  # => false
      #
      #   person.pets << Pet.new(name: 'Snoop')
      #   person.pets.count # => 0
      #   person.pets.any?  # => true
      #
      # You can also pass a block to define criteria. The behavior
      # is the same, it returns true if the collection based on the
      # criteria is not empty.
      #
      #   person.pets
      #   # => [#<Pet name: "Snoop", group: "dogs">]
      #
      #   person.pets.any? do |pet|
      #     pet.group == 'cats'
      #   end
      #   # => false
      #
      #   person.pets.any? do |pet|
      #     pet.group == 'dogs'
      #   end
      #   # => true
      def any?(&block)
        @association.any?(&block)
      end

      # Returns true if the collection has more than one record.
      # Equivalent to <tt>collection.size > 1</tt>.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.count #=> 1
      #   person.pets.many? #=> false
      #
      #   person.pets << Pet.new(name: 'Snoopy')
      #   person.pets.count #=> 2
      #   person.pets.many? #=> true
      #
      # You can also pass a block to define criteria. The
      # behavior is the same, it returns true if the collection
      # based on the criteria has more than one record.
      #
      #   person.pets
      #   # => [
      #   #      #<Pet name: "Gorby", group: "cats">,
      #   #      #<Pet name: "Puff", group: "cats">,
      #   #      #<Pet name: "Snoop", group: "dogs">
      #   #    ]
      #
      #   person.pets.many? do |pet|
      #     pet.group == 'dogs'
      #   end
      #   # => false
      #
      #   person.pets.many? do |pet|
      #     pet.group == 'cats'
      #   end
      #   # => true
      def many?(&block)
        @association.many?(&block)
      end

      # Returns +true+ if the given object is present in the collection.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets # => [#<Pet id: 20, name: "Snoop">]
      #
      #   person.pets.include?(Pet.find(20)) # => true
      #   person.pets.include?(Pet.find(21)) # => false
      def include?(record)
        @association.include?(record)
      end

      alias_method :new, :build

      def proxy_association
        @association
      end

      # We don't want this object to be put on the scoping stack, because
      # that could create an infinite loop where we call an @association
      # method, which gets the current scope, which is this object, which
      # delegates to @association, and so on.
      def scoping
        @association.scope.scoping { yield }
      end

      # Returns a <tt>Relation</tt> object for the records in this association
      def scope
        association = @association

        @association.scope.extending! do
          define_method(:proxy_association) { association }
        end
      end

      # :nodoc:
      alias spawn scope

      # Equivalent to <tt>Array#==</tt>. Returns +true+ if the two arrays
      # contain the same number of elements and if each element is equal
      # to the corresponding element in the other array, otherwise returns
      # +false+.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>
      #   #    ]
      #
      #   other = person.pets.to_ary
      #
      #   person.pets == other
      #   # => true
      #
      #   other = [Pet.new(id: 1), Pet.new(id: 2)]
      #
      #   person.pets == other
      #   # => false
      def ==(other)
        load_target == other
      end

      # Returns a new array of objects from the collection. If the collection
      # hasn't been loaded, it fetches the records from the database.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets
      #   # => [
      #   #       #<Pet id: 4, name: "Benny", person_id: 1>,
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      #
      #   other_pets = person.pets.to_ary
      #   # => [
      #   #       #<Pet id: 4, name: "Benny", person_id: 1>,
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      #
      #   other_pets.replace([Pet.new(name: 'BooGoo')])
      #
      #   other_pets
      #   # => [#<Pet id: nil, name: "BooGoo", person_id: 1>]
      #
      #   person.pets
      #   # This is not affected by replace
      #   # => [
      #   #       #<Pet id: 4, name: "Benny", person_id: 1>,
      #   #       #<Pet id: 5, name: "Brain", person_id: 1>,
      #   #       #<Pet id: 6, name: "Boss",  person_id: 1>
      #   #    ]
      def to_ary
        load_target.dup
      end
      alias_method :to_a, :to_ary

      # Adds one or more +records+ to the collection by setting their foreign keys
      # to the association‘s primary key. Returns +self+, so several appends may be
      # chained together.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets.size # => 0
      #   person.pets << Pet.new(name: 'Fancy-Fancy')
      #   person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
      #   person.pets.size # => 3
      #
      #   person.id # => 1
      #   person.pets
      #   # => [
      #   #      #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
      #   #      #<Pet id: 2, name: "Spook", person_id: 1>,
      #   #      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
      #   #    ]
      def <<(*records)
        proxy_association.concat(records) && self
      end
      alias_method :push, :<<

      # Equivalent to +delete_all+. The difference is that returns +self+, instead
      # of an array with the deleted objects, so methods can be chained. See
      # +delete_all+ for more information.
      def clear
        delete_all
        self
      end

      # Reloads the collection from the database. Returns +self+.
      # Equivalent to <tt>collection(true)</tt>.
      #
      #   class Person < ActiveRecord::Base
      #     has_many :pets
      #   end
      #
      #   person.pets # fetches pets from the database
      #   # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
      #
      #   person.pets # uses the pets cache
      #   # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
      #
      #   person.pets.reload # fetches pets from the database
      #   # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
      #
      #   person.pets(true)  # fetches pets from the database
      #   # => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
      def reload
        proxy_association.reload
        self
      end
    end
  end
end
module ActiveRecord
  # = Active Record Has And Belongs To Many Association
  module Associations
    class HasAndBelongsToManyAssociation < CollectionAssociation #:nodoc:
      attr_reader :join_table

      def initialize(owner, reflection)
        @join_table = Arel::Table.new(reflection.join_table)
        super
      end

      def insert_record(record, validate = true, raise = false)
        if record.new_record?
          if raise
            record.save!(:validate => validate)
          else
            return unless record.save(:validate => validate)
          end
        end

        if options[:insert_sql]
          owner.connection.insert(interpolate(options[:insert_sql], record))
        else
          stmt = join_table.compile_insert(
            join_table[reflection.foreign_key]             => owner.id,
            join_table[reflection.association_foreign_key] => record.id
          )

          owner.connection.insert stmt
        end

        record
      end

      private

        def count_records
          load_target.size
        end

        def delete_records(records, method)
          if sql = options[:delete_sql]
            records = load_target if records == :all
            records.each { |record| owner.connection.delete(interpolate(sql, record)) }
          else
            relation  = join_table
            condition = relation[reflection.foreign_key].eq(owner.id)

            unless records == :all
              condition = condition.and(
                relation[reflection.association_foreign_key]
                  .in(records.map { |x| x.id }.compact)
              )
            end

            owner.connection.delete(relation.where(condition).compile_delete)
          end
        end

        def invertible_for?(record)
          false
        end
    end
  end
end
module ActiveRecord
  # = Active Record Has Many Association
  module Associations
    # This is the proxy that handles a has many association.
    #
    # If the association has a <tt>:through</tt> option further specialization
    # is provided by its child HasManyThroughAssociation.
    class HasManyAssociation < CollectionAssociation #:nodoc:

      def handle_dependency
        case options[:dependent]
        when :restrict, :restrict_with_exception
          raise ActiveRecord::DeleteRestrictionError.new(reflection.name) unless empty?

        when :restrict_with_error
          unless empty?
            record = klass.human_attribute_name(reflection.name).downcase
            owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record)
            false
          end

        else
          if options[:dependent] == :destroy
            # No point in executing the counter update since we're going to destroy the parent anyway
            load_target.each(&:mark_for_destruction)
          end

          delete_all
        end
      end

      def insert_record(record, validate = true, raise = false)
        set_owner_attributes(record)

        if raise
          record.save!(:validate => validate)
        else
          record.save(:validate => validate)
        end
      end

      private

        # Returns the number of records in this collection.
        #
        # If the association has a counter cache it gets that value. Otherwise
        # it will attempt to do a count via SQL, bounded to <tt>:limit</tt> if
        # there's one. Some configuration options like :group make it impossible
        # to do an SQL count, in those cases the array count will be used.
        #
        # That does not depend on whether the collection has already been loaded
        # or not. The +size+ method is the one that takes the loaded flag into
        # account and delegates to +count_records+ if needed.
        #
        # If the collection is empty the target is set to an empty array and
        # the loaded flag is set to true as well.
        def count_records
          count = if has_cached_counter?
            owner.send(:read_attribute, cached_counter_attribute_name)
          elsif options[:counter_sql] || options[:finder_sql]
            reflection.klass.count_by_sql(custom_counter_sql)
          else
            scope.count
          end

          # If there's nothing in the database and @target has no new records
          # we are certain the current target is an empty array. This is a
          # documented side-effect of the method that may avoid an extra SELECT.
          @target ||= [] and loaded! if count == 0

          [association_scope.limit_value, count].compact.min
        end

        def has_cached_counter?(reflection = reflection)
          owner.attribute_present?(cached_counter_attribute_name(reflection))
        end

        def cached_counter_attribute_name(reflection = reflection)
          options[:counter_cache] || "#{reflection.name}_count"
        end

        def update_counter(difference, reflection = reflection)
          if has_cached_counter?(reflection)
            counter = cached_counter_attribute_name(reflection)
            owner.class.update_counters(owner.id, counter => difference)
            owner[counter] += difference
            owner.changed_attributes.delete(counter) # eww
          end
        end

        # This shit is nasty. We need to avoid the following situation:
        #
        #   * An associated record is deleted via record.destroy
        #   * Hence the callbacks run, and they find a belongs_to on the record with a
        #     :counter_cache options which points back at our owner. So they update the
        #     counter cache.
        #   * In which case, we must make sure to *not* update the counter cache, or else
        #     it will be decremented twice.
        #
        # Hence this method.
        def inverse_updates_counter_cache?(reflection = reflection)
          counter_name = cached_counter_attribute_name(reflection)
          reflection.klass.reflect_on_all_associations(:belongs_to).any? { |inverse_reflection|
            inverse_reflection.counter_cache_column == counter_name
          }
        end

        # Deletes the records according to the <tt>:dependent</tt> option.
        def delete_records(records, method)
          if method == :destroy
            records.each { |r| r.destroy }
            update_counter(-records.length) unless inverse_updates_counter_cache?
          else
            if records == :all
              scope = self.scope
            else
              keys  = records.map { |r| r[reflection.association_primary_key] }
              scope = self.scope.where(reflection.association_primary_key => keys)
            end

            if method == :delete_all
              update_counter(-scope.delete_all)
            else
              update_counter(-scope.update_all(reflection.foreign_key => nil))
            end
          end
        end

        def foreign_key_present?
          owner.attribute_present?(reflection.association_primary_key)
        end
    end
  end
end

module ActiveRecord
  # = Active Record Has Many Through Association
  module Associations
    class HasManyThroughAssociation < HasManyAssociation #:nodoc:
      include ThroughAssociation

      def initialize(owner, reflection)
        super

        @through_records     = {}
        @through_association = nil
      end

      # Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been
      # loaded and calling collection.size if it has. If it's more likely than not that the collection does
      # have a size larger than zero, and you need to fetch that collection afterwards, it'll take one fewer
      # SELECT query if you use #length.
      def size
        if has_cached_counter?
          owner.send(:read_attribute, cached_counter_attribute_name)
        elsif loaded?
          target.size
        else
          count
        end
      end

      def concat(*records)
        unless owner.new_record?
          records.flatten.each do |record|
            raise_on_type_mismatch(record)
            record.save! if record.new_record?
          end
        end

        super
      end

      def concat_records(records)
        ensure_not_nested

        records = super

        if owner.new_record? && records
          records.flatten.each do |record|
            build_through_record(record)
          end
        end

        records
      end

      def insert_record(record, validate = true, raise = false)
        ensure_not_nested

        if record.new_record?
          if raise
            record.save!(:validate => validate)
          else
            return unless record.save(:validate => validate)
          end
        end

        save_through_record(record)
        update_counter(1)
        record
      end

      private

        def through_association
          @through_association ||= owner.association(through_reflection.name)
        end

        # We temporarily cache through record that has been build, because if we build a
        # through record in build_record and then subsequently call insert_record, then we
        # want to use the exact same object.
        #
        # However, after insert_record has been called, we clear the cache entry because
        # we want it to be possible to have multiple instances of the same record in an
        # association
        def build_through_record(record)
          @through_records[record.object_id] ||= begin
            ensure_mutable

            through_record = through_association.build
            through_record.send("#{source_reflection.name}=", record)
            through_record
          end
        end

        def save_through_record(record)
          build_through_record(record).save!
        ensure
          @through_records.delete(record.object_id)
        end

        def build_record(attributes)
          ensure_not_nested

          record = super(attributes)

          inverse = source_reflection.inverse_of
          if inverse
            if inverse.macro == :has_many
              record.send(inverse.name) << build_through_record(record)
            elsif inverse.macro == :has_one
              record.send("#{inverse.name}=", build_through_record(record))
            end
          end

          record
        end

        def target_reflection_has_associated_record?
          !(through_reflection.macro == :belongs_to && owner[through_reflection.foreign_key].blank?)
        end

        def update_through_counter?(method)
          case method
          when :destroy
            !inverse_updates_counter_cache?(through_reflection)
          when :nullify
            false
          else
            true
          end
        end

        def delete_records(records, method)
          ensure_not_nested

          # This is unoptimised; it will load all the target records
          # even when we just want to delete everything.
          records = load_target if records == :all

          scope = through_association.scope
          scope.where! construct_join_attributes(*records)

          case method
          when :destroy
            count = scope.destroy_all.length
          when :nullify
            count = scope.update_all(source_reflection.foreign_key => nil)
          else
            count = scope.delete_all
          end

          delete_through_records(records)

          if source_reflection.options[:counter_cache]
            counter = source_reflection.counter_cache_column
            klass.decrement_counter counter, records.map(&:id)
          end

          if through_reflection.macro == :has_many && update_through_counter?(method)
            update_counter(-count, through_reflection)
          end

          update_counter(-count)
        end

        def through_records_for(record)
          attributes = construct_join_attributes(record)
          candidates = Array.wrap(through_association.target)
          candidates.find_all { |c| c.attributes.slice(*attributes.keys) == attributes }
        end

        def delete_through_records(records)
          records.each do |record|
            through_records = through_records_for(record)

            if through_reflection.macro == :has_many
              through_records.each { |r| through_association.target.delete(r) }
            else
              if through_records.include?(through_association.target)
                through_association.target = nil
              end
            end

            @through_records.delete(record.object_id)
          end
        end

        def find_target
          return [] unless target_reflection_has_associated_record?
          scope.to_a
        end

        # NOTE - not sure that we can actually cope with inverses here
        def invertible_for?(record)
          false
        end
    end
  end
end

module ActiveRecord
  # = Active Record Belongs To Has One Association
  module Associations
    class HasOneAssociation < SingularAssociation #:nodoc:

      def handle_dependency
        case options[:dependent]
        when :restrict, :restrict_with_exception
          raise ActiveRecord::DeleteRestrictionError.new(reflection.name) if load_target

        when :restrict_with_error
          if load_target
            record = klass.human_attribute_name(reflection.name).downcase
            owner.errors.add(:base, :"restrict_dependent_destroy.one", record: record)
            false
          end

        else
          delete
        end
      end

      def replace(record, save = true)
        raise_on_type_mismatch(record) if record
        load_target

        # If target and record are nil, or target is equal to record,
        # we don't need to have transaction.
        if (target || record) && target != record
          transaction_if(save) do
            remove_target!(options[:dependent]) if target && !target.destroyed?

            if record
              set_owner_attributes(record)
              set_inverse_instance(record)

              if owner.persisted? && save && !record.save
                nullify_owner_attributes(record)
                set_owner_attributes(target) if target
                raise RecordNotSaved, "Failed to save the new associated #{reflection.name}."
              end
            end
          end
        end

        self.target = record
      end

      def delete(method = options[:dependent])
        if load_target
          case method
            when :delete
              target.delete
            when :destroy
              target.destroy
            when :nullify
              target.update_columns(reflection.foreign_key => nil)
          end
        end
      end

      private

        # The reason that the save param for replace is false, if for create (not just build),
        # is because the setting of the foreign keys is actually handled by the scoping when
        # the record is instantiated, and so they are set straight away and do not need to be
        # updated within replace.
        def set_new_record(record)
          replace(record, false)
        end

        def remove_target!(method)
          case method
            when :delete
              target.delete
            when :destroy
              target.destroy
            else
              nullify_owner_attributes(target)

              if target.persisted? && owner.persisted? && !target.save
                set_owner_attributes(target)
                raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " +
                                      "The record failed to save after its foreign key was set to nil."
              end
          end
        end

        def nullify_owner_attributes(record)
          record[reflection.foreign_key] = nil
        end

        def transaction_if(value)
          if value
            reflection.klass.transaction { yield }
          else
            yield
          end
        end
    end
  end
end
module ActiveRecord
  # = Active Record Has One Through Association
  module Associations
    class HasOneThroughAssociation < HasOneAssociation #:nodoc:
      include ThroughAssociation

      def replace(record)
        create_through_record(record)
        self.target = record
      end

      private

        def create_through_record(record)
          ensure_not_nested

          through_proxy  = owner.association(through_reflection.name)
          through_record = through_proxy.send(:load_target)

          if through_record && !record
            through_record.destroy
          elsif record
            attributes = construct_join_attributes(record)

            if through_record
              through_record.update(attributes)
            elsif owner.new_record?
              through_proxy.build(attributes)
            else
              through_proxy.create(attributes)
            end
          end
        end
    end
  end
end
module ActiveRecord
  module Associations
    class JoinDependency # :nodoc:
      class JoinAssociation < JoinPart # :nodoc:
        include JoinHelper

        # The reflection of the association represented
        attr_reader :reflection

        # The JoinDependency object which this JoinAssociation exists within. This is mainly
        # relevant for generating aliases which do not conflict with other joins which are
        # part of the query.
        attr_reader :join_dependency

        # A JoinBase instance representing the active record we are joining onto.
        # (So in Author.has_many :posts, the Author would be that base record.)
        attr_reader :parent

        # What type of join will be generated, either Arel::InnerJoin (default) or Arel::OuterJoin
        attr_accessor :join_type

        # These implement abstract methods from the superclass
        attr_reader :aliased_prefix

        attr_reader :tables

        delegate :options, :through_reflection, :source_reflection, :chain, :to => :reflection
        delegate :table, :table_name, :to => :parent, :prefix => :parent
        delegate :alias_tracker, :to => :join_dependency

        alias :alias_suffix :parent_table_name

        def initialize(reflection, join_dependency, parent = nil)
          reflection.check_validity!

          if reflection.options[:polymorphic]
            raise EagerLoadPolymorphicError.new(reflection)
          end

          super(reflection.klass)

          @reflection      = reflection
          @join_dependency = join_dependency
          @parent          = parent
          @join_type       = Arel::InnerJoin
          @aliased_prefix  = "t#{ join_dependency.join_parts.size }"
          @tables          = construct_tables.reverse
        end

        def ==(other)
          other.class == self.class &&
            other.reflection == reflection &&
            other.parent == parent
        end

        def find_parent_in(other_join_dependency)
          other_join_dependency.join_parts.detect do |join_part|
            parent == join_part
          end
        end

        def join_to(relation)
          tables        = @tables.dup
          foreign_table = parent_table
          foreign_klass = parent.active_record

          # The chain starts with the target table, but we want to end with it here (makes
          # more sense in this context), so we reverse
          chain.reverse.each_with_index do |reflection, i|
            table = tables.shift

            case reflection.source_macro
            when :belongs_to
              key         = reflection.association_primary_key
              foreign_key = reflection.foreign_key
            when :has_and_belongs_to_many
              # Join the join table first...
              relation.from(join(
                table,
                table[reflection.foreign_key].
                  eq(foreign_table[reflection.active_record_primary_key])
              ))

              foreign_table, table = table, tables.shift

              key         = reflection.association_primary_key
              foreign_key = reflection.association_foreign_key
            else
              key         = reflection.foreign_key
              foreign_key = reflection.active_record_primary_key
            end

            constraint = build_constraint(reflection, table, key, foreign_table, foreign_key)

            scope_chain_items = scope_chain[i]

            if reflection.type
              scope_chain_items += [
                ActiveRecord::Relation.new(reflection.klass, table)
                  .where(reflection.type => foreign_klass.base_class.name)
              ]
            end

            scope_chain_items.each do |item|
              unless item.is_a?(Relation)
                item = ActiveRecord::Relation.new(reflection.klass, table).instance_exec(self, &item)
              end

              constraint = constraint.and(item.arel.constraints) unless item.arel.constraints.empty?
            end

            relation.from(join(table, constraint))

            # The current table in this iteration becomes the foreign table in the next
            foreign_table, foreign_klass = table, reflection.klass
          end

          relation
        end

        def build_constraint(reflection, table, key, foreign_table, foreign_key)
          constraint = table[key].eq(foreign_table[foreign_key])

          if reflection.klass.finder_needs_type_condition?
            constraint = table.create_and([
              constraint,
              reflection.klass.send(:type_condition, table)
            ])
          end

          constraint
        end

        def join_relation(joining_relation)
          self.join_type = Arel::OuterJoin
          joining_relation.joins(self)
        end

        def table
          tables.last
        end

        def aliased_table_name
          table.table_alias || table.name
        end

        def scope_chain
          @scope_chain ||= reflection.scope_chain.reverse
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class JoinDependency # :nodoc:
      class JoinBase < JoinPart # :nodoc:
        def ==(other)
          other.class == self.class &&
            other.active_record == active_record
        end

        def aliased_prefix
          "t0"
        end

        def table
          Arel::Table.new(table_name, arel_engine)
        end

        def aliased_table_name
          active_record.table_name
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class JoinDependency # :nodoc:
      # A JoinPart represents a part of a JoinDependency. It is an abstract class, inherited
      # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which
      # everything else is being joined onto. A JoinAssociation represents an association which
      # is joining to the base. A JoinAssociation may result in more than one actual join
      # operations (for example a has_and_belongs_to_many JoinAssociation would result in
      # two; one for the join table and one for the target table).
      class JoinPart # :nodoc:
        # The Active Record class which this join part is associated 'about'; for a JoinBase
        # this is the actual base model, for a JoinAssociation this is the target model of the
        # association.
        attr_reader :active_record

        delegate :table_name, :column_names, :primary_key, :reflections, :arel_engine, :to => :active_record

        def initialize(active_record)
          @active_record = active_record
          @cached_record = {}
          @column_names_with_alias = nil
        end

        def aliased_table
          Arel::Nodes::TableAlias.new table, aliased_table_name
        end

        def ==(other)
          raise NotImplementedError
        end

        # An Arel::Table for the active_record
        def table
          raise NotImplementedError
        end

        # The prefix to be used when aliasing columns in the active_record's table
        def aliased_prefix
          raise NotImplementedError
        end

        # The alias for the active_record's table
        def aliased_table_name
          raise NotImplementedError
        end

        # The alias for the primary key of the active_record's table
        def aliased_primary_key
          "#{aliased_prefix}_r0"
        end

        # An array of [column_name, alias] pairs for the table
        def column_names_with_alias
          unless @column_names_with_alias
            @column_names_with_alias = []

            ([primary_key] + (column_names - [primary_key])).compact.each_with_index do |column_name, i|
              @column_names_with_alias << [column_name, "#{aliased_prefix}_r#{i}"]
            end
          end
          @column_names_with_alias
        end

        def extract_record(row)
          Hash[column_names_with_alias.map{|cn, an| [cn, row[an]]}]
        end

        def record_id(row)
          row[aliased_primary_key]
        end

        def instantiate(row)
          @cached_record[record_id(row)] ||= active_record.send(:instantiate, extract_record(row))
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class JoinDependency # :nodoc:
      autoload :JoinPart,        'active_record/associations/join_dependency/join_part'
      autoload :JoinBase,        'active_record/associations/join_dependency/join_base'
      autoload :JoinAssociation, 'active_record/associations/join_dependency/join_association'

      attr_reader :join_parts, :reflections, :alias_tracker, :active_record

      def initialize(base, associations, joins)
        @active_record = base
        @table_joins   = joins
        @join_parts    = [JoinBase.new(base)]
        @associations  = {}
        @reflections   = []
        @alias_tracker = AliasTracker.new(base.connection, joins)
        @alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
        build(associations)
      end

      def graft(*associations)
        associations.each do |association|
          join_associations.detect {|a| association == a} ||
            build(association.reflection.name, association.find_parent_in(self) || join_base, association.join_type)
        end
        self
      end

      def join_associations
        join_parts.last(join_parts.length - 1)
      end

      def join_base
        join_parts.first
      end

      def columns
        join_parts.collect { |join_part|
          table = join_part.aliased_table
          join_part.column_names_with_alias.collect{ |column_name, aliased_name|
            table[column_name].as Arel.sql(aliased_name)
          }
        }.flatten
      end

      def instantiate(rows)
        primary_key = join_base.aliased_primary_key
        parents = {}

        records = rows.map { |model|
          primary_id = model[primary_key]
          parent = parents[primary_id] ||= join_base.instantiate(model)
          construct(parent, @associations, join_associations, model)
          parent
        }.uniq

        remove_duplicate_results!(active_record, records, @associations)
        records
      end

      def remove_duplicate_results!(base, records, associations)
        case associations
        when Symbol, String
          reflection = base.reflections[associations]
          remove_uniq_by_reflection(reflection, records)
        when Array
          associations.each do |association|
            remove_duplicate_results!(base, records, association)
          end
        when Hash
          associations.each_key do |name|
            reflection = base.reflections[name]
            remove_uniq_by_reflection(reflection, records)

            parent_records = []
            records.each do |record|
              if descendant = record.send(reflection.name)
                if reflection.collection?
                  parent_records.concat descendant.target.uniq
                else
                  parent_records << descendant
                end
              end
            end

            remove_duplicate_results!(reflection.klass, parent_records, associations[name]) unless parent_records.empty?
          end
        end
      end

      protected

      def cache_joined_association(association)
        associations = []
        parent = association.parent
        while parent != join_base
          associations.unshift(parent.reflection.name)
          parent = parent.parent
        end
        ref = @associations
        associations.each do |key|
          ref = ref[key]
        end
        ref[association.reflection.name] ||= {}
      end

      def build(associations, parent = nil, join_type = Arel::InnerJoin)
        parent ||= join_parts.last
        case associations
        when Symbol, String
          reflection = parent.reflections[associations.to_s.intern] or
          raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it?"
          unless join_association = find_join_association(reflection, parent)
            @reflections << reflection
            join_association = build_join_association(reflection, parent)
            join_association.join_type = join_type
            @join_parts << join_association
            cache_joined_association(join_association)
          end
          join_association
        when Array
          associations.each do |association|
            build(association, parent, join_type)
          end
        when Hash
          associations.keys.sort_by { |a| a.to_s }.each do |name|
            join_association = build(name, parent, join_type)
            build(associations[name], join_association, join_type)
          end
        else
          raise ConfigurationError, associations.inspect
        end
      end

      def find_join_association(name_or_reflection, parent)
        if String === name_or_reflection
          name_or_reflection = name_or_reflection.to_sym
        end

        join_associations.detect { |j|
          j.reflection == name_or_reflection && j.parent == parent
        }
      end

      def remove_uniq_by_reflection(reflection, records)
        if reflection && reflection.collection?
          records.each { |record| record.send(reflection.name).target.uniq! }
        end
      end

      def build_join_association(reflection, parent)
        JoinAssociation.new(reflection, self, parent)
      end

      def construct(parent, associations, join_parts, row)
        case associations
        when Symbol, String
          name = associations.to_s

          join_part = join_parts.detect { |j|
            j.reflection.name.to_s == name &&
              j.parent_table_name == parent.class.table_name }

            raise(ConfigurationError, "No such association") unless join_part

            join_parts.delete(join_part)
            construct_association(parent, join_part, row)
        when Array
          associations.each do |association|
            construct(parent, association, join_parts, row)
          end
        when Hash
          associations.sort_by { |k,_| k.to_s }.each do |association_name, assoc|
            association = construct(parent, association_name, join_parts, row)
            construct(association, assoc, join_parts, row) if association
          end
        else
          raise ConfigurationError, associations.inspect
        end
      end

      def construct_association(record, join_part, row)
        return if record.id.to_s != join_part.parent.record_id(row).to_s

        macro = join_part.reflection.macro
        if macro == :has_one
          return record.association(join_part.reflection.name).target if record.association_cache.key?(join_part.reflection.name)
          association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil?
          set_target_and_inverse(join_part, association, record)
        else
          association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil?
          case macro
          when :has_many, :has_and_belongs_to_many
            other = record.association(join_part.reflection.name)
            other.loaded!
            other.target.push(association) if association
            other.set_inverse_instance(association)
          when :belongs_to
            set_target_and_inverse(join_part, association, record)
          else
            raise ConfigurationError, "unknown macro: #{join_part.reflection.macro}"
          end
        end
        association
      end

      def set_target_and_inverse(join_part, association, record)
        other = record.association(join_part.reflection.name)
        other.target = association
        other.set_inverse_instance(association)
      end
    end
  end
end
module ActiveRecord
  module Associations
    # Helper class module which gets mixed into JoinDependency::JoinAssociation and AssociationScope
    module JoinHelper #:nodoc:

      def join_type
        Arel::InnerJoin
      end

      private

      def construct_tables
        tables = []
        chain.each do |reflection|
          tables << alias_tracker.aliased_table_for(
            table_name_for(reflection),
            table_alias_for(reflection, reflection != self.reflection)
          )

          if reflection.source_macro == :has_and_belongs_to_many
            tables << alias_tracker.aliased_table_for(
              (reflection.source_reflection || reflection).join_table,
              table_alias_for(reflection, true)
            )
          end
        end
        tables
      end

      def table_name_for(reflection)
        reflection.table_name
      end

      def table_alias_for(reflection, join = false)
        name = "#{reflection.plural_name}_#{alias_suffix}"
        name << "_join" if join
        name
      end

      def join(table, constraint)
        table.create_join(table, table.create_on(constraint), join_type)
      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class Association #:nodoc:
        attr_reader :owners, :reflection, :preload_scope, :model, :klass

        def initialize(klass, owners, reflection, preload_scope)
          @klass         = klass
          @owners        = owners
          @reflection    = reflection
          @preload_scope = preload_scope
          @model         = owners.first && owners.first.class
          @scope         = nil
          @owners_by_key = nil
        end

        def run
          unless owners.first.association(reflection.name).loaded?
            preload
          end
        end

        def preload
          raise NotImplementedError
        end

        def scope
          @scope ||= build_scope
        end

        def records_for(ids)
          scope.where(association_key.in(ids))
        end

        def table
          klass.arel_table
        end

        # The name of the key on the associated records
        def association_key_name
          raise NotImplementedError
        end

        # This is overridden by HABTM as the condition should be on the foreign_key column in
        # the join table
        def association_key
          table[association_key_name]
        end

        # The name of the key on the model which declares the association
        def owner_key_name
          raise NotImplementedError
        end

        # We're converting to a string here because postgres will return the aliased association
        # key in a habtm as a string (for whatever reason)
        def owners_by_key
          @owners_by_key ||= owners.group_by do |owner|
            key = owner[owner_key_name]
            key && key.to_s
          end
        end

        def options
          reflection.options
        end

        private

        def associated_records_by_owner
          owners_map = owners_by_key
          owner_keys = owners_map.keys.compact

          if klass.nil? || owner_keys.empty?
            records = []
          else
            # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
            # Make several smaller queries if necessary or make one query if the adapter supports it
            sliced  = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
            records = sliced.map { |slice| records_for(slice).to_a }.flatten
          end

          # Each record may have multiple owners, and vice-versa
          records_by_owner = Hash[owners.map { |owner| [owner, []] }]
          records.each do |record|
            owner_key = record[association_key_name].to_s

            owners_map[owner_key].each do |owner|
              records_by_owner[owner] << record
            end
          end
          records_by_owner
        end

        def reflection_scope
          @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(nil, &reflection.scope) : klass.unscoped
        end

        def build_scope
          scope = klass.unscoped
          scope.default_scoped = true

          values         = reflection_scope.values
          preload_values = preload_scope.values

          scope.where_values      = Array(values[:where])      + Array(preload_values[:where])
          scope.references_values = Array(values[:references]) + Array(preload_values[:references])

          scope.select!   preload_values[:select] || values[:select] || table[Arel.star]
          scope.includes! preload_values[:includes] || values[:includes]

          if options[:as]
            scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
          end

          scope
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class BelongsTo < SingularAssociation #:nodoc:

        def association_key_name
          reflection.options[:primary_key] || klass && klass.primary_key
        end

        def owner_key_name
          reflection.foreign_key
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class CollectionAssociation < Association #:nodoc:

        private

        def build_scope
          super.order(preload_scope.values[:order] || reflection_scope.values[:order])
        end

        def preload
          associated_records_by_owner.each do |owner, records|
            association = owner.association(reflection.name)
            association.loaded!
            association.target.concat(records)
            records.each { |record| association.set_inverse_instance(record) }
          end
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class HasAndBelongsToMany < CollectionAssociation #:nodoc:
        attr_reader :join_table

        def initialize(klass, records, reflection, preload_options)
          super
          @join_table = Arel::Table.new(reflection.join_table).alias('t0')
        end

        # Unlike the other associations, we want to get a raw array of rows so that we can
        # access the aliased column on the join table
        def records_for(ids)
          scope = super
          klass.connection.select_all(scope.arel, 'SQL', scope.bind_values)
        end

        def owner_key_name
          reflection.active_record_primary_key
        end

        def association_key_name
          'ar_association_key_name'
        end

        def association_key
          join_table[reflection.foreign_key]
        end

        private

        # Once we have used the join table column (in super), we manually instantiate the
        # actual records, ensuring that we don't create more than one instances of the same
        # record
        def associated_records_by_owner
          records = {}
          super.each do |owner_key, rows|
            rows.map! { |row| records[row[klass.primary_key]] ||= klass.instantiate(row) }
          end
        end

        def build_scope
          super.joins(join).select(join_select)
        end

        def join_select
          association_key.as(Arel.sql(association_key_name))
        end

        def join
          condition = table[reflection.association_primary_key].eq(
            join_table[reflection.association_foreign_key])

          table.create_join(join_table, table.create_on(condition))
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class HasMany < CollectionAssociation #:nodoc:

        def association_key_name
          reflection.foreign_key
        end

        def owner_key_name
          reflection.active_record_primary_key
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class HasManyThrough < CollectionAssociation #:nodoc:
        include ThroughAssociation

        def associated_records_by_owner
          super.each do |owner, records|
            records.uniq! if reflection_scope.uniq_value
          end
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class HasOne < SingularAssociation #:nodoc:

        def association_key_name
          reflection.foreign_key
        end

        def owner_key_name
          reflection.active_record_primary_key
        end

        private

        def build_scope
          super.order(preload_scope.values[:order] || reflection_scope.values[:order])
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class HasOneThrough < SingularAssociation #:nodoc:
        include ThroughAssociation
      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      class SingularAssociation < Association #:nodoc:

        private

        def preload
          associated_records_by_owner.each do |owner, associated_records|
            record = associated_records.first

            association = owner.association(reflection.name)
            association.target = record
            association.set_inverse_instance(record)
          end
        end

      end
    end
  end
end
module ActiveRecord
  module Associations
    class Preloader
      module ThroughAssociation #:nodoc:

        def through_reflection
          reflection.through_reflection
        end

        def source_reflection
          reflection.source_reflection
        end

        def associated_records_by_owner
          through_records = through_records_by_owner

          Preloader.new(through_records.values.flatten, source_reflection.name, reflection_scope).run

          through_records.each do |owner, records|
            records.map! { |r| r.send(source_reflection.name) }.flatten!
            records.compact!
          end
        end

        private

        def through_records_by_owner
          Preloader.new(owners, through_reflection.name, through_scope).run

          Hash[owners.map do |owner|
            through_records = Array.wrap(owner.send(through_reflection.name))

            # Dont cache the association - we would only be caching a subset
            if (through_scope != through_reflection.klass.unscoped) ||
               (reflection.options[:source_type] && through_reflection.collection?)
              owner.association(through_reflection.name).reset
            end

            [owner, through_records]
          end]
        end

        def through_scope
          through_scope = through_reflection.klass.unscoped

          if options[:source_type]
            through_scope.where! reflection.foreign_type => options[:source_type]
          else
            unless reflection_scope.where_values.empty?
              through_scope.includes_values = reflection_scope.values[:includes] || options[:source]
              through_scope.where_values    = reflection_scope.values[:where]
            end

            through_scope.order!      reflection_scope.values[:order]
            through_scope.references! reflection_scope.values[:references]
          end

          through_scope
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    # Implements the details of eager loading of Active Record associations.
    #
    # Note that 'eager loading' and 'preloading' are actually the same thing.
    # However, there are two different eager loading strategies.
    #
    # The first one is by using table joins. This was only strategy available
    # prior to Rails 2.1. Suppose that you have an Author model with columns
    # 'name' and 'age', and a Book model with columns 'name' and 'sales'. Using
    # this strategy, Active Record would try to retrieve all data for an author
    # and all of its books via a single query:
    #
    #   SELECT * FROM authors
    #   LEFT OUTER JOIN books ON authors.id = books.author_id
    #   WHERE authors.name = 'Ken Akamatsu'
    #
    # However, this could result in many rows that contain redundant data. After
    # having received the first row, we already have enough data to instantiate
    # the Author object. In all subsequent rows, only the data for the joined
    # 'books' table is useful; the joined 'authors' data is just redundant, and
    # processing this redundant data takes memory and CPU time. The problem
    # quickly becomes worse and worse as the level of eager loading increases
    # (i.e. if Active Record is to eager load the associations' associations as
    # well).
    #
    # The second strategy is to use multiple database queries, one for each
    # level of association. Since Rails 2.1, this is the default strategy. In
    # situations where a table join is necessary (e.g. when the +:conditions+
    # option references an association's column), it will fallback to the table
    # join strategy.
    class Preloader #:nodoc:
      extend ActiveSupport::Autoload

      eager_autoload do
        autoload :Association,           'active_record/associations/preloader/association'
        autoload :SingularAssociation,   'active_record/associations/preloader/singular_association'
        autoload :CollectionAssociation, 'active_record/associations/preloader/collection_association'
        autoload :ThroughAssociation,    'active_record/associations/preloader/through_association'

        autoload :HasMany,             'active_record/associations/preloader/has_many'
        autoload :HasManyThrough,      'active_record/associations/preloader/has_many_through'
        autoload :HasOne,              'active_record/associations/preloader/has_one'
        autoload :HasOneThrough,       'active_record/associations/preloader/has_one_through'
        autoload :HasAndBelongsToMany, 'active_record/associations/preloader/has_and_belongs_to_many'
        autoload :BelongsTo,           'active_record/associations/preloader/belongs_to'
      end

      attr_reader :records, :associations, :preload_scope, :model

      # Eager loads the named associations for the given Active Record record(s).
      #
      # In this description, 'association name' shall refer to the name passed
      # to an association creation method. For example, a model that specifies
      # <tt>belongs_to :author</tt>, <tt>has_many :buyers</tt> has association
      # names +:author+ and +:buyers+.
      #
      # == Parameters
      # +records+ is an array of ActiveRecord::Base. This array needs not be flat,
      # i.e. +records+ itself may also contain arrays of records. In any case,
      # +preload_associations+ will preload the all associations records by
      # flattening +records+.
      #
      # +associations+ specifies one or more associations that you want to
      # preload. It may be:
      # - a Symbol or a String which specifies a single association name. For
      #   example, specifying +:books+ allows this method to preload all books
      #   for an Author.
      # - an Array which specifies multiple association names. This array
      #   is processed recursively. For example, specifying <tt>[:avatar, :books]</tt>
      #   allows this method to preload an author's avatar as well as all of his
      #   books.
      # - a Hash which specifies multiple association names, as well as
      #   association names for the to-be-preloaded association objects. For
      #   example, specifying <tt>{ author: :avatar }</tt> will preload a
      #   book's author, as well as that author's avatar.
      #
      # +:associations+ has the same format as the +:include+ option for
      # <tt>ActiveRecord::Base.find</tt>. So +associations+ could look like this:
      #
      #   :books
      #   [ :books, :author ]
      #   { author: :avatar }
      #   [ :books, { author: :avatar } ]
      def initialize(records, associations, preload_scope = nil)
        @records       = Array.wrap(records).compact.uniq
        @associations  = Array.wrap(associations)
        @preload_scope = preload_scope || Relation.new(nil, nil)
      end

      def run
        unless records.empty?
          associations.each { |association| preload(association) }
        end
      end

      private

      def preload(association)
        case association
        when Hash
          preload_hash(association)
        when Symbol
          preload_one(association)
        when String
          preload_one(association.to_sym)
        else
          raise ArgumentError, "#{association.inspect} was not recognised for preload"
        end
      end

      def preload_hash(association)
        association.each do |parent, child|
          Preloader.new(records, parent, preload_scope).run
          Preloader.new(records.map { |record| record.send(parent) }.flatten, child).run
        end
      end

      # Not all records have the same class, so group then preload group on the reflection
      # itself so that if various subclass share the same association then we do not split
      # them unnecessarily
      #
      # Additionally, polymorphic belongs_to associations can have multiple associated
      # classes, depending on the polymorphic_type field. So we group by the classes as
      # well.
      def preload_one(association)
        grouped_records(association).each do |reflection, klasses|
          klasses.each do |klass, records|
            preloader_for(reflection).new(klass, records, reflection, preload_scope).run
          end
        end
      end

      def grouped_records(association)
        Hash[
          records_by_reflection(association).map do |reflection, records|
            [reflection, records.group_by { |record| association_klass(reflection, record) }]
          end
        ]
      end

      def records_by_reflection(association)
        records.group_by do |record|
          reflection = record.class.reflections[association]

          unless reflection
            raise ActiveRecord::ConfigurationError, "Association named '#{association}' was not found; " \
                                                    "perhaps you misspelled it?"
          end

          reflection
        end
      end

      def association_klass(reflection, record)
        if reflection.macro == :belongs_to && reflection.options[:polymorphic]
          klass = record.send(reflection.foreign_type)
          klass && klass.constantize
        else
          reflection.klass
        end
      end

      def preloader_for(reflection)
        case reflection.macro
        when :has_many
          reflection.options[:through] ? HasManyThrough : HasMany
        when :has_one
          reflection.options[:through] ? HasOneThrough : HasOne
        when :has_and_belongs_to_many
          HasAndBelongsToMany
        when :belongs_to
          BelongsTo
        end
      end
    end
  end
end
module ActiveRecord
  module Associations
    class SingularAssociation < Association #:nodoc:
      # Implements the reader method, e.g. foo.bar for Foo.has_one :bar
      def reader(force_reload = false)
        if force_reload
          klass.uncached { reload }
        elsif !loaded? || stale_target?
          reload
        end

        target
      end

      # Implements the writer method, e.g. foo.bar= for Foo.belongs_to :bar
      def writer(record)
        replace(record)
      end

      def create(attributes = {}, &block)
        create_record(attributes, &block)
      end

      def create!(attributes = {}, &block)
        create_record(attributes, true, &block)
      end

      def build(attributes = {})
        record = build_record(attributes)
        yield(record) if block_given?
        set_new_record(record)
        record
      end

      private

        def create_scope
          scope.scope_for_create.stringify_keys.except(klass.primary_key)
        end

        def find_target
          scope.first.tap { |record| set_inverse_instance(record) }
        end

        # Implemented by subclasses
        def replace(record)
          raise NotImplementedError, "Subclasses must implement a replace(record) method"
        end

        def set_new_record(record)
          replace(record)
        end

        def create_record(attributes, raise_error = false)
          record = build_record(attributes)
          yield(record) if block_given?
          saved = record.save
          set_new_record(record)
          raise RecordInvalid.new(record) if !saved && raise_error
          record
        end
    end
  end
end
module ActiveRecord
  # = Active Record Through Association
  module Associations
    module ThroughAssociation #:nodoc:

      delegate :source_reflection, :through_reflection, :chain, :to => :reflection

      protected

        # We merge in these scopes for two reasons:
        #
        #   1. To get the default_scope conditions for any of the other reflections in the chain
        #   2. To get the type conditions for any STI models in the chain
        def target_scope
          scope = super
          chain[1..-1].each do |reflection|
            scope = scope.merge(
              reflection.klass.all.with_default_scope.
                except(:select, :create_with, :includes, :preload, :joins, :eager_load)
            )
          end
          scope
        end

      private

        # Construct attributes for :through pointing to owner and associate. This is used by the
        # methods which create and delete records on the association.
        #
        # We only support indirectly modifying through associations which has a belongs_to source.
        # This is the "has_many :tags, through: :taggings" situation, where the join model
        # typically has a belongs_to on both side. In other words, associations which could also
        # be represented as has_and_belongs_to_many associations.
        #
        # We do not support creating/deleting records on the association where the source has
        # some other type, because this opens up a whole can of worms, and in basically any
        # situation it is more natural for the user to just create or modify their join records
        # directly as required.
        def construct_join_attributes(*records)
          ensure_mutable

          join_attributes = {
            source_reflection.foreign_key =>
              records.map { |record|
                record.send(source_reflection.association_primary_key(reflection.klass))
              }
          }

          if options[:source_type]
            join_attributes[source_reflection.foreign_type] =
              records.map { |record| record.class.base_class.name }
          end

          if records.count == 1
            Hash[join_attributes.map { |k, v| [k, v.first] }]
          else
            join_attributes
          end
        end

        # Note: this does not capture all cases, for example it would be crazy to try to
        # properly support stale-checking for nested associations.
        def stale_state
          if through_reflection.macro == :belongs_to
            owner[through_reflection.foreign_key] && owner[through_reflection.foreign_key].to_s
          end
        end

        def foreign_key_present?
          through_reflection.macro == :belongs_to &&
          !owner[through_reflection.foreign_key].nil?
        end

        def ensure_mutable
          if source_reflection.macro != :belongs_to
            raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
          end
        end

        def ensure_not_nested
          if reflection.nested?
            raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
          end
        end
    end
  end
end
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/string/conversions'
require 'active_support/core_ext/module/remove_method'
require 'active_record/errors'

module ActiveRecord
  class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
    def initialize(reflection, associated_class = nil)
      super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
    end
  end

  class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
    def initialize(owner_class_name, reflection)
      super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}")
    end
  end

  class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
    def initialize(owner_class_name, reflection, source_reflection)
      super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
    end
  end

  class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
    def initialize(owner_class_name, reflection)
      super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
    end
  end

  class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
    def initialize(owner_class_name, reflection, source_reflection)
      super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
    end
  end

  class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
    def initialize(owner_class_name, reflection, through_reflection)
      super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
    end
  end

  class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
    def initialize(reflection)
      through_reflection      = reflection.through_reflection
      source_reflection_names = reflection.source_reflection_names
      source_associations     = reflection.through_reflection.klass.reflect_on_all_associations.collect { |a| a.name.inspect }
      super("Could not find the source association(s) #{source_reflection_names.collect{ |a| a.inspect }.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
    end
  end

  class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
    def initialize(owner, reflection)
      super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
    end
  end

  class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
    def initialize(owner, reflection)
      super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
    end
  end

  class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
    def initialize(owner, reflection)
      super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
    end
  end

  class HasManyThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
    def initialize(owner, reflection)
      super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
    end
  end

  class HasAndBelongsToManyAssociationForeignKeyNeeded < ActiveRecordError #:nodoc:
    def initialize(reflection)
      super("Cannot create self referential has_and_belongs_to_many association on '#{reflection.class_name rescue nil}##{reflection.name rescue nil}'. :association_foreign_key cannot be the same as the :foreign_key.")
    end
  end

  class EagerLoadPolymorphicError < ActiveRecordError #:nodoc:
    def initialize(reflection)
      super("Can not eagerly load the polymorphic association #{reflection.name.inspect}")
    end
  end

  class ReadOnlyAssociation < ActiveRecordError #:nodoc:
    def initialize(reflection)
      super("Can not add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
    end
  end

  # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
  # (has_many, has_one) when there is at least 1 child associated instance.
  # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
  class DeleteRestrictionError < ActiveRecordError #:nodoc:
    def initialize(name)
      super("Cannot delete record because of dependent #{name}")
    end
  end

  # See ActiveRecord::Associations::ClassMethods for documentation.
  module Associations # :nodoc:
    extend ActiveSupport::Autoload
    extend ActiveSupport::Concern

    # These classes will be loaded when associations are created.
    # So there is no need to eager load them.
    autoload :Association,           'active_record/associations/association'
    autoload :SingularAssociation,   'active_record/associations/singular_association'
    autoload :CollectionAssociation, 'active_record/associations/collection_association'
    autoload :CollectionProxy,       'active_record/associations/collection_proxy'

    autoload :BelongsToAssociation,            'active_record/associations/belongs_to_association'
    autoload :BelongsToPolymorphicAssociation, 'active_record/associations/belongs_to_polymorphic_association'
    autoload :HasAndBelongsToManyAssociation,  'active_record/associations/has_and_belongs_to_many_association'
    autoload :HasManyAssociation,              'active_record/associations/has_many_association'
    autoload :HasManyThroughAssociation,       'active_record/associations/has_many_through_association'
    autoload :HasOneAssociation,               'active_record/associations/has_one_association'
    autoload :HasOneThroughAssociation,        'active_record/associations/has_one_through_association'
    autoload :ThroughAssociation,              'active_record/associations/through_association'

    module Builder #:nodoc:
      autoload :Association,           'active_record/associations/builder/association'
      autoload :SingularAssociation,   'active_record/associations/builder/singular_association'
      autoload :CollectionAssociation, 'active_record/associations/builder/collection_association'

      autoload :BelongsTo,           'active_record/associations/builder/belongs_to'
      autoload :HasOne,              'active_record/associations/builder/has_one'
      autoload :HasMany,             'active_record/associations/builder/has_many'
      autoload :HasAndBelongsToMany, 'active_record/associations/builder/has_and_belongs_to_many'
    end

    eager_autoload do
      autoload :Preloader,        'active_record/associations/preloader'
      autoload :JoinDependency,   'active_record/associations/join_dependency'
      autoload :AssociationScope, 'active_record/associations/association_scope'
      autoload :AliasTracker,     'active_record/associations/alias_tracker'
      autoload :JoinHelper,       'active_record/associations/join_helper'
    end

    # Clears out the association cache.
    def clear_association_cache #:nodoc:
      @association_cache.clear if persisted?
    end

    # :nodoc:
    attr_reader :association_cache

    # Returns the association instance for the given name, instantiating it if it doesn't already exist
    def association(name) #:nodoc:
      association = association_instance_get(name)

      if association.nil?
        reflection  = self.class.reflect_on_association(name)
        association = reflection.association_class.new(self, reflection)
        association_instance_set(name, association)
      end

      association
    end

    private
      # Returns the specified association instance if it responds to :loaded?, nil otherwise.
      def association_instance_get(name)
        @association_cache[name.to_sym]
      end

      # Set the specified association instance.
      def association_instance_set(name, association)
        @association_cache[name] = association
      end

    # Associations are a set of macro-like class methods for tying objects together through
    # foreign keys. They express relationships like "Project has one Project Manager"
    # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
    # class which are specialized according to the collection or association symbol and the
    # options hash. It works much the same way as Ruby's own <tt>attr*</tt>
    # methods.
    #
    #   class Project < ActiveRecord::Base
    #     belongs_to              :portfolio
    #     has_one                 :project_manager
    #     has_many                :milestones
    #     has_and_belongs_to_many :categories
    #   end
    #
    # The project class now has the following methods (and more) to ease the traversal and
    # manipulation of its relationships:
    # * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
    # * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
    # * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
    #   <tt>Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id),</tt>
    #   <tt>Project#milestones.build, Project#milestones.create</tt>
    # * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt>
    #   <tt>Project#categories.delete(category1), Project#categories.destroy(category1)</tt>
    #
    # === A word of warning
    #
    # Don't create associations that have the same name as instance methods of
    # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
    # its model, it will override the inherited method and break things.
    # For instance, +attributes+ and +connection+ would be bad choices for association names.
    #
    # == Auto-generated methods
    #
    # === Singular associations (one-to-one)
    #                                     |            |  belongs_to  |
    #   generated methods                 | belongs_to | :polymorphic | has_one
    #   ----------------------------------+------------+--------------+---------
    #   other                             |     X      |      X       |    X
    #   other=(other)                     |     X      |      X       |    X
    #   build_other(attributes={})        |     X      |              |    X
    #   create_other(attributes={})       |     X      |              |    X
    #   create_other!(attributes={})      |     X      |              |    X
    #
    # ===Collection associations (one-to-many / many-to-many)
    #                                     |       |          | has_many
    #   generated methods                 | habtm | has_many | :through
    #   ----------------------------------+-------+----------+----------
    #   others                            |   X   |    X     |    X
    #   others=(other,other,...)          |   X   |    X     |    X
    #   other_ids                         |   X   |    X     |    X
    #   other_ids=(id,id,...)             |   X   |    X     |    X
    #   others<<                          |   X   |    X     |    X
    #   others.push                       |   X   |    X     |    X
    #   others.concat                     |   X   |    X     |    X
    #   others.build(attributes={})       |   X   |    X     |    X
    #   others.create(attributes={})      |   X   |    X     |    X
    #   others.create!(attributes={})     |   X   |    X     |    X
    #   others.size                       |   X   |    X     |    X
    #   others.length                     |   X   |    X     |    X
    #   others.count                      |   X   |    X     |    X
    #   others.sum(*args)                 |   X   |    X     |    X
    #   others.empty?                     |   X   |    X     |    X
    #   others.clear                      |   X   |    X     |    X
    #   others.delete(other,other,...)    |   X   |    X     |    X
    #   others.delete_all                 |   X   |    X     |    X
    #   others.destroy(other,other,...)   |   X   |    X     |    X
    #   others.destroy_all                |   X   |    X     |    X
    #   others.find(*args)                |   X   |    X     |    X
    #   others.exists?                    |   X   |    X     |    X
    #   others.uniq                       |   X   |    X     |    X
    #   others.reset                      |   X   |    X     |    X
    #
    # === Overriding generated methods
    #
    # Association methods are generated in a module that is included into the model class,
    # which allows you to easily override with your own methods and call the original
    # generated method with +super+. For example:
    #
    #   class Car < ActiveRecord::Base
    #     belongs_to :owner
    #     belongs_to :old_owner
    #     def owner=(new_owner)
    #       self.old_owner = self.owner
    #       super
    #     end
    #   end
    #
    # If your model class is <tt>Project</tt>, the module is
    # named <tt>Project::GeneratedFeatureMethods</tt>. The GeneratedFeatureMethods module is
    # included in the model class immediately after the (anonymous) generated attributes methods
    # module, meaning an association will override the methods for an attribute with the same name.
    #
    # == Cardinality and associations
    #
    # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
    # relationships between models. Each model uses an association to describe its role in
    # the relation. The +belongs_to+ association is always used in the model that has
    # the foreign key.
    #
    # === One-to-one
    #
    # Use +has_one+ in the base, and +belongs_to+ in the associated model.
    #
    #   class Employee < ActiveRecord::Base
    #     has_one :office
    #   end
    #   class Office < ActiveRecord::Base
    #     belongs_to :employee    # foreign key - employee_id
    #   end
    #
    # === One-to-many
    #
    # Use +has_many+ in the base, and +belongs_to+ in the associated model.
    #
    #   class Manager < ActiveRecord::Base
    #     has_many :employees
    #   end
    #   class Employee < ActiveRecord::Base
    #     belongs_to :manager     # foreign key - manager_id
    #   end
    #
    # === Many-to-many
    #
    # There are two ways to build a many-to-many relationship.
    #
    # The first way uses a +has_many+ association with the <tt>:through</tt> option and a join model, so
    # there are two stages of associations.
    #
    #   class Assignment < ActiveRecord::Base
    #     belongs_to :programmer  # foreign key - programmer_id
    #     belongs_to :project     # foreign key - project_id
    #   end
    #   class Programmer < ActiveRecord::Base
    #     has_many :assignments
    #     has_many :projects, through: :assignments
    #   end
    #   class Project < ActiveRecord::Base
    #     has_many :assignments
    #     has_many :programmers, through: :assignments
    #   end
    #
    # For the second way, use +has_and_belongs_to_many+ in both models. This requires a join table
    # that has no corresponding model or primary key.
    #
    #   class Programmer < ActiveRecord::Base
    #     has_and_belongs_to_many :projects       # foreign keys in the join table
    #   end
    #   class Project < ActiveRecord::Base
    #     has_and_belongs_to_many :programmers    # foreign keys in the join table
    #   end
    #
    # Choosing which way to build a many-to-many relationship is not always simple.
    # If you need to work with the relationship model as its own entity,
    # use <tt>has_many :through</tt>. Use +has_and_belongs_to_many+ when working with legacy schemas or when
    # you never work directly with the relationship itself.
    #
    # == Is it a +belongs_to+ or +has_one+ association?
    #
    # Both express a 1-1 relationship. The difference is mostly where to place the foreign
    # key, which goes on the table for the class declaring the +belongs_to+ relationship.
    #
    #   class User < ActiveRecord::Base
    #     # I reference an account.
    #     belongs_to :account
    #   end
    #
    #   class Account < ActiveRecord::Base
    #     # One user references me.
    #     has_one :user
    #   end
    #
    # The tables for these classes could look something like:
    #
    #   CREATE TABLE users (
    #     id int(11) NOT NULL auto_increment,
    #     account_id int(11) default NULL,
    #     name varchar default NULL,
    #     PRIMARY KEY  (id)
    #   )
    #
    #   CREATE TABLE accounts (
    #     id int(11) NOT NULL auto_increment,
    #     name varchar default NULL,
    #     PRIMARY KEY  (id)
    #   )
    #
    # == Unsaved objects and associations
    #
    # You can manipulate objects and associations before they are saved to the database, but
    # there is some special behavior you should be aware of, mostly involving the saving of
    # associated objects.
    #
    # You can set the :autosave option on a <tt>has_one</tt>, <tt>belongs_to</tt>,
    # <tt>has_many</tt>, or <tt>has_and_belongs_to_many</tt> association. Setting it
    # to +true+ will _always_ save the members, whereas setting it to +false+ will
    # _never_ save the members. More details about :autosave option is available at
    # autosave_association.rb .
    #
    # === One-to-one associations
    #
    # * Assigning an object to a +has_one+ association automatically saves that object and
    #   the object being replaced (if there is one), in order to update their foreign
    #   keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
    # * If either of these saves fail (due to one of the objects being invalid), an
    #   <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
    #   cancelled.
    # * If you wish to assign an object to a +has_one+ association without saving it,
    #   use the <tt>build_association</tt> method (documented below). The object being
    #   replaced will still be saved to update its foreign key.
    # * Assigning an object to a +belongs_to+ association does not save the object, since
    #   the foreign key field belongs on the parent. It does not save the parent either.
    #
    # === Collections
    #
    # * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
    #   saves that object, except if the parent object (the owner of the collection) is not yet
    #   stored in the database.
    # * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
    #   fails, then <tt>push</tt> returns +false+.
    # * If saving fails while replacing the collection (via <tt>association=</tt>), an
    #   <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
    #   cancelled.
    # * You can add an object to a collection without automatically saving it by using the
    #   <tt>collection.build</tt> method (documented below).
    # * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
    #   saved when the parent is saved.
    #
    # == Customizing the query
    #
    # Associations are built from <tt>Relation</tt>s, and you can use the <tt>Relation</tt> syntax
    # to customize them. For example, to add a condition:
    #
    #   class Blog < ActiveRecord::Base
    #     has_many :published_posts, -> { where published: true }, class_name: 'Post'
    #   end
    #
    # Inside the <tt>-> { ... }</tt> block you can use all of the usual <tt>Relation</tt> methods.
    #
    # === Accessing the owner object
    #
    # Sometimes it is useful to have access to the owner object when building the query. The owner
    # is passed as a parameter to the block. For example, the following association would find all
    # events that occur on the user's birthday:
    #
    #   class User < ActiveRecord::Base
    #     has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: 'Event'
    #   end
    #
    # == Association callbacks
    #
    # Similar to the normal callbacks that hook into the life cycle of an Active Record object,
    # you can also define callbacks that get triggered when you add an object to or remove an
    # object from an association collection.
    #
    #   class Project
    #     has_and_belongs_to_many :developers, after_add: :evaluate_velocity
    #
    #     def evaluate_velocity(developer)
    #       ...
    #     end
    #   end
    #
    # It's possible to stack callbacks by passing them as an array. Example:
    #
    #   class Project
    #     has_and_belongs_to_many :developers,
    #                             after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
    #   end
    #
    # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
    #
    # Should any of the +before_add+ callbacks throw an exception, the object does not get
    # added to the collection. Same with the +before_remove+ callbacks; if an exception is
    # thrown the object doesn't get removed.
    #
    # == Association extensions
    #
    # The proxy objects that control the access to associations can be extended through anonymous
    # modules. This is especially beneficial for adding new finders, creators, and other
    # factory-type methods that are only used as part of this association.
    #
    #   class Account < ActiveRecord::Base
    #     has_many :people do
    #       def find_or_create_by_name(name)
    #         first_name, last_name = name.split(" ", 2)
    #         find_or_create_by(first_name: first_name, last_name: last_name)
    #       end
    #     end
    #   end
    #
    #   person = Account.first.people.find_or_create_by_name("David Heinemeier Hansson")
    #   person.first_name # => "David"
    #   person.last_name  # => "Heinemeier Hansson"
    #
    # If you need to share the same extensions between many associations, you can use a named
    # extension module.
    #
    #   module FindOrCreateByNameExtension
    #     def find_or_create_by_name(name)
    #       first_name, last_name = name.split(" ", 2)
    #       find_or_create_by(first_name: first_name, last_name: last_name)
    #     end
    #   end
    #
    #   class Account < ActiveRecord::Base
    #     has_many :people, -> { extending FindOrCreateByNameExtension }
    #   end
    #
    #   class Company < ActiveRecord::Base
    #     has_many :people, -> { extending FindOrCreateByNameExtension }
    #   end
    #
    # Some extensions can only be made to work with knowledge of the association's internals.
    # Extensions can access relevant state using the following methods (where +items+ is the
    # name of the association):
    #
    # * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
    # * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
    # * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
    #   the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
    #
    # However, inside the actual extension code, you will not have access to the <tt>record</tt> as
    # above. In this case, you can access <tt>proxy_association</tt>. For example,
    # <tt>record.association(:items)</tt> and <tt>record.items.proxy_association</tt> will return
    # the same object, allowing you to make calls like <tt>proxy_association.owner</tt> inside
    # association extensions.
    #
    # == Association Join Models
    #
    # Has Many associations can be configured with the <tt>:through</tt> option to use an
    # explicit join model to retrieve the data. This operates similarly to a
    # +has_and_belongs_to_many+ association. The advantage is that you're able to add validations,
    # callbacks, and extra attributes on the join model. Consider the following schema:
    #
    #   class Author < ActiveRecord::Base
    #     has_many :authorships
    #     has_many :books, through: :authorships
    #   end
    #
    #   class Authorship < ActiveRecord::Base
    #     belongs_to :author
    #     belongs_to :book
    #   end
    #
    #   @author = Author.first
    #   @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
    #   @author.books                              # selects all books by using the Authorship join model
    #
    # You can also go through a +has_many+ association on the join model:
    #
    #   class Firm < ActiveRecord::Base
    #     has_many   :clients
    #     has_many   :invoices, through: :clients
    #   end
    #
    #   class Client < ActiveRecord::Base
    #     belongs_to :firm
    #     has_many   :invoices
    #   end
    #
    #   class Invoice < ActiveRecord::Base
    #     belongs_to :client
    #   end
    #
    #   @firm = Firm.first
    #   @firm.clients.collect { |c| c.invoices }.flatten # select all invoices for all clients of the firm
    #   @firm.invoices                                   # selects all invoices by going through the Client join model
    #
    # Similarly you can go through a +has_one+ association on the join model:
    #
    #   class Group < ActiveRecord::Base
    #     has_many   :users
    #     has_many   :avatars, through: :users
    #   end
    #
    #   class User < ActiveRecord::Base
    #     belongs_to :group
    #     has_one    :avatar
    #   end
    #
    #   class Avatar < ActiveRecord::Base
    #     belongs_to :user
    #   end
    #
    #   @group = Group.first
    #   @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
    #   @group.avatars                                # selects all avatars by going through the User join model.
    #
    # An important caveat with going through +has_one+ or +has_many+ associations on the
    # join model is that these associations are *read-only*. For example, the following
    # would not work following the previous example:
    #
    #   @group.avatars << Avatar.new   # this would work if User belonged_to Avatar rather than the other way around
    #   @group.avatars.delete(@group.avatars.last)  # so would this
    #
    # If you are using a +belongs_to+ on the join model, it is a good idea to set the
    # <tt>:inverse_of</tt> option on the +belongs_to+, which will mean that the following example
    # works correctly (where <tt>tags</tt> is a +has_many+ <tt>:through</tt> association):
    #
    #   @post = Post.first
    #   @tag = @post.tags.build name: "ruby"
    #   @tag.save
    #
    # The last line ought to save the through record (a <tt>Taggable</tt>). This will only work if the
    # <tt>:inverse_of</tt> is set:
    #
    #   class Taggable < ActiveRecord::Base
    #     belongs_to :post
    #     belongs_to :tag, inverse_of: :taggings
    #   end
    #
    # == Nested Associations
    #
    # You can actually specify *any* association with the <tt>:through</tt> option, including an
    # association which has a <tt>:through</tt> option itself. For example:
    #
    #   class Author < ActiveRecord::Base
    #     has_many :posts
    #     has_many :comments, through: :posts
    #     has_many :commenters, through: :comments
    #   end
    #
    #   class Post < ActiveRecord::Base
    #     has_many :comments
    #   end
    #
    #   class Comment < ActiveRecord::Base
    #     belongs_to :commenter
    #   end
    #
    #   @author = Author.first
    #   @author.commenters # => People who commented on posts written by the author
    #
    # An equivalent way of setting up this association this would be:
    #
    #   class Author < ActiveRecord::Base
    #     has_many :posts
    #     has_many :commenters, through: :posts
    #   end
    #
    #   class Post < ActiveRecord::Base
    #     has_many :comments
    #     has_many :commenters, through: :comments
    #   end
    #
    #   class Comment < ActiveRecord::Base
    #     belongs_to :commenter
    #   end
    #
    # When using nested association, you will not be able to modify the association because there
    # is not enough information to know what modification to make. For example, if you tried to
    # add a <tt>Commenter</tt> in the example above, there would be no way to tell how to set up the
    # intermediate <tt>Post</tt> and <tt>Comment</tt> objects.
    #
    # == Polymorphic Associations
    #
    # Polymorphic associations on models are not restricted on what types of models they
    # can be associated with. Rather, they specify an interface that a +has_many+ association
    # must adhere to.
    #
    #   class Asset < ActiveRecord::Base
    #     belongs_to :attachable, polymorphic: true
    #   end
    #
    #   class Post < ActiveRecord::Base
    #     has_many :assets, as: :attachable         # The :as option specifies the polymorphic interface to use.
    #   end
    #
    #   @asset.attachable = @post
    #
    # This works by using a type column in addition to a foreign key to specify the associated
    # record. In the Asset example, you'd need an +attachable_id+ integer column and an
    # +attachable_type+ string column.
    #
    # Using polymorphic associations in combination with single table inheritance (STI) is
    # a little tricky. In order for the associations to work as expected, ensure that you
    # store the base model for the STI models in the type column of the polymorphic
    # association. To continue with the asset example above, suppose there are guest posts
    # and member posts that use the posts table for STI. In this case, there must be a +type+
    # column in the posts table.
    #
    #   class Asset < ActiveRecord::Base
    #     belongs_to :attachable, polymorphic: true
    #
    #     def attachable_type=(sType)
    #        super(sType.to_s.classify.constantize.base_class.to_s)
    #     end
    #   end
    #
    #   class Post < ActiveRecord::Base
    #     # because we store "Post" in attachable_type now dependent: :destroy will work
    #     has_many :assets, as: :attachable, dependent: :destroy
    #   end
    #
    #   class GuestPost < Post
    #   end
    #
    #   class MemberPost < Post
    #   end
    #
    # == Caching
    #
    # All of the methods are built on a simple caching principle that will keep the result
    # of the last query around unless specifically instructed not to. The cache is even
    # shared across methods to make it even cheaper to use the macro-added methods without
    # worrying too much about performance at the first go.
    #
    #   project.milestones             # fetches milestones from the database
    #   project.milestones.size        # uses the milestone cache
    #   project.milestones.empty?      # uses the milestone cache
    #   project.milestones(true).size  # fetches milestones from the database
    #   project.milestones             # uses the milestone cache
    #
    # == Eager loading of associations
    #
    # Eager loading is a way to find objects of a certain class and a number of named associations.
    # This is one of the easiest ways of to prevent the dreaded 1+N problem in which fetching 100
    # posts that each need to display their author triggers 101 database queries. Through the
    # use of eager loading, the 101 queries can be reduced to 2.
    #
    #   class Post < ActiveRecord::Base
    #     belongs_to :author
    #     has_many   :comments
    #   end
    #
    # Consider the following loop using the class above:
    #
    #   Post.all.each do |post|
    #     puts "Post:            " + post.title
    #     puts "Written by:      " + post.author.name
    #     puts "Last comment on: " + post.comments.first.created_on
    #   end
    #
    # To iterate over these one hundred posts, we'll generate 201 database queries. Let's
    # first just optimize it for retrieving the author:
    #
    #   Post.includes(:author).each do |post|
    #
    # This references the name of the +belongs_to+ association that also used the <tt>:author</tt>
    # symbol. After loading the posts, find will collect the +author_id+ from each one and load
    # all the referenced authors with one query. Doing so will cut down the number of queries
    # from 201 to 102.
    #
    # We can improve upon the situation further by referencing both associations in the finder with:
    #
    #   Post.includes(:author, :comments).each do |post|
    #
    # This will load all comments with a single query. This reduces the total number of queries
    # to 3. More generally the number of queries will be 1 plus the number of associations
    # named (except if some of the associations are polymorphic +belongs_to+ - see below).
    #
    # To include a deep hierarchy of associations, use a hash:
    #
    #   Post.includes(:author, {comments: {author: :gravatar}}).each do |post|
    #
    # That'll grab not only all the comments but all their authors and gravatar pictures.
    # You can mix and match symbols, arrays and hashes in any combination to describe the
    # associations you want to load.
    #
    # All of this power shouldn't fool you into thinking that you can pull out huge amounts
    # of data with no performance penalty just because you've reduced the number of queries.
    # The database still needs to send all the data to Active Record and it still needs to
    # be processed. So it's no catch-all for performance problems, but it's a great way to
    # cut down on the number of queries in a situation as the one described above.
    #
    # Since only one table is loaded at a time, conditions or orders cannot reference tables
    # other than the main one. If this is the case Active Record falls back to the previously
    # used LEFT OUTER JOIN based strategy. For example
    #
    #   Post.includes([:author, :comments]).where(['comments.approved = ?', true])
    #
    # This will result in a single SQL query with joins along the lines of:
    # <tt>LEFT OUTER JOIN comments ON comments.post_id = posts.id</tt> and
    # <tt>LEFT OUTER JOIN authors ON authors.id = posts.author_id</tt>. Note that using conditions
    # like this can have unintended consequences.
    # In the above example posts with no approved comments are not returned at all, because
    # the conditions apply to the SQL statement as a whole and not just to the association.
    # You must disambiguate column references for this fallback to happen, for example
    # <tt>order: "author.name DESC"</tt> will work but <tt>order: "name DESC"</tt> will not.
    #
    # If you do want eager load only some members of an association it is usually more natural
    # to include an association which has conditions defined on it:
    #
    #   class Post < ActiveRecord::Base
    #     has_many :approved_comments, -> { where approved: true }, class_name: 'Comment'
    #   end
    #
    #   Post.includes(:approved_comments)
    #
    # This will load posts and eager load the +approved_comments+ association, which contains
    # only those comments that have been approved.
    #
    # If you eager load an association with a specified <tt>:limit</tt> option, it will be ignored,
    # returning all the associated objects:
    #
    #   class Picture < ActiveRecord::Base
    #     has_many :most_recent_comments, -> { order('id DESC').limit(10) }, class_name: 'Comment'
    #   end
    #
    #   Picture.includes(:most_recent_comments).first.most_recent_comments # => returns all associated comments.
    #
    # Eager loading is supported with polymorphic associations.
    #
    #   class Address < ActiveRecord::Base
    #     belongs_to :addressable, polymorphic: true
    #   end
    #
    # A call that tries to eager load the addressable model
    #
    #   Address.includes(:addressable)
    #
    # This will execute one query to load the addresses and load the addressables with one
    # query per addressable type.
    # For example if all the addressables are either of class Person or Company then a total
    # of 3 queries will be executed. The list of addressable types to load is determined on
    # the back of the addresses loaded. This is not supported if Active Record has to fallback
    # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
    # The reason is that the parent model's type is a column value so its corresponding table
    # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
    #
    # == Table Aliasing
    #
    # Active Record uses table aliasing in the case that a table is referenced multiple times
    # in a join. If a table is referenced only once, the standard table name is used. The
    # second time, the table is aliased as <tt>#{reflection_name}_#{parent_table_name}</tt>.
    # Indexes are appended for any more successive uses of the table name.
    #
    #   Post.joins(:comments)
    #   # => SELECT ... FROM posts INNER JOIN comments ON ...
    #   Post.joins(:special_comments) # STI
    #   # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
    #   Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
    #   # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
    #
    # Acts as tree example:
    #
    #   TreeMixin.joins(:children)
    #   # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
    #   TreeMixin.joins(children: :parent)
    #   # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
    #                               INNER JOIN parents_mixins ...
    #   TreeMixin.joins(children: {parent: :children})
    #   # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
    #                               INNER JOIN parents_mixins ...
    #                               INNER JOIN mixins childrens_mixins_2
    #
    # Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
    #
    #   Post.joins(:categories)
    #   # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
    #   Post.joins(categories: :posts)
    #   # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
    #                              INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
    #   Post.joins(categories: {posts: :categories})
    #   # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
    #                              INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
    #                              INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
    #
    # If you wish to specify your own custom joins using <tt>joins</tt> method, those table
    # names will take precedence over the eager associations:
    #
    #   Post.joins(:comments).joins("inner join comments ...")
    #   # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
    #   Post.joins(:comments, :special_comments).joins("inner join comments ...")
    #   # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
    #                              INNER JOIN comments special_comments_posts ...
    #                              INNER JOIN comments ...
    #
    # Table aliases are automatically truncated according to the maximum length of table identifiers
    # according to the specific database.
    #
    # == Modules
    #
    # By default, associations will look for objects within the current module scope. Consider:
    #
    #   module MyApplication
    #     module Business
    #       class Firm < ActiveRecord::Base
    #         has_many :clients
    #       end
    #
    #       class Client < ActiveRecord::Base; end
    #     end
    #   end
    #
    # When <tt>Firm#clients</tt> is called, it will in turn call
    # <tt>MyApplication::Business::Client.find_all_by_firm_id(firm.id)</tt>.
    # If you want to associate with a class in another module scope, this can be done by
    # specifying the complete class name.
    #
    #   module MyApplication
    #     module Business
    #       class Firm < ActiveRecord::Base; end
    #     end
    #
    #     module Billing
    #       class Account < ActiveRecord::Base
    #         belongs_to :firm, class_name: "MyApplication::Business::Firm"
    #       end
    #     end
    #   end
    #
    # == Bi-directional associations
    #
    # When you specify an association there is usually an association on the associated model
    # that specifies the same relationship in reverse. For example, with the following models:
    #
    #    class Dungeon < ActiveRecord::Base
    #      has_many :traps
    #      has_one :evil_wizard
    #    end
    #
    #    class Trap < ActiveRecord::Base
    #      belongs_to :dungeon
    #    end
    #
    #    class EvilWizard < ActiveRecord::Base
    #      belongs_to :dungeon
    #    end
    #
    # The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
    # the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
    # is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
    # Active Record doesn't know anything about these inverse relationships and so no object
    # loading optimization is possible. For example:
    #
    #    d = Dungeon.first
    #    t = d.traps.first
    #    d.level == t.dungeon.level # => true
    #    d.level = 10
    #    d.level == t.dungeon.level # => false
    #
    # The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
    # the same object data from the database, but are actually different in-memory copies
    # of that data. Specifying the <tt>:inverse_of</tt> option on associations lets you tell
    # Active Record about inverse relationships and it will optimise object loading. For
    # example, if we changed our model definitions to:
    #
    #    class Dungeon < ActiveRecord::Base
    #      has_many :traps, inverse_of: :dungeon
    #      has_one :evil_wizard, inverse_of: :dungeon
    #    end
    #
    #    class Trap < ActiveRecord::Base
    #      belongs_to :dungeon, inverse_of: :traps
    #    end
    #
    #    class EvilWizard < ActiveRecord::Base
    #      belongs_to :dungeon, inverse_of: :evil_wizard
    #    end
    #
    # Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
    # in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
    #
    # There are limitations to <tt>:inverse_of</tt> support:
    #
    # * does not work with <tt>:through</tt> associations.
    # * does not work with <tt>:polymorphic</tt> associations.
    # * for +belongs_to+ associations +has_many+ inverse associations are ignored.
    #
    # == Deleting from associations
    #
    # === Dependent associations
    #
    # +has_many+, +has_one+ and +belongs_to+ associations support the <tt>:dependent</tt> option.
    # This allows you to specify that associated records should be deleted when the owner is
    # deleted.
    #
    # For example:
    #
    #     class Author
    #       has_many :posts, dependent: :destroy
    #     end
    #     Author.find(1).destroy # => Will destroy all of the author's posts, too
    #
    # The <tt>:dependent</tt> option can have different values which specify how the deletion
    # is done. For more information, see the documentation for this option on the different
    # specific association types. When no option is given, the behavior is to do nothing
    # with the associated records when destroying a record.
    #
    # Note that <tt>:dependent</tt> is implemented using Rails' callback
    # system, which works by processing callbacks in order. Therefore, other
    # callbacks declared either before or after the <tt>:dependent</tt> option
    # can affect what it does.
    #
    # === Delete or destroy?
    #
    # +has_many+ and +has_and_belongs_to_many+ associations have the methods <tt>destroy</tt>,
    # <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>.
    #
    # For +has_and_belongs_to_many+, <tt>delete</tt> and <tt>destroy</tt> are the same: they
    # cause the records in the join table to be removed.
    #
    # For +has_many+, <tt>destroy</tt> will always call the <tt>destroy</tt> method of the
    # record(s) being removed so that callbacks are run. However <tt>delete</tt> will either
    # do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
    # if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
    # The default strategy is <tt>:nullify</tt> (set the foreign keys to <tt>nil</tt>), except for
    # +has_many+ <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
    # the join records, without running their callbacks).
    #
    # There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that
    # it returns the association rather than the records which have been deleted.
    #
    # === What gets deleted?
    #
    # There is a potential pitfall here: +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>
    # associations have records in join tables, as well as the associated records. So when we
    # call one of these deletion methods, what exactly should be deleted?
    #
    # The answer is that it is assumed that deletion on an association is about removing the
    # <i>link</i> between the owner and the associated object(s), rather than necessarily the
    # associated objects themselves. So with +has_and_belongs_to_many+ and +has_many+
    # <tt>:through</tt>, the join records will be deleted, but the associated records won't.
    #
    # This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by_name('food'))</tt>
    # you would want the 'food' tag to be unlinked from the post, rather than for the tag itself
    # to be removed from the database.
    #
    # However, there are examples where this strategy doesn't make sense. For example, suppose
    # a person has many projects, and each project has many tasks. If we deleted one of a person's
    # tasks, we would probably not want the project to be deleted. In this scenario, the delete method
    # won't actually work: it can only be used if the association on the join model is a
    # +belongs_to+. In other situations you are expected to perform operations directly on
    # either the associated records or the <tt>:through</tt> association.
    #
    # With a regular +has_many+ there is no distinction between the "associated records"
    # and the "link", so there is only one choice for what gets deleted.
    #
    # With +has_and_belongs_to_many+ and +has_many+ <tt>:through</tt>, if you want to delete the
    # associated records themselves, you can always do something along the lines of
    # <tt>person.tasks.each(&:destroy)</tt>.
    #
    # == Type safety with <tt>ActiveRecord::AssociationTypeMismatch</tt>
    #
    # If you attempt to assign an object to an association that doesn't match the inferred
    # or specified <tt>:class_name</tt>, you'll get an <tt>ActiveRecord::AssociationTypeMismatch</tt>.
    #
    # == Options
    #
    # All of the association macros can be specialized through options. This makes cases
    # more complex than the simple and guessable ones possible.
    module ClassMethods
      # Specifies a one-to-many association. The following methods for retrieval and query of
      # collections of associated objects will be added:
      #
      # [collection(force_reload = false)]
      #   Returns an array of all the associated objects.
      #   An empty array is returned if none are found.
      # [collection<<(object, ...)]
      #   Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
      #   Note that this operation instantly fires update sql without waiting for the save or update call on the
      #   parent object.
      # [collection.delete(object, ...)]
      #   Removes one or more objects from the collection by setting their foreign keys to +NULL+.
      #   Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
      #   and deleted if they're associated with <tt>dependent: :delete_all</tt>.
      #
      #   If the <tt>:through</tt> option is used, then the join records are deleted (rather than
      #   nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
      #   <tt>dependent: :nullify</tt> to override this.
      # [collection.destroy(object, ...)]
      #   Removes one or more objects from the collection by running <tt>destroy</tt> on
      #   each record, regardless of any dependent option, ensuring callbacks are run.
      #
      #   If the <tt>:through</tt> option is used, then the join records are destroyed
      #   instead, not the objects themselves.
      # [collection=objects]
      #   Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
      #   option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
      #   direct.
      # [collection_singular_ids]
      #   Returns an array of the associated objects' ids
      # [collection_singular_ids=ids]
      #   Replace the collection with the objects identified by the primary keys in +ids+. This
      #   method loads the models and calls <tt>collection=</tt>. See above.
      # [collection.clear]
      #   Removes every object from the collection. This destroys the associated objects if they
      #   are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
      #   database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
      #   If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
      #   Join models are directly deleted.
      # [collection.empty?]
      #   Returns +true+ if there are no associated objects.
      # [collection.size]
      #   Returns the number of associated objects.
      # [collection.find(...)]
      #   Finds an associated object according to the same rules as ActiveRecord::Base.find.
      # [collection.exists?(...)]
      #   Checks whether an associated object with the given conditions exists.
      #   Uses the same rules as ActiveRecord::Base.exists?.
      # [collection.build(attributes = {}, ...)]
      #   Returns one or more new objects of the collection type that have been instantiated
      #   with +attributes+ and linked to this object through a foreign key, but have not yet
      #   been saved.
      # [collection.create(attributes = {})]
      #   Returns a new object of the collection type that has been instantiated
      #   with +attributes+, linked to this object through a foreign key, and that has already
      #   been saved (if it passed the validation). *Note*: This only works if the base model
      #   already exists in the DB, not if it is a new (unsaved) record!
      #
      # (*Note*: +collection+ is replaced with the symbol passed as the first argument, so
      # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.)
      #
      # === Example
      #
      # Example: A Firm class declares <tt>has_many :clients</tt>, which will add:
      # * <tt>Firm#clients</tt> (similar to <tt>Client.where(firm_id: id)</tt>)
      # * <tt>Firm#clients<<</tt>
      # * <tt>Firm#clients.delete</tt>
      # * <tt>Firm#clients.destroy</tt>
      # * <tt>Firm#clients=</tt>
      # * <tt>Firm#client_ids</tt>
      # * <tt>Firm#client_ids=</tt>
      # * <tt>Firm#clients.clear</tt>
      # * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>)
      # * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
      # * <tt>Firm#clients.find</tt> (similar to <tt>Client.where(firm_id: id).find(id)</tt>)
      # * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
      # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new("firm_id" => id)</tt>)
      # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new("firm_id" => id); c.save; c</tt>)
      # The declaration can also include an options hash to specialize the behavior of the association.
      #
      # === Options
      # [:class_name]
      #   Specify the class name of the association. Use it only if that name can't be inferred
      #   from the association name. So <tt>has_many :products</tt> will by default be linked
      #   to the Product class, but if the real class name is SpecialProduct, you'll have to
      #   specify it with this option.
      # [:foreign_key]
      #   Specify the foreign key used for the association. By default this is guessed to be the name
      #   of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_many+
      #   association will use "person_id" as the default <tt>:foreign_key</tt>.
      # [:primary_key]
      #   Specify the method that returns the primary key used for the association. By default this is +id+.
      # [:dependent]
      #   Controls what happens to the associated objects when
      #   their owner is destroyed. Note that these are implemented as
      #   callbacks, and Rails executes callbacks in order. Therefore, other
      #   similar callbacks may affect the :dependent behavior, and the
      #   :dependent behavior may affect other callbacks.
      #
      #   * <tt>:destroy</tt> causes all the associated objects to also be destroyed
      #   * <tt>:delete_all</tt> causes all the asssociated objects to be deleted directly from the database (so callbacks will not execute)
      #   * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Callbacks are not executed.
      #   * <tt>:restrict_with_exception</tt> causes an exception to be raised if there are any associated records
      #   * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects
      #
      #   If using with the <tt>:through</tt> option, the association on the join model must be
      #   a +belongs_to+, and the records which get deleted are the join records, rather than
      #   the associated records.
      # [:counter_cache]
      #   This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
      #   when you customized the name of your <tt>:counter_cache</tt> on the <tt>belongs_to</tt> association.
      # [:as]
      #   Specifies a polymorphic interface (See <tt>belongs_to</tt>).
      # [:through]
      #   Specifies an association through which to perform the query. This can be any other type
      #   of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
      #   <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
      #   source reflection.
      #
      #   If the association on the join model is a +belongs_to+, the collection can be modified
      #   and the records on the <tt>:through</tt> model will be automatically created and removed
      #   as appropriate. Otherwise, the collection is read-only, so you should manipulate the
      #   <tt>:through</tt> association directly.
      #
      #   If you are going to modify the association (rather than just read from it), then it is
      #   a good idea to set the <tt>:inverse_of</tt> option on the source association on the
      #   join model. This allows associated records to be built which will automatically create
      #   the appropriate join model records when they are saved. (See the 'Association Join Models'
      #   section above.)
      # [:source]
      #   Specifies the source association name used by <tt>has_many :through</tt> queries.
      #   Only use it if the name cannot be inferred from the association.
      #   <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
      #   <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
      # [:source_type]
      #   Specifies type of the source association used by <tt>has_many :through</tt> queries where the source
      #   association is a polymorphic +belongs_to+.
      # [:validate]
      #   If +false+, don't validate the associated objects when saving the parent object. true by default.
      # [:autosave]
      #   If true, always save the associated objects or destroy them if marked for destruction,
      #   when saving the parent object. If false, never save or destroy the associated objects.
      #   By default, only save associated objects that are new records. This option is implemented as a
      #   before_save callback. Because callbacks are run in the order they are defined, associated objects
      #   may need to be explicitly saved in any user-defined before_save callbacks.
      #
      #   Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
      # [:inverse_of]
      #   Specifies the name of the <tt>belongs_to</tt> association on the associated object
      #   that is the inverse of this <tt>has_many</tt> association. Does not work in combination
      #   with <tt>:through</tt> or <tt>:as</tt> options.
      #   See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
      #
      # Option examples:
      #   has_many :comments, -> { order "posted_on" }
      #   has_many :comments, -> { includes :author }
      #   has_many :people, -> { where("deleted = 0").order("name") }, class_name: "Person"
      #   has_many :tracks, -> { order "position" }, dependent: :destroy
      #   has_many :comments, dependent: :nullify
      #   has_many :tags, as: :taggable
      #   has_many :reports, -> { readonly }
      #   has_many :subscribers, through: :subscriptions, source: :user
      def has_many(name, scope = nil, options = {}, &extension)
        Builder::HasMany.build(self, name, scope, options, &extension)
      end

      # Specifies a one-to-one association with another class. This method should only be used
      # if the other class contains the foreign key. If the current class contains the foreign key,
      # then you should use +belongs_to+ instead. See also ActiveRecord::Associations::ClassMethods's overview
      # on when to use has_one and when to use belongs_to.
      #
      # The following methods for retrieval and query of a single associated object will be added:
      #
      # [association(force_reload = false)]
      #   Returns the associated object. +nil+ is returned if none is found.
      # [association=(associate)]
      #   Assigns the associate object, extracts the primary key, sets it as the foreign key,
      #   and saves the associate object.
      # [build_association(attributes = {})]
      #   Returns a new object of the associated type that has been instantiated
      #   with +attributes+ and linked to this object through a foreign key, but has not
      #   yet been saved.
      # [create_association(attributes = {})]
      #   Returns a new object of the associated type that has been instantiated
      #   with +attributes+, linked to this object through a foreign key, and that
      #   has already been saved (if it passed the validation).
      # [create_association!(attributes = {})]
      #   Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
      #   if the record is invalid.
      #
      # (+association+ is replaced with the symbol passed as the first argument, so
      # <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.)
      #
      # === Example
      #
      # An Account class declares <tt>has_one :beneficiary</tt>, which will add:
      # * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.where(account_id: id).first</tt>)
      # * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
      # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new("account_id" => id)</tt>)
      # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save; b</tt>)
      # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new("account_id" => id); b.save!; b</tt>)
      #
      # === Options
      #
      # The declaration can also include an options hash to specialize the behavior of the association.
      #
      # Options are:
      # [:class_name]
      #   Specify the class name of the association. Use it only if that name can't be inferred
      #   from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
      #   if the real class name is Person, you'll have to specify it with this option.
      # [:dependent]
      #   Controls what happens to the associated object when
      #   its owner is destroyed:
      #
      #   * <tt>:destroy</tt> causes the associated object to also be destroyed
      #   * <tt>:delete</tt> causes the asssociated object to be deleted directly from the database (so callbacks will not execute)
      #   * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
      #   * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
      #   * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
      # [:foreign_key]
      #   Specify the foreign key used for the association. By default this is guessed to be the name
      #   of this class in lower-case and "_id" suffixed. So a Person class that makes a +has_one+ association
      #   will use "person_id" as the default <tt>:foreign_key</tt>.
      # [:primary_key]
      #   Specify the method that returns the primary key used for the association. By default this is +id+.
      # [:as]
      #   Specifies a polymorphic interface (See <tt>belongs_to</tt>).
      # [:through]
      #   Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
      #   <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
      #   source reflection. You can only use a <tt>:through</tt> query through a <tt>has_one</tt>
      #   or <tt>belongs_to</tt> association on the join model.
      # [:source]
      #   Specifies the source association name used by <tt>has_one :through</tt> queries.
      #   Only use it if the name cannot be inferred from the association.
      #   <tt>has_one :favorite, through: :favorites</tt> will look for a
      #   <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
      # [:source_type]
      #   Specifies type of the source association used by <tt>has_one :through</tt> queries where the source
      #   association is a polymorphic +belongs_to+.
      # [:validate]
      #   If +false+, don't validate the associated object when saving the parent object. +false+ by default.
      # [:autosave]
      #   If true, always save the associated object or destroy it if marked for destruction,
      #   when saving the parent object. If false, never save or destroy the associated object.
      #   By default, only save the associated object if it's a new record.
      #
      #   Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
      # [:inverse_of]
      #   Specifies the name of the <tt>belongs_to</tt> association on the associated object
      #   that is the inverse of this <tt>has_one</tt> association. Does not work in combination
      #   with <tt>:through</tt> or <tt>:as</tt> options.
      #   See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
      #
      # Option examples:
      #   has_one :credit_card, dependent: :destroy  # destroys the associated credit card
      #   has_one :credit_card, dependent: :nullify  # updates the associated records foreign
      #                                                 # key value to NULL rather than destroying it
      #   has_one :last_comment, -> { order 'posted_on' }, class_name: "Comment"
      #   has_one :project_manager, -> { where role: 'project_manager' }, class_name: "Person"
      #   has_one :attachment, as: :attachable
      #   has_one :boss, readonly: :true
      #   has_one :club, through: :membership
      #   has_one :primary_address, -> { where primary: true }, through: :addressables, source: :addressable
      def has_one(name, scope = nil, options = {})
        Builder::HasOne.build(self, name, scope, options)
      end

      # Specifies a one-to-one association with another class. This method should only be used
      # if this class contains the foreign key. If the other class contains the foreign key,
      # then you should use +has_one+ instead. See also ActiveRecord::Associations::ClassMethods's overview
      # on when to use +has_one+ and when to use +belongs_to+.
      #
      # Methods will be added for retrieval and query for a single associated object, for which
      # this object holds an id:
      #
      # [association(force_reload = false)]
      #   Returns the associated object. +nil+ is returned if none is found.
      # [association=(associate)]
      #   Assigns the associate object, extracts the primary key, and sets it as the foreign key.
      # [build_association(attributes = {})]
      #   Returns a new object of the associated type that has been instantiated
      #   with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
      # [create_association(attributes = {})]
      #   Returns a new object of the associated type that has been instantiated
      #   with +attributes+, linked to this object through a foreign key, and that
      #   has already been saved (if it passed the validation).
      # [create_association!(attributes = {})]
      #   Does the same as <tt>create_association</tt>, but raises <tt>ActiveRecord::RecordInvalid</tt>
      #   if the record is invalid.
      #
      # (+association+ is replaced with the symbol passed as the first argument, so
      # <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.)
      #
      # === Example
      #
      # A Post class declares <tt>belongs_to :author</tt>, which will add:
      # * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>)
      # * <tt>Post#author=(author)</tt> (similar to <tt>post.author_id = author.id</tt>)
      # * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
      # * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
      # * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
      # The declaration can also include an options hash to specialize the behavior of the association.
      #
      # === Options
      #
      # [:class_name]
      #   Specify the class name of the association. Use it only if that name can't be inferred
      #   from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
      #   if the real class name is Person, you'll have to specify it with this option.
      # [:foreign_key]
      #   Specify the foreign key used for the association. By default this is guessed to be the name
      #   of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
      #   association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
      #   <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
      #   of "favorite_person_id".
      # [:foreign_type]
      #   Specify the column used to store the associated object's type, if this is a polymorphic
      #   association. By default this is guessed to be the name of the association with a "_type"
      #   suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
      #   association will use "taggable_type" as the default <tt>:foreign_type</tt>.
      # [:primary_key]
      #   Specify the method that returns the primary key of associated object used for the association.
      #   By default this is id.
      # [:dependent]
      #   If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
      #   <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
      #   This option should not be specified when <tt>belongs_to</tt> is used in conjunction with
      #   a <tt>has_many</tt> relationship on another class because of the potential to leave
      #   orphaned records behind.
      # [:counter_cache]
      #   Caches the number of belonging objects on the associate class through the use of +increment_counter+
      #   and +decrement_counter+. The counter cache is incremented when an object of this
      #   class is created and decremented when it's destroyed. This requires that a column
      #   named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
      #   is used on the associate class (such as a Post class) - that is the migration for
      #   <tt>#{table_name}_count</tt> is created on the associate class (such that Post.comments_count will
      #   return the count cached, see note below). You can also specify a custom counter
      #   cache column by providing a column name instead of a +true+/+false+ value to this
      #   option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
      #   Note: Specifying a counter cache will add it to that model's list of readonly attributes
      #   using +attr_readonly+.
      # [:polymorphic]
      #   Specify this association is a polymorphic association by passing +true+.
      #   Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
      #   to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
      # [:validate]
      #   If +false+, don't validate the associated objects when saving the parent object. +false+ by default.
      # [:autosave]
      #   If true, always save the associated object or destroy it if marked for destruction, when
      #   saving the parent object.
      #   If false, never save or destroy the associated object.
      #   By default, only save the associated object if it's a new record.
      #
      #   Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
      # [:touch]
      #   If true, the associated object will be touched (the updated_at/on attributes set to now)
      #   when this record is either saved or destroyed. If you specify a symbol, that attribute
      #   will be updated with the current time in addition to the updated_at/on attribute.
      # [:inverse_of]
      #   Specifies the name of the <tt>has_one</tt> or <tt>has_many</tt> association on the associated
      #   object that is the inverse of this <tt>belongs_to</tt> association. Does not work in
      #   combination with the <tt>:polymorphic</tt> options.
      #   See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
      #
      # Option examples:
      #   belongs_to :firm, foreign_key: "client_of"
      #   belongs_to :person, primary_key: "name", foreign_key: "person_name"
      #   belongs_to :author, class_name: "Person", foreign_key: "author_id"
      #   belongs_to :valid_coupon, ->(o) { where "discounts > #{o.payments_count}" },
      #                             class_name: "Coupon", foreign_key: "coupon_id"
      #   belongs_to :attachable, polymorphic: true
      #   belongs_to :project, readonly: true
      #   belongs_to :post, counter_cache: true
      #   belongs_to :company, touch: true
      #   belongs_to :company, touch: :employees_last_updated_at
      def belongs_to(name, scope = nil, options = {})
        Builder::BelongsTo.build(self, name, scope, options)
      end

      # Specifies a many-to-many relationship with another class. This associates two classes via an
      # intermediate join table. Unless the join table is explicitly specified as an option, it is
      # guessed using the lexical order of the class names. So a join between Developer and Project
      # will give the default join table name of "developers_projects" because "D" precedes "P" alphabetically.
      # Note that this precedence is calculated using the <tt><</tt> operator for String. This
      # means that if the strings are of different lengths, and the strings are equal when compared
      # up to the shortest length, then the longer string is considered of higher
      # lexical precedence than the shorter one. For example, one would expect the tables "paper_boxes" and "papers"
      # to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes",
      # but it in fact generates a join table name of "paper_boxes_papers". Be aware of this caveat, and use the
      # custom <tt>:join_table</tt> option if you need to.
      #
      # The join table should not have a primary key or a model associated with it. You must manually generate the
      # join table with a migration such as this:
      #
      #   class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
      #     def change
      #       create_table :developers_projects, id: false do |t|
      #         t.integer :developer_id
      #         t.integer :project_id
      #       end
      #     end
      #   end
      #
      # It's also a good idea to add indexes to each of those columns to speed up the joins process.
      # However, in MySQL it is advised to add a compound index for both of the columns as MySQL only
      # uses one index per table during the lookup.
      #
      # Adds the following methods for retrieval and query:
      #
      # [collection(force_reload = false)]
      #   Returns an array of all the associated objects.
      #   An empty array is returned if none are found.
      # [collection<<(object, ...)]
      #   Adds one or more objects to the collection by creating associations in the join table
      #   (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
      #   Note that this operation instantly fires update sql without waiting for the save or update call on the
      #   parent object.
      # [collection.delete(object, ...)]
      #   Removes one or more objects from the collection by removing their associations from the join table.
      #   This does not destroy the objects.
      # [collection.destroy(object, ...)]
      #   Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
      #   This does not destroy the objects.
      # [collection=objects]
      #   Replaces the collection's content by deleting and adding objects as appropriate.
      # [collection_singular_ids]
      #   Returns an array of the associated objects' ids.
      # [collection_singular_ids=ids]
      #   Replace the collection by the objects identified by the primary keys in +ids+.
      # [collection.clear]
      #   Removes every object from the collection. This does not destroy the objects.
      # [collection.empty?]
      #   Returns +true+ if there are no associated objects.
      # [collection.size]
      #   Returns the number of associated objects.
      # [collection.find(id)]
      #   Finds an associated object responding to the +id+ and that
      #   meets the condition that it has to be associated with this object.
      #   Uses the same rules as ActiveRecord::Base.find.
      # [collection.exists?(...)]
      #   Checks whether an associated object with the given conditions exists.
      #   Uses the same rules as ActiveRecord::Base.exists?.
      # [collection.build(attributes = {})]
      #   Returns a new object of the collection type that has been instantiated
      #   with +attributes+ and linked to this object through the join table, but has not yet been saved.
      # [collection.create(attributes = {})]
      #   Returns a new object of the collection type that has been instantiated
      #   with +attributes+, linked to this object through the join table, and that has already been
      #   saved (if it passed the validation).
      #
      # (+collection+ is replaced with the symbol passed as the first argument, so
      # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.)
      #
      # === Example
      #
      # A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
      # * <tt>Developer#projects</tt>
      # * <tt>Developer#projects<<</tt>
      # * <tt>Developer#projects.delete</tt>
      # * <tt>Developer#projects.destroy</tt>
      # * <tt>Developer#projects=</tt>
      # * <tt>Developer#project_ids</tt>
      # * <tt>Developer#project_ids=</tt>
      # * <tt>Developer#projects.clear</tt>
      # * <tt>Developer#projects.empty?</tt>
      # * <tt>Developer#projects.size</tt>
      # * <tt>Developer#projects.find(id)</tt>
      # * <tt>Developer#projects.exists?(...)</tt>
      # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("developer_id" => id)</tt>)
      # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("developer_id" => id); c.save; c</tt>)
      # The declaration may include an options hash to specialize the behavior of the association.
      #
      # === Options
      #
      # [:class_name]
      #   Specify the class name of the association. Use it only if that name can't be inferred
      #   from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
      #   Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
      # [:join_table]
      #   Specify the name of the join table if the default based on lexical order isn't what you want.
      #   <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
      #   MUST be declared underneath any +has_and_belongs_to_many+ declaration in order to work.
      # [:foreign_key]
      #   Specify the foreign key used for the association. By default this is guessed to be the name
      #   of this class in lower-case and "_id" suffixed. So a Person class that makes
      #   a +has_and_belongs_to_many+ association to Project will use "person_id" as the
      #   default <tt>:foreign_key</tt>.
      # [:association_foreign_key]
      #   Specify the foreign key used for the association on the receiving side of the association.
      #   By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
      #   So if a Person class makes a +has_and_belongs_to_many+ association to Project,
      #   the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
      # [:readonly]
      #   If true, all the associated objects are readonly through the association.
      # [:validate]
      #   If +false+, don't validate the associated objects when saving the parent object. +true+ by default.
      # [:autosave]
      #   If true, always save the associated objects or destroy them if marked for destruction, when
      #   saving the parent object.
      #   If false, never save or destroy the associated objects.
      #   By default, only save associated objects that are new records.
      #
      #   Note that <tt>accepts_nested_attributes_for</tt> sets <tt>:autosave</tt> to <tt>true</tt>.
      #
      # Option examples:
      #   has_and_belongs_to_many :projects
      #   has_and_belongs_to_many :projects, -> { includes :milestones, :manager }
      #   has_and_belongs_to_many :nations, class_name: "Country"
      #   has_and_belongs_to_many :categories, join_table: "prods_cats"
      #   has_and_belongs_to_many :categories, -> { readonly }
      def has_and_belongs_to_many(name, scope = nil, options = {}, &extension)
        Builder::HasAndBelongsToMany.build(self, name, scope, options, &extension)
      end
    end
  end
end

module ActiveRecord
  module AttributeAssignment
    extend ActiveSupport::Concern
    include ActiveModel::DeprecatedMassAssignmentSecurity
    include ActiveModel::ForbiddenAttributesProtection

    # Allows you to set all the attributes by passing in a hash of attributes with
    # keys matching the attribute names (which again matches the column names).
    #
    # If the passed hash responds to <tt>permitted?</tt> method and the return value
    # of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
    # exception is raised.
    def assign_attributes(new_attributes)
      return if new_attributes.blank?

      attributes                  = new_attributes.stringify_keys
      multi_parameter_attributes  = []
      nested_parameter_attributes = []

      attributes = sanitize_for_mass_assignment(attributes)

      attributes.each do |k, v|
        if k.include?("(")
          multi_parameter_attributes << [ k, v ]
        elsif v.is_a?(Hash)
          nested_parameter_attributes << [ k, v ]
        else
          _assign_attribute(k, v)
        end
      end

      assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
      assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
    end

    alias attributes= assign_attributes

    private

    def _assign_attribute(k, v)
      public_send("#{k}=", v)
    rescue NoMethodError
      if respond_to?("#{k}=")
        raise
      else
        raise UnknownAttributeError, "unknown attribute: #{k}"
      end
    end

    # Assign any deferred nested attributes after the base attributes have been set.
    def assign_nested_parameter_attributes(pairs)
      pairs.each { |k, v| _assign_attribute(k, v) }
    end

    # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
    # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
    # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
    # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
    # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum and
    # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
    def assign_multiparameter_attributes(pairs)
      execute_callstack_for_multiparameter_attributes(
        extract_callstack_for_multiparameter_attributes(pairs)
      )
    end

    def execute_callstack_for_multiparameter_attributes(callstack)
      errors = []
      callstack.each do |name, values_with_empty_parameters|
        begin
          send("#{name}=", MultiparameterAttribute.new(self, name, values_with_empty_parameters).read_value)
        rescue => ex
          errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
        end
      end
      unless errors.empty?
        error_descriptions = errors.map { |ex| ex.message }.join(",")
        raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
      end
    end

    def extract_callstack_for_multiparameter_attributes(pairs)
      attributes = { }

      pairs.each do |(multiparameter_name, value)|
        attribute_name = multiparameter_name.split("(").first
        attributes[attribute_name] ||= {}

        parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
        attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
      end

      attributes
    end

    def type_cast_attribute_value(multiparameter_name, value)
      multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
    end

    def find_parameter_position(multiparameter_name)
      multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
    end

    class MultiparameterAttribute #:nodoc:
      attr_reader :object, :name, :values, :column

      def initialize(object, name, values)
        @object = object
        @name   = name
        @values = values
      end

      def read_value
        return if values.values.compact.empty?

        @column = object.class.reflect_on_aggregation(name.to_sym) || object.column_for_attribute(name)
        klass   = column.klass

        if klass == Time
          read_time
        elsif klass == Date
          read_date
        else
          read_other(klass)
        end
      end

      private

      def instantiate_time_object(set_values)
        if object.class.send(:create_time_zone_conversion_attribute?, name, column)
          Time.zone.local(*set_values)
        else
          Time.send(object.class.default_timezone, *set_values)
        end
      end

      def read_time
        # If column is a :time (and not :date or :timestamp) there is no need to validate if
        # there are year/month/day fields
        if column.type == :time
          # if the column is a time set the values to their defaults as January 1, 1970, but only if they're nil
          { 1 => 1970, 2 => 1, 3 => 1 }.each do |key,value|
            values[key] ||= value
          end
        else
          # else column is a timestamp, so if Date bits were not provided, error
          validate_missing_parameters!([1,2,3])

          # If Date bits were provided but blank, then return nil
          return if blank_date_parameter?
        end

        max_position = extract_max_param(6)
        set_values   = values.values_at(*(1..max_position))
        # If Time bits are not there, then default to 0
        (3..5).each { |i| set_values[i] = set_values[i].presence || 0 }
        instantiate_time_object(set_values)
      end

      def read_date
        return if blank_date_parameter?
        set_values = values.values_at(1,2,3)
        begin
          Date.new(*set_values)
        rescue ArgumentError # if Date.new raises an exception on an invalid date
          instantiate_time_object(set_values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
        end
      end

      def read_other(klass)
        max_position = extract_max_param
        positions    = (1..max_position)
        validate_missing_parameters!(positions)

        set_values = values.values_at(*positions)
        klass.new(*set_values)
      end

      # Checks whether some blank date parameter exists. Note that this is different
      # than the validate_missing_parameters! method, since it just checks for blank
      # positions instead of missing ones, and does not raise in case one blank position
      # exists. The caller is responsible to handle the case of this returning true.
      def blank_date_parameter?
        (1..3).any? { |position| values[position].blank? }
      end

      # If some position is not provided, it errors out a missing parameter exception.
      def validate_missing_parameters!(positions)
        if missing_parameter = positions.detect { |position| !values.key?(position) }
          raise ArgumentError.new("Missing Parameter - #{name}(#{missing_parameter})")
        end
      end

      def extract_max_param(upper_cap = 100)
        [values.keys.max, upper_cap].min
      end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    # = Active Record Attribute Methods Before Type Cast
    #
    # <tt>ActiveRecord::AttributeMethods::BeforeTypeCast</tt> provides a way to
    # read the value of the attributes before typecasting and deserialization.
    #
    #   class Task < ActiveRecord::Base
    #   end
    #
    #   task = Task.new(id: '1', completed_on: '2012-10-21')
    #   task.id           # => 1
    #   task.completed_on # => Sun, 21 Oct 2012
    #
    #   task.attributes_before_type_cast
    #   # => {"id"=>"1", "completed_on"=>"2012-10-21", ... }
    #   task.read_attribute_before_type_cast('id')           # => "1"
    #   task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
    #
    # In addition to #read_attribute_before_type_cast and #attributes_before_type_cast,
    # it declares a method for all attributes with the <tt>*_before_type_cast</tt>
    # suffix.
    #
    #   task.id_before_type_cast           # => "1"
    #   task.completed_on_before_type_cast # => "2012-10-21"
    module BeforeTypeCast
      extend ActiveSupport::Concern

      included do
        attribute_method_suffix "_before_type_cast"
      end

      # Returns the value of the attribute identified by +attr_name+ before
      # typecasting and deserialization.
      #
      #   class Task < ActiveRecord::Base
      #   end
      #
      #   task = Task.new(id: '1', completed_on: '2012-10-21')
      #   task.read_attribute('id')                            # => 1
      #   task.read_attribute_before_type_cast('id')           # => '1'
      #   task.read_attribute('completed_on')                  # => Sun, 21 Oct 2012
      #   task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
      def read_attribute_before_type_cast(attr_name)
        @attributes[attr_name]
      end

      # Returns a hash of attributes before typecasting and deserialization.
      #
      #   class Task < ActiveRecord::Base
      #   end
      #
      #   task = Task.new(title: nil, is_done: true, completed_on: '2012-10-21')
      #   task.attributes
      #   # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>Sun, 21 Oct 2012, "created_at"=>nil, "updated_at"=>nil}
      #   task.attributes_before_type_cast
      #   # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
      def attributes_before_type_cast
        @attributes
      end

      private

      # Handle *_before_type_cast for method_missing.
      def attribute_before_type_cast(attribute_name)
        read_attribute_before_type_cast(attribute_name)
      end
    end
  end
end
require 'active_support/core_ext/module/attribute_accessors'

module ActiveRecord
  module AttributeMethods
    module Dirty # :nodoc:
      extend ActiveSupport::Concern

      include ActiveModel::Dirty

      included do
        if self < ::ActiveRecord::Timestamp
          raise "You cannot include Dirty after Timestamp"
        end

        class_attribute :partial_writes, instance_writer: false
        self.partial_writes = true

        def self.partial_updates=(v); self.partial_writes = v; end
        def self.partial_updates?; partial_writes?; end
        def self.partial_updates; partial_writes; end

        ActiveSupport::Deprecation.deprecate_methods(
          singleton_class,
          :partial_updates= => :partial_writes=,
          :partial_updates? => :partial_writes?,
          :partial_updates  => :partial_writes
        )
      end

      # Attempts to +save+ the record and clears changed attributes if successful.
      def save(*)
        if status = super
          @previously_changed = changes
          @changed_attributes.clear
        end
        status
      end

      # Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
      def save!(*)
        super.tap do
          @previously_changed = changes
          @changed_attributes.clear
        end
      end

      # <tt>reload</tt> the record and clears changed attributes.
      def reload(*)
        super.tap do
          @previously_changed.clear
          @changed_attributes.clear
        end
      end

    private
      # Wrap write_attribute to remember original attribute value.
      def write_attribute(attr, value)
        attr = attr.to_s

        # The attribute already has an unsaved change.
        if attribute_changed?(attr)
          old = @changed_attributes[attr]
          @changed_attributes.delete(attr) unless _field_changed?(attr, old, value)
        else
          old = clone_attribute_value(:read_attribute, attr)
          @changed_attributes[attr] = old if _field_changed?(attr, old, value)
        end

        # Carry on.
        super(attr, value)
      end

      def update_record(*)
        partial_writes? ? super(keys_for_partial_write) : super
      end

      def create_record(*)
        partial_writes? ? super(keys_for_partial_write) : super
      end

      # Serialized attributes should always be written in case they've been
      # changed in place.
      def keys_for_partial_write
        changed | (attributes.keys & self.class.serialized_attributes.keys)
      end

      def _field_changed?(attr, old, value)
        if column = column_for_attribute(attr)
          if column.number? && (changes_from_nil_to_empty_string?(column, old, value) ||
                                changes_from_zero_to_string?(old, value))
            value = nil
          else
            value = column.type_cast(value)
          end
        end

        old != value
      end

      def changes_from_nil_to_empty_string?(column, old, value)
        # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
        # Hence we don't record it as a change if the value changes from nil to ''.
        # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
        # be typecast back to 0 (''.to_i => 0)
        column.null && (old.nil? || old == 0) && value.blank?
      end

      def changes_from_zero_to_string?(old, value)
        # For columns with old 0 and value non-empty string
        old == 0 && value.is_a?(String) && value.present? && value != '0'
      end
    end
  end
end
require 'set'

module ActiveRecord
  module AttributeMethods
    module PrimaryKey
      extend ActiveSupport::Concern

      # Returns this record's primary key value wrapped in an Array if one is
      # available.
      def to_key
        key = self.id
        [key] if key
      end

      # Returns the primary key value.
      def id
        read_attribute(self.class.primary_key)
      end

      # Sets the primary key value.
      def id=(value)
        write_attribute(self.class.primary_key, value) if self.class.primary_key
      end

      # Queries the primary key value.
      def id?
        query_attribute(self.class.primary_key)
      end

      # Returns the primary key value before type cast.
      def id_before_type_cast
        read_attribute_before_type_cast(self.class.primary_key)
      end

      protected

      def attribute_method?(attr_name)
        attr_name == 'id' || super
      end

      module ClassMethods
        def define_method_attribute(attr_name)
          super

          if attr_name == primary_key && attr_name != 'id'
            generated_attribute_methods.send(:alias_method, :id, primary_key)
          end
        end

        ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast).to_set

        def dangerous_attribute_method?(method_name)
          super && !ID_ATTRIBUTE_METHODS.include?(method_name)
        end

        # Defines the primary key field -- can be overridden in subclasses.
        # Overwriting will negate any effect of the +primary_key_prefix_type+
        # setting, though.
        def primary_key
          @primary_key = reset_primary_key unless defined? @primary_key
          @primary_key
        end

        # Returns a quoted version of the primary key name, used to construct
        # SQL statements.
        def quoted_primary_key
          @quoted_primary_key ||= connection.quote_column_name(primary_key)
        end

        def reset_primary_key #:nodoc:
          if self == base_class
            self.primary_key = get_primary_key(base_class.name)
          else
            self.primary_key = base_class.primary_key
          end
        end

        def get_primary_key(base_name) #:nodoc:
          return 'id' if base_name.blank?

          case primary_key_prefix_type
          when :table_name
            base_name.foreign_key(false)
          when :table_name_with_underscore
            base_name.foreign_key
          else
            if ActiveRecord::Base != self && table_exists?
              connection.schema_cache.primary_keys[table_name]
            else
              'id'
            end
          end
        end

        # Sets the name of the primary key column.
        #
        #   class Project < ActiveRecord::Base
        #     self.primary_key = 'sysid'
        #   end
        #
        # You can also define the +primary_key+ method yourself:
        #
        #   class Project < ActiveRecord::Base
        #     def self.primary_key
        #       'foo_' + super
        #     end
        #   end
        #
        #   Project.primary_key # => "foo_id"
        def primary_key=(value)
          @primary_key        = value && value.to_s
          @quoted_primary_key = nil
        end
      end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    module Query
      extend ActiveSupport::Concern

      included do
        attribute_method_suffix "?"
      end

      def query_attribute(attr_name)
        value = read_attribute(attr_name) { |n| missing_attribute(n, caller) }

        case value
        when true        then true
        when false, nil  then false
        else
          column = self.class.columns_hash[attr_name]
          if column.nil?
            if Numeric === value || value !~ /[^0-9]/
              !value.to_i.zero?
            else
              return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
              !value.blank?
            end
          elsif column.number?
            !value.zero?
          else
            !value.blank?
          end
        end
      end

      private
        # Handle *? for method_missing.
        def attribute?(attribute_name)
          query_attribute(attribute_name)
        end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    module Read
      extend ActiveSupport::Concern

      ATTRIBUTE_TYPES_CACHED_BY_DEFAULT = [:datetime, :timestamp, :time, :date]

      included do
        class_attribute :attribute_types_cached_by_default, instance_writer: false
        self.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
      end

      module ClassMethods
        # +cache_attributes+ allows you to declare which converted attribute
        # values should be cached. Usually caching only pays off for attributes
        # with expensive conversion methods, like time related columns (e.g.
        # +created_at+, +updated_at+).
        def cache_attributes(*attribute_names)
          cached_attributes.merge attribute_names.map { |attr| attr.to_s }
        end

        # Returns the attributes which are cached. By default time related columns
        # with datatype <tt>:datetime, :timestamp, :time, :date</tt> are cached.
        def cached_attributes
          @cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
        end

        # Returns +true+ if the provided attribute is being cached.
        def cache_attribute?(attr_name)
          cached_attributes.include?(attr_name)
        end

        protected

        # We want to generate the methods via module_eval rather than
        # define_method, because define_method is slower on dispatch and
        # uses more memory (because it creates a closure).
        #
        # But sometimes the database might return columns with
        # characters that are not allowed in normal method names (like
        # 'my_column(omg)'. So to work around this we first define with
        # the __temp__ identifier, and then use alias method to rename
        # it to what we want.
        #
        # We are also defining a constant to hold the frozen string of
        # the attribute name. Using a constant means that we do not have
        # to allocate an object on each call to the attribute method.
        # Making it frozen means that it doesn't get duped when used to
        # key the @attributes_cache in read_attribute.
        def define_method_attribute(name)
          safe_name = name.unpack('h*').first
          generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
            def __temp__#{safe_name}
              read_attribute(AttrNames::ATTR_#{safe_name}) { |n| missing_attribute(n, caller) }
            end
            alias_method #{name.inspect}, :__temp__#{safe_name}
            undef_method :__temp__#{safe_name}
          STR
        end

        private

        def cacheable_column?(column)
          if attribute_types_cached_by_default == ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
            ! serialized_attributes.include? column.name
          else
            attribute_types_cached_by_default.include?(column.type)
          end
        end
      end

      # Returns the value of the attribute identified by <tt>attr_name</tt> after
      # it has been typecast (for example, "2004-12-12" in a data column is cast
      # to a date object, like Date.new(2004, 12, 12)).
      def read_attribute(attr_name)
        # If it's cached, just return it
        # We use #[] first as a perf optimization for non-nil values. See https://gist.github.com/3552829.
        name = attr_name.to_s
        @attributes_cache[name] || @attributes_cache.fetch(name) {
          column = @columns_hash.fetch(name) {
            return @attributes.fetch(name) {
              if name == 'id' && self.class.primary_key != name
                read_attribute(self.class.primary_key)
              end
            }
          }

          value = @attributes.fetch(name) {
            return block_given? ? yield(name) : nil
          }

          if self.class.cache_attribute?(name)
            @attributes_cache[name] = column.type_cast(value)
          else
            column.type_cast value
          end
        }
      end

      private

      def attribute(attribute_name)
        read_attribute(attribute_name)
      end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    module Serialization
      extend ActiveSupport::Concern

      included do
        # Returns a hash of all the attributes that have been specified for
        # serialization as keys and their class restriction as values.
        class_attribute :serialized_attributes, instance_accessor: false
        self.serialized_attributes = {}
      end

      module ClassMethods
        # If you have an attribute that needs to be saved to the database as an
        # object, and retrieved as the same object, then specify the name of that
        # attribute using this method and it will be handled automatically. The
        # serialization is done through YAML. If +class_name+ is specified, the
        # serialized object must be of that class on retrieval or
        # <tt>SerializationTypeMismatch</tt> will be raised.
        #
        # ==== Parameters
        #
        # * +attr_name+ - The field name that should be serialized.
        # * +class_name+ - Optional, class name that the object type should be equal to.
        #
        # ==== Example
        #
        #   # Serialize a preferences attribute.
        #   class User < ActiveRecord::Base
        #     serialize :preferences
        #   end
        def serialize(attr_name, class_name = Object)
          include Behavior

          coder = if [:load, :dump].all? { |x| class_name.respond_to?(x) }
                    class_name
                  else
                    Coders::YAMLColumn.new(class_name)
                  end

          # merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy
          # has its own hash of own serialized attributes
          self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
        end
      end

      def serialized_attributes
        message = "Instance level serialized_attributes method is deprecated, please use class level method."
        ActiveSupport::Deprecation.warn message
        defined?(@serialized_attributes) ? @serialized_attributes : self.class.serialized_attributes
      end

      class Type # :nodoc:
        def initialize(column)
          @column = column
        end

        def type_cast(value)
          value.unserialized_value
        end

        def type
          @column.type
        end
      end

      class Attribute < Struct.new(:coder, :value, :state) # :nodoc:
        def unserialized_value
          state == :serialized ? unserialize : value
        end

        def serialized_value
          state == :unserialized ? serialize : value
        end

        def unserialize
          self.state = :unserialized
          self.value = coder.load(value)
        end

        def serialize
          self.state = :serialized
          self.value = coder.dump(value)
        end
      end

      # This is only added to the model when serialize is called, which
      # ensures we do not make things slower when serialization is not used.
      module Behavior #:nodoc:
        extend ActiveSupport::Concern

        module ClassMethods
          def initialize_attributes(attributes, options = {})
            serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized
            super(attributes, options)

            serialized_attributes.each do |key, coder|
              if attributes.key?(key)
                attributes[key] = Attribute.new(coder, attributes[key], serialized)
              end
            end

            attributes
          end
        end

        def type_cast_attribute_for_write(column, value)
          if column && coder = self.class.serialized_attributes[column.name]
            Attribute.new(coder, value, :unserialized)
          else
            super
          end
        end

        def _field_changed?(attr, old, value)
          if self.class.serialized_attributes.include?(attr)
            old != value
          else
            super
          end
        end

        def read_attribute_before_type_cast(attr_name)
          if self.class.serialized_attributes.include?(attr_name)
            super.unserialized_value
          else
            super
          end
        end

        def attributes_before_type_cast
          super.dup.tap do |attributes|
            self.class.serialized_attributes.each_key do |key|
              if attributes.key?(key)
                attributes[key] = attributes[key].unserialized_value
              end
            end
          end
        end

        def typecasted_attribute_value(name)
          if self.class.serialized_attributes.include?(name)
            @attributes[name].serialized_value
          else
            super
          end
        end
      end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    module TimeZoneConversion
      class Type # :nodoc:
        def initialize(column)
          @column = column
        end

        def type_cast(value)
          value = @column.type_cast(value)
          value.acts_like?(:time) ? value.in_time_zone : value
        end

        def type
          @column.type
        end
      end

      extend ActiveSupport::Concern

      included do
        mattr_accessor :time_zone_aware_attributes, instance_writer: false
        self.time_zone_aware_attributes = false

        class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
        self.skip_time_zone_conversion_for_attributes = []
      end

      module ClassMethods
        protected
        # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
        # This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
        def define_method_attribute=(attr_name)
          if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
            method_body, line = <<-EOV, __LINE__ + 1
              def #{attr_name}=(time)
                time_with_zone = time.respond_to?(:in_time_zone) ? time.in_time_zone : nil
                previous_time = attribute_changed?("#{attr_name}") ? changed_attributes["#{attr_name}"] : read_attribute(:#{attr_name})
                write_attribute(:#{attr_name}, time)
                #{attr_name}_will_change! if previous_time != time_with_zone
                @attributes_cache["#{attr_name}"] = time_with_zone
              end
            EOV
            generated_attribute_methods.module_eval(method_body, __FILE__, line)
          else
            super
          end
        end

        private
        def create_time_zone_conversion_attribute?(name, column)
          time_zone_aware_attributes &&
            !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) &&
            [:datetime, :timestamp].include?(column.type)
        end
      end
    end
  end
end
module ActiveRecord
  module AttributeMethods
    module Write
      extend ActiveSupport::Concern

      included do
        attribute_method_suffix "="
      end

      module ClassMethods
        protected

        # See define_method_attribute in read.rb for an explanation of
        # this code.
        def define_method_attribute=(name)
          safe_name = name.unpack('h*').first
          generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
            def __temp__#{safe_name}=(value)
              write_attribute(AttrNames::ATTR_#{safe_name}, value)
            end
            alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
            undef_method :__temp__#{safe_name}=
          STR
        end
      end

      # Updates the attribute identified by <tt>attr_name</tt> with the
      # specified +value+. Empty strings for fixnum and float columns are
      # turned into +nil+.
      def write_attribute(attr_name, value)
        attr_name = attr_name.to_s
        attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
        @attributes_cache.delete(attr_name)
        column = column_for_attribute(attr_name)

        # If we're dealing with a binary column, write the data to the cache
        # so we don't attempt to typecast multiple times.
        if column && column.binary?
          @attributes_cache[attr_name] = value
        end

        if column || @attributes.has_key?(attr_name)
          @attributes[attr_name] = type_cast_attribute_for_write(column, value)
        else
          raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{attr_name}'"
        end
      end
      alias_method :raw_write_attribute, :write_attribute

      private
      # Handle *= for method_missing.
      def attribute=(attribute_name, value)
        write_attribute(attribute_name, value)
      end

      def type_cast_attribute_for_write(column, value)
        return value unless column

        column.type_cast_for_write value
      end
    end
  end
end
require 'active_support/core_ext/enumerable'

module ActiveRecord
  # = Active Record Attribute Methods
  module AttributeMethods
    extend ActiveSupport::Concern
    include ActiveModel::AttributeMethods

    included do
      include Read
      include Write
      include BeforeTypeCast
      include Query
      include PrimaryKey
      include TimeZoneConversion
      include Dirty
      include Serialization
    end

    module ClassMethods
      # Generates all the attribute related methods for columns in the database
      # accessors, mutators and query methods.
      def define_attribute_methods # :nodoc:
        # Use a mutex; we don't want two thread simaltaneously trying to define
        # attribute methods.
        @attribute_methods_mutex.synchronize do
          return if attribute_methods_generated?
          superclass.define_attribute_methods unless self == base_class
          super(column_names)
          @attribute_methods_generated = true
        end
      end

      def attribute_methods_generated? # :nodoc:
        @attribute_methods_generated ||= false
      end

      def undefine_attribute_methods # :nodoc:
        super if attribute_methods_generated?
        @attribute_methods_generated = false
      end

      # Raises a <tt>ActiveRecord::DangerousAttributeError</tt> exception when an
      # \Active \Record method is defined in the model, otherwise +false+.
      #
      #   class Person < ActiveRecord::Base
      #     def save
      #       'already defined by Active Record'
      #     end
      #   end
      #
      #   Person.instance_method_already_implemented?(:save)
      #   # => ActiveRecord::DangerousAttributeError: save is defined by ActiveRecord
      #
      #   Person.instance_method_already_implemented?(:name)
      #   # => false
      def instance_method_already_implemented?(method_name)
        if dangerous_attribute_method?(method_name)
          raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord"
        end

        if superclass == Base
          super
        else
          # If B < A and A defines its own attribute method, then we don't want to overwrite that.
          defined = method_defined_within?(method_name, superclass, superclass.generated_attribute_methods)
          defined && !ActiveRecord::Base.method_defined?(method_name) || super
        end
      end

      # A method name is 'dangerous' if it is already defined by Active Record, but
      # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
      def dangerous_attribute_method?(name) # :nodoc:
        method_defined_within?(name, Base)
      end

      def method_defined_within?(name, klass, sup = klass.superclass) # :nodoc:
        if klass.method_defined?(name) || klass.private_method_defined?(name)
          if sup.method_defined?(name) || sup.private_method_defined?(name)
            klass.instance_method(name).owner != sup.instance_method(name).owner
          else
            true
          end
        else
          false
        end
      end

      # Returns +true+ if +attribute+ is an attribute method and table exists,
      # +false+ otherwise.
      #
      #   class Person < ActiveRecord::Base
      #   end
      #
      #   Person.attribute_method?('name')   # => true
      #   Person.attribute_method?(:age=)    # => true
      #   Person.attribute_method?(:nothing) # => false
      def attribute_method?(attribute)
        super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
      end

      # Returns an array of column names as strings if it's not an abstract class and
      # table exists. Otherwise it returns an empty array.
      #
      #   class Person < ActiveRecord::Base
      #   end
      #
      #   Person.attribute_names
      #   # => ["id", "created_at", "updated_at", "name", "age"]
      def attribute_names
        @attribute_names ||= if !abstract_class? && table_exists?
            column_names
          else
            []
          end
      end
    end

    # If we haven't generated any methods yet, generate them, then
    # see if we've created the method we're looking for.
    def method_missing(method, *args, &block) # :nodoc:
      unless self.class.attribute_methods_generated?
        self.class.define_attribute_methods

        if respond_to_without_attributes?(method)
          send(method, *args, &block)
        else
          super
        end
      else
        super
      end
    end

    def attribute_missing(match, *args, &block) # :nodoc:
      if self.class.columns_hash[match.attr_name]
        ActiveSupport::Deprecation.warn(
          "The method `#{match.method_name}', matching the attribute `#{match.attr_name}' has " \
          "dispatched through method_missing. This shouldn't happen, because `#{match.attr_name}' " \
          "is a column of the table. If this error has happened through normal usage of Active " \
          "Record (rather than through your own code or external libraries), please report it as " \
          "a bug."
        )
      end

      super
    end

    # A Person object with a name attribute can ask <tt>person.respond_to?(:name)</tt>,
    # <tt>person.respond_to?(:name=)</tt>, and <tt>person.respond_to?(:name?)</tt>
    # which will all return +true+. It also define the attribute methods if they have
    # not been generated.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.new
    #   person.respond_to(:name)    # => true
    #   person.respond_to(:name=)   # => true
    #   person.respond_to(:name?)   # => true
    #   person.respond_to('age')    # => true
    #   person.respond_to('age=')   # => true
    #   person.respond_to('age?')   # => true
    #   person.respond_to(:nothing) # => false
    def respond_to?(name, include_private = false)
      self.class.define_attribute_methods unless self.class.attribute_methods_generated?
      super
    end

    # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.new
    #   person.has_attribute?(:name)    # => true
    #   person.has_attribute?('age')    # => true
    #   person.has_attribute?(:nothing) # => false
    def has_attribute?(attr_name)
      @attributes.has_key?(attr_name.to_s)
    end

    # Returns an array of names for the attributes available on this object.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.new
    #   person.attribute_names
    #   # => ["id", "created_at", "updated_at", "name", "age"]
    def attribute_names
      @attributes.keys
    end

    # Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.create(name: 'Francesco', age: 22)
    #   person.attributes
    #   # => {"id"=>3, "created_at"=>Sun, 21 Oct 2012 04:53:04, "updated_at"=>Sun, 21 Oct 2012 04:53:04, "name"=>"Francesco", "age"=>22}
    def attributes
      attribute_names.each_with_object({}) { |name, attrs|
        attrs[name] = read_attribute(name)
      }
    end

    # Returns an <tt>#inspect</tt>-like string for the value of the
    # attribute +attr_name+. String attributes are truncated upto 50
    # characters, and Date and Time attributes are returned in the
    # <tt>:db</tt> format. Other attributes return the value of
    # <tt>#inspect</tt> without modification.
    #
    #   person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
    #
    #   person.attribute_for_inspect(:name)
    #   # => "\"David Heinemeier Hansson David Heinemeier Hansson D...\""
    #
    #   person.attribute_for_inspect(:created_at)
    #   # => "\"2012-10-22 00:15:07\""
    def attribute_for_inspect(attr_name)
      value = read_attribute(attr_name)

      if value.is_a?(String) && value.length > 50
        "#{value[0..50]}...".inspect
      elsif value.is_a?(Date) || value.is_a?(Time)
        %("#{value.to_s(:db)}")
      else
        value.inspect
      end
    end

    # Returns +true+ if the specified +attribute+ has been set by the user or by a
    # database load and is neither +nil+ nor <tt>empty?</tt> (the latter only applies
    # to objects that respond to <tt>empty?</tt>, most notably Strings). Otherwise, +false+.
    # Note that it always returns +true+ with boolean attributes.
    #
    #   class Task < ActiveRecord::Base
    #   end
    #
    #   person = Task.new(title: '', is_done: false)
    #   person.attribute_present?(:title)   # => false
    #   person.attribute_present?(:is_done) # => true
    #   person.name = 'Francesco'
    #   person.is_done = true
    #   person.attribute_present?(:title)   # => true
    #   person.attribute_present?(:is_done) # => true
    def attribute_present?(attribute)
      value = read_attribute(attribute)
      !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
    end

    # Returns the column object for the named attribute. Returns +nil+ if the
    # named attribute not exists.
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.new
    #   person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
    #   # => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
    #
    #   person.column_for_attribute(:nothing)
    #   # => nil
    def column_for_attribute(name)
      # FIXME: should this return a null object for columns that don't exist?
      self.class.columns_hash[name.to_s]
    end

    # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
    # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)). It raises
    # <tt>ActiveModel::MissingAttributeError</tt> if the identified attribute is missing.
    #
    # Alias for the <tt>read_attribute</tt> method.
    #
    #   class Person < ActiveRecord::Base
    #     belongs_to :organization
    #   end
    #
    #   person = Person.new(name: 'Francesco', age: '22')
    #   person[:name] # => "Francesco"
    #   person[:age]  # => 22
    #
    #   person = Person.select('id').first
    #   person[:name]            # => ActiveModel::MissingAttributeError: missing attribute: name
    #   person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute: organization_id
    def [](attr_name)
      read_attribute(attr_name) { |n| missing_attribute(n, caller) }
    end

    # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
    # (Alias for the protected <tt>write_attribute</tt> method).
    #
    #   class Person < ActiveRecord::Base
    #   end
    #
    #   person = Person.new
    #   person[:age] = '22'
    #   person[:age] # => 22
    #   person[:age] # => Fixnum
    def []=(attr_name, value)
      write_attribute(attr_name, value)
    end

    protected

    def clone_attributes(reader_method = :read_attribute, attributes = {}) # :nodoc:
      attribute_names.each do |name|
        attributes[name] = clone_attribute_value(reader_method, name)
      end
      attributes
    end

    def clone_attribute_value(reader_method, attribute_name) # :nodoc:
      value = send(reader_method, attribute_name)
      value.duplicable? ? value.clone : value
    rescue TypeError, NoMethodError
      value
    end

    def arel_attributes_with_values_for_create(attribute_names) # :nodoc:
      arel_attributes_with_values(attributes_for_create(attribute_names))
    end

    def arel_attributes_with_values_for_update(attribute_names) # :nodoc:
      arel_attributes_with_values(attributes_for_update(attribute_names))
    end

    def attribute_method?(attr_name) # :nodoc:
      defined?(@attributes) && @attributes.include?(attr_name)
    end

    private

    # Returns a Hash of the Arel::Attributes and attribute values that have been
    # type casted for use in an Arel insert/update method.
    def arel_attributes_with_values(attribute_names)
      attrs = {}
      arel_table = self.class.arel_table

      attribute_names.each do |name|
        attrs[arel_table[name]] = typecasted_attribute_value(name)
      end
      attrs
    end

    # Filters the primary keys and readonly attributes from the attribute names.
    def attributes_for_update(attribute_names)
      attribute_names.select do |name|
        column_for_attribute(name) && !pk_attribute?(name) && !readonly_attribute?(name)
      end
    end

    # Filters out the primary keys, from the attribute names, when the primary
    # key is to be generated (e.g. the id attribute has no value).
    def attributes_for_create(attribute_names)
      attribute_names.select do |name|
        column_for_attribute(name) && !(pk_attribute?(name) && id.nil?)
      end
    end

    def readonly_attribute?(name)
      self.class.readonly_attributes.include?(name)
    end

    def pk_attribute?(name)
      column_for_attribute(name).primary
    end

    def typecasted_attribute_value(name)
      # FIXME: we need @attributes to be used consistently.
      # If the values stored in @attributes were already typecasted, this code
      # could be simplified
      read_attribute(name)
    end
  end
end
module ActiveRecord
  # = Active Record Autosave Association
  #
  # +AutosaveAssociation+ is a module that takes care of automatically saving
  # associated records when their parent is saved. In addition to saving, it
  # also destroys any associated records that were marked for destruction.
  # (See +mark_for_destruction+ and <tt>marked_for_destruction?</tt>).
  #
  # Saving of the parent, its associations, and the destruction of marked
  # associations, all happen inside a transaction. This should never leave the
  # database in an inconsistent state.
  #
  # If validations for any of the associations fail, their error messages will
  # be applied to the parent.
  #
  # Note that it also means that associations marked for destruction won't
  # be destroyed directly. They will however still be marked for destruction.
  #
  # Note that <tt>autosave: false</tt> is not same as not declaring <tt>:autosave</tt>.
  # When the <tt>:autosave</tt> option is not present new associations are saved.
  #
  # == Validation
  #
  # Children records are validated unless <tt>:validate</tt> is +false+.
  #
  # == Callbacks
  #
  # Association with autosave option defines several callbacks on your
  # model (before_save, after_create, after_update). Please note that
  # callbacks are executed in the order they were defined in
  # model. You should avoid modifying the association content, before
  # autosave callbacks are executed. Placing your callbacks after
  # associations is usually a good practice.
  #
  # === One-to-one Example
  #
  #   class Post
  #     has_one :author, autosave: true
  #   end
  #
  # Saving changes to the parent and its associated model can now be performed
  # automatically _and_ atomically:
  #
  #   post = Post.find(1)
  #   post.title       # => "The current global position of migrating ducks"
  #   post.author.name # => "alloy"
  #
  #   post.title = "On the migration of ducks"
  #   post.author.name = "Eloy Duran"
  #
  #   post.save
  #   post.reload
  #   post.title       # => "On the migration of ducks"
  #   post.author.name # => "Eloy Duran"
  #
  # Destroying an associated model, as part of the parent's save action, is as
  # simple as marking it for destruction:
  #
  #   post.author.mark_for_destruction
  #   post.author.marked_for_destruction? # => true
  #
  # Note that the model is _not_ yet removed from the database:
  #
  #   id = post.author.id
  #   Author.find_by_id(id).nil? # => false
  #
  #   post.save
  #   post.reload.author # => nil
  #
  # Now it _is_ removed from the database:
  #
  #   Author.find_by_id(id).nil? # => true
  #
  # === One-to-many Example
  #
  # When <tt>:autosave</tt> is not declared new children are saved when their parent is saved:
  #
  #   class Post
  #     has_many :comments # :autosave option is not declared
  #   end
  #
  #   post = Post.new(title: 'ruby rocks')
  #   post.comments.build(body: 'hello world')
  #   post.save # => saves both post and comment
  #
  #   post = Post.create(title: 'ruby rocks')
  #   post.comments.build(body: 'hello world')
  #   post.save # => saves both post and comment
  #
  #   post = Post.create(title: 'ruby rocks')
  #   post.comments.create(body: 'hello world')
  #   post.save # => saves both post and comment
  #
  # When <tt>:autosave</tt> is true all children are saved, no matter whether they
  # are new records or not:
  #
  #   class Post
  #     has_many :comments, autosave: true
  #   end
  #
  #   post = Post.create(title: 'ruby rocks')
  #   post.comments.create(body: 'hello world')
  #   post.comments[0].body = 'hi everyone'
  #   post.save # => saves both post and comment, with 'hi everyone' as body
  #
  # Destroying one of the associated models as part of the parent's save action
  # is as simple as marking it for destruction:
  #
  #   post.comments.last.mark_for_destruction
  #   post.comments.last.marked_for_destruction? # => true
  #   post.comments.length # => 2
  #
  # Note that the model is _not_ yet removed from the database:
  #
  #   id = post.comments.last.id
  #   Comment.find_by_id(id).nil? # => false
  #
  #   post.save
  #   post.reload.comments.length # => 1
  #
  # Now it _is_ removed from the database:
  #
  #   Comment.find_by_id(id).nil? # => true

  module AutosaveAssociation
    extend ActiveSupport::Concern

    module AssociationBuilderExtension #:nodoc:
      def build
        model.send(:add_autosave_association_callbacks, reflection)
        super
      end
    end

    included do
      Associations::Builder::Association.class_eval do
        self.valid_options << :autosave
        include AssociationBuilderExtension
      end
    end

    module ClassMethods
      private

      def define_non_cyclic_method(name, reflection, &block)
        define_method(name) do |*args|
          result = true; @_already_called ||= {}
          # Loop prevention for validation of associations
          unless @_already_called[[name, reflection.name]]
            begin
              @_already_called[[name, reflection.name]]=true
              result = instance_eval(&block)
            ensure
              @_already_called[[name, reflection.name]]=false
            end
          end

          result
        end
      end

      # Adds validation and save callbacks for the association as specified by
      # the +reflection+.
      #
      # For performance reasons, we don't check whether to validate at runtime.
      # However the validation and callback methods are lazy and those methods
      # get created when they are invoked for the very first time. However,
      # this can change, for instance, when using nested attributes, which is
      # called _after_ the association has been defined. Since we don't want
      # the callbacks to get defined multiple times, there are guards that
      # check if the save or validation methods have already been defined
      # before actually defining them.
      def add_autosave_association_callbacks(reflection)
        save_method = :"autosave_associated_records_for_#{reflection.name}"
        validation_method = :"validate_associated_records_for_#{reflection.name}"
        collection = reflection.collection?

        unless method_defined?(save_method)
          if collection
            before_save :before_save_collection_association

            define_non_cyclic_method(save_method, reflection) { save_collection_association(reflection) }
            # Doesn't use after_save as that would save associations added in after_create/after_update twice
            after_create save_method
            after_update save_method
          elsif reflection.macro == :has_one
            define_method(save_method) { save_has_one_association(reflection) }
            # Configures two callbacks instead of a single after_save so that
            # the model may rely on their execution order relative to its
            # own callbacks.
            #
            # For example, given that after_creates run before after_saves, if
            # we configured instead an after_save there would be no way to fire
            # a custom after_create callback after the child association gets
            # created.
            after_create save_method
            after_update save_method
          else
            define_non_cyclic_method(save_method, reflection) { save_belongs_to_association(reflection) }
            before_save save_method
          end
        end

        if reflection.validate? && !method_defined?(validation_method)
          method = (collection ? :validate_collection_association : :validate_single_association)
          define_non_cyclic_method(validation_method, reflection) { send(method, reflection) }
          validate validation_method
        end
      end
    end

    # Reloads the attributes of the object as usual and clears <tt>marked_for_destruction</tt> flag.
    def reload(options = nil)
      @marked_for_destruction = false
      super
    end

    # Marks this record to be destroyed as part of the parents save transaction.
    # This does _not_ actually destroy the record instantly, rather child record will be destroyed
    # when <tt>parent.save</tt> is called.
    #
    # Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
    def mark_for_destruction
      @marked_for_destruction = true
    end

    # Returns whether or not this record will be destroyed as part of the parents save transaction.
    #
    # Only useful if the <tt>:autosave</tt> option on the parent is enabled for this associated model.
    def marked_for_destruction?
      @marked_for_destruction
    end

    # Returns whether or not this record has been changed in any way (including whether
    # any of its nested autosave associations are likewise changed)
    def changed_for_autosave?
      new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
    end

    private

    # Returns the record for an association collection that should be validated
    # or saved. If +autosave+ is +false+ only new records will be returned,
    # unless the parent is/was a new record itself.
    def associated_records_to_validate_or_save(association, new_record, autosave)
      if new_record
        association && association.target
      elsif autosave
        association.target.find_all { |record| record.changed_for_autosave? }
      else
        association.target.find_all { |record| record.new_record? }
      end
    end

    # go through nested autosave associations that are loaded in memory (without loading
    # any new ones), and return true if is changed for autosave
    def nested_records_changed_for_autosave?
      self.class.reflect_on_all_autosave_associations.any? do |reflection|
        association = association_instance_get(reflection.name)
        association && Array.wrap(association.target).any? { |a| a.changed_for_autosave? }
      end
    end

    # Validate the association if <tt>:validate</tt> or <tt>:autosave</tt> is
    # turned on for the association.
    def validate_single_association(reflection)
      association = association_instance_get(reflection.name)
      record      = association && association.reader
      association_valid?(reflection, record) if record
    end

    # Validate the associated records if <tt>:validate</tt> or
    # <tt>:autosave</tt> is turned on for the association specified by
    # +reflection+.
    def validate_collection_association(reflection)
      if association = association_instance_get(reflection.name)
        if records = associated_records_to_validate_or_save(association, new_record?, reflection.options[:autosave])
          records.each { |record| association_valid?(reflection, record) }
        end
      end
    end

    # Returns whether or not the association is valid and applies any errors to
    # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
    # enabled records if they're marked_for_destruction? or destroyed.
    def association_valid?(reflection, record)
      return true if record.destroyed? || record.marked_for_destruction?

      unless valid = record.valid?(validation_context)
        if reflection.options[:autosave]
          record.errors.each do |attribute, message|
            attribute = "#{reflection.name}.#{attribute}"
            errors[attribute] << message
            errors[attribute].uniq!
          end
        else
          errors.add(reflection.name)
        end
      end
      valid
    end

    # Is used as a before_save callback to check while saving a collection
    # association whether or not the parent was a new record before saving.
    def before_save_collection_association
      @new_record_before_save = new_record?
      true
    end

    # Saves any new associated records, or all loaded autosave associations if
    # <tt>:autosave</tt> is enabled on the association.
    #
    # In addition, it destroys all children that were marked for destruction
    # with mark_for_destruction.
    #
    # This all happens inside a transaction, _if_ the Transactions module is included into
    # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
    def save_collection_association(reflection)
      if association = association_instance_get(reflection.name)
        autosave = reflection.options[:autosave]

        if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
          records_to_destroy = []
          records.each do |record|
            next if record.destroyed?

            saved = true

            if autosave && record.marked_for_destruction?
              records_to_destroy << record
            elsif autosave != false && (@new_record_before_save || record.new_record?)
              if autosave
                saved = association.insert_record(record, false)
              else
                association.insert_record(record) unless reflection.nested?
              end
            elsif autosave
              saved = record.save(:validate => false)
            end

            raise ActiveRecord::Rollback unless saved
          end

          records_to_destroy.each do |record|
            association.destroy(record)
          end
        end

        # reconstruct the scope now that we know the owner's id
        association.send(:reset_scope) if association.respond_to?(:reset_scope)
      end
    end

    # Saves the associated record if it's new or <tt>:autosave</tt> is enabled
    # on the association.
    #
    # In addition, it will destroy the association if it was marked for
    # destruction with mark_for_destruction.
    #
    # This all happens inside a transaction, _if_ the Transactions module is included into
    # ActiveRecord::Base after the AutosaveAssociation module, which it does by default.
    def save_has_one_association(reflection)
      association = association_instance_get(reflection.name)
      record      = association && association.load_target
      if record && !record.destroyed?
        autosave = reflection.options[:autosave]

        if autosave && record.marked_for_destruction?
          record.destroy
        else
          key = reflection.options[:primary_key] ? send(reflection.options[:primary_key]) : id
          if autosave != false && (new_record? || record.new_record? || record[reflection.foreign_key] != key || autosave)
            unless reflection.through_reflection
              record[reflection.foreign_key] = key
            end

            saved = record.save(:validate => !autosave)
            raise ActiveRecord::Rollback if !saved && autosave
            saved
          end
        end
      end
    end

    # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
    #
    # In addition, it will destroy the association if it was marked for destruction.
    def save_belongs_to_association(reflection)
      association = association_instance_get(reflection.name)
      record      = association && association.load_target
      if record && !record.destroyed?
        autosave = reflection.options[:autosave]

        if autosave && record.marked_for_destruction?
          self[reflection.foreign_key] = nil
          record.destroy
        elsif autosave != false
          saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)

          if association.updated?
            association_id = record.send(reflection.options[:primary_key] || :id)
            self[reflection.foreign_key] = association_id
            association.loaded!
          end

          saved if autosave
        end
      end
    end
  end
end
require 'yaml'
require 'set'
require 'active_support/benchmarkable'
require 'active_support/dependencies'
require 'active_support/descendants_tracker'
require 'active_support/time'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/class/delegating_attributes'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/hash/deep_merge'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/introspection'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/class/subclasses'
require 'arel'
require 'active_record/errors'
require 'active_record/log_subscriber'
require 'active_record/explain_subscriber'

module ActiveRecord #:nodoc:
  # = Active Record
  #
  # Active Record objects don't specify their attributes directly, but rather infer them from
  # the table definition with which they're linked. Adding, removing, and changing attributes
  # and their type is done directly in the database. Any change is instantly reflected in the
  # Active Record objects. The mapping that binds a given Active Record class to a certain
  # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
  #
  # See the mapping rules in table_name and the full example in link:files/activerecord/README_rdoc.html for more insight.
  #
  # == Creation
  #
  # Active Records accept constructor parameters either in a hash or as a block. The hash
  # method is especially useful when you're receiving the data from somewhere else, like an
  # HTTP request. It works like this:
  #
  #   user = User.new(name: "David", occupation: "Code Artist")
  #   user.name # => "David"
  #
  # You can also use block initialization:
  #
  #   user = User.new do |u|
  #     u.name = "David"
  #     u.occupation = "Code Artist"
  #   end
  #
  # And of course you can just create a bare object and specify the attributes after the fact:
  #
  #   user = User.new
  #   user.name = "David"
  #   user.occupation = "Code Artist"
  #
  # == Conditions
  #
  # Conditions can either be specified as a string, array, or hash representing the WHERE-part of an SQL statement.
  # The array form is to be used when the condition input is tainted and requires sanitization. The string form can
  # be used for statements that don't involve tainted data. The hash form works much like the array form, except
  # only equality and range is possible. Examples:
  #
  #   class User < ActiveRecord::Base
  #     def self.authenticate_unsafely(user_name, password)
  #       where("user_name = '#{user_name}' AND password = '#{password}'").first
  #     end
  #
  #     def self.authenticate_safely(user_name, password)
  #       where("user_name = ? AND password = ?", user_name, password).first
  #     end
  #
  #     def self.authenticate_safely_simply(user_name, password)
  #       where(user_name: user_name, password: password).first
  #     end
  #   end
  #
  # The <tt>authenticate_unsafely</tt> method inserts the parameters directly into the query
  # and is thus susceptible to SQL-injection attacks if the <tt>user_name</tt> and +password+
  # parameters come directly from an HTTP request. The <tt>authenticate_safely</tt> and
  # <tt>authenticate_safely_simply</tt> both will sanitize the <tt>user_name</tt> and +password+
  # before inserting them in the query, which will ensure that an attacker can't escape the
  # query and fake the login (or worse).
  #
  # When using multiple parameters in the conditions, it can easily become hard to read exactly
  # what the fourth or fifth question mark is supposed to represent. In those cases, you can
  # resort to named bind variables instead. That's done by replacing the question marks with
  # symbols and supplying a hash with values for the matching symbol keys:
  #
  #   Company.where(
  #     "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
  #     { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
  #   ).first
  #
  # Similarly, a simple hash without a statement will generate conditions based on equality with the SQL AND
  # operator. For instance:
  #
  #   Student.where(first_name: "Harvey", status: 1)
  #   Student.where(params[:student])
  #
  # A range may be used in the hash to use the SQL BETWEEN operator:
  #
  #   Student.where(grade: 9..12)
  #
  # An array may be used in the hash to use the SQL IN operator:
  #
  #   Student.where(grade: [9,11,12])
  #
  # When joining tables, nested hashes or keys written in the form 'table_name.column_name'
  # can be used to qualify the table name of a particular condition. For instance:
  #
  #   Student.joins(:schools).where(schools: { category: 'public' })
  #   Student.joins(:schools).where('schools.category' => 'public' )
  #
  # == Overwriting default accessors
  #
  # All column values are automatically available through basic accessors on the Active Record
  # object, but sometimes you want to specialize this behavior. This can be done by overwriting
  # the default accessors (using the same name as the attribute) and calling
  # <tt>read_attribute(attr_name)</tt> and <tt>write_attribute(attr_name, value)</tt> to actually
  # change things.
  #
  #   class Song < ActiveRecord::Base
  #     # Uses an integer of seconds to hold the length of the song
  #
  #     def length=(minutes)
  #       write_attribute(:length, minutes.to_i * 60)
  #     end
  #
  #     def length
  #       read_attribute(:length) / 60
  #     end
  #   end
  #
  # You can alternatively use <tt>self[:attribute]=(value)</tt> and <tt>self[:attribute]</tt>
  # instead of <tt>write_attribute(:attribute, value)</tt> and <tt>read_attribute(:attribute)</tt>.
  #
  # == Attribute query methods
  #
  # In addition to the basic accessors, query methods are also automatically available on the Active Record object.
  # Query methods allow you to test whether an attribute value is present.
  #
  # For example, an Active Record User with the <tt>name</tt> attribute has a <tt>name?</tt> method that you can call
  # to determine whether the user has a name:
  #
  #   user = User.new(name: "David")
  #   user.name? # => true
  #
  #   anonymous = User.new(name: "")
  #   anonymous.name? # => false
  #
  # == Accessing attributes before they have been typecasted
  #
  # Sometimes you want to be able to read the raw attribute data without having the column-determined
  # typecast run its course first. That can be done by using the <tt><attribute>_before_type_cast</tt>
  # accessors that all attributes have. For example, if your Account model has a <tt>balance</tt> attribute,
  # you can call <tt>account.balance_before_type_cast</tt> or <tt>account.id_before_type_cast</tt>.
  #
  # This is especially useful in validation situations where the user might supply a string for an
  # integer field and you want to display the original string back in an error message. Accessing the
  # attribute normally would typecast the string to 0, which isn't what you want.
  #
  # == Dynamic attribute-based finders
  #
  # Dynamic attribute-based finders are a cleaner way of getting (and/or creating) objects
  # by simple queries without turning to SQL. They work by appending the name of an attribute
  # to <tt>find_by_</tt> like <tt>Person.find_by_user_name</tt>.
  # Instead of writing <tt>Person.where(user_name: user_name).first</tt>, you just do
  # <tt>Person.find_by_user_name(user_name)</tt>.
  #
  # It's possible to add an exclamation point (!) on the end of the dynamic finders to get them to raise an
  # <tt>ActiveRecord::RecordNotFound</tt> error if they do not return any records,
  # like <tt>Person.find_by_last_name!</tt>.
  #
  # It's also possible to use multiple attributes in the same find by separating them with "_and_".
  #
  #  Person.where(user_name: user_name, password: password).first
  #  Person.find_by_user_name_and_password(user_name, password) # with dynamic finder
  #
  # It's even possible to call these dynamic finder methods on relations and named scopes.
  #
  #   Payment.order("created_on").find_by_amount(50)
  #
  # == Saving arrays, hashes, and other non-mappable objects in text columns
  #
  # Active Record can serialize any object in text columns using YAML. To do so, you must
  # specify this with a call to the class method +serialize+.
  # This makes it possible to store arrays, hashes, and other non-mappable objects without doing
  # any additional work.
  #
  #   class User < ActiveRecord::Base
  #     serialize :preferences
  #   end
  #
  #   user = User.create(preferences: { "background" => "black", "display" => large })
  #   User.find(user.id).preferences # => { "background" => "black", "display" => large }
  #
  # You can also specify a class option as the second parameter that'll raise an exception
  # if a serialized object is retrieved as a descendant of a class not in the hierarchy.
  #
  #   class User < ActiveRecord::Base
  #     serialize :preferences, Hash
  #   end
  #
  #   user = User.create(preferences: %w( one two three ))
  #   User.find(user.id).preferences    # raises SerializationTypeMismatch
  #
  # When you specify a class option, the default value for that attribute will be a new
  # instance of that class.
  #
  #   class User < ActiveRecord::Base
  #     serialize :preferences, OpenStruct
  #   end
  #
  #   user = User.new
  #   user.preferences.theme_color = "red"
  #
  #
  # == Single table inheritance
  #
  # Active Record allows inheritance by storing the name of the class in a column that by
  # default is named "type" (can be changed by overwriting <tt>Base.inheritance_column</tt>).
  # This means that an inheritance looking like this:
  #
  #   class Company < ActiveRecord::Base; end
  #   class Firm < Company; end
  #   class Client < Company; end
  #   class PriorityClient < Client; end
  #
  # When you do <tt>Firm.create(name: "37signals")</tt>, this record will be saved in
  # the companies table with type = "Firm". You can then fetch this row again using
  # <tt>Company.where(name: '37signals').first</tt> and it will return a Firm object.
  #
  # If you don't have a type column defined in your table, single-table inheritance won't
  # be triggered. In that case, it'll work just like normal subclasses with no special magic
  # for differentiating between them or reloading the right type with find.
  #
  # Note, all the attributes for all the cases are kept in the same table. Read more:
  # http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html
  #
  # == Connection to multiple databases in different models
  #
  # Connections are usually created through ActiveRecord::Base.establish_connection and retrieved
  # by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this
  # connection. But you can also set a class-specific connection. For example, if Course is an
  # ActiveRecord::Base, but resides in a different database, you can just say <tt>Course.establish_connection</tt>
  # and Course and all of its subclasses will use this connection instead.
  #
  # This feature is implemented by keeping a connection pool in ActiveRecord::Base that is
  # a Hash indexed by the class. If a connection is requested, the retrieve_connection method
  # will go up the class-hierarchy until a connection is found in the connection pool.
  #
  # == Exceptions
  #
  # * ActiveRecordError - Generic error class and superclass of all other errors raised by Active Record.
  # * AdapterNotSpecified - The configuration hash used in <tt>establish_connection</tt> didn't include an
  #   <tt>:adapter</tt> key.
  # * AdapterNotFound - The <tt>:adapter</tt> key used in <tt>establish_connection</tt> specified a
  #   non-existent adapter
  #   (or a bad spelling of an existing one).
  # * AssociationTypeMismatch - The object assigned to the association wasn't of the type
  #   specified in the association definition.
  # * AttributeAssignmentError - An error occurred while doing a mass assignment through the
  #   <tt>attributes=</tt> method.
  #   You can inspect the +attribute+ property of the exception object to determine which attribute
  #   triggered the error.
  # * ConnectionNotEstablished - No connection has been established. Use <tt>establish_connection</tt>
  #   before querying.
  # * MultiparameterAssignmentErrors - Collection of errors that occurred during a mass assignment using the
  #   <tt>attributes=</tt> method. The +errors+ property of this exception contains an array of
  #   AttributeAssignmentError
  #   objects that should be inspected to determine which attributes triggered the errors.
  # * RecordInvalid - raised by save! and create! when the record is invalid.
  # * RecordNotFound - No record responded to the +find+ method. Either the row with the given ID doesn't exist
  #   or the row didn't meet the additional restrictions. Some +find+ calls do not raise this exception to signal
  #   nothing was found, please check its documentation for further details.
  # * SerializationTypeMismatch - The serialized object wasn't of the class specified as the second parameter.
  # * StatementInvalid - The database server rejected the SQL statement. The precise error is added in the message.
  #
  # *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
  # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
  # instances in the current object space.
  class Base
    extend ActiveModel::Naming

    extend ActiveSupport::Benchmarkable
    extend ActiveSupport::DescendantsTracker

    extend ConnectionHandling
    extend QueryCache::ClassMethods
    extend Querying
    extend Translation
    extend DynamicMatchers
    extend Explain

    include Persistence
    include ReadonlyAttributes
    include ModelSchema
    include Inheritance
    include Scoping
    include Sanitization
    include AttributeAssignment
    include ActiveModel::Conversion
    include Integration
    include Validations
    include CounterCache
    include Locking::Optimistic
    include Locking::Pessimistic
    include AttributeMethods
    include Callbacks
    include Timestamp
    include Associations
    include ActiveModel::SecurePassword
    include AutosaveAssociation
    include NestedAttributes
    include Aggregations
    include Transactions
    include Reflection
    include Serialization
    include Store
    include Core
  end

  ActiveSupport.run_load_hooks(:active_record, Base)
end
module ActiveRecord
  # = Active Record Callbacks
  #
  # Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic
  # before or after an alteration of the object state. This can be used to make sure that associated and
  # dependent objects are deleted when +destroy+ is called (by overwriting +before_destroy+) or to massage attributes
  # before they're validated (by overwriting +before_validation+). As an example of the callbacks initiated, consider
  # the <tt>Base#save</tt> call for a new record:
  #
  # * (-) <tt>save</tt>
  # * (-) <tt>valid</tt>
  # * (1) <tt>before_validation</tt>
  # * (-) <tt>validate</tt>
  # * (2) <tt>after_validation</tt>
  # * (3) <tt>before_save</tt>
  # * (4) <tt>before_create</tt>
  # * (-) <tt>create</tt>
  # * (5) <tt>after_create</tt>
  # * (6) <tt>after_save</tt>
  # * (7) <tt>after_commit</tt>
  #
  # Also, an <tt>after_rollback</tt> callback can be configured to be triggered whenever a rollback is issued.
  # Check out <tt>ActiveRecord::Transactions</tt> for more details about <tt>after_commit</tt> and
  # <tt>after_rollback</tt>.
  #
  # Lastly an <tt>after_find</tt> and <tt>after_initialize</tt> callback is triggered for each object that
  # is found and instantiated by a finder, with <tt>after_initialize</tt> being triggered after new objects
  # are instantiated as well.
  #
  # That's a total of twelve callbacks, which gives you immense power to react and prepare for each state in the
  # Active Record life cycle. The sequence for calling <tt>Base#save</tt> for an existing record is similar,
  # except that each <tt>_create</tt> callback is replaced by the corresponding <tt>_update</tt> callback.
  #
  # Examples:
  #   class CreditCard < ActiveRecord::Base
  #     # Strip everything but digits, so the user can specify "555 234 34" or
  #     # "5552-3434" and both will mean "55523434"
  #     before_validation(on: :create) do
  #       self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
  #     end
  #   end
  #
  #   class Subscription < ActiveRecord::Base
  #     before_create :record_signup
  #
  #     private
  #       def record_signup
  #         self.signed_up_on = Date.today
  #       end
  #   end
  #
  #   class Firm < ActiveRecord::Base
  #     # Destroys the associated clients and people when the firm is destroyed
  #     before_destroy { |record| Person.destroy_all "firm_id = #{record.id}"   }
  #     before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
  #   end
  #
  # == Inheritable callback queues
  #
  # Besides the overwritable callback methods, it's also possible to register callbacks through the
  # use of the callback macros. Their main advantage is that the macros add behavior into a callback
  # queue that is kept intact down through an inheritance hierarchy.
  #
  #   class Topic < ActiveRecord::Base
  #     before_destroy :destroy_author
  #   end
  #
  #   class Reply < Topic
  #     before_destroy :destroy_readers
  #   end
  #
  # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is
  # run, both +destroy_author+ and +destroy_readers+ are called. Contrast this to the following situation
  # where the +before_destroy+ method is overridden:
  #
  #   class Topic < ActiveRecord::Base
  #     def before_destroy() destroy_author end
  #   end
  #
  #   class Reply < Topic
  #     def before_destroy() destroy_readers end
  #   end
  #
  # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+.
  # So, use the callback macros when you want to ensure that a certain callback is called for the entire
  # hierarchy, and use the regular overwriteable methods when you want to leave it up to each descendant
  # to decide whether they want to call +super+ and trigger the inherited callbacks.
  #
  # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the
  # callbacks before specifying the associations. Otherwise, you might trigger the loading of a
  # child before the parent has registered the callbacks and they won't be inherited.
  #
  # == Types of callbacks
  #
  # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
  # inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects
  # are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
  # creating mix-ins), and inline eval methods are deprecated.
  #
  # The method reference callbacks work by specifying a protected or private method available in the object, like this:
  #
  #   class Topic < ActiveRecord::Base
  #     before_destroy :delete_parents
  #
  #     private
  #       def delete_parents
  #         self.class.delete_all "parent_id = #{id}"
  #       end
  #   end
  #
  # The callback objects have methods named after the callback called with the record as the only parameter, such as:
  #
  #   class BankAccount < ActiveRecord::Base
  #     before_save      EncryptionWrapper.new
  #     after_save       EncryptionWrapper.new
  #     after_initialize EncryptionWrapper.new
  #   end
  #
  #   class EncryptionWrapper
  #     def before_save(record)
  #       record.credit_card_number = encrypt(record.credit_card_number)
  #     end
  #
  #     def after_save(record)
  #       record.credit_card_number = decrypt(record.credit_card_number)
  #     end
  #
  #     alias_method :after_find, :after_save
  #
  #     private
  #       def encrypt(value)
  #         # Secrecy is committed
  #       end
  #
  #       def decrypt(value)
  #         # Secrecy is unveiled
  #       end
  #   end
  #
  # So you specify the object you want messaged on a given callback. When that callback is triggered, the object has
  # a method by the name of the callback messaged. You can make these callbacks more flexible by passing in other
  # initialization data such as the name of the attribute to work with:
  #
  #   class BankAccount < ActiveRecord::Base
  #     before_save      EncryptionWrapper.new("credit_card_number")
  #     after_save       EncryptionWrapper.new("credit_card_number")
  #     after_initialize EncryptionWrapper.new("credit_card_number")
  #   end
  #
  #   class EncryptionWrapper
  #     def initialize(attribute)
  #       @attribute = attribute
  #     end
  #
  #     def before_save(record)
  #       record.send("#{@attribute}=", encrypt(record.send("#{@attribute}")))
  #     end
  #
  #     def after_save(record)
  #       record.send("#{@attribute}=", decrypt(record.send("#{@attribute}")))
  #     end
  #
  #     alias_method :after_find, :after_save
  #
  #     private
  #       def encrypt(value)
  #         # Secrecy is committed
  #       end
  #
  #       def decrypt(value)
  #         # Secrecy is unveiled
  #       end
  #   end
  #
  # The callback macros usually accept a symbol for the method they're supposed to run, but you can also
  # pass a "method string", which will then be evaluated within the binding of the callback. Example:
  #
  #   class Topic < ActiveRecord::Base
  #     before_destroy 'self.class.delete_all "parent_id = #{id}"'
  #   end
  #
  # Notice that single quotes (') are used so the <tt>#{id}</tt> part isn't evaluated until the callback
  # is triggered. Also note that these inline callbacks can be stacked just like the regular ones:
  #
  #   class Topic < ActiveRecord::Base
  #     before_destroy 'self.class.delete_all "parent_id = #{id}"',
  #                    'puts "Evaluated after parents are destroyed"'
  #   end
  #
  # == <tt>before_validation*</tt> returning statements
  #
  # If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be
  # aborted and <tt>Base#save</tt> will return +false+. If Base#save! is called it will raise a
  # ActiveRecord::RecordInvalid exception. Nothing will be appended to the errors object.
  #
  # == Canceling callbacks
  #
  # If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are
  # cancelled. If an <tt>after_*</tt> callback returns +false+, all the later callbacks are cancelled.
  # Callbacks are generally run in the order they are defined, with the exception of callbacks defined as
  # methods on the model, which are called last.
  #
  # == Ordering callbacks
  #
  # Sometimes the code needs that the callbacks execute in a specific order. For example, a +before_destroy+
  # callback (+log_children+ in this case) should be executed before the children get destroyed by the +dependent: destroy+ option.
  #
  # Let's look at the code below:
  #
  #   class Topic < ActiveRecord::Base
  #     has_many :children, dependent: destroy
  #
  #     before_destroy :log_children
  #
  #     private
  #       def log_children
  #         # Child processing
  #       end
  #   end
  #
  # In this case, the problem is that when the +before_destroy+ callback is executed, the children are not available
  # because the +destroy+ callback gets executed first. You can use the +prepend+ option on the +before_destroy+ callback to avoid this.
  #
  #   class Topic < ActiveRecord::Base
  #     has_many :children, dependent: destroy
  #
  #     before_destroy :log_children, prepend: true
  #
  #     private
  #       def log_children
  #         # Child processing
  #       end
  #   end
  #
  # This way, the +before_destroy+ gets executed before the <tt>dependent: destroy</tt> is called, and the data is still available.
  #
  # == Transactions
  #
  # The entire callback chain of a +save+, <tt>save!</tt>, or +destroy+ call runs
  # within a transaction. That includes <tt>after_*</tt> hooks. If everything
  # goes fine a COMMIT is executed once the chain has been completed.
  #
  # If a <tt>before_*</tt> callback cancels the action a ROLLBACK is issued. You
  # can also trigger a ROLLBACK raising an exception in any of the callbacks,
  # including <tt>after_*</tt> hooks. Note, however, that in that case the client
  # needs to be aware of it because an ordinary +save+ will raise such exception
  # instead of quietly returning +false+.
  #
  # == Debugging callbacks
  #
  # The callback chain is accessible via the <tt>_*_callbacks</tt> method on an object. ActiveModel Callbacks support
  # <tt>:before</tt>, <tt>:after</tt> and <tt>:around</tt> as values for the <tt>kind</tt> property. The <tt>kind</tt> property
  # defines what part of the chain the callback runs in.
  #
  # To find all callbacks in the before_save callback chain:
  #
  #   Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }
  #
  # Returns an array of callback objects that form the before_save chain.
  #
  # To further check if the before_save chain contains a proc defined as <tt>rest_when_dead</tt> use the <tt>filter</tt> property of the callback object:
  #
  #   Topic._save_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:rest_when_dead)
  #
  # Returns true or false depending on whether the proc is contained in the before_save callback chain on a Topic model.
  #
  module Callbacks
    extend ActiveSupport::Concern

    CALLBACKS = [
      :after_initialize, :after_find, :after_touch, :before_validation, :after_validation,
      :before_save, :around_save, :after_save, :before_create, :around_create,
      :after_create, :before_update, :around_update, :after_update,
      :before_destroy, :around_destroy, :after_destroy, :after_commit, :after_rollback
    ]

    module ClassMethods
      include ActiveModel::Callbacks
    end

    included do
      include ActiveModel::Validations::Callbacks

      define_model_callbacks :initialize, :find, :touch, :only => :after
      define_model_callbacks :save, :create, :update, :destroy
    end

    def destroy #:nodoc:
      run_callbacks(:destroy) { super }
    end

    def touch(*) #:nodoc:
      run_callbacks(:touch) { super }
    end

  private

    def create_or_update #:nodoc:
      run_callbacks(:save) { super }
    end

    def create_record #:nodoc:
      run_callbacks(:create) { super }
    end

    def update_record(*) #:nodoc:
      run_callbacks(:update) { super }
    end
  end
end
require 'yaml'

module ActiveRecord
  module Coders # :nodoc:
    class YAMLColumn # :nodoc:
      RESCUE_ERRORS = [ ArgumentError, Psych::SyntaxError ]

      attr_accessor :object_class

      def initialize(object_class = Object)
        @object_class = object_class
      end

      def dump(obj)
        return if obj.nil?

        unless obj.is_a?(object_class)
          raise SerializationTypeMismatch,
            "Attribute was supposed to be a #{object_class}, but was a #{obj.class}. -- #{obj.inspect}"
        end
        YAML.dump obj
      end

      def load(yaml)
        return object_class.new if object_class != Object && yaml.nil?
        return yaml unless yaml.is_a?(String) && yaml =~ /^---/
        begin
          obj = YAML.load(yaml)

          unless obj.is_a?(object_class) || obj.nil?
            raise SerializationTypeMismatch,
              "Attribute was supposed to be a #{object_class}, but was a #{obj.class}"
          end
          obj ||= object_class.new if object_class != Object

          obj
        rescue *RESCUE_ERRORS
          yaml
        end
      end
    end
  end
end
require 'thread'
require 'thread_safe'
require 'monitor'
require 'set'

module ActiveRecord
  # Raised when a connection could not be obtained within the connection
  # acquisition timeout period: because max connections in pool
  # are in use.
  class ConnectionTimeoutError < ConnectionNotEstablished
  end

  module ConnectionAdapters
    # Connection pool base class for managing Active Record database
    # connections.
    #
    # == Introduction
    #
    # A connection pool synchronizes thread access to a limited number of
    # database connections. The basic idea is that each thread checks out a
    # database connection from the pool, uses that connection, and checks the
    # connection back in. ConnectionPool is completely thread-safe, and will
    # ensure that a connection cannot be used by two threads at the same time,
    # as long as ConnectionPool's contract is correctly followed. It will also
    # handle cases in which there are more threads than connections: if all
    # connections have been checked out, and a thread tries to checkout a
    # connection anyway, then ConnectionPool will wait until some other thread
    # has checked in a connection.
    #
    # == Obtaining (checking out) a connection
    #
    # Connections can be obtained and used from a connection pool in several
    # ways:
    #
    # 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and
    #    earlier (pre-connection-pooling). Eventually, when you're done with
    #    the connection(s) and wish it to be returned to the pool, you call
    #    ActiveRecord::Base.clear_active_connections!. This will be the
    #    default behavior for Active Record when used in conjunction with
    #    Action Pack's request handling cycle.
    # 2. Manually check out a connection from the pool with
    #    ActiveRecord::Base.connection_pool.checkout. You are responsible for
    #    returning this connection to the pool when finished by calling
    #    ActiveRecord::Base.connection_pool.checkin(connection).
    # 3. Use ActiveRecord::Base.connection_pool.with_connection(&block), which
    #    obtains a connection, yields it as the sole argument to the block,
    #    and returns it to the pool after the block completes.
    #
    # Connections in the pool are actually AbstractAdapter objects (or objects
    # compatible with AbstractAdapter's interface).
    #
    # == Options
    #
    # There are several connection-pooling-related options that you can add to
    # your database connection configuration:
    #
    # * +pool+: number indicating size of connection pool (default 5)
    # * +checkout_timeout+: number of seconds to block and wait for a connection
    #   before giving up and raising a timeout error (default 5 seconds).
    # * +reaping_frequency+: frequency in seconds to periodically run the
    #   Reaper, which attempts to find and close dead connections, which can
    #   occur if a programmer forgets to close a connection at the end of a
    #   thread or a thread dies unexpectedly. (Default nil, which means don't
    #   run the Reaper).
    # * +dead_connection_timeout+: number of seconds from last checkout
    #   after which the Reaper will consider a connection reapable. (default
    #   5 seconds).
    class ConnectionPool
      # Threadsafe, fair, FIFO queue.  Meant to be used by ConnectionPool
      # with which it shares a Monitor.  But could be a generic Queue.
      #
      # The Queue in stdlib's 'thread' could replace this class except
      # stdlib's doesn't support waiting with a timeout.
      class Queue
        def initialize(lock = Monitor.new)
          @lock = lock
          @cond = @lock.new_cond
          @num_waiting = 0
          @queue = []
        end

        # Test if any threads are currently waiting on the queue.
        def any_waiting?
          synchronize do
            @num_waiting > 0
          end
        end

        # Return the number of threads currently waiting on this
        # queue.
        def num_waiting
          synchronize do
            @num_waiting
          end
        end

        # Add +element+ to the queue.  Never blocks.
        def add(element)
          synchronize do
            @queue.push element
            @cond.signal
          end
        end

        # If +element+ is in the queue, remove and return it, or nil.
        def delete(element)
          synchronize do
            @queue.delete(element)
          end
        end

        # Remove all elements from the queue.
        def clear
          synchronize do
            @queue.clear
          end
        end

        # Remove the head of the queue.
        #
        # If +timeout+ is not given, remove and return the head the
        # queue if the number of available elements is strictly
        # greater than the number of threads currently waiting (that
        # is, don't jump ahead in line).  Otherwise, return nil.
        #
        # If +timeout+ is given, block if it there is no element
        # available, waiting up to +timeout+ seconds for an element to
        # become available.
        #
        # Raises:
        # - ConnectionTimeoutError if +timeout+ is given and no element
        # becomes available after +timeout+ seconds,
        def poll(timeout = nil)
          synchronize do
            if timeout
              no_wait_poll || wait_poll(timeout)
            else
              no_wait_poll
            end
          end
        end

        private

        def synchronize(&block)
          @lock.synchronize(&block)
        end

        # Test if the queue currently contains any elements.
        def any?
          !@queue.empty?
        end

        # A thread can remove an element from the queue without
        # waiting if an only if the number of currently available
        # connections is strictly greater than the number of waiting
        # threads.
        def can_remove_no_wait?
          @queue.size > @num_waiting
        end

        # Removes and returns the head of the queue if possible, or nil.
        def remove
          @queue.shift
        end

        # Remove and return the head the queue if the number of
        # available elements is strictly greater than the number of
        # threads currently waiting.  Otherwise, return nil.
        def no_wait_poll
          remove if can_remove_no_wait?
        end

        # Waits on the queue up to +timeout+ seconds, then removes and
        # returns the head of the queue.
        def wait_poll(timeout)
          @num_waiting += 1

          t0 = Time.now
          elapsed = 0
          loop do
            @cond.wait(timeout - elapsed)

            return remove if any?

            elapsed = Time.now - t0
            if elapsed >= timeout
              msg = 'could not obtain a database connection within %0.3f seconds (waited %0.3f seconds)' %
                [timeout, elapsed]
              raise ConnectionTimeoutError, msg
            end
          end
        ensure
          @num_waiting -= 1
        end
      end

      # Every +frequency+ seconds, the reaper will call +reap+ on +pool+.
      # A reaper instantiated with a nil frequency will never reap the
      # connection pool.
      #
      # Configure the frequency by setting "reaping_frequency" in your
      # database yaml file.
      class Reaper
        attr_reader :pool, :frequency

        def initialize(pool, frequency)
          @pool      = pool
          @frequency = frequency
        end

        def run
          return unless frequency
          Thread.new(frequency, pool) { |t, p|
            while true
              sleep t
              p.reap
            end
          }
        end
      end

      include MonitorMixin

      attr_accessor :automatic_reconnect, :checkout_timeout, :dead_connection_timeout
      attr_reader :spec, :connections, :size, :reaper

      # Creates a new ConnectionPool object. +spec+ is a ConnectionSpecification
      # object which describes database connection information (e.g. adapter,
      # host name, username, password, etc), as well as the maximum size for
      # this ConnectionPool.
      #
      # The default ConnectionPool maximum size is 5.
      def initialize(spec)
        super()

        @spec = spec

        @checkout_timeout = spec.config[:checkout_timeout] || 5
        @dead_connection_timeout = spec.config[:dead_connection_timeout] || 5
        @reaper  = Reaper.new self, spec.config[:reaping_frequency]
        @reaper.run

        # default max pool size to 5
        @size = (spec.config[:pool] && spec.config[:pool].to_i) || 5

        # The cache of reserved connections mapped to threads
        @reserved_connections = ThreadSafe::Cache.new(:initial_capacity => @size)

        @connections         = []
        @automatic_reconnect = true

        @available = Queue.new self
      end

      # Hack for tests to be able to add connections.  Do not call outside of tests
      def insert_connection_for_test!(c) #:nodoc:
        synchronize do
          @connections << c
          @available.add c
        end
      end

      # Retrieve the connection associated with the current thread, or call
      # #checkout to obtain one if necessary.
      #
      # #connection can be called any number of times; the connection is
      # held in a hash keyed by the thread id.
      def connection
        # this is correctly done double-checked locking
        # (ThreadSafe::Cache's lookups have volatile semantics)
        @reserved_connections[current_connection_id] || synchronize do
          @reserved_connections[current_connection_id] ||= checkout
        end
      end

      # Is there an open connection that is being used for the current thread?
      def active_connection?
        synchronize do
          @reserved_connections.fetch(current_connection_id) {
            return false
          }.in_use?
        end
      end

      # Signal that the thread is finished with the current connection.
      # #release_connection releases the connection-thread association
      # and returns the connection to the pool.
      def release_connection(with_id = current_connection_id)
        synchronize do
          conn = @reserved_connections.delete(with_id)
          checkin conn if conn
        end
      end

      # If a connection already exists yield it to the block. If no connection
      # exists checkout a connection, yield it to the block, and checkin the
      # connection when finished.
      def with_connection
        connection_id = current_connection_id
        fresh_connection = true unless active_connection?
        yield connection
      ensure
        release_connection(connection_id) if fresh_connection
      end

      # Returns true if a connection has already been opened.
      def connected?
        synchronize { @connections.any? }
      end

      # Disconnects all connections in the pool, and clears the pool.
      def disconnect!
        synchronize do
          @reserved_connections.clear
          @connections.each do |conn|
            checkin conn
            conn.disconnect!
          end
          @connections = []
          @available.clear
        end
      end

      # Clears the cache which maps classes.
      def clear_reloadable_connections!
        synchronize do
          @reserved_connections.clear
          @connections.each do |conn|
            checkin conn
            conn.disconnect! if conn.requires_reloading?
          end
          @connections.delete_if do |conn|
            conn.requires_reloading?
          end
          @available.clear
          @connections.each do |conn|
            @available.add conn
          end
        end
      end

      def clear_stale_cached_connections! # :nodoc:
        reap
      end
      deprecate :clear_stale_cached_connections! => "Please use #reap instead"

      # Check-out a database connection from the pool, indicating that you want
      # to use it. You should call #checkin when you no longer need this.
      #
      # This is done by either returning and leasing existing connection, or by
      # creating a new connection and leasing it.
      #
      # If all connections are leased and the pool is at capacity (meaning the
      # number of currently leased connections is greater than or equal to the
      # size limit set), an ActiveRecord::ConnectionTimeoutError exception will be raised.
      #
      # Returns: an AbstractAdapter object.
      #
      # Raises:
      # - ConnectionTimeoutError: no connection can be obtained from the pool.
      def checkout
        synchronize do
          conn = acquire_connection
          conn.lease
          checkout_and_verify(conn)
        end
      end

      # Check-in a database connection back into the pool, indicating that you
      # no longer need this connection.
      #
      # +conn+: an AbstractAdapter object, which was obtained by earlier by
      # calling +checkout+ on this pool.
      def checkin(conn)
        synchronize do
          conn.run_callbacks :checkin do
            conn.expire
          end

          release conn

          @available.add conn
        end
      end

      # Remove a connection from the connection pool.  The connection will
      # remain open and active but will no longer be managed by this pool.
      def remove(conn)
        synchronize do
          @connections.delete conn
          @available.delete conn

          # FIXME: we might want to store the key on the connection so that removing
          # from the reserved hash will be a little easier.
          release conn

          @available.add checkout_new_connection if @available.any_waiting?
        end
      end

      # Removes dead connections from the pool.  A dead connection can occur
      # if a programmer forgets to close a connection at the end of a thread
      # or a thread dies unexpectedly.
      def reap
        synchronize do
          stale = Time.now - @dead_connection_timeout
          connections.dup.each do |conn|
            remove conn if conn.in_use? && stale > conn.last_use && !conn.active?
          end
        end
      end

      private

      # Acquire a connection by one of 1) immediately removing one
      # from the queue of available connections, 2) creating a new
      # connection if the pool is not at capacity, 3) waiting on the
      # queue for a connection to become available.
      #
      # Raises:
      # - ConnectionTimeoutError if a connection could not be acquired
      def acquire_connection
        if conn = @available.poll
          conn
        elsif @connections.size < @size
          checkout_new_connection
        else
          @available.poll(@checkout_timeout)
        end
      end

      def release(conn)
        thread_id = if @reserved_connections[current_connection_id] == conn
          current_connection_id
        else
          @reserved_connections.keys.find { |k|
            @reserved_connections[k] == conn
          }
        end

        @reserved_connections.delete thread_id if thread_id
      end

      def new_connection
        Base.send(spec.adapter_method, spec.config)
      end

      def current_connection_id #:nodoc:
        Base.connection_id ||= Thread.current.object_id
      end

      def checkout_new_connection
        raise ConnectionNotEstablished unless @automatic_reconnect

        c = new_connection
        c.pool = self
        @connections << c
        c
      end

      def checkout_and_verify(c)
        c.run_callbacks :checkout do
          c.verify!
        end
        c
      end
    end

    # ConnectionHandler is a collection of ConnectionPool objects. It is used
    # for keeping separate connection pools for Active Record models that connect
    # to different databases.
    #
    # For example, suppose that you have 5 models, with the following hierarchy:
    #
    #  |
    #  +-- Book
    #  |    |
    #  |    +-- ScaryBook
    #  |    +-- GoodBook
    #  +-- Author
    #  +-- BankAccount
    #
    # Suppose that Book is to connect to a separate database (i.e. one other
    # than the default database). Then Book, ScaryBook and GoodBook will all use
    # the same connection pool. Likewise, Author and BankAccount will use the
    # same connection pool. However, the connection pool used by Author/BankAccount
    # is not the same as the one used by Book/ScaryBook/GoodBook.
    #
    # Normally there is only a single ConnectionHandler instance, accessible via
    # ActiveRecord::Base.connection_handler. Active Record models use this to
    # determine the connection pool that they should use.
    class ConnectionHandler
      def initialize
        # These caches are keyed by klass.name, NOT klass. Keying them by klass
        # alone would lead to memory leaks in development mode as all previous
        # instances of the class would stay in memory.
        @owner_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k|
          h[k] = ThreadSafe::Cache.new(:initial_capacity => 2)
        end
        @class_to_pool = ThreadSafe::Cache.new(:initial_capacity => 2) do |h,k|
          h[k] = ThreadSafe::Cache.new
        end
      end

      def connection_pool_list
        owner_to_pool.values.compact
      end

      def connection_pools
        ActiveSupport::Deprecation.warn(
          "In the next release, this will return the same as #connection_pool_list. " \
          "(An array of pools, rather than a hash mapping specs to pools.)"
        )
        Hash[connection_pool_list.map { |pool| [pool.spec, pool] }]
      end

      def establish_connection(owner, spec)
        @class_to_pool.clear
        raise RuntimeError, "Anonymous class is not allowed." unless owner.name
        owner_to_pool[owner.name] = ConnectionAdapters::ConnectionPool.new(spec)
      end

      # Returns true if there are any active connections among the connection
      # pools that the ConnectionHandler is managing.
      def active_connections?
        connection_pool_list.any?(&:active_connection?)
      end

      # Returns any connections in use by the current thread back to the pool,
      # and also returns connections to the pool cached by threads that are no
      # longer alive.
      def clear_active_connections!
        connection_pool_list.each(&:release_connection)
      end

      # Clears the cache which maps classes.
      def clear_reloadable_connections!
        connection_pool_list.each(&:clear_reloadable_connections!)
      end

      def clear_all_connections!
        connection_pool_list.each(&:disconnect!)
      end

      # Locate the connection of the nearest super class. This can be an
      # active or defined connection: if it is the latter, it will be
      # opened and set as the active connection for the class it was defined
      # for (not necessarily the current class).
      def retrieve_connection(klass) #:nodoc:
        pool = retrieve_connection_pool(klass)
        (pool && pool.connection) or raise ConnectionNotEstablished
      end

      # Returns true if a connection that's accessible to this class has
      # already been opened.
      def connected?(klass)
        conn = retrieve_connection_pool(klass)
        conn && conn.connected?
      end

      # Remove the connection for this class. This will close the active
      # connection and the defined connection (if they exist). The result
      # can be used as an argument for establish_connection, for easily
      # re-establishing the connection.
      def remove_connection(owner)
        if pool = owner_to_pool.delete(owner.name)
          @class_to_pool.clear
          pool.automatic_reconnect = false
          pool.disconnect!
          pool.spec.config
        end
      end

      # Retrieving the connection pool happens a lot so we cache it in @class_to_pool.
      # This makes retrieving the connection pool O(1) once the process is warm.
      # When a connection is established or removed, we invalidate the cache.
      #
      # Ideally we would use #fetch here, as class_to_pool[klass] may sometimes be nil.
      # However, benchmarking (https://gist.github.com/3552829) showed that #fetch is
      # significantly slower than #[]. So in the nil case, no caching will take place,
      # but that's ok since the nil case is not the common one that we wish to optimise
      # for.
      def retrieve_connection_pool(klass)
        class_to_pool[klass.name] ||= begin
          until pool = pool_for(klass)
            klass = klass.superclass
            break unless klass <= Base
          end

          class_to_pool[klass.name] = pool
        end
      end

      private

      def owner_to_pool
        @owner_to_pool[Process.pid]
      end

      def class_to_pool
        @class_to_pool[Process.pid]
      end

      def pool_for(owner)
        owner_to_pool.fetch(owner.name) {
          if ancestor_pool = pool_from_any_process_for(owner)
            # A connection was established in an ancestor process that must have
            # subsequently forked. We can't reuse the connection, but we can copy
            # the specification and establish a new connection with it.
            establish_connection owner, ancestor_pool.spec
          else
            owner_to_pool[owner.name] = nil
          end
        }
      end

      def pool_from_any_process_for(owner)
        owner_to_pool = @owner_to_pool.values.find { |v| v[owner.name] }
        owner_to_pool && owner_to_pool[owner.name]
      end
    end

    class ConnectionManagement
      def initialize(app)
        @app = app
      end

      def call(env)
        testing = env.key?('rack.test')

        response = @app.call(env)
        response[2] = ::Rack::BodyProxy.new(response[2]) do
          ActiveRecord::Base.clear_active_connections! unless testing
        end

        response
      rescue
        ActiveRecord::Base.clear_active_connections! unless testing
        raise
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module DatabaseLimits

      # Returns the maximum length of a table alias.
      def table_alias_length
        255
      end

      # Returns the maximum length of a column name.
      def column_name_length
        64
      end

      # Returns the maximum length of a table name.
      def table_name_length
        64
      end

      # Returns the maximum length of an index name.
      def index_name_length
        64
      end

      # Returns the maximum number of columns per table.
      def columns_per_table
        1024
      end

      # Returns the maximum number of indexes per table.
      def indexes_per_table
        16
      end

      # Returns the maximum number of columns in a multicolumn index.
      def columns_per_multicolumn_index
        16
      end

      # Returns the maximum number of elements in an IN (x,y,z) clause.
      # nil means no limit.
      def in_clause_length
        nil
      end

      # Returns the maximum length of an SQL query.
      def sql_query_length
        1048575
      end

      # Returns maximum number of joins in a single query.
      def joins_per_query
        256
      end

    end
  end
end
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module DatabaseStatements
      def initialize
        super
        reset_transaction
      end

      # Converts an arel AST to SQL
      def to_sql(arel, binds = [])
        if arel.respond_to?(:ast)
          binds = binds.dup
          visitor.accept(arel.ast) do
            quote(*binds.shift.reverse)
          end
        else
          arel
        end
      end

      # Returns an array of record hashes with the column names as keys and
      # column values as values.
      def select_all(arel, name = nil, binds = [])
        select(to_sql(arel, binds), name, binds)
      end

      # Returns a record hash with the column names as keys and column values
      # as values.
      def select_one(arel, name = nil, binds = [])
        result = select_all(arel, name, binds)
        result.first if result
      end

      # Returns a single value from a record
      def select_value(arel, name = nil, binds = [])
        if result = select_one(arel, name, binds)
          result.values.first
        end
      end

      # Returns an array of the values of the first column in a select:
      #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
      def select_values(arel, name = nil)
        result = select_rows(to_sql(arel, []), name)
        result.map { |v| v[0] }
      end

      # Returns an array of arrays containing the field values.
      # Order is the same as that returned by +columns+.
      def select_rows(sql, name = nil)
      end
      undef_method :select_rows

      # Executes the SQL statement in the context of this connection.
      def execute(sql, name = nil)
      end
      undef_method :execute

      # Executes +sql+ statement in the context of this connection using
      # +binds+ as the bind substitutes. +name+ is logged along with
      # the executed +sql+ statement.
      def exec_query(sql, name = 'SQL', binds = [])
      end

      # Executes insert +sql+ statement in the context of this connection using
      # +binds+ as the bind substitutes. +name+ is logged along with
      # the executed +sql+ statement.
      def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
        exec_query(sql, name, binds)
      end

      # Executes delete +sql+ statement in the context of this connection using
      # +binds+ as the bind substitutes. +name+ is logged along with
      # the executed +sql+ statement.
      def exec_delete(sql, name, binds)
        exec_query(sql, name, binds)
      end

      # Executes update +sql+ statement in the context of this connection using
      # +binds+ as the bind substitutes. +name+ is logged along with
      # the executed +sql+ statement.
      def exec_update(sql, name, binds)
        exec_query(sql, name, binds)
      end

      # Returns the last auto-generated ID from the affected table.
      #
      # +id_value+ will be returned unless the value is nil, in
      # which case the database will attempt to calculate the last inserted
      # id and return that value.
      #
      # If the next id was calculated in advance (as in Oracle), it should be
      # passed in as +id_value+.
      def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
        sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
        value      = exec_insert(sql, name, binds, pk, sequence_name)
        id_value || last_inserted_id(value)
      end

      # Executes the update statement and returns the number of rows affected.
      def update(arel, name = nil, binds = [])
        exec_update(to_sql(arel, binds), name, binds)
      end

      # Executes the delete statement and returns the number of rows affected.
      def delete(arel, name = nil, binds = [])
        exec_delete(to_sql(arel, binds), name, binds)
      end

      # Returns +true+ when the connection adapter supports prepared statement
      # caching, otherwise returns +false+
      def supports_statement_cache?
        false
      end

      # Runs the given block in a database transaction, and returns the result
      # of the block.
      #
      # == Nested transactions support
      #
      # Most databases don't support true nested transactions. At the time of
      # writing, the only database that supports true nested transactions that
      # we're aware of, is MS-SQL.
      #
      # In order to get around this problem, #transaction will emulate the effect
      # of nested transactions, by using savepoints:
      # http://dev.mysql.com/doc/refman/5.0/en/savepoint.html
      # Savepoints are supported by MySQL and PostgreSQL, but not SQLite3.
      #
      # It is safe to call this method if a database transaction is already open,
      # i.e. if #transaction is called within another #transaction block. In case
      # of a nested call, #transaction will behave as follows:
      #
      # - The block will be run without doing anything. All database statements
      #   that happen within the block are effectively appended to the already
      #   open database transaction.
      # - However, if +:requires_new+ is set, the block will be wrapped in a
      #   database savepoint acting as a sub-transaction.
      #
      # === Caveats
      #
      # MySQL doesn't support DDL transactions. If you perform a DDL operation,
      # then any created savepoints will be automatically released. For example,
      # if you've created a savepoint, then you execute a CREATE TABLE statement,
      # then the savepoint that was created will be automatically released.
      #
      # This means that, on MySQL, you shouldn't execute DDL operations inside
      # a #transaction call that you know might create a savepoint. Otherwise,
      # #transaction will raise exceptions when it tries to release the
      # already-automatically-released savepoints:
      #
      #   Model.connection.transaction do  # BEGIN
      #     Model.connection.transaction(requires_new: true) do  # CREATE SAVEPOINT active_record_1
      #       Model.connection.create_table(...)
      #       # active_record_1 now automatically released
      #     end  # RELEASE SAVEPOINT active_record_1  <--- BOOM! database error!
      #   end
      #
      # == Transaction isolation
      #
      # If your database supports setting the isolation level for a transaction, you can set
      # it like so:
      #
      #   Post.transaction(isolation: :serializable) do
      #     # ...
      #   end
      #
      # Valid isolation levels are:
      #
      # * <tt>:read_uncommitted</tt>
      # * <tt>:read_committed</tt>
      # * <tt>:repeatable_read</tt>
      # * <tt>:serializable</tt>
      #
      # You should consult the documentation for your database to understand the
      # semantics of these different levels:
      #
      # * http://www.postgresql.org/docs/9.1/static/transaction-iso.html
      # * https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
      #
      # An <tt>ActiveRecord::TransactionIsolationError</tt> will be raised if:
      #
      # * The adapter does not support setting the isolation level
      # * You are joining an existing open transaction
      # * You are creating a nested (savepoint) transaction
      #
      # The mysql, mysql2 and postgresql adapters support setting the transaction
      # isolation level. However, support is disabled for mysql versions below 5,
      # because they are affected by a bug[http://bugs.mysql.com/bug.php?id=39170]
      # which means the isolation level gets persisted outside the transaction.
      def transaction(options = {})
        options.assert_valid_keys :requires_new, :joinable, :isolation

        if !options[:requires_new] && current_transaction.joinable?
          if options[:isolation]
            raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
          end

          yield
        else
          within_new_transaction(options) { yield }
        end
      rescue ActiveRecord::Rollback
        # rollbacks are silently swallowed
      end

      def within_new_transaction(options = {}) #:nodoc:
        transaction = begin_transaction(options)
        yield
      rescue Exception => error
        rollback_transaction if transaction
        raise
      ensure
        begin
          commit_transaction unless error
        rescue Exception
          rollback_transaction
          raise
        end
      end

      def current_transaction #:nodoc:
        @transaction
      end

      def transaction_open?
        @transaction.open?
      end

      def begin_transaction(options = {}) #:nodoc:
        @transaction = @transaction.begin(options)
      end

      def commit_transaction #:nodoc:
        @transaction = @transaction.commit
      end

      def rollback_transaction #:nodoc:
        @transaction = @transaction.rollback
      end

      def reset_transaction #:nodoc:
        @transaction = ClosedTransaction.new(self)
      end

      # Register a record with the current transaction so that its after_commit and after_rollback callbacks
      # can be called.
      def add_transaction_record(record)
        @transaction.add_record(record)
      end

      # Begins the transaction (and turns off auto-committing).
      def begin_db_transaction()    end

      def transaction_isolation_levels
        {
          read_uncommitted: "READ UNCOMMITTED",
          read_committed:   "READ COMMITTED",
          repeatable_read:  "REPEATABLE READ",
          serializable:     "SERIALIZABLE"
        }
      end

      # Begins the transaction with the isolation level set. Raises an error by
      # default; adapters that support setting the isolation level should implement
      # this method.
      def begin_isolated_db_transaction(isolation)
        raise ActiveRecord::TransactionIsolationError, "adapter does not support setting transaction isolation"
      end

      # Commits the transaction (and turns on auto-committing).
      def commit_db_transaction()   end

      # Rolls back the transaction (and turns on auto-committing). Must be
      # done if the transaction block raises an exception or returns false.
      def rollback_db_transaction() end

      def default_sequence_name(table, column)
        nil
      end

      # Set the sequence to the max value of the table's column.
      def reset_sequence!(table, column, sequence = nil)
        # Do nothing by default. Implement for PostgreSQL, Oracle, ...
      end

      # Inserts the given fixture into the table. Overridden in adapters that require
      # something beyond a simple insert (eg. Oracle).
      def insert_fixture(fixture, table_name)
        columns = schema_cache.columns_hash(table_name)

        key_list   = []
        value_list = fixture.map do |name, value|
          key_list << quote_column_name(name)
          quote(value, columns[name])
        end

        execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
      end

      def empty_insert_statement_value
        "DEFAULT VALUES"
      end

      def case_sensitive_equality_operator
        "="
      end

      def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
        "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{quoted_table_name} #{where_sql})"
      end

      # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
      #
      # The +limit+ may be anything that can evaluate to a string via #to_s. It
      # should look like an integer, or a comma-delimited list of integers, or
      # an Arel SQL literal.
      #
      # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
      # Returns the sanitized limit parameter, either as an integer, or as a
      # string which contains a comma-delimited list of integers.
      def sanitize_limit(limit)
        if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
          limit
        elsif limit.to_s =~ /,/
          Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
        else
          Integer(limit)
        end
      end

      # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
      # on mysql (even when aliasing the tables), but mysql allows using JOIN directly in
      # an UPDATE statement, so in the mysql adapters we redefine this to do that.
      def join_to_update(update, select) #:nodoc:
        key = update.key
        subselect = subquery_for(key, select)

        update.where key.in(subselect)
      end

      def join_to_delete(delete, select, key) #:nodoc:
        subselect = subquery_for(key, select)

        delete.where key.in(subselect)
      end

      protected

        # Return a subquery for the given key using the join information.
        def subquery_for(key, select)
          subselect = select.clone
          subselect.projections = [key]
          subselect
        end

        # Returns an array of record hashes with the column names as keys and
        # column values as values.
        def select(sql, name = nil, binds = [])
        end
        undef_method :select

        # Returns the last auto-generated ID from the affected table.
        def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
          execute(sql, name)
          id_value
        end

        # Executes the update statement and returns the number of rows affected.
        def update_sql(sql, name = nil)
          execute(sql, name)
        end

        # Executes the delete statement and returns the number of rows affected.
        def delete_sql(sql, name = nil)
          update_sql(sql, name)
        end

      def sql_for_insert(sql, pk, id_value, sequence_name, binds)
        [sql, binds]
      end

      def last_inserted_id(result)
        row = result.rows.first
        row && row.first
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module QueryCache
      class << self
        def included(base) #:nodoc:
          dirties_query_cache base, :insert, :update, :delete
        end

        def dirties_query_cache(base, *method_names)
          method_names.each do |method_name|
            base.class_eval <<-end_code, __FILE__, __LINE__ + 1
              def #{method_name}(*)                         # def update_with_query_dirty(*)
                clear_query_cache if @query_cache_enabled   #   clear_query_cache if @query_cache_enabled
                super                                       #   super
              end                                           # end
            end_code
          end
        end
      end

      attr_reader :query_cache, :query_cache_enabled

      # Enable the query cache within the block.
      def cache
        old, @query_cache_enabled = @query_cache_enabled, true
        yield
      ensure
        clear_query_cache
        @query_cache_enabled = old
      end

      def enable_query_cache!
        @query_cache_enabled = true
      end

      def disable_query_cache!
        @query_cache_enabled = false
      end

      # Disable the query cache within the block.
      def uncached
        old, @query_cache_enabled = @query_cache_enabled, false
        yield
      ensure
        @query_cache_enabled = old
      end

      # Clears the query cache.
      #
      # One reason you may wish to call this method explicitly is between queries
      # that ask the database to randomize results. Otherwise the cache would see
      # the same SQL query and repeatedly return the same result each time, silently
      # undermining the randomness you were expecting.
      def clear_query_cache
        @query_cache.clear
      end

      def select_all(arel, name = nil, binds = [])
        if @query_cache_enabled && !locked?(arel)
          sql = to_sql(arel, binds)
          cache_sql(sql, binds) { super(sql, name, binds) }
        else
          super
        end
      end

      private

      def cache_sql(sql, binds)
        result =
          if @query_cache[sql].key?(binds)
            ActiveSupport::Notifications.instrument("sql.active_record",
              :sql => sql, :binds => binds, :name => "CACHE", :connection_id => object_id)
            @query_cache[sql][binds]
          else
            @query_cache[sql][binds] = yield
          end

        # FIXME: we should guarantee that all cached items are Result
        # objects.  Then we can avoid this conditional
        if ActiveRecord::Result === result
          result.dup
        else
          result.collect { |row| row.dup }
        end
      end

      # If arel is locked this is a SELECT ... FOR UPDATE or somesuch. Such
      # queries should not be cached.
      def locked?(arel)
        arel.respond_to?(:locked) && arel.locked
      end
    end
  end
end
require 'active_support/core_ext/big_decimal/conversions'

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module Quoting
      # Quotes the column value to help prevent
      # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection].
      def quote(value, column = nil)
        # records are quoted as their primary key
        return value.quoted_id if value.respond_to?(:quoted_id)

        case value
        when String, ActiveSupport::Multibyte::Chars
          value = value.to_s
          return "'#{quote_string(value)}'" unless column

          case column.type
          when :binary then "'#{quote_string(column.string_to_binary(value))}'"
          when :integer then value.to_i.to_s
          when :float then value.to_f.to_s
          else
            "'#{quote_string(value)}'"
          end

        when true, false
          if column && column.type == :integer
            value ? '1' : '0'
          elsif column && [:text, :string, :binary].include?(column.type)
            value ? "'1'" : "'0'"
          else
            value ? quoted_true : quoted_false
          end
          # BigDecimals need to be put in a non-normalized form and quoted.
        when nil        then "NULL"
        when Numeric, ActiveSupport::Duration
          value = BigDecimal === value ? value.to_s('F') : value.to_s
          if column && ![:integer, :float, :decimal].include?(column.type)
            value = "'#{value}'"
          end
          value
        when Date, Time then "'#{quoted_date(value)}'"
        when Symbol     then "'#{quote_string(value.to_s)}'"
        when Class      then "'#{value.to_s}'"
        else
          "'#{quote_string(YAML.dump(value))}'"
        end
      end

      # Cast a +value+ to a type that the database understands. For example,
      # SQLite does not understand dates, so this method will convert a Date
      # to a String.
      def type_cast(value, column)
        return value.id if value.respond_to?(:quoted_id)

        case value
        when String, ActiveSupport::Multibyte::Chars
          value = value.to_s
          return value unless column

          case column.type
          when :binary then value
          when :integer then value.to_i
          when :float then value.to_f
          else
            value
          end

        when true, false
          if column && column.type == :integer
            value ? 1 : 0
          else
            value ? 't' : 'f'
          end
          # BigDecimals need to be put in a non-normalized form and quoted.
        when nil        then nil
        when BigDecimal then value.to_s('F')
        when Numeric    then value
        when Date, Time then quoted_date(value)
        when Symbol     then value.to_s
        else
          to_type = column ? " to #{column.type}" : ""
          raise TypeError, "can't cast #{value.class}#{to_type}"
        end
      end

      # Quotes a string, escaping any ' (single quote) and \ (backslash)
      # characters.
      def quote_string(s)
        s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
      end

      # Quotes the column name. Defaults to no quoting.
      def quote_column_name(column_name)
        column_name
      end

      # Quotes the table name. Defaults to column name quoting.
      def quote_table_name(table_name)
        quote_column_name(table_name)
      end

      # Override to return the quoted table name for assignment. Defaults to
      # table quoting.
      #
      # This works for mysql and mysql2 where table.column can be used to
      # resolve ambiguity.
      #
      # We override this in the sqlite and postgresql adapters to use only
      # the column name (as per syntax requirements).
      def quote_table_name_for_assignment(table, attr)
        quote_table_name("#{table}.#{attr}")
      end

      def quoted_true
        "'t'"
      end

      def quoted_false
        "'f'"
      end

      def quoted_date(value)
        if value.acts_like?(:time)
          zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal

          if value.respond_to?(zone_conversion_method)
            value = value.send(zone_conversion_method)
          end
        end

        value.to_s(:db)
      end
    end
  end
end
require 'date'
require 'set'
require 'bigdecimal'
require 'bigdecimal/util'

module ActiveRecord
  module ConnectionAdapters #:nodoc:
    # Abstract representation of an index definition on a table. Instances of
    # this type are typically created and returned by methods in database
    # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
    class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where) #:nodoc:
    end

    # Abstract representation of a column definition. Instances of this type
    # are typically created by methods in TableDefinition, and added to the
    # +columns+ attribute of said TableDefinition object, in order to be used
    # for generating a number of table creation or table changing SQL statements.
    class ColumnDefinition < Struct.new(:base, :name, :type, :limit, :precision, :scale, :default, :null) #:nodoc:

      def string_to_binary(value)
        value
      end

      def sql_type
        base.type_to_sql(type.to_sym, limit, precision, scale)
      end

      def to_sql
        column_sql = "#{base.quote_column_name(name)} #{sql_type}"
        column_options = {}
        column_options[:null] = null unless null.nil?
        column_options[:default] = default unless default.nil?
        add_column_options!(column_sql, column_options) unless type.to_sym == :primary_key
        column_sql
      end

      private

        def add_column_options!(sql, options)
          base.add_column_options!(sql, options.merge(:column => self))
        end
    end

    # Represents the schema of an SQL table in an abstract way. This class
    # provides methods for manipulating the schema representation.
    #
    # Inside migration files, the +t+ object in +create_table+ and
    # +change_table+ is actually of this type:
    #
    #   class SomeMigration < ActiveRecord::Migration
    #     def up
    #       create_table :foo do |t|
    #         puts t.class  # => "ActiveRecord::ConnectionAdapters::TableDefinition"
    #       end
    #     end
    #
    #     def down
    #       ...
    #     end
    #   end
    #
    # The table definitions
    # The Columns are stored as a ColumnDefinition in the +columns+ attribute.
    class TableDefinition
      # An array of ColumnDefinition objects, representing the column changes
      # that have been defined.
      attr_accessor :columns, :indexes

      def initialize(base)
        @columns = []
        @columns_hash = {}
        @indexes = {}
        @base = base
      end

      def xml(*args)
        raise NotImplementedError unless %w{
          sqlite mysql mysql2
        }.include? @base.adapter_name.downcase

        options = args.extract_options!
        column(args[0], :text, options)
      end

      # Appends a primary key definition to the table definition.
      # Can be called multiple times, but this is probably not a good idea.
      def primary_key(name)
        column(name, :primary_key)
      end

      # Returns a ColumnDefinition for the column with name +name+.
      def [](name)
        @columns_hash[name.to_s]
      end

      # Instantiates a new column for the table.
      # The +type+ parameter is normally one of the migrations native types,
      # which is one of the following:
      # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
      # <tt>:integer</tt>, <tt>:float</tt>, <tt>:decimal</tt>,
      # <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>,
      # <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>.
      #
      # You may use a type not in this list as long as it is supported by your
      # database (for example, "polygon" in MySQL), but this will not be database
      # agnostic and should usually be avoided.
      #
      # Available options are (none of these exists by default):
      # * <tt>:limit</tt> -
      #   Requests a maximum column length. This is number of characters for <tt>:string</tt> and
      #   <tt>:text</tt> columns and number of bytes for <tt>:binary</tt> and <tt>:integer</tt> columns.
      # * <tt>:default</tt> -
      #   The column's default value. Use nil for NULL.
      # * <tt>:null</tt> -
      #   Allows or disallows +NULL+ values in the column. This option could
      #   have been named <tt>:null_allowed</tt>.
      # * <tt>:precision</tt> -
      #   Specifies the precision for a <tt>:decimal</tt> column.
      # * <tt>:scale</tt> -
      #   Specifies the scale for a <tt>:decimal</tt> column.
      #
      # For clarity's sake: the precision is the number of significant digits,
      # while the scale is the number of digits that can be stored following
      # the decimal point. For example, the number 123.45 has a precision of 5
      # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
      # range from -999.99 to 999.99.
      #
      # Please be aware of different RDBMS implementations behavior with
      # <tt>:decimal</tt> columns:
      # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
      #   <tt>:precision</tt>, and makes no comments about the requirements of
      #   <tt>:precision</tt>.
      # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
      #   Default is (10,0).
      # * PostgreSQL: <tt>:precision</tt> [1..infinity],
      #   <tt>:scale</tt> [0..infinity]. No default.
      # * SQLite2: Any <tt>:precision</tt> and <tt>:scale</tt> may be used.
      #   Internal storage as strings. No default.
      # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
      #   but the maximum supported <tt>:precision</tt> is 16. No default.
      # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
      #   Default is (38,0).
      # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
      #   Default unknown.
      # * Firebird: <tt>:precision</tt> [1..18], <tt>:scale</tt> [0..18].
      #   Default (9,0). Internal types NUMERIC and DECIMAL have different
      #   storage rules, decimal being better.
      # * FrontBase?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
      #   Default (38,0). WARNING Max <tt>:precision</tt>/<tt>:scale</tt> for
      #   NUMERIC is 19, and DECIMAL is 38.
      # * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
      #   Default (38,0).
      # * Sybase: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
      #   Default (38,0).
      # * OpenBase?: Documentation unclear. Claims storage in <tt>double</tt>.
      #
      # This method returns <tt>self</tt>.
      #
      # == Examples
      #  # Assuming +td+ is an instance of TableDefinition
      #  td.column(:granted, :boolean)
      #  # granted BOOLEAN
      #
      #  td.column(:picture, :binary, limit: 2.megabytes)
      #  # => picture BLOB(2097152)
      #
      #  td.column(:sales_stage, :string, limit: 20, default: 'new', null: false)
      #  # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
      #
      #  td.column(:bill_gates_money, :decimal, precision: 15, scale: 2)
      #  # => bill_gates_money DECIMAL(15,2)
      #
      #  td.column(:sensor_reading, :decimal, precision: 30, scale: 20)
      #  # => sensor_reading DECIMAL(30,20)
      #
      #  # While <tt>:scale</tt> defaults to zero on most databases, it
      #  # probably wouldn't hurt to include it.
      #  td.column(:huge_integer, :decimal, precision: 30)
      #  # => huge_integer DECIMAL(30)
      #
      #  # Defines a column with a database-specific type.
      #  td.column(:foo, 'polygon')
      #  # => foo polygon
      #
      # == Short-hand examples
      #
      # Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types.
      # They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
      # in a single statement.
      #
      # What can be written like this with the regular calls to column:
      #
      #   create_table :products do |t|
      #     t.column :shop_id,    :integer
      #     t.column :creator_id, :integer
      #     t.column :name,       :string, default: "Untitled"
      #     t.column :value,      :string, default: "Untitled"
      #     t.column :created_at, :datetime
      #     t.column :updated_at, :datetime
      #   end
      #
      # can also be written as follows using the short-hand:
      #
      #   create_table :products do |t|
      #     t.integer :shop_id, :creator_id
      #     t.string  :name, :value, default: "Untitled"
      #     t.timestamps
      #   end
      #
      # There's a short-hand method for each of the type values declared at the top. And then there's
      # TableDefinition#timestamps that'll add +created_at+ and +updated_at+ as datetimes.
      #
      # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
      # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of
      # options, these will be used when creating the <tt>_type</tt> column. The <tt>:index</tt> option
      # will also create an index, similar to calling <tt>add_index</tt>. So what can be written like this:
      #
      #   create_table :taggings do |t|
      #     t.integer :tag_id, :tagger_id, :taggable_id
      #     t.string  :tagger_type
      #     t.string  :taggable_type, default: 'Photo'
      #   end
      #   add_index :taggings, :tag_id, name: 'index_taggings_on_tag_id'
      #   add_index :taggings, [:tagger_id, :tagger_type]
      #
      # Can also be written as follows using references:
      #
      #   create_table :taggings do |t|
      #     t.references :tag, index: { name: 'index_taggings_on_tag_id' }
      #     t.references :tagger, polymorphic: true, index: true
      #     t.references :taggable, polymorphic: { default: 'Photo' }
      #   end
      def column(name, type, options = {})
        name = name.to_s
        type = type.to_sym

        if primary_key_column_name == name
          raise ArgumentError, "you can't redefine the primary key column '#{name}'. To define a custom primary key, pass { id: false } to create_table."
        end

        column = self[name] || new_column_definition(@base, name, type)

        limit = options.fetch(:limit) do
          native[type][:limit] if native[type].is_a?(Hash)
        end

        column.limit     = limit
        column.precision = options[:precision]
        column.scale     = options[:scale]
        column.default   = options[:default]
        column.null      = options[:null]
        self
      end

      [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
        define_method column_type do |*args|
          options = args.extract_options!
          column_names = args
          column_names.each { |name| column(name, column_type, options) }
        end
      end

      # Adds index options to the indexes hash, keyed by column name
      # This is primarily used to track indexes that need to be created after the table
      #
      #   index(:account_id, name: 'index_projects_on_account_id')
      def index(column_name, options = {})
        indexes[column_name] = options
      end

      # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
      # <tt>:updated_at</tt> to the table.
      def timestamps(*args)
        options = args.extract_options!
        column(:created_at, :datetime, options)
        column(:updated_at, :datetime, options)
      end

      def references(*args)
        options = args.extract_options!
        polymorphic = options.delete(:polymorphic)
        index_options = options.delete(:index)
        args.each do |col|
          column("#{col}_id", :integer, options)
          column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
          index(polymorphic ? %w(id type).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options
        end
      end
      alias :belongs_to :references

      # Returns a String whose contents are the column definitions
      # concatenated together. This string can then be prepended and appended to
      # to generate the final SQL to create the table.
      def to_sql
        @columns.map { |c| c.to_sql } * ', '
      end

      private
      def new_column_definition(base, name, type)
        definition = ColumnDefinition.new base, name, type
        @columns << definition
        @columns_hash[name] = definition
        definition
      end

      def primary_key_column_name
        primary_key_column = columns.detect { |c| c.type == :primary_key }
        primary_key_column && primary_key_column.name
      end

      def native
        @base.native_database_types
      end
    end

    # Represents an SQL table in an abstract way for updating a table.
    # Also see TableDefinition and SchemaStatements#create_table
    #
    # Available transformations are:
    #
    #   change_table :table do |t|
    #     t.column
    #     t.index
    #     t.rename_index
    #     t.timestamps
    #     t.change
    #     t.change_default
    #     t.rename
    #     t.references
    #     t.belongs_to
    #     t.string
    #     t.text
    #     t.integer
    #     t.float
    #     t.decimal
    #     t.datetime
    #     t.timestamp
    #     t.time
    #     t.date
    #     t.binary
    #     t.boolean
    #     t.remove
    #     t.remove_references
    #     t.remove_belongs_to
    #     t.remove_index
    #     t.remove_timestamps
    #   end
    #
    class Table
      def initialize(table_name, base)
        @table_name = table_name
        @base = base
      end

      # Adds a new column to the named table.
      # See TableDefinition#column for details of the options you can use.
      #
      # ====== Creating a simple column
      #  t.column(:name, :string)
      def column(column_name, type, options = {})
        @base.add_column(@table_name, column_name, type, options)
      end

      # Checks to see if a column exists. See SchemaStatements#column_exists?
      def column_exists?(column_name, type = nil, options = {})
        @base.column_exists?(@table_name, column_name, type, options)
      end

      # Adds a new index to the table. +column_name+ can be a single Symbol, or
      # an Array of Symbols. See SchemaStatements#add_index
      #
      # ====== Creating a simple index
      #  t.index(:name)
      # ====== Creating a unique index
      #  t.index([:branch_id, :party_id], unique: true)
      # ====== Creating a named index
      #  t.index([:branch_id, :party_id], unique: true, name: 'by_branch_party')
      def index(column_name, options = {})
        @base.add_index(@table_name, column_name, options)
      end

      # Checks to see if an index exists. See SchemaStatements#index_exists?
      def index_exists?(column_name, options = {})
        @base.index_exists?(@table_name, column_name, options)
      end

      # Renames the given index on the table.
      #
      #  t.rename_index(:user_id, :account_id)
      def rename_index(index_name, new_index_name)
        @base.rename_index(@table_name, index_name, new_index_name)
      end

      # Adds timestamps (+created_at+ and +updated_at+) columns to the table. See SchemaStatements#add_timestamps
      #
      #  t.timestamps
      def timestamps
        @base.add_timestamps(@table_name)
      end

      # Changes the column's definition according to the new options.
      # See TableDefinition#column for details of the options you can use.
      #
      #  t.change(:name, :string, limit: 80)
      #  t.change(:description, :text)
      def change(column_name, type, options = {})
        @base.change_column(@table_name, column_name, type, options)
      end

      # Sets a new default value for a column. See SchemaStatements#change_column_default
      #
      #  t.change_default(:qualification, 'new')
      #  t.change_default(:authorized, 1)
      def change_default(column_name, default)
        @base.change_column_default(@table_name, column_name, default)
      end

      # Removes the column(s) from the table definition.
      #
      #  t.remove(:qualification)
      #  t.remove(:qualification, :experience)
      def remove(*column_names)
        @base.remove_columns(@table_name, *column_names)
      end

      # Removes the given index from the table.
      #
      # ====== Remove the index_table_name_on_column in the table_name table
      #   t.remove_index :column
      # ====== Remove the index named index_table_name_on_branch_id in the table_name table
      #   t.remove_index column: :branch_id
      # ====== Remove the index named index_table_name_on_branch_id_and_party_id in the table_name table
      #   t.remove_index column: [:branch_id, :party_id]
      # ====== Remove the index named by_branch_party in the table_name table
      #   t.remove_index name: :by_branch_party
      def remove_index(options = {})
        @base.remove_index(@table_name, options)
      end

      # Removes the timestamp columns (+created_at+ and +updated_at+) from the table.
      #
      #  t.remove_timestamps
      def remove_timestamps
        @base.remove_timestamps(@table_name)
      end

      # Renames a column.
      #
      #  t.rename(:description, :name)
      def rename(column_name, new_column_name)
        @base.rename_column(@table_name, column_name, new_column_name)
      end

      # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
      # <tt>references</tt> and <tt>belongs_to</tt> are acceptable.
      #
      #  t.references(:user)
      #  t.belongs_to(:supplier, polymorphic: true)
      #
      def references(*args)
        options = args.extract_options!
        args.each do |ref_name|
          @base.add_reference(@table_name, ref_name, options)
        end
      end
      alias :belongs_to :references

      # Removes a reference. Optionally removes a +type+ column.
      # <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
      #
      #  t.remove_references(:user)
      #  t.remove_belongs_to(:supplier, polymorphic: true)
      #
      def remove_references(*args)
        options = args.extract_options!
        args.each do |ref_name|
          @base.remove_reference(@table_name, ref_name, options)
        end
      end
      alias :remove_belongs_to :remove_references

      # Adds a column or columns of a specified type
      #
      #  t.string(:goat)
      #  t.string(:goat, :sheep)
      [:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean].each do |column_type|
        define_method column_type do |*args|
          options = args.extract_options!
          args.each do |name|
            @base.add_column(@table_name, name, column_type, options)
          end
        end  
      end

      private
        def native
          @base.native_database_types
        end
    end

  end
end
module ActiveRecord
  module ConnectionAdapters # :nodoc:
    # The goal of this module is to move Adapter specific column
    # definitions to the Adapter instead of having it in the schema
    # dumper itself. This code represents the normal case.
    # We can then redefine how certain data types may be handled in the schema dumper on the 
    # Adapter level by over-writing this code inside the database spececific adapters
    module ColumnDumper
      def column_spec(column, types)
        spec = prepare_column_options(column, types)
        (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.to_s}: ")}
        spec
      end

      # This can be overridden on a Adapter level basis to support other
      # extended datatypes (Example: Adding an array option in the
      # PostgreSQLAdapter)
      def prepare_column_options(column, types)
        spec = {}
        spec[:name]      = column.name.inspect

        # AR has an optimization which handles zero-scale decimals as integers. This
        # code ensures that the dumper still dumps the column as a decimal.
        spec[:type]      = if column.type == :integer && /^(numeric|decimal)/ =~ column.sql_type
                             'decimal'
                           else
                             column.type.to_s
                           end
        spec[:limit]     = column.limit.inspect if column.limit != types[column.type][:limit] && spec[:type] != 'decimal'
        spec[:precision] = column.precision.inspect if column.precision
        spec[:scale]     = column.scale.inspect if column.scale
        spec[:null]      = 'false' unless column.null
        spec[:default]   = default_string(column.default) if column.has_default?
        spec
      end

      # Lists the valid migration options
      def migration_keys
        [:name, :limit, :precision, :scale, :default, :null]
      end

      private

        def default_string(value)
          case value
          when BigDecimal
            value.to_s
          when Date, DateTime, Time
            "'#{value.to_s(:db)}'"
          when Range
            # infinity dumps as Infinity, which causes uninitialized constant error
            value.inspect.gsub('Infinity', '::Float::INFINITY')
          else
            value.inspect
          end
        end
    end
  end
end
require 'active_record/migration/join_table'

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    module SchemaStatements
      include ActiveRecord::Migration::JoinTable

      # Returns a Hash of mappings from the abstract data types to the native
      # database types. See TableDefinition#column for details on the recognized
      # abstract data types.
      def native_database_types
        {}
      end

      # Truncates a table alias according to the limits of the current adapter.
      def table_alias_for(table_name)
        table_name[0...table_alias_length].tr('.', '_')
      end

      # Checks to see if the table +table_name+ exists on the database.
      #
      #   table_exists?(:developers)
      def table_exists?(table_name)
        tables.include?(table_name.to_s)
      end

      # Returns an array of indexes for the given table.
      # def indexes(table_name, name = nil) end

      # Checks to see if an index exists on a table for a given index definition.
      #
      #  # Check an index exists
      #  index_exists?(:suppliers, :company_id)
      #
      #  # Check an index on multiple columns exists
      #  index_exists?(:suppliers, [:company_id, :company_type])
      #
      #  # Check a unique index exists
      #  index_exists?(:suppliers, :company_id, unique: true)
      #
      #  # Check an index with a custom name exists
      #  index_exists?(:suppliers, :company_id, name: "idx_company_id"
      def index_exists?(table_name, column_name, options = {})
        column_names = Array(column_name)
        index_name = options.key?(:name) ? options[:name].to_s : index_name(table_name, :column => column_names)
        if options[:unique]
          indexes(table_name).any?{ |i| i.unique && i.name == index_name }
        else
          indexes(table_name).any?{ |i| i.name == index_name }
        end
      end

      # Returns an array of Column objects for the table specified by +table_name+.
      # See the concrete implementation for details on the expected parameter values.
      def columns(table_name) end

      # Checks to see if a column exists in a given table.
      #
      #  # Check a column exists
      #  column_exists?(:suppliers, :name)
      #
      #  # Check a column exists of a particular type
      #  column_exists?(:suppliers, :name, :string)
      #
      #  # Check a column exists with a specific definition
      #  column_exists?(:suppliers, :name, :string, limit: 100)
      #  column_exists?(:suppliers, :name, :string, default: 'default')
      #  column_exists?(:suppliers, :name, :string, null: false)
      #  column_exists?(:suppliers, :tax, :decimal, precision: 8, scale: 2)
      def column_exists?(table_name, column_name, type = nil, options = {})
        columns(table_name).any?{ |c| c.name == column_name.to_s &&
                                      (!type                     || c.type == type) &&
                                      (!options.key?(:limit)     || c.limit == options[:limit]) &&
                                      (!options.key?(:precision) || c.precision == options[:precision]) &&
                                      (!options.key?(:scale)     || c.scale == options[:scale]) &&
                                      (!options.key?(:default)   || c.default == options[:default]) &&
                                      (!options.key?(:null)      || c.null == options[:null]) }
      end

      # Creates a new table with the name +table_name+. +table_name+ may either
      # be a String or a Symbol.
      #
      # There are two ways to work with +create_table+. You can use the block
      # form or the regular form, like this:
      #
      # === Block form
      #  # create_table() passes a TableDefinition object to the block.
      #  # This form will not only create the table, but also columns for the
      #  # table.
      #
      #  create_table(:suppliers) do |t|
      #    t.column :name, :string, limit: 60
      #    # Other fields here
      #  end
      #
      # === Block form, with shorthand
      #  # You can also use the column types as method calls, rather than calling the column method.
      #  create_table(:suppliers) do |t|
      #    t.string :name, limit: 60
      #    # Other fields here
      #  end
      #
      # === Regular form
      #  # Creates a table called 'suppliers' with no columns.
      #  create_table(:suppliers)
      #  # Add a column to 'suppliers'.
      #  add_column(:suppliers, :name, :string, {limit: 60})
      #
      # The +options+ hash can include the following keys:
      # [<tt>:id</tt>]
      #   Whether to automatically add a primary key column. Defaults to true.
      #   Join tables for +has_and_belongs_to_many+ should set it to false.
      # [<tt>:primary_key</tt>]
      #   The name of the primary key, if one is to be added automatically.
      #   Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
      #
      #   Also note that this just sets the primary key in the table. You additionally
      #   need to configure the primary key in the model via +self.primary_key=+.
      #   Models do NOT auto-detect the primary key from their table definition.
      #
      # [<tt>:options</tt>]
      #   Any extra options you want appended to the table definition.
      # [<tt>:temporary</tt>]
      #   Make a temporary table.
      # [<tt>:force</tt>]
      #   Set to true to drop the table before creating it.
      #   Defaults to false.
      #
      # ====== Add a backend specific option to the generated SQL (MySQL)
      #  create_table(:suppliers, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
      # generates:
      #  CREATE TABLE suppliers (
      #    id int(11) DEFAULT NULL auto_increment PRIMARY KEY
      #  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
      #
      # ====== Rename the primary key column
      #  create_table(:objects, primary_key: 'guid') do |t|
      #    t.column :name, :string, limit: 80
      #  end
      # generates:
      #  CREATE TABLE objects (
      #    guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
      #    name varchar(80)
      #  )
      #
      # ====== Do not add a primary key column
      #  create_table(:categories_suppliers, id: false) do |t|
      #    t.column :category_id, :integer
      #    t.column :supplier_id, :integer
      #  end
      # generates:
      #  CREATE TABLE categories_suppliers (
      #    category_id int,
      #    supplier_id int
      #  )
      #
      # See also TableDefinition#column for details on how to create columns.
      def create_table(table_name, options = {})
        td = table_definition
        td.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false

        yield td if block_given?

        if options[:force] && table_exists?(table_name)
          drop_table(table_name, options)
        end

        create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
        create_sql << "#{quote_table_name(table_name)} ("
        create_sql << td.to_sql
        create_sql << ") #{options[:options]}"
        execute create_sql
        td.indexes.each_pair { |c,o| add_index table_name, c, o }
      end

      # Creates a new join table with the name created using the lexical order of the first two
      # arguments. These arguments can be a String or a Symbol.
      #
      #  # Creates a table called 'assemblies_parts' with no id.
      #  create_join_table(:assemblies, :parts)
      #
      # You can pass a +options+ hash can include the following keys:
      # [<tt>:table_name</tt>]
      #   Sets the table name overriding the default
      # [<tt>:column_options</tt>]
      #   Any extra options you want appended to the columns definition.
      # [<tt>:options</tt>]
      #   Any extra options you want appended to the table definition.
      # [<tt>:temporary</tt>]
      #   Make a temporary table.
      # [<tt>:force</tt>]
      #   Set to true to drop the table before creating it.
      #   Defaults to false.
      #
      # ====== Add a backend specific option to the generated SQL (MySQL)
      #  create_join_table(:assemblies, :parts, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8')
      # generates:
      #  CREATE TABLE assemblies_parts (
      #    assembly_id int NOT NULL,
      #    part_id int NOT NULL,
      #  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
      def create_join_table(table_1, table_2, options = {})
        join_table_name = find_join_table_name(table_1, table_2, options)

        column_options = options.delete(:column_options) || {}
        column_options.reverse_merge!(null: false)

        t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }

        create_table(join_table_name, options.merge!(id: false)) do |td|
          td.integer t1_column, column_options
          td.integer t2_column, column_options
          yield td if block_given?
        end
      end

      # Drops the join table specified by the given arguments.
      # See create_join_table for details.
      #
      # Although this command ignores the block if one is given, it can be helpful
      # to provide one in a migration's +change+ method so it can be reverted.
      # In that case, the block will be used by create_join_table.
      def drop_join_table(table_1, table_2, options = {})
        join_table_name = find_join_table_name(table_1, table_2, options)
        drop_table(join_table_name)
      end

      # A block for changing columns in +table+.
      #
      #  # change_table() yields a Table instance
      #  change_table(:suppliers) do |t|
      #    t.column :name, :string, limit: 60
      #    # Other column alterations here
      #  end
      #
      # The +options+ hash can include the following keys:
      # [<tt>:bulk</tt>]
      #   Set this to true to make this a bulk alter query, such as
      #   ALTER TABLE `users` ADD COLUMN age INT(11), ADD COLUMN birthdate DATETIME ...
      #
      #   Defaults to false.
      #
      # ====== Add a column
      #  change_table(:suppliers) do |t|
      #    t.column :name, :string, limit: 60
      #  end
      #
      # ====== Add 2 integer columns
      #  change_table(:suppliers) do |t|
      #    t.integer :width, :height, null: false, default: 0
      #  end
      #
      # ====== Add created_at/updated_at columns
      #  change_table(:suppliers) do |t|
      #    t.timestamps
      #  end
      #
      # ====== Add a foreign key column
      #  change_table(:suppliers) do |t|
      #    t.references :company
      #  end
      #
      # Creates a <tt>company_id(integer)</tt> column
      #
      # ====== Add a polymorphic foreign key column
      #  change_table(:suppliers) do |t|
      #    t.belongs_to :company, polymorphic: true
      #  end
      #
      # Creates <tt>company_type(varchar)</tt> and <tt>company_id(integer)</tt> columns
      #
      # ====== Remove a column
      #  change_table(:suppliers) do |t|
      #    t.remove :company
      #  end
      #
      # ====== Remove several columns
      #  change_table(:suppliers) do |t|
      #    t.remove :company_id
      #    t.remove :width, :height
      #  end
      #
      # ====== Remove an index
      #  change_table(:suppliers) do |t|
      #    t.remove_index :company_id
      #  end
      #
      # See also Table for details on
      # all of the various column transformation
      def change_table(table_name, options = {})
        if supports_bulk_alter? && options[:bulk]
          recorder = ActiveRecord::Migration::CommandRecorder.new(self)
          yield Table.new(table_name, recorder)
          bulk_change_table(table_name, recorder.commands)
        else
          yield Table.new(table_name, self)
        end
      end

      # Renames a table.
      #
      #  rename_table('octopuses', 'octopi')
      def rename_table(table_name, new_name)
        raise NotImplementedError, "rename_table is not implemented"
      end

      # Drops a table from the database.
      #
      # Although this command ignores +options+ and the block if one is given, it can be helpful
      # to provide these in a migration's +change+ method so it can be reverted.
      # In that case, +options+ and the block will be used by create_table.
      def drop_table(table_name, options = {})
        execute "DROP TABLE #{quote_table_name(table_name)}"
      end

      # Adds a new column to the named table.
      # See TableDefinition#column for details of the options you can use.
      def add_column(table_name, column_name, type, options = {})
        add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
        add_column_options!(add_column_sql, options)
        execute(add_column_sql)
      end

      # Removes the given columns from the table definition.
      #
      #  remove_columns(:suppliers, :qualification, :experience)
      def remove_columns(table_name, *column_names)
        raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.empty?
        column_names.each do |column_name|
          remove_column(table_name, column_name)
        end
      end

      # Removes the column from the table definition.
      #
      #  remove_column(:suppliers, :qualification)
      #
      # The +type+ and +options+ parameters will be ignored if present. It can be helpful
      # to provide these in a migration's +change+ method so it can be reverted.
      # In that case, +type+ and +options+ will be used by add_column.
      def remove_column(table_name, column_name, type = nil, options = {})
        execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
      end

      # Changes the column's definition according to the new options.
      # See TableDefinition#column for details of the options you can use.
      #
      #  change_column(:suppliers, :name, :string, limit: 80)
      #  change_column(:accounts, :description, :text)
      def change_column(table_name, column_name, type, options = {})
        raise NotImplementedError, "change_column is not implemented"
      end

      # Sets a new default value for a column.
      #
      #  change_column_default(:suppliers, :qualification, 'new')
      #  change_column_default(:accounts, :authorized, 1)
      #  change_column_default(:users, :email, nil)
      def change_column_default(table_name, column_name, default)
        raise NotImplementedError, "change_column_default is not implemented"
      end

      # Renames a column.
      #
      #  rename_column(:suppliers, :description, :name)
      def rename_column(table_name, column_name, new_column_name)
        raise NotImplementedError, "rename_column is not implemented"
      end

      # Adds a new index to the table. +column_name+ can be a single Symbol, or
      # an Array of Symbols.
      #
      # The index will be named after the table and the column name(s), unless
      # you pass <tt>:name</tt> as an option.
      #
      # ====== Creating a simple index
      #  add_index(:suppliers, :name)
      # generates
      #  CREATE INDEX suppliers_name_index ON suppliers(name)
      #
      # ====== Creating a unique index
      #  add_index(:accounts, [:branch_id, :party_id], unique: true)
      # generates
      #  CREATE UNIQUE INDEX accounts_branch_id_party_id_index ON accounts(branch_id, party_id)
      #
      # ====== Creating a named index
      #  add_index(:accounts, [:branch_id, :party_id], unique: true, name: 'by_branch_party')
      # generates
      #  CREATE UNIQUE INDEX by_branch_party ON accounts(branch_id, party_id)
      #
      # ====== Creating an index with specific key length
      #  add_index(:accounts, :name, name: 'by_name', length: 10)
      # generates
      #  CREATE INDEX by_name ON accounts(name(10))
      #
      #  add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
      # generates
      #  CREATE INDEX by_name_surname ON accounts(name(10), surname(15))
      #
      # Note: SQLite doesn't support index length
      #
      # ====== Creating an index with a sort order (desc or asc, asc is the default)
      #  add_index(:accounts, [:branch_id, :party_id, :surname], order: {branch_id: :desc, party_id: :asc})
      # generates
      #  CREATE INDEX by_branch_desc_party ON accounts(branch_id DESC, party_id ASC, surname)
      #
      # Note: mysql doesn't yet support index order (it accepts the syntax but ignores it)
      #
      # ====== Creating a partial index
      #  add_index(:accounts, [:branch_id, :party_id], unique: true, where: "active")
      # generates
      #  CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
      #
      # Note: only supported by PostgreSQL
      #
      def add_index(table_name, column_name, options = {})
        index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
        execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
      end

      # Remove the given index from the table.
      #
      # Remove the index_accounts_on_column in the accounts table.
      #   remove_index :accounts, :column
      # Remove the index named index_accounts_on_branch_id in the accounts table.
      #   remove_index :accounts, column: :branch_id
      # Remove the index named index_accounts_on_branch_id_and_party_id in the accounts table.
      #   remove_index :accounts, column: [:branch_id, :party_id]
      # Remove the index named by_branch_party in the accounts table.
      #   remove_index :accounts, name: :by_branch_party
      def remove_index(table_name, options = {})
        remove_index!(table_name, index_name_for_remove(table_name, options))
      end

      def remove_index!(table_name, index_name) #:nodoc:
        execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
      end

      # Rename an index.
      #
      # Rename the index_people_on_last_name index to index_users_on_last_name
      #   rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
      def rename_index(table_name, old_name, new_name)
        # this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance)
        old_index_def = indexes(table_name).detect { |i| i.name == old_name }
        return unless old_index_def
        remove_index(table_name, :name => old_name)
        add_index(table_name, old_index_def.columns, :name => new_name, :unique => old_index_def.unique)
      end

      def index_name(table_name, options) #:nodoc:
        if Hash === options
          if options[:column]
            "index_#{table_name}_on_#{Array(options[:column]) * '_and_'}"
          elsif options[:name]
            options[:name]
          else
            raise ArgumentError, "You must specify the index name"
          end
        else
          index_name(table_name, :column => options)
        end
      end

      # Verify the existence of an index with a given name.
      #
      # The default argument is returned if the underlying implementation does not define the indexes method,
      # as there's no way to determine the correct answer in that case.
      def index_name_exists?(table_name, index_name, default)
        return default unless respond_to?(:indexes)
        index_name = index_name.to_s
        indexes(table_name).detect { |i| i.name == index_name }
      end

      # Adds a reference. Optionally adds a +type+ column, if <tt>:polymorphic</tt> option is provided.
      # <tt>add_reference</tt> and <tt>add_belongs_to</tt> are acceptable.
      #
      # ====== Create a user_id column
      #  add_reference(:products, :user)
      #
      # ====== Create a supplier_id and supplier_type columns
      #  add_belongs_to(:products, :supplier, polymorphic: true)
      #
      # ====== Create a supplier_id, supplier_type columns and appropriate index
      #  add_reference(:products, :supplier, polymorphic: true, index: true)
      #
      def add_reference(table_name, ref_name, options = {})
        polymorphic = options.delete(:polymorphic)
        index_options = options.delete(:index)
        add_column(table_name, "#{ref_name}_id", :integer, options)
        add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
        add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : nil) if index_options
      end
      alias :add_belongs_to :add_reference

      # Removes the reference(s). Also removes a +type+ column if one exists.
      # <tt>remove_reference</tt>, <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
      #
      # ====== Remove the reference
      #  remove_reference(:products, :user, index: true)
      #
      # ====== Remove polymorphic reference
      #  remove_reference(:products, :supplier, polymorphic: true)
      #
      def remove_reference(table_name, ref_name, options = {})
        remove_column(table_name, "#{ref_name}_id")
        remove_column(table_name, "#{ref_name}_type") if options[:polymorphic]
      end
      alias :remove_belongs_to :remove_reference

      # Returns a string of <tt>CREATE TABLE</tt> SQL statement(s) for recreating the
      # entire structure of the database.
      def structure_dump
      end

      def dump_schema_information #:nodoc:
        sm_table = ActiveRecord::Migrator.schema_migrations_table_name

        ActiveRecord::SchemaMigration.order('version').map { |sm|
          "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');"
        }.join "\n\n"
      end

      # Should not be called normally, but this operation is non-destructive.
      # The migrations module handles this automatically.
      def initialize_schema_migrations_table
        ActiveRecord::SchemaMigration.create_table
      end

      def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths)
        migrations_paths = Array(migrations_paths)
        version = version.to_i
        sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)

        migrated = select_values("SELECT version FROM #{sm_table}").map { |v| v.to_i }
        paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }
        versions = Dir[*paths].map do |filename|
          filename.split('/').last.split('_').first.to_i
        end

        unless migrated.include?(version)
          execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')"
        end

        inserted = Set.new
        (versions - migrated).each do |v|
          if inserted.include?(v)
            raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict."
          elsif v < version
            execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
            inserted << v
          end
        end
      end

      def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
        if native = native_database_types[type.to_sym]
          column_type_sql = (native.is_a?(Hash) ? native[:name] : native).dup

          if type == :decimal # ignore limit, use precision and scale
            scale ||= native[:scale]

            if precision ||= native[:precision]
              if scale
                column_type_sql << "(#{precision},#{scale})"
              else
                column_type_sql << "(#{precision})"
              end
            elsif scale
              raise ArgumentError, "Error adding decimal column: precision cannot be empty if scale is specified"
            end

          elsif (type != :primary_key) && (limit ||= native.is_a?(Hash) && native[:limit])
            column_type_sql << "(#{limit})"
          end

          column_type_sql
        else
          type
        end
      end

      def add_column_options!(sql, options) #:nodoc:
        sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
        # must explicitly check for :null to allow change_column to work on migrations
        if options[:null] == false
          sql << " NOT NULL"
        end
      end

      # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
      # Both PostgreSQL and Oracle overrides this for custom DISTINCT syntax.
      #
      #   distinct("posts.id", "posts.created_at desc")
      def distinct(columns, order_by)
        "DISTINCT #{columns}"
      end

      # Adds timestamps (created_at and updated_at) columns to the named table.
      #
      #  add_timestamps(:suppliers)
      def add_timestamps(table_name)
        add_column table_name, :created_at, :datetime
        add_column table_name, :updated_at, :datetime
      end

      # Removes the timestamp columns (created_at and updated_at) from the table definition.
      #
      #  remove_timestamps(:suppliers)
      def remove_timestamps(table_name)
        remove_column table_name, :updated_at
        remove_column table_name, :created_at
      end

      protected
        def add_index_sort_order(option_strings, column_names, options = {})
          if options.is_a?(Hash) && order = options[:order]
            case order
            when Hash
              column_names.each {|name| option_strings[name] += " #{order[name].upcase}" if order.has_key?(name)}
            when String
              column_names.each {|name| option_strings[name] += " #{order.upcase}"}
            end
          end

          return option_strings
        end

        # Overridden by the mysql adapter for supporting index lengths
        def quoted_columns_for_index(column_names, options = {})
          option_strings = Hash[column_names.map {|name| [name, '']}]

          # add index sort order if supported
          if supports_index_sort_order?
            option_strings = add_index_sort_order(option_strings, column_names, options)
          end

          column_names.map {|name| quote_column_name(name) + option_strings[name]}
        end

        def options_include_default?(options)
          options.include?(:default) && !(options[:null] == false && options[:default].nil?)
        end

        def add_index_options(table_name, column_name, options = {})
          column_names = Array(column_name)
          index_name   = index_name(table_name, column: column_names)

          if Hash === options # legacy support, since this param was a string
            options.assert_valid_keys(:unique, :order, :name, :where, :length)

            index_type = options[:unique] ? "UNIQUE" : ""
            index_name = options[:name].to_s if options.key?(:name)

            if supports_partial_index?
              index_options = options[:where] ? " WHERE #{options[:where]}" : ""
            end
          else
            if options
              message = "Passing a string as third argument of `add_index` is deprecated and will" +
                " be removed in Rails 4.1." +
                " Use add_index(#{table_name.inspect}, #{column_name.inspect}, unique: true) instead"

              ActiveSupport::Deprecation.warn message
            end

            index_type = options
          end

          if index_name.length > index_name_length
            raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters"
          end
          if index_name_exists?(table_name, index_name, false)
            raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
          end
          index_columns = quoted_columns_for_index(column_names, options).join(", ")

          [index_name, index_type, index_columns, index_options]
        end

        def index_name_for_remove(table_name, options = {})
          index_name = index_name(table_name, options)

          unless index_name_exists?(table_name, index_name, true)
            raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
          end

          index_name
        end

        def columns_for_remove(table_name, *column_names)
          ActiveSupport::Deprecation.warn("columns_for_remove is deprecated and will be removed in the future")
          raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)") if column_names.blank?
          column_names.map {|column_name| quote_column_name(column_name) }
        end

      private
      def table_definition
        TableDefinition.new(self)
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class Transaction #:nodoc:
      attr_reader :connection

      def initialize(connection)
        @connection = connection
        @state = TransactionState.new 
      end

      def state
        @state
      end
    end

    class TransactionState

      VALID_STATES = Set.new([:committed, :rolledback, nil])

      def initialize(state = nil)
        @state = state
      end

      def committed?
        @state == :committed
      end

      def rolledback?
        @state == :rolledback
      end

      def set_state(state)
        if !VALID_STATES.include?(state)
          raise ArgumentError, "Invalid transaction state: #{state}"
        end
        @state = state
      end
    end

    class ClosedTransaction < Transaction #:nodoc:
      def number
        0
      end

      def begin(options = {})
        RealTransaction.new(connection, self, options)
      end

      def closed?
        true
      end

      def open?
        false
      end

      def joinable?
        false
      end

      # This is a noop when there are no open transactions
      def add_record(record)
      end
    end

    class OpenTransaction < Transaction #:nodoc:
      attr_reader :parent, :records
      attr_writer :joinable

      def initialize(connection, parent, options = {})
        super connection

        @parent    = parent
        @records   = []
        @finishing = false
        @joinable  = options.fetch(:joinable, true)
      end

      # This state is necesarry so that we correctly handle stuff that might
      # happen in a commit/rollback. But it's kinda distasteful. Maybe we can
      # find a better way to structure it in the future.
      def finishing?
        @finishing
      end

      def joinable?
        @joinable && !finishing?
      end

      def number
        if finishing?
          parent.number
        else
          parent.number + 1
        end
      end

      def begin(options = {})
        if finishing?
          parent.begin
        else
          SavepointTransaction.new(connection, self, options)
        end
      end

      def rollback
        @finishing = true
        perform_rollback
        parent
      end

      def commit
        @finishing = true
        perform_commit
        parent
      end

      def add_record(record)
        records << record
      end

      def rollback_records
        @state.set_state(:rolledback)
        records.uniq.each do |record|
          begin
            record.rolledback!(parent.closed?)
          rescue => e
            record.logger.error(e) if record.respond_to?(:logger) && record.logger
          end
        end
      end

      def commit_records
        @state.set_state(:committed)
        records.uniq.each do |record|
          begin
            record.committed!
          rescue => e
            record.logger.error(e) if record.respond_to?(:logger) && record.logger
          end
        end
      end

      def closed?
        false
      end

      def open?
        true
      end
    end

    class RealTransaction < OpenTransaction #:nodoc:
      def initialize(connection, parent, options = {})
        super

        if options[:isolation]
          connection.begin_isolated_db_transaction(options[:isolation])
        else
          connection.begin_db_transaction
        end
      end

      def perform_rollback
        connection.rollback_db_transaction
        rollback_records
      end

      def perform_commit
        connection.commit_db_transaction
        commit_records
      end
    end

    class SavepointTransaction < OpenTransaction #:nodoc:
      def initialize(connection, parent, options = {})
        if options[:isolation]
          raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
        end

        super
        connection.create_savepoint
      end

      def perform_rollback
        connection.rollback_to_savepoint
        rollback_records
      end

      def perform_commit
        connection.release_savepoint
        records.each { |r| parent.add_record(r) }
      end
    end
  end
end
require 'date'
require 'bigdecimal'
require 'bigdecimal/util'
require 'active_support/core_ext/benchmark'
require 'active_record/connection_adapters/schema_cache'
require 'active_record/connection_adapters/abstract/schema_dumper'
require 'monitor'

module ActiveRecord
  module ConnectionAdapters # :nodoc:
    extend ActiveSupport::Autoload

    autoload :Column
    autoload :ConnectionSpecification

    autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
      autoload :IndexDefinition
      autoload :ColumnDefinition
      autoload :TableDefinition
      autoload :Table
    end

    autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
      autoload :ConnectionHandler
      autoload :ConnectionManagement
    end

    autoload_under 'abstract' do
      autoload :SchemaStatements
      autoload :DatabaseStatements
      autoload :DatabaseLimits
      autoload :Quoting
      autoload :ConnectionPool
      autoload :QueryCache
    end

    autoload_at 'active_record/connection_adapters/abstract/transaction' do
      autoload :ClosedTransaction
      autoload :RealTransaction
      autoload :SavepointTransaction
    end

    # Active Record supports multiple database systems. AbstractAdapter and
    # related classes form the abstraction layer which makes this possible.
    # An AbstractAdapter represents a connection to a database, and provides an
    # abstract interface for database-specific functionality such as establishing
    # a connection, escaping values, building the right SQL fragments for ':offset'
    # and ':limit' options, etc.
    #
    # All the concrete database adapters follow the interface laid down in this class.
    # ActiveRecord::Base.connection returns an AbstractAdapter object, which
    # you can use.
    #
    # Most of the methods in the adapter are useful during migrations. Most
    # notably, the instance methods provided by SchemaStatement are very useful.
    class AbstractAdapter
      include Quoting, DatabaseStatements, SchemaStatements
      include DatabaseLimits
      include QueryCache
      include ActiveSupport::Callbacks
      include MonitorMixin
      include ColumnDumper

      define_callbacks :checkout, :checkin

      attr_accessor :visitor, :pool
      attr_reader :schema_cache, :last_use, :in_use, :logger
      alias :in_use? :in_use

      def initialize(connection, logger = nil, pool = nil) #:nodoc:
        super()

        @connection          = connection
        @in_use              = false
        @instrumenter        = ActiveSupport::Notifications.instrumenter
        @last_use            = false
        @logger              = logger
        @pool                = pool
        @query_cache         = Hash.new { |h,sql| h[sql] = {} }
        @query_cache_enabled = false
        @schema_cache        = SchemaCache.new self
        @visitor             = nil
      end

      def lease
        synchronize do
          unless in_use
            @in_use   = true
            @last_use = Time.now
          end
        end
      end

      def schema_cache=(cache)
        cache.connection = self
        @schema_cache = cache
      end

      def expire
        @in_use = false
      end

      # Returns the human-readable name of the adapter. Use mixed case - one
      # can always use downcase if needed.
      def adapter_name
        'Abstract'
      end

      # Does this adapter support migrations? Backend specific, as the
      # abstract adapter always returns +false+.
      def supports_migrations?
        false
      end

      # Can this adapter determine the primary key for tables not attached
      # to an Active Record class, such as join tables? Backend specific, as
      # the abstract adapter always returns +false+.
      def supports_primary_key?
        false
      end

      # Does this adapter support using DISTINCT within COUNT? This is +true+
      # for all adapters except sqlite.
      def supports_count_distinct?
        true
      end

      # Does this adapter support DDL rollbacks in transactions? That is, would
      # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
      # SQL Server, and others support this. MySQL and others do not.
      def supports_ddl_transactions?
        false
      end

      def supports_bulk_alter?
        false
      end

      # Does this adapter support savepoints? PostgreSQL and MySQL do,
      # SQLite < 3.6.8 does not.
      def supports_savepoints?
        false
      end

      # Should primary key values be selected from their corresponding
      # sequence before the insert statement? If true, next_sequence_value
      # is called before each insert to set the record's primary key.
      # This is false for all adapters but Firebird.
      def prefetch_primary_key?(table_name = nil)
        false
      end

      # Does this adapter support index sort order?
      def supports_index_sort_order?
        false
      end

      # Does this adapter support partial indices?
      def supports_partial_index?
        false
      end

      # Does this adapter support explain? As of this writing sqlite3,
      # mysql2, and postgresql are the only ones that do.
      def supports_explain?
        false
      end

      # Does this adapter support setting the isolation level for a transaction?
      def supports_transaction_isolation?
        false
      end

      # Does this adapter support database extensions? As of this writing only
      # postgresql does.
      def supports_extensions?
        false
      end

      # A list of extensions, to be filled in by adapters that support them. At
      # the moment only postgresql does.
      def extensions
        []
      end

      # QUOTING ==================================================

      # Returns a bind substitution value given a +column+ and list of current
      # +binds+.
      def substitute_at(column, index)
        Arel::Nodes::BindParam.new '?'
      end

      # REFERENTIAL INTEGRITY ====================================

      # Override to turn off referential integrity while executing <tt>&block</tt>.
      def disable_referential_integrity
        yield
      end

      # CONNECTION MANAGEMENT ====================================

      # Checks whether the connection to the database is still active. This includes
      # checking whether the database is actually capable of responding, i.e. whether
      # the connection isn't stale.
      def active?
      end

      # Disconnects from the database if already connected, and establishes a
      # new connection with the database. Implementors should call super if they
      # override the default implementation.
      def reconnect!
        clear_cache!
        reset_transaction
      end

      # Disconnects from the database if already connected. Otherwise, this
      # method does nothing.
      def disconnect!
        clear_cache!
        reset_transaction
      end

      # Reset the state of this connection, directing the DBMS to clear
      # transactions and other connection-related server-side state. Usually a
      # database-dependent operation.
      #
      # The default implementation does nothing; the implementation should be
      # overridden by concrete adapters.
      def reset!
        # this should be overridden by concrete adapters
      end

      ###
      # Clear any caching the database adapter may be doing, for example
      # clearing the prepared statement cache. This is database specific.
      def clear_cache!
        # this should be overridden by concrete adapters
      end

      # Returns true if its required to reload the connection between requests for development mode.
      # This is not the case for Ruby/MySQL and it's not necessary for any adapters except SQLite.
      def requires_reloading?
        false
      end

      # Checks whether the connection to the database is still active (i.e. not stale).
      # This is done under the hood by calling <tt>active?</tt>. If the connection
      # is no longer active, then this method will reconnect to the database.
      def verify!(*ignored)
        reconnect! unless active?
      end

      # Provides access to the underlying database driver for this adapter. For
      # example, this method returns a Mysql object in case of MysqlAdapter,
      # and a PGconn object in case of PostgreSQLAdapter.
      #
      # This is useful for when you need to call a proprietary method such as
      # PostgreSQL's lo_* methods.
      def raw_connection
        @connection
      end

      def open_transactions
        @transaction.number
      end

      def increment_open_transactions
        ActiveSupport::Deprecation.warn "#increment_open_transactions is deprecated and has no effect"
      end

      def decrement_open_transactions
        ActiveSupport::Deprecation.warn "#decrement_open_transactions is deprecated and has no effect"
      end

      def transaction_joinable=(joinable)
        message = "#transaction_joinable= is deprecated. Please pass the :joinable option to #begin_transaction instead."
        ActiveSupport::Deprecation.warn message
        @transaction.joinable = joinable
      end

      def create_savepoint
      end

      def rollback_to_savepoint
      end

      def release_savepoint
      end

      def case_sensitive_modifier(node)
        node
      end

      def case_insensitive_comparison(table, attribute, column, value)
        table[attribute].lower.eq(table.lower(value))
      end

      def current_savepoint_name
        "active_record_#{open_transactions}"
      end

      # Check the connection back in to the connection pool
      def close
        pool.checkin self
      end

      protected

      def log(sql, name = "SQL", binds = [])
        @instrumenter.instrument(
          "sql.active_record",
          :sql           => sql,
          :name          => name,
          :connection_id => object_id,
          :binds         => binds) { yield }
      rescue => e
        message = "#{e.class.name}: #{e.message}: #{sql}"
        @logger.error message if @logger
        exception = translate_exception(e, message)
        exception.set_backtrace e.backtrace
        raise exception
      end

      def translate_exception(exception, message)
        # override in derived class
        ActiveRecord::StatementInvalid.new(message)
      end
    end
  end
end
require 'arel/visitors/bind_visitor'

module ActiveRecord
  module ConnectionAdapters
    class AbstractMysqlAdapter < AbstractAdapter
      class Column < ConnectionAdapters::Column # :nodoc:
        attr_reader :collation, :strict

        def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false)
          @strict    = strict
          @collation = collation

          super(name, default, sql_type, null)
        end

        def extract_default(default)
          if blob_or_text_column?
            if default.blank?
              null || strict ? nil : ''
            else
              raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
            end
          elsif missing_default_forged_as_empty_string?(default)
            nil
          else
            super
          end
        end

        def has_default?
          return false if blob_or_text_column? #mysql forbids defaults on blob and text columns
          super
        end
        
        def blob_or_text_column?
          sql_type =~ /blob/i || type == :text
        end

        # Must return the relevant concrete adapter
        def adapter
          raise NotImplementedError
        end

        def case_sensitive?
          collation && !collation.match(/_ci$/)
        end

        private

        def simplified_type(field_type)
          return :boolean if adapter.emulate_booleans && field_type.downcase.index("tinyint(1)")

          case field_type
          when /enum/i, /set/i then :string
          when /year/i         then :integer
          when /bit/i          then :binary
          else
            super
          end
        end

        def extract_limit(sql_type)
          case sql_type
          when /blob|text/i
            case sql_type
            when /tiny/i
              255
            when /medium/i
              16777215
            when /long/i
              2147483647 # mysql only allows 2^31-1, not 2^32-1, somewhat inconsistently with the tiny/medium/normal cases
            else
              super # we could return 65535 here, but we leave it undecorated by default
            end
          when /^bigint/i;    8
          when /^int/i;       4
          when /^mediumint/i; 3
          when /^smallint/i;  2
          when /^tinyint/i;   1
          when /^enum\((.+)\)/i
            $1.split(',').map{|enum| enum.strip.length - 2}.max
          else
            super
          end
        end

        # MySQL misreports NOT NULL column default when none is given.
        # We can't detect this for columns which may have a legitimate ''
        # default (string) but we can for others (integer, datetime, boolean,
        # and the rest).
        #
        # Test whether the column has default '', is not null, and is not
        # a type allowing default ''.
        def missing_default_forged_as_empty_string?(default)
          type != :string && !null && default == ''
        end
      end

      ##
      # :singleton-method:
      # By default, the MysqlAdapter will consider all columns of type <tt>tinyint(1)</tt>
      # as boolean. If you wish to disable this emulation (which was the default
      # behavior in versions 0.13.1 and earlier) you can add the following line
      # to your application.rb file:
      #
      #   ActiveRecord::ConnectionAdapters::Mysql[2]Adapter.emulate_booleans = false
      class_attribute :emulate_booleans
      self.emulate_booleans = true

      LOST_CONNECTION_ERROR_MESSAGES = [
        "Server shutdown in progress",
        "Broken pipe",
        "Lost connection to MySQL server during query",
        "MySQL server has gone away" ]

      QUOTED_TRUE, QUOTED_FALSE = '1', '0'

      NATIVE_DATABASE_TYPES = {
        :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
        :string      => { :name => "varchar", :limit => 255 },
        :text        => { :name => "text" },
        :integer     => { :name => "int", :limit => 4 },
        :float       => { :name => "float" },
        :decimal     => { :name => "decimal" },
        :datetime    => { :name => "datetime" },
        :timestamp   => { :name => "datetime" },
        :time        => { :name => "time" },
        :date        => { :name => "date" },
        :binary      => { :name => "blob" },
        :boolean     => { :name => "tinyint", :limit => 1 }
      }

      class BindSubstitution < Arel::Visitors::MySQL # :nodoc:
        include Arel::Visitors::BindVisitor
      end

      # FIXME: Make the first parameter more similar for the two adapters
      def initialize(connection, logger, connection_options, config)
        super(connection, logger)
        @connection_options, @config = connection_options, config
        @quoted_column_names, @quoted_table_names = {}, {}

        if config.fetch(:prepared_statements) { true }
          @visitor = Arel::Visitors::MySQL.new self
        else
          @visitor = BindSubstitution.new self
        end
      end

      def adapter_name #:nodoc:
        self.class::ADAPTER_NAME
      end

      # Returns true, since this connection adapter supports migrations.
      def supports_migrations?
        true
      end

      def supports_primary_key?
        true
      end

      # Returns true, since this connection adapter supports savepoints.
      def supports_savepoints?
        true
      end

      def supports_bulk_alter? #:nodoc:
        true
      end

      # Technically MySQL allows to create indexes with the sort order syntax
      # but at the moment (5.5) it doesn't yet implement them
      def supports_index_sort_order?
        true
      end

      # MySQL 4 technically support transaction isolation, but it is affected by a bug
      # where the transaction level gets persisted for the whole session:
      #
      # http://bugs.mysql.com/bug.php?id=39170
      def supports_transaction_isolation?
        version[0] >= 5
      end

      def native_database_types
        NATIVE_DATABASE_TYPES
      end

      # HELPER METHODS ===========================================

      # The two drivers have slightly different ways of yielding hashes of results, so
      # this method must be implemented to provide a uniform interface.
      def each_hash(result) # :nodoc:
        raise NotImplementedError
      end

      # Overridden by the adapters to instantiate their specific Column type.
      def new_column(field, default, type, null, collation) # :nodoc:
        Column.new(field, default, type, null, collation)
      end

      # Must return the Mysql error number from the exception, if the exception has an
      # error number.
      def error_number(exception) # :nodoc:
        raise NotImplementedError
      end

      # QUOTING ==================================================

      def quote(value, column = nil)
        if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
          s = column.class.string_to_binary(value).unpack("H*")[0]
          "x'#{s}'"
        else
          super
        end
      end

      def quote_column_name(name) #:nodoc:
        @quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`"
      end

      def quote_table_name(name) #:nodoc:
        @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`')
      end

      def quoted_true
        QUOTED_TRUE
      end

      def quoted_false
        QUOTED_FALSE
      end

      # REFERENTIAL INTEGRITY ====================================

      def disable_referential_integrity(&block) #:nodoc:
        old = select_value("SELECT @@FOREIGN_KEY_CHECKS")

        begin
          update("SET FOREIGN_KEY_CHECKS = 0")
          yield
        ensure
          update("SET FOREIGN_KEY_CHECKS = #{old}")
        end
      end

      # DATABASE STATEMENTS ======================================

      # Executes the SQL statement in the context of this connection.
      def execute(sql, name = nil)
        if name == :skip_logging
          @connection.query(sql)
        else
          log(sql, name) { @connection.query(sql) }
        end
      rescue ActiveRecord::StatementInvalid => exception
        if exception.message.split(":").first =~ /Packets out of order/
          raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
        else
          raise
        end
      end

      # MysqlAdapter has to free a result after using it, so we use this method to write
      # stuff in an abstract way without concerning ourselves about whether it needs to be
      # explicitly freed or not.
      def execute_and_free(sql, name = nil) #:nodoc:
        yield execute(sql, name)
      end

      def update_sql(sql, name = nil) #:nodoc:
        super
        @connection.affected_rows
      end

      def begin_db_transaction
        execute "BEGIN"
      rescue
        # Transactions aren't supported
      end

      def begin_isolated_db_transaction(isolation)
        execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
        begin_db_transaction
      rescue
        # Transactions aren't supported
      end

      def commit_db_transaction #:nodoc:
        execute "COMMIT"
      rescue
        # Transactions aren't supported
      end

      def rollback_db_transaction #:nodoc:
        execute "ROLLBACK"
      rescue
        # Transactions aren't supported
      end

      def create_savepoint
        execute("SAVEPOINT #{current_savepoint_name}")
      end

      def rollback_to_savepoint
        execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
      end

      def release_savepoint
        execute("RELEASE SAVEPOINT #{current_savepoint_name}")
      end

      # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
      # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
      # these, we must use a subquery.
      def join_to_update(update, select) #:nodoc:
        if select.limit || select.offset || select.orders.any?
          super
        else
          update.table select.source
          update.wheres = select.constraints
        end
      end

      def empty_insert_statement_value
        "VALUES ()"
      end

      # SCHEMA STATEMENTS ========================================

      def structure_dump #:nodoc:
        if supports_views?
          sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"
        else
          sql = "SHOW TABLES"
        end

        select_all(sql, 'SCHEMA').map { |table|
          table.delete('Table_type')
          sql = "SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}"
          exec_query(sql, 'SCHEMA').first['Create Table'] + ";\n\n"
        }.join
      end

      # Drops the database specified on the +name+ attribute
      # and creates it again using the provided +options+.
      def recreate_database(name, options = {})
        drop_database(name)
        create_database(name, options)
      end

      # Create a new MySQL database with optional <tt>:charset</tt> and <tt>:collation</tt>.
      # Charset defaults to utf8.
      #
      # Example:
      #   create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
      #   create_database 'matt_development'
      #   create_database 'matt_development', charset: :big5
      def create_database(name, options = {})
        if options[:collation]
          execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`"
        else
          execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`"
        end
      end

      # Drops a MySQL database.
      #
      # Example:
      #   drop_database('sebastian_development')
      def drop_database(name) #:nodoc:
        execute "DROP DATABASE IF EXISTS `#{name}`"
      end

      def current_database
        select_value 'SELECT DATABASE() as db'
      end

      # Returns the database character set.
      def charset
        show_variable 'character_set_database'
      end

      # Returns the database collation strategy.
      def collation
        show_variable 'collation_database'
      end

      def tables(name = nil, database = nil, like = nil) #:nodoc:
        sql = "SHOW TABLES "
        sql << "IN #{quote_table_name(database)} " if database
        sql << "LIKE #{quote(like)}" if like

        execute_and_free(sql, 'SCHEMA') do |result|
          result.collect { |field| field.first }
        end
      end

      def table_exists?(name)
        return false unless name
        return true if tables(nil, nil, name).any?

        name          = name.to_s
        schema, table = name.split('.', 2)

        unless table # A table was provided without a schema
          table  = schema
          schema = nil
        end

        tables(nil, schema, table).any?
      end

      # Returns an array of indexes for the given table.
      def indexes(table_name, name = nil) #:nodoc:
        indexes = []
        current_index = nil
        execute_and_free("SHOW KEYS FROM #{quote_table_name(table_name)}", 'SCHEMA') do |result|
          each_hash(result) do |row|
            if current_index != row[:Key_name]
              next if row[:Key_name] == 'PRIMARY' # skip the primary key
              current_index = row[:Key_name]
              indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], [])
            end

            indexes.last.columns << row[:Column_name]
            indexes.last.lengths << row[:Sub_part]
          end
        end

        indexes
      end

      # Returns an array of +Column+ objects for the table specified by +table_name+.
      def columns(table_name)#:nodoc:
        sql = "SHOW FULL FIELDS FROM #{quote_table_name(table_name)}"
        execute_and_free(sql, 'SCHEMA') do |result|
          each_hash(result).map do |field|
            new_column(field[:Field], field[:Default], field[:Type], field[:Null] == "YES", field[:Collation])
          end
        end
      end

      def create_table(table_name, options = {}) #:nodoc:
        super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB"))
      end

      def bulk_change_table(table_name, operations) #:nodoc:
        sqls = operations.map do |command, args|
          table, arguments = args.shift, args
          method = :"#{command}_sql"

          if respond_to?(method, true)
            send(method, table, *arguments)
          else
            raise "Unknown method called : #{method}(#{arguments.inspect})"
          end
        end.flatten.join(", ")

        execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
      end

      # Renames a table.
      #
      # Example:
      #   rename_table('octopuses', 'octopi')
      def rename_table(table_name, new_name)
        execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
      end

      def add_column(table_name, column_name, type, options = {})
        execute("ALTER TABLE #{quote_table_name(table_name)} #{add_column_sql(table_name, column_name, type, options)}")
      end

      def change_column_default(table_name, column_name, default)
        column = column_for(table_name, column_name)
        change_column table_name, column_name, column.sql_type, :default => default
      end

      def change_column_null(table_name, column_name, null, default = nil)
        column = column_for(table_name, column_name)

        unless null || default.nil?
          execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
        end

        change_column table_name, column_name, column.sql_type, :null => null
      end

      def change_column(table_name, column_name, type, options = {}) #:nodoc:
        execute("ALTER TABLE #{quote_table_name(table_name)} #{change_column_sql(table_name, column_name, type, options)}")
      end

      def rename_column(table_name, column_name, new_column_name) #:nodoc:
        execute("ALTER TABLE #{quote_table_name(table_name)} #{rename_column_sql(table_name, column_name, new_column_name)}")
      end

      # Maps logical Rails types to MySQL-specific data types.
      def type_to_sql(type, limit = nil, precision = nil, scale = nil)
        case type.to_s
        when 'binary'
          case limit
          when 0..0xfff;           "varbinary(#{limit})"
          when nil;                "blob"
          when 0x1000..0xffffffff; "blob(#{limit})"
          else raise(ActiveRecordError, "No binary type has character length #{limit}")
          end
        when 'integer'
          case limit
          when 1; 'tinyint'
          when 2; 'smallint'
          when 3; 'mediumint'
          when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
          when 5..8; 'bigint'
          else raise(ActiveRecordError, "No integer type has byte size #{limit}")
          end
        when 'text'
          case limit
          when 0..0xff;               'tinytext'
          when nil, 0x100..0xffff;    'text'
          when 0x10000..0xffffff;     'mediumtext'
          when 0x1000000..0xffffffff; 'longtext'
          else raise(ActiveRecordError, "No text type has character length #{limit}")
          end
        else
          super
        end
      end

      def add_column_position!(sql, options)
        if options[:first]
          sql << " FIRST"
        elsif options[:after]
          sql << " AFTER #{quote_column_name(options[:after])}"
        end
      end

      # SHOW VARIABLES LIKE 'name'
      def show_variable(name)
        variables = select_all("SHOW VARIABLES LIKE '#{name}'", 'SCHEMA')
        variables.first['Value'] unless variables.empty?
      end

      # Returns a table's primary key and belonging sequence.
      def pk_and_sequence_for(table)
        execute_and_free("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA') do |result|
          create_table = each_hash(result).first[:"Create Table"]
          if create_table.to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/
            keys = $1.split(",").map { |key| key.delete('`"') }
            keys.length == 1 ? [keys.first, nil] : nil
          else
            nil
          end
        end
      end

      # Returns just a table's primary key
      def primary_key(table)
        pk_and_sequence = pk_and_sequence_for(table)
        pk_and_sequence && pk_and_sequence.first
      end

      def case_sensitive_modifier(node)
        Arel::Nodes::Bin.new(node)
      end

      def case_insensitive_comparison(table, attribute, column, value)
        if column.case_sensitive?
          super
        else
          table[attribute].eq(value)
        end
      end

      def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
        where_sql
      end

      def strict_mode?
        @config.fetch(:strict, true)
      end

      protected

      # MySQL is too stupid to create a temporary table for use subquery, so we have
      # to give it some prompting in the form of a subsubquery. Ugh!
      def subquery_for(key, select)
        subsubselect = select.clone
        subsubselect.projections = [key]

        subselect = Arel::SelectManager.new(select.engine)
        subselect.project Arel.sql(key.name)
        subselect.from subsubselect.as('__active_record_temp')
      end

      def add_index_length(option_strings, column_names, options = {})
        if options.is_a?(Hash) && length = options[:length]
          case length
          when Hash
            column_names.each {|name| option_strings[name] += "(#{length[name]})" if length.has_key?(name) && length[name].present?}
          when Fixnum
            column_names.each {|name| option_strings[name] += "(#{length})"}
          end
        end

        return option_strings
      end

      def quoted_columns_for_index(column_names, options = {})
        option_strings = Hash[column_names.map {|name| [name, '']}]

        # add index length
        option_strings = add_index_length(option_strings, column_names, options)

        # add index sort order
        option_strings = add_index_sort_order(option_strings, column_names, options)

        column_names.map {|name| quote_column_name(name) + option_strings[name]}
      end

      def translate_exception(exception, message)
        case error_number(exception)
        when 1062
          RecordNotUnique.new(message, exception)
        when 1452
          InvalidForeignKey.new(message, exception)
        else
          super
        end
      end

      def add_column_sql(table_name, column_name, type, options = {})
        add_column_sql = "ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
        add_column_options!(add_column_sql, options)
        add_column_position!(add_column_sql, options)
        add_column_sql
      end

      def change_column_sql(table_name, column_name, type, options = {})
        column = column_for(table_name, column_name)

        unless options_include_default?(options)
          options[:default] = column.default
        end

        unless options.has_key?(:null)
          options[:null] = column.null
        end

        change_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
        add_column_options!(change_column_sql, options)
        add_column_position!(change_column_sql, options)
        change_column_sql
      end

      def rename_column_sql(table_name, column_name, new_column_name)
        options = {}

        if column = columns(table_name).find { |c| c.name == column_name.to_s }
          options[:default] = column.default
          options[:null] = column.null
        else
          raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
        end

        current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
        rename_column_sql = "CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}"
        add_column_options!(rename_column_sql, options)
        rename_column_sql
      end

      def remove_column_sql(table_name, column_name, type = nil, options = {})
        "DROP #{quote_column_name(column_name)}"
      end

      def remove_columns_sql(table_name, *column_names)
        column_names.map {|column_name| remove_column_sql(table_name, column_name) }
      end

      def add_index_sql(table_name, column_name, options = {})
        index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
        "ADD #{index_type} INDEX #{index_name} (#{index_columns})"
      end

      def remove_index_sql(table_name, options = {})
        index_name = index_name_for_remove(table_name, options)
        "DROP INDEX #{index_name}"
      end

      def add_timestamps_sql(table_name)
        [add_column_sql(table_name, :created_at, :datetime), add_column_sql(table_name, :updated_at, :datetime)]
      end

      def remove_timestamps_sql(table_name)
        [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)]
      end

      private

      def supports_views?
        version[0] >= 5
      end

      def column_for(table_name, column_name)
        unless column = columns(table_name).find { |c| c.name == column_name.to_s }
          raise "No such column: #{table_name}.#{column_name}"
        end
        column
      end

      def configure_connection
        variables = @config[:variables] || {}

        # By default, MySQL 'where id is null' selects the last inserted id.
        # Turn this off. http://dev.rubyonrails.org/ticket/6778
        variables[:sql_auto_is_null] = 0

        # Increase timeout so the server doesn't disconnect us.
        wait_timeout = @config[:wait_timeout]
        wait_timeout = 2147483 unless wait_timeout.is_a?(Fixnum)
        variables[:wait_timeout] = wait_timeout

        # Make MySQL reject illegal values rather than truncating or blanking them, see
        # http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_all_tables
        # If the user has provided another value for sql_mode, don't replace it.
        if strict_mode? && !variables.has_key?(:sql_mode)
          variables[:sql_mode] = 'STRICT_ALL_TABLES'
        end

        # NAMES does not have an equals sign, see
        # http://dev.mysql.com/doc/refman/5.0/en/set-statement.html#id944430
        # (trailing comma because variable_assignments will always have content)
        encoding = "NAMES #{@config[:encoding]}, " if @config[:encoding]

        # Gather up all of the SET variables...
        variable_assignments = variables.map do |k, v|
          if v == ':default' || v == :default
            "@@SESSION.#{k.to_s} = DEFAULT" # Sets the value to the global or compile default
          elsif !v.nil?
            "@@SESSION.#{k.to_s} = #{quote(v)}"
          end
          # or else nil; compact to clear nils out
        end.compact.join(', ')

        # ...and send them all in one query
        execute("SET #{encoding} #{variable_assignments}", :skip_logging)
      end
    end
  end
end
require 'set'

module ActiveRecord
  # :stopdoc:
  module ConnectionAdapters
    # An abstract definition of a column in a table.
    class Column
      TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set
      FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set

      module Format
        ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
        ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
      end

      attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
      attr_accessor :primary, :coder

      alias :encoded? :coder

      # Instantiates a new column in the table.
      #
      # +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
      # +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
      # +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
      # <tt>company_name varchar(60)</tt>.
      # It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
      # +null+ determines if this column allows +NULL+ values.
      def initialize(name, default, sql_type = nil, null = true)
        @name      = name
        @sql_type  = sql_type
        @null      = null
        @limit     = extract_limit(sql_type)
        @precision = extract_precision(sql_type)
        @scale     = extract_scale(sql_type)
        @type      = simplified_type(sql_type)
        @default   = extract_default(default)
        @primary   = nil
        @coder     = nil
      end

      # Returns +true+ if the column is either of type string or text.
      def text?
        type == :string || type == :text
      end

      # Returns +true+ if the column is either of type integer, float or decimal.
      def number?
        type == :integer || type == :float || type == :decimal
      end

      def has_default?
        !default.nil?
      end

      # Returns the Ruby class that corresponds to the abstract data type.
      def klass
        case type
        when :integer                     then Fixnum
        when :float                       then Float
        when :decimal                     then BigDecimal
        when :datetime, :timestamp, :time then Time
        when :date                        then Date
        when :text, :string, :binary      then String
        when :boolean                     then Object
        end
      end

      def binary?
        type == :binary
      end

      # Casts a Ruby value to something appropriate for writing to the database.
      def type_cast_for_write(value)
        return value unless number?

        case value
        when FalseClass
          0
        when TrueClass
          1
        when String
          value.presence
        else
          value
        end
      end

      # Casts value (which is a String) to an appropriate instance.
      def type_cast(value)
        return nil if value.nil?
        return coder.load(value) if encoded?

        klass = self.class

        case type
        when :string, :text        then value
        when :integer              then klass.value_to_integer(value)
        when :float                then value.to_f
        when :decimal              then klass.value_to_decimal(value)
        when :datetime, :timestamp then klass.string_to_time(value)
        when :time                 then klass.string_to_dummy_time(value)
        when :date                 then klass.value_to_date(value)
        when :binary               then klass.binary_to_string(value)
        when :boolean              then klass.value_to_boolean(value)
        else value
        end
      end

      def type_cast_code(var_name)
        message = "Column#type_cast_code is deprecated in favor of using Column#type_cast only, " \
                  "and it is going to be removed in future Rails versions."
        ActiveSupport::Deprecation.warn message

        klass = self.class.name

        case type
        when :string, :text        then var_name
        when :integer              then "#{klass}.value_to_integer(#{var_name})"
        when :float                then "#{var_name}.to_f"
        when :decimal              then "#{klass}.value_to_decimal(#{var_name})"
        when :datetime, :timestamp then "#{klass}.string_to_time(#{var_name})"
        when :time                 then "#{klass}.string_to_dummy_time(#{var_name})"
        when :date                 then "#{klass}.value_to_date(#{var_name})"
        when :binary               then "#{klass}.binary_to_string(#{var_name})"
        when :boolean              then "#{klass}.value_to_boolean(#{var_name})"
        when :hstore               then "#{klass}.string_to_hstore(#{var_name})"
        when :inet, :cidr          then "#{klass}.string_to_cidr(#{var_name})"
        when :json                 then "#{klass}.string_to_json(#{var_name})"
        else var_name
        end
      end

      # Returns the human name of the column name.
      #
      # ===== Examples
      #  Column.new('sales_stage', ...).human_name # => 'Sales stage'
      def human_name
        Base.human_attribute_name(@name)
      end

      def extract_default(default)
        type_cast(default)
      end

      # Used to convert from Strings to BLOBs
      def string_to_binary(value)
        self.class.string_to_binary(value)
      end

      class << self
        # Used to convert from Strings to BLOBs
        def string_to_binary(value)
          value
        end

        # Used to convert from BLOBs to Strings
        def binary_to_string(value)
          value
        end

        def value_to_date(value)
          if value.is_a?(String)
            return nil if value.blank?
            fast_string_to_date(value) || fallback_string_to_date(value)
          elsif value.respond_to?(:to_date)
            value.to_date
          else
            value
          end
        end

        def string_to_time(string)
          return string unless string.is_a?(String)
          return nil if string.blank?

          fast_string_to_time(string) || fallback_string_to_time(string)
        end

        def string_to_dummy_time(string)
          return string unless string.is_a?(String)
          return nil if string.blank?

          dummy_time_string = "2000-01-01 #{string}"

          fast_string_to_time(dummy_time_string) || begin
            time_hash = Date._parse(dummy_time_string)
            return nil if time_hash[:hour].nil?
            new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
          end
        end

        # convert something to a boolean
        def value_to_boolean(value)
          if value.is_a?(String) && value.blank?
            nil
          else
            TRUE_VALUES.include?(value)
          end
        end

        # Used to convert values to integer.
        # handle the case when an integer column is used to store boolean values
        def value_to_integer(value)
          case value
          when TrueClass, FalseClass
            value ? 1 : 0
          else
            value.to_i rescue nil
          end
        end

        # convert something to a BigDecimal
        def value_to_decimal(value)
          # Using .class is faster than .is_a? and
          # subclasses of BigDecimal will be handled
          # in the else clause
          if value.class == BigDecimal
            value
          elsif value.respond_to?(:to_d)
            value.to_d
          else
            value.to_s.to_d
          end
        end

        protected
          # '0.123456' -> 123456
          # '1.123456' -> 123456
          def microseconds(time)
            time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
          end

          def new_date(year, mon, mday)
            if year && year != 0
              Date.new(year, mon, mday) rescue nil
            end
          end

          def new_time(year, mon, mday, hour, min, sec, microsec)
            # Treat 0000-00-00 00:00:00 as nil.
            return nil if year.nil? || (year == 0 && mon == 0 && mday == 0)

            Time.send(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
          end

          def fast_string_to_date(string)
            if string =~ Format::ISO_DATE
              new_date $1.to_i, $2.to_i, $3.to_i
            end
          end

          # Doesn't handle time zones.
          def fast_string_to_time(string)
            if string =~ Format::ISO_DATETIME
              microsec = ($7.to_r * 1_000_000).to_i
              new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
            end
          end

          def fallback_string_to_date(string)
            new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
          end

          def fallback_string_to_time(string)
            time_hash = Date._parse(string)
            time_hash[:sec_fraction] = microseconds(time_hash)

            new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
          end
      end

      private
        def extract_limit(sql_type)
          $1.to_i if sql_type =~ /\((.*)\)/
        end

        def extract_precision(sql_type)
          $2.to_i if sql_type =~ /^(numeric|decimal|number)\((\d+)(,\d+)?\)/i
        end

        def extract_scale(sql_type)
          case sql_type
            when /^(numeric|decimal|number)\((\d+)\)/i then 0
            when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
          end
        end

        def simplified_type(field_type)
          case field_type
          when /int/i
            :integer
          when /float|double/i
            :float
          when /decimal|numeric|number/i
            extract_scale(field_type) == 0 ? :integer : :decimal
          when /datetime/i
            :datetime
          when /timestamp/i
            :timestamp
          when /time/i
            :time
          when /date/i
            :date
          when /clob/i, /text/i
            :text
          when /blob/i, /binary/i
            :binary
          when /char/i, /string/i
            :string
          when /boolean/i
            :boolean
          end
        end
    end
  end
  # :startdoc:
end
require 'uri'

module ActiveRecord
  module ConnectionAdapters
    class ConnectionSpecification #:nodoc:
      attr_reader :config, :adapter_method

      def initialize(config, adapter_method)
        @config, @adapter_method = config, adapter_method
      end

      def initialize_dup(original)
        @config = original.config.dup
      end

      ##
      # Builds a ConnectionSpecification from user input
      class Resolver # :nodoc:
        attr_reader :config, :klass, :configurations

        def initialize(config, configurations)
          @config         = config
          @configurations = configurations
        end

        def spec
          case config
          when nil
            raise AdapterNotSpecified unless defined?(Rails.env)
            resolve_string_connection Rails.env
          when Symbol, String
            resolve_string_connection config.to_s
          when Hash
            resolve_hash_connection config
          end
        end

        private
        def resolve_string_connection(spec) # :nodoc:
          hash = configurations.fetch(spec) do |k|
            connection_url_to_hash(k)
          end

          raise(AdapterNotSpecified, "#{spec} database is not configured") unless hash

          resolve_hash_connection hash
        end

        def resolve_hash_connection(spec) # :nodoc:
          spec = spec.symbolize_keys

          raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)

          begin
            require "active_record/connection_adapters/#{spec[:adapter]}_adapter"
          rescue LoadError => e
            raise LoadError, "Please install the #{spec[:adapter]} adapter: `gem install activerecord-#{spec[:adapter]}-adapter` (#{e.message})", e.backtrace
          end

          adapter_method = "#{spec[:adapter]}_connection"

          ConnectionSpecification.new(spec, adapter_method)
        end

        # For DATABASE_URL, accept a limited concept of ints and floats
        SIMPLE_INT = /\A\d+\z/
        SIMPLE_FLOAT = /\A\d+\.\d+\z/

        def connection_url_to_hash(url) # :nodoc:
          config = URI.parse url
          adapter = config.scheme
          adapter = "postgresql" if adapter == "postgres"
          spec = { :adapter  => adapter,
                   :username => config.user,
                   :password => config.password,
                   :port     => config.port,
                   :database => config.path.sub(%r{^/},""),
                   :host     => config.host }

          spec.reject!{ |_,value| value.blank? }

          uri_parser = URI::Parser.new

          spec.map { |key,value| spec[key] = uri_parser.unescape(value) if value.is_a?(String) }

          if config.query
            options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys

            options.each { |key, value| options[key] = type_cast_value(value) }

            spec.merge!(options)
          end

          spec
        end

        def type_cast_value(value)
          case value
          when SIMPLE_INT
            value.to_i
          when SIMPLE_FLOAT
            value.to_f
          when 'true'
            true
          when 'false'
            false
          else
            value
          end
        end
      end
    end
  end
end
require 'active_record/connection_adapters/abstract_mysql_adapter'

gem 'mysql2', '~> 0.3.10'
require 'mysql2'

module ActiveRecord
  module ConnectionHandling
    # Establishes a connection to the database that's used by all Active Record objects.
    def mysql2_connection(config)
      config = config.symbolize_keys

      config[:username] = 'root' if config[:username].nil?

      if Mysql2::Client.const_defined? :FOUND_ROWS
        config[:flags] = Mysql2::Client::FOUND_ROWS
      end

      client = Mysql2::Client.new(config)
      options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
      ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
    end
  end

  module ConnectionAdapters
    class Mysql2Adapter < AbstractMysqlAdapter

      class Column < AbstractMysqlAdapter::Column # :nodoc:
        def adapter
          Mysql2Adapter
        end
      end

      ADAPTER_NAME = 'Mysql2'

      def initialize(connection, logger, connection_options, config)
        super
        @visitor = BindSubstitution.new self
        configure_connection
      end

      def supports_explain?
        true
      end

      # HELPER METHODS ===========================================

      def each_hash(result) # :nodoc:
        if block_given?
          result.each(:as => :hash, :symbolize_keys => true) do |row|
            yield row
          end
        else
          to_enum(:each_hash, result)
        end
      end

      def new_column(field, default, type, null, collation) # :nodoc:
        Column.new(field, default, type, null, collation, strict_mode?)
      end

      def error_number(exception)
        exception.error_number if exception.respond_to?(:error_number)
      end

      # QUOTING ==================================================

      def quote_string(string)
        @connection.escape(string)
      end

      # CONNECTION MANAGEMENT ====================================

      def active?
        return false unless @connection
        @connection.ping
      end

      def reconnect!
        super
        disconnect!
        connect
      end
      alias :reset! :reconnect!

      # Disconnects from the database if already connected.
      # Otherwise, this method does nothing.
      def disconnect!
        super
        unless @connection.nil?
          @connection.close
          @connection = nil
        end
      end

      # DATABASE STATEMENTS ======================================

      def explain(arel, binds = [])
        sql     = "EXPLAIN #{to_sql(arel, binds.dup)}"
        start   = Time.now
        result  = exec_query(sql, 'EXPLAIN', binds)
        elapsed = Time.now - start

        ExplainPrettyPrinter.new.pp(result, elapsed)
      end

      class ExplainPrettyPrinter # :nodoc:
        # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
        # MySQL shell:
        #
        #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
        #   | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra       |
        #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
        #   |  1 | SIMPLE      | users | const | PRIMARY       | PRIMARY | 4       | const |    1 |             |
        #   |  1 | SIMPLE      | posts | ALL   | NULL          | NULL    | NULL    | NULL  |    1 | Using where |
        #   +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
        #   2 rows in set (0.00 sec)
        #
        # This is an exercise in Ruby hyperrealism :).
        def pp(result, elapsed)
          widths    = compute_column_widths(result)
          separator = build_separator(widths)

          pp = []

          pp << separator
          pp << build_cells(result.columns, widths)
          pp << separator

          result.rows.each do |row|
            pp << build_cells(row, widths)
          end

          pp << separator
          pp << build_footer(result.rows.length, elapsed)

          pp.join("\n") + "\n"
        end

        private

        def compute_column_widths(result)
          [].tap do |widths|
            result.columns.each_with_index do |column, i|
              cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
              widths << cells_in_column.map(&:length).max
            end
          end
        end

        def build_separator(widths)
          padding = 1
          '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
        end

        def build_cells(items, widths)
          cells = []
          items.each_with_index do |item, i|
            item = 'NULL' if item.nil?
            justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
            cells << item.to_s.send(justifier, widths[i])
          end
          '| ' + cells.join(' | ') + ' |'
        end

        def build_footer(nrows, elapsed)
          rows_label = nrows == 1 ? 'row' : 'rows'
          "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
        end
      end

      # FIXME: re-enable the following once a "better" query_cache solution is in core
      #
      # The overrides below perform much better than the originals in AbstractAdapter
      # because we're able to take advantage of mysql2's lazy-loading capabilities
      #
      # # Returns a record hash with the column names as keys and column values
      # # as values.
      # def select_one(sql, name = nil)
      #   result = execute(sql, name)
      #   result.each(as: :hash) do |r|
      #     return r
      #   end
      # end
      #
      # # Returns a single value from a record
      # def select_value(sql, name = nil)
      #   result = execute(sql, name)
      #   if first = result.first
      #     first.first
      #   end
      # end
      #
      # # Returns an array of the values of the first column in a select:
      # #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
      # def select_values(sql, name = nil)
      #   execute(sql, name).map { |row| row.first }
      # end

      # Returns an array of arrays containing the field values.
      # Order is the same as that returned by +columns+.
      def select_rows(sql, name = nil)
        execute(sql, name).to_a
      end

      # Executes the SQL statement in the context of this connection.
      def execute(sql, name = nil)
        # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
        # made since we established the connection
        @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone

        super
      end

      def exec_query(sql, name = 'SQL', binds = [])
        result = execute(sql, name)
        ActiveRecord::Result.new(result.fields, result.to_a)
      end

      alias exec_without_stmt exec_query

      # Returns an array of record hashes with the column names as keys and
      # column values as values.
      def select(sql, name = nil, binds = [])
        exec_query(sql, name)
      end

      def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
        super
        id_value || @connection.last_id
      end
      alias :create :insert_sql

      def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
        execute to_sql(sql, binds), name
      end

      def exec_delete(sql, name, binds)
        execute to_sql(sql, binds), name
        @connection.affected_rows
      end
      alias :exec_update :exec_delete

      def last_inserted_id(result)
        @connection.last_id
      end

      private

      def connect
        @connection = Mysql2::Client.new(@config)
        configure_connection
      end

      def configure_connection
        @connection.query_options.merge!(:as => :array)
        super
      end

      def version
        @version ||= @connection.info[:version].scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
      end
    end
  end
end
require 'active_record/connection_adapters/abstract_mysql_adapter'
require 'active_record/connection_adapters/statement_pool'
require 'active_support/core_ext/hash/keys'

gem 'mysql', '~> 2.9'
require 'mysql'

class Mysql
  class Time
    def to_date
      Date.new(year, month, day)
    end
  end
  class Stmt; include Enumerable end
  class Result; include Enumerable end
end

module ActiveRecord
  module ConnectionHandling
    # Establishes a connection to the database that's used by all Active Record objects.
    def mysql_connection(config) # :nodoc:
      config = config.symbolize_keys
      host     = config[:host]
      port     = config[:port]
      socket   = config[:socket]
      username = config[:username] ? config[:username].to_s : 'root'
      password = config[:password].to_s
      database = config[:database]

      mysql = Mysql.init
      mysql.ssl_set(config[:sslkey], config[:sslcert], config[:sslca], config[:sslcapath], config[:sslcipher]) if config[:sslca] || config[:sslkey]

      default_flags = Mysql.const_defined?(:CLIENT_MULTI_RESULTS) ? Mysql::CLIENT_MULTI_RESULTS : 0
      default_flags |= Mysql::CLIENT_FOUND_ROWS if Mysql.const_defined?(:CLIENT_FOUND_ROWS)
      options = [host, username, password, database, port, socket, default_flags]
      ConnectionAdapters::MysqlAdapter.new(mysql, logger, options, config)
    end
  end

  module ConnectionAdapters
    # The MySQL adapter will work with both Ruby/MySQL, which is a Ruby-based MySQL adapter that comes bundled with Active Record, and with
    # the faster C-based MySQL/Ruby adapter (available both as a gem and from http://www.tmtm.org/en/mysql/ruby/).
    #
    # Options:
    #
    # * <tt>:host</tt> - Defaults to "localhost".
    # * <tt>:port</tt> - Defaults to 3306.
    # * <tt>:socket</tt> - Defaults to "/tmp/mysql.sock".
    # * <tt>:username</tt> - Defaults to "root"
    # * <tt>:password</tt> - Defaults to nothing.
    # * <tt>:database</tt> - The name of the database. No default, must be provided.
    # * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
    # * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
    # * <tt>:strict</tt> - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html)
    # * <tt>:variables</tt> - (Optional) A hash session variables to send as `SET @@SESSION.key = value` on each database connection. Use the value `:default` to set a variable to its DEFAULT value. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/set-statement.html).
    # * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection.
    # * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
    # * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
    # * <tt>:sslcapath</tt> - Necessary to use MySQL with an SSL connection.
    # * <tt>:sslcipher</tt> - Necessary to use MySQL with an SSL connection.
    #
    class MysqlAdapter < AbstractMysqlAdapter

      class Column < AbstractMysqlAdapter::Column #:nodoc:
        def self.string_to_time(value)
          return super unless Mysql::Time === value
          new_time(
            value.year,
            value.month,
            value.day,
            value.hour,
            value.minute,
            value.second,
            value.second_part)
        end

        def self.string_to_dummy_time(v)
          return super unless Mysql::Time === v
          new_time(2000, 01, 01, v.hour, v.minute, v.second, v.second_part)
        end

        def self.string_to_date(v)
          return super unless Mysql::Time === v
          new_date(v.year, v.month, v.day)
        end

        def adapter
          MysqlAdapter
        end
      end

      ADAPTER_NAME = 'MySQL'

      class StatementPool < ConnectionAdapters::StatementPool
        def initialize(connection, max = 1000)
          super
          @cache = Hash.new { |h,pid| h[pid] = {} }
        end

        def each(&block); cache.each(&block); end
        def key?(key);    cache.key?(key); end
        def [](key);      cache[key]; end
        def length;       cache.length; end
        def delete(key);  cache.delete(key); end

        def []=(sql, key)
          while @max <= cache.size
            cache.shift.last[:stmt].close
          end
          cache[sql] = key
        end

        def clear
          cache.values.each do |hash|
            hash[:stmt].close
          end
          cache.clear
        end

        private
        def cache
          @cache[Process.pid]
        end
      end

      def initialize(connection, logger, connection_options, config)
        super
        @statements = StatementPool.new(@connection,
                                        config.fetch(:statement_limit) { 1000 })
        @client_encoding = nil
        connect
      end

      # Returns true, since this connection adapter supports prepared statement
      # caching.
      def supports_statement_cache?
        true
      end

      # HELPER METHODS ===========================================

      def each_hash(result) # :nodoc:
        if block_given?
          result.each_hash do |row|
            row.symbolize_keys!
            yield row
          end
        else
          to_enum(:each_hash, result)
        end
      end

      def new_column(field, default, type, null, collation) # :nodoc:
        Column.new(field, default, type, null, collation, strict_mode?)
      end

      def error_number(exception) # :nodoc:
        exception.errno if exception.respond_to?(:errno)
      end

      # QUOTING ==================================================

      def type_cast(value, column)
        return super unless value == true || value == false

        value ? 1 : 0
      end

      def quote_string(string) #:nodoc:
        @connection.quote(string)
      end

      # CONNECTION MANAGEMENT ====================================

      def active?
        if @connection.respond_to?(:stat)
          @connection.stat
        else
          @connection.query 'select 1'
        end

        # mysql-ruby doesn't raise an exception when stat fails.
        if @connection.respond_to?(:errno)
          @connection.errno.zero?
        else
          true
        end
      rescue Mysql::Error
        false
      end

      def reconnect!
        super
        disconnect!
        connect
      end

      # Disconnects from the database if already connected. Otherwise, this
      # method does nothing.
      def disconnect!
        super
        @connection.close rescue nil
      end

      def reset!
        if @connection.respond_to?(:change_user)
          # See http://bugs.mysql.com/bug.php?id=33540 -- the workaround way to
          # reset the connection is to change the user to the same user.
          @connection.change_user(@config[:username], @config[:password], @config[:database])
          configure_connection
        end
      end

      # DATABASE STATEMENTS ======================================

      def select_rows(sql, name = nil)
        @connection.query_with_result = true
        rows = exec_query(sql, name).rows
        @connection.more_results && @connection.next_result    # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
        rows
      end

      # Clears the prepared statements cache.
      def clear_cache!
        @statements.clear
      end

      # Taken from here:
      #   https://github.com/tmtm/ruby-mysql/blob/master/lib/mysql/charset.rb
      # Author: TOMITA Masahiro <tommy@tmtm.org>
      ENCODINGS = {
        "armscii8" => nil,
        "ascii"    => Encoding::US_ASCII,
        "big5"     => Encoding::Big5,
        "binary"   => Encoding::ASCII_8BIT,
        "cp1250"   => Encoding::Windows_1250,
        "cp1251"   => Encoding::Windows_1251,
        "cp1256"   => Encoding::Windows_1256,
        "cp1257"   => Encoding::Windows_1257,
        "cp850"    => Encoding::CP850,
        "cp852"    => Encoding::CP852,
        "cp866"    => Encoding::IBM866,
        "cp932"    => Encoding::Windows_31J,
        "dec8"     => nil,
        "eucjpms"  => Encoding::EucJP_ms,
        "euckr"    => Encoding::EUC_KR,
        "gb2312"   => Encoding::EUC_CN,
        "gbk"      => Encoding::GBK,
        "geostd8"  => nil,
        "greek"    => Encoding::ISO_8859_7,
        "hebrew"   => Encoding::ISO_8859_8,
        "hp8"      => nil,
        "keybcs2"  => nil,
        "koi8r"    => Encoding::KOI8_R,
        "koi8u"    => Encoding::KOI8_U,
        "latin1"   => Encoding::ISO_8859_1,
        "latin2"   => Encoding::ISO_8859_2,
        "latin5"   => Encoding::ISO_8859_9,
        "latin7"   => Encoding::ISO_8859_13,
        "macce"    => Encoding::MacCentEuro,
        "macroman" => Encoding::MacRoman,
        "sjis"     => Encoding::SHIFT_JIS,
        "swe7"     => nil,
        "tis620"   => Encoding::TIS_620,
        "ucs2"     => Encoding::UTF_16BE,
        "ujis"     => Encoding::EucJP_ms,
        "utf8"     => Encoding::UTF_8,
        "utf8mb4"  => Encoding::UTF_8,
      }

      # Get the client encoding for this database
      def client_encoding
        return @client_encoding if @client_encoding

        result = exec_query(
          "SHOW VARIABLES WHERE Variable_name = 'character_set_client'",
          'SCHEMA')
        @client_encoding = ENCODINGS[result.rows.last.last]
      end

      def exec_query(sql, name = 'SQL', binds = [])
        # If the configuration sets prepared_statements:false, binds will
        # always be empty, since the bind variables will have been already
        # substituted and removed from binds by BindVisitor, so this will
        # effectively disable prepared statement usage completely.
        if binds.empty?
          result_set, affected_rows = exec_without_stmt(sql, name)
        else
          result_set, affected_rows = exec_stmt(sql, name, binds)
        end

        yield affected_rows if block_given?

        result_set
      end

      def last_inserted_id(result)
        @connection.insert_id
      end

      module Fields
        class Type
          def type; end

          def type_cast_for_write(value)
            value
          end
        end

        class Identity < Type
          def type_cast(value); value; end
        end

        class Integer < Type
          def type_cast(value)
            return if value.nil?

            value.to_i rescue value ? 1 : 0
          end
        end

        class Date < Type
          def type; :date; end

          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is mysql
            # specific
            ConnectionAdapters::Column.value_to_date value
          end
        end

        class DateTime < Type
          def type; :datetime; end

          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is mysql
            # specific
            ConnectionAdapters::Column.string_to_time value
          end
        end

        class Time < Type
          def type; :time; end

          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is mysql
            # specific
            ConnectionAdapters::Column.string_to_dummy_time value
          end
        end

        class Float < Type
          def type; :float; end

          def type_cast(value)
            return if value.nil?

            value.to_f
          end
        end

        class Decimal < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::Column.value_to_decimal value
          end
        end

        class Boolean < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::Column.value_to_boolean value
          end
        end

        TYPES = {}

        # Register an MySQL +type_id+ with a typcasting object in
        # +type+.
        def self.register_type(type_id, type)
          TYPES[type_id] = type
        end

        def self.alias_type(new, old)
          TYPES[new] = TYPES[old]
        end

        register_type Mysql::Field::TYPE_TINY,    Fields::Boolean.new
        register_type Mysql::Field::TYPE_LONG,    Fields::Integer.new
        alias_type Mysql::Field::TYPE_LONGLONG,   Mysql::Field::TYPE_LONG
        alias_type Mysql::Field::TYPE_NEWDECIMAL, Mysql::Field::TYPE_LONG

        register_type Mysql::Field::TYPE_VAR_STRING, Fields::Identity.new
        register_type Mysql::Field::TYPE_BLOB, Fields::Identity.new
        register_type Mysql::Field::TYPE_DATE, Fields::Date.new
        register_type Mysql::Field::TYPE_DATETIME, Fields::DateTime.new
        register_type Mysql::Field::TYPE_TIME, Fields::Time.new
        register_type Mysql::Field::TYPE_FLOAT, Fields::Float.new

        Mysql::Field.constants.grep(/TYPE/).map { |class_name|
          Mysql::Field.const_get class_name
        }.reject { |const| TYPES.key? const }.each do |const|
          register_type const, Fields::Identity.new
        end
      end

      def exec_without_stmt(sql, name = 'SQL') # :nodoc:
        # Some queries, like SHOW CREATE TABLE don't work through the prepared
        # statement API. For those queries, we need to use this method. :'(
        log(sql, name) do
          result = @connection.query(sql)
          affected_rows = @connection.affected_rows

          if result
            types = {}
            result.fetch_fields.each { |field|
              if field.decimals > 0
                types[field.name] = Fields::Decimal.new
              else
                types[field.name] = Fields::TYPES.fetch(field.type) {
                  Fields::Identity.new
                }
              end
            }
            result_set = ActiveRecord::Result.new(types.keys, result.to_a, types)
            result.free
          else
            result_set = ActiveRecord::Result.new([], [])
          end

          [result_set, affected_rows]
        end
      end

      def execute_and_free(sql, name = nil)
        result = execute(sql, name)
        ret = yield result
        result.free
        ret
      end

      def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
        super sql, name
        id_value || @connection.insert_id
      end
      alias :create :insert_sql

      def exec_delete(sql, name, binds)
        affected_rows = 0

        exec_query(sql, name, binds) do |n|
          affected_rows = n
        end

        affected_rows
      end
      alias :exec_update :exec_delete

      def begin_db_transaction #:nodoc:
        exec_query "BEGIN"
      rescue Mysql::Error
        # Transactions aren't supported
      end

      private

      def exec_stmt(sql, name, binds)
        cache = {}
        log(sql, name, binds) do
          if binds.empty?
            stmt = @connection.prepare(sql)
          else
            cache = @statements[sql] ||= {
              :stmt => @connection.prepare(sql)
            }
            stmt = cache[:stmt]
          end

          begin
            stmt.execute(*binds.map { |col, val| type_cast(val, col) })
          rescue Mysql::Error => e
            # Older versions of MySQL leave the prepared statement in a bad
            # place when an error occurs. To support older mysql versions, we
            # need to close the statement and delete the statement from the
            # cache.
            stmt.close
            @statements.delete sql
            raise e
          end

          cols = nil
          if metadata = stmt.result_metadata
            cols = cache[:cols] ||= metadata.fetch_fields.map { |field|
              field.name
            }
          end

          result_set = ActiveRecord::Result.new(cols, stmt.to_a) if cols
          affected_rows = stmt.affected_rows

          stmt.result_metadata.free if cols
          stmt.free_result
          stmt.close if binds.empty?

          [result_set, affected_rows]
        end
      end

      def connect
        encoding = @config[:encoding]
        if encoding
          @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
        end

        if @config[:sslca] || @config[:sslkey]
          @connection.ssl_set(@config[:sslkey], @config[:sslcert], @config[:sslca], @config[:sslcapath], @config[:sslcipher])
        end

        @connection.options(Mysql::OPT_CONNECT_TIMEOUT, @config[:connect_timeout]) if @config[:connect_timeout]
        @connection.options(Mysql::OPT_READ_TIMEOUT, @config[:read_timeout]) if @config[:read_timeout]
        @connection.options(Mysql::OPT_WRITE_TIMEOUT, @config[:write_timeout]) if @config[:write_timeout]

        @connection.real_connect(*@connection_options)

        # reconnect must be set after real_connect is called, because real_connect sets it to false internally
        @connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=)

        configure_connection
      end

      # Many Rails applications monkey-patch a replacement of the configure_connection method
      # and don't call 'super', so leave this here even though it looks superfluous.
      def configure_connection
        super
      end

      def select(sql, name = nil, binds = [])
        @connection.query_with_result = true
        rows = exec_query(sql, name, binds)
        @connection.more_results && @connection.next_result    # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
        rows
      end

      # Returns the version of the connected MySQL server.
      def version
        @version ||= @connection.server_info.scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLColumn < Column
      module ArrayParser
        private
          # Loads pg_array_parser if available. String parsing can be
          # performed quicker by a native extension, which will not create
          # a large amount of Ruby objects that will need to be garbage
          # collected. pg_array_parser has a C and Java extension
          begin
            require 'pg_array_parser'
            include PgArrayParser
          rescue LoadError
            def parse_pg_array(string)
              parse_data(string, 0)
            end
          end

          def parse_data(string, index)
            local_index = index
            array = []
            while(local_index < string.length)
              case string[local_index]
              when '{'
                local_index,array = parse_array_contents(array, string, local_index + 1)
              when '}'
                return array
              end
              local_index += 1
            end

            array
          end

          def parse_array_contents(array, string, index)
            is_escaping = false
            is_quoted = false
            was_quoted = false
            current_item = ''

            local_index = index
            while local_index
              token = string[local_index]
              if is_escaping
                current_item << token
                is_escaping = false
              else
                if is_quoted
                  case token
                  when '"'
                    is_quoted = false
                    was_quoted = true
                  when "\\"
                    is_escaping = true
                  else
                    current_item << token
                  end
                else
                  case token
                  when "\\"
                    is_escaping = true
                  when ','
                    add_item_to_array(array, current_item, was_quoted)
                    current_item = ''
                    was_quoted = false
                  when '"'
                    is_quoted = true
                  when '{'
                    internal_items = []
                    local_index,internal_items = parse_array_contents(internal_items, string, local_index + 1)
                    array.push(internal_items)
                  when '}'
                    add_item_to_array(array, current_item, was_quoted)
                    return local_index,array
                  else
                    current_item << token
                  end
                end
              end

              local_index += 1
            end
            return local_index,array
          end

          def add_item_to_array(array, current_item, quoted)
            if current_item.length == 0
            elsif !quoted && current_item == 'NULL'
              array.push nil
            else
              array.push current_item
            end
          end
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLColumn < Column
      module Cast
        def string_to_time(string)
          return string unless String === string

          case string
          when 'infinity'; 1.0 / 0.0
          when '-infinity'; -1.0 / 0.0
          when / BC$/
            super("-" + string.sub(/ BC$/, ""))
          else
            super
          end
        end

        def hstore_to_string(object)
          if Hash === object
            object.map { |k,v|
              "#{escape_hstore(k)}=>#{escape_hstore(v)}"
            }.join ','
          else
            object
          end
        end

        def string_to_hstore(string)
          if string.nil?
            nil
          elsif String === string
            Hash[string.scan(HstorePair).map { |k,v|
              v = v.upcase == 'NULL' ? nil : v.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
              k = k.gsub(/^"(.*)"$/,'\1').gsub(/\\(.)/, '\1')
              [k,v]
            }]
          else
            string
          end
        end

        def json_to_string(object)
          if Hash === object
            ActiveSupport::JSON.encode(object)
          else
            object
          end
        end

        def array_to_string(value, column, adapter, should_be_quoted = false)
          casted_values = value.map do |val|
            if String === val
              if val == "NULL"
                "\"#{val}\""
              else
                quote_and_escape(adapter.type_cast(val, column, true))
              end
            else
              adapter.type_cast(val, column, true)
            end
          end
          "{#{casted_values.join(',')}}"
        end

        def range_to_string(object)
          from = object.begin.respond_to?(:infinite?) && object.begin.infinite? ? '' : object.begin
          to   = object.end.respond_to?(:infinite?) && object.end.infinite? ? '' : object.end
          "[#{from},#{to}#{object.exclude_end? ? ')' : ']'}"
        end

        def string_to_json(string)
          if String === string
            ActiveSupport::JSON.decode(string)
          else
            string
          end
        end

        def string_to_cidr(string)
          if string.nil?
            nil
          elsif String === string
            IPAddr.new(string)
          else
            string
          end
        end

        def cidr_to_string(object)
          if IPAddr === object
            "#{object.to_s}/#{object.instance_variable_get(:@mask_addr).to_s(2).count('1')}"
          else
            object
          end
        end

        def string_to_array(string, oid)
          parse_pg_array(string).map{|val| oid.type_cast val}
        end

        private

          HstorePair = begin
            quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
            unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
            /(#{quoted_string}|#{unquoted_string})\s*=>\s*(#{quoted_string}|#{unquoted_string})/
          end

          def escape_hstore(value)
            if value.nil?
              'NULL'
            else
              if value == ""
                '""'
              else
                '"%s"' % value.to_s.gsub(/(["\\])/, '\\\\\1')
              end
            end
          end

          def quote_and_escape(value)
            case value
            when "NULL"
              value
            else
              "\"#{value.gsub(/"/,"\\\"")}\""
            end
          end
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      module DatabaseStatements
        def explain(arel, binds = [])
          sql = "EXPLAIN #{to_sql(arel, binds)}"
          ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
        end

        class ExplainPrettyPrinter # :nodoc:
          # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
          # PostgreSQL shell:
          #
          #                                     QUERY PLAN
          #   ------------------------------------------------------------------------------
          #    Nested Loop Left Join  (cost=0.00..37.24 rows=8 width=0)
          #      Join Filter: (posts.user_id = users.id)
          #      ->  Index Scan using users_pkey on users  (cost=0.00..8.27 rows=1 width=4)
          #            Index Cond: (id = 1)
          #      ->  Seq Scan on posts  (cost=0.00..28.88 rows=8 width=4)
          #            Filter: (posts.user_id = 1)
          #   (6 rows)
          #
          def pp(result)
            header = result.columns.first
            lines  = result.rows.map(&:first)

            # We add 2 because there's one char of padding at both sides, note
            # the extra hyphens in the example above.
            width = [header, *lines].map(&:length).max + 2

            pp = []

            pp << header.center(width).rstrip
            pp << '-' * width

            pp += lines.map {|line| " #{line}"}

            nrows = result.rows.length
            rows_label = nrows == 1 ? 'row' : 'rows'
            pp << "(#{nrows} #{rows_label})"

            pp.join("\n") + "\n"
          end
        end

        # Executes a SELECT query and returns an array of rows. Each row is an
        # array of field values.
        def select_rows(sql, name = nil)
          select_raw(sql, name).last
        end

        # Executes an INSERT query and returns the new record's ID
        def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
          unless pk
            # Extract the table from the insert sql. Yuck.
            table_ref = extract_table_ref_from_insert_sql(sql)
            pk = primary_key(table_ref) if table_ref
          end

          if pk && use_insert_returning?
            select_value("#{sql} RETURNING #{quote_column_name(pk)}")
          elsif pk
            super
            last_insert_id_value(sequence_name || default_sequence_name(table_ref, pk))
          else
            super
          end
        end

        def create
          super.insert
        end

        # create a 2D array representing the result set
        def result_as_array(res) #:nodoc:
          # check if we have any binary column and if they need escaping
          ftypes = Array.new(res.nfields) do |i|
            [i, res.ftype(i)]
          end

          rows = res.values
          return rows unless ftypes.any? { |_, x|
            x == BYTEA_COLUMN_TYPE_OID || x == MONEY_COLUMN_TYPE_OID
          }

          typehash = ftypes.group_by { |_, type| type }
          binaries = typehash[BYTEA_COLUMN_TYPE_OID] || []
          monies   = typehash[MONEY_COLUMN_TYPE_OID] || []

          rows.each do |row|
            # unescape string passed BYTEA field (OID == 17)
            binaries.each do |index, _|
              row[index] = unescape_bytea(row[index])
            end

            # If this is a money type column and there are any currency symbols,
            # then strip them off. Indeed it would be prettier to do this in
            # PostgreSQLColumn.string_to_decimal but would break form input
            # fields that call value_before_type_cast.
            monies.each do |index, _|
              data = row[index]
              # Because money output is formatted according to the locale, there are two
              # cases to consider (note the decimal separators):
              #  (1) $12,345,678.12
              #  (2) $12.345.678,12
              case data
              when /^-?\D+[\d,]+\.\d{2}$/  # (1)
                data.gsub!(/[^-\d.]/, '')
              when /^-?\D+[\d.]+,\d{2}$/  # (2)
                data.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
              end
            end
          end
        end

        # Queries the database and returns the results in an Array-like object
        def query(sql, name = nil) #:nodoc:
          log(sql, name) do
            result_as_array @connection.async_exec(sql)
          end
        end

        # Executes an SQL statement, returning a PGresult object on success
        # or raising a PGError exception otherwise.
        def execute(sql, name = nil)
          log(sql, name) do
            @connection.async_exec(sql)
          end
        end

        def substitute_at(column, index)
          Arel::Nodes::BindParam.new "$#{index + 1}"
        end

        def exec_query(sql, name = 'SQL', binds = [])
          log(sql, name, binds) do
            result = binds.empty? ? exec_no_cache(sql, binds) :
                                    exec_cache(sql, binds)

            types = {}
            result.fields.each_with_index do |fname, i|
              ftype = result.ftype i
              fmod  = result.fmod i
              types[fname] = OID::TYPE_MAP.fetch(ftype, fmod) { |oid, mod|
                warn "unknown OID: #{fname}(#{oid}) (#{sql})"
                OID::Identity.new
              }
            end

            ret = ActiveRecord::Result.new(result.fields, result.values, types)
            result.clear
            return ret
          end
        end

        def exec_delete(sql, name = 'SQL', binds = [])
          log(sql, name, binds) do
            result = binds.empty? ? exec_no_cache(sql, binds) :
                                    exec_cache(sql, binds)
            affected = result.cmd_tuples
            result.clear
            affected
          end
        end
        alias :exec_update :exec_delete

        def sql_for_insert(sql, pk, id_value, sequence_name, binds)
          unless pk
            # Extract the table from the insert sql. Yuck.
            table_ref = extract_table_ref_from_insert_sql(sql)
            pk = primary_key(table_ref) if table_ref
          end

          if pk && use_insert_returning?
            sql = "#{sql} RETURNING #{quote_column_name(pk)}"
          end

          [sql, binds]
        end

        def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
          val = exec_query(sql, name, binds)
          if !use_insert_returning? && pk
            unless sequence_name
              table_ref = extract_table_ref_from_insert_sql(sql)
              sequence_name = default_sequence_name(table_ref, pk)
              return val unless sequence_name
            end
            last_insert_id_result(sequence_name)
          else
            val
          end
        end

        # Executes an UPDATE query and returns the number of affected tuples.
        def update_sql(sql, name = nil)
          super.cmd_tuples
        end

        # Begins a transaction.
        def begin_db_transaction
          execute "BEGIN"
        end

        def begin_isolated_db_transaction(isolation)
          begin_db_transaction
          execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
        end

        # Commits a transaction.
        def commit_db_transaction
          execute "COMMIT"
        end

        # Aborts a transaction.
        def rollback_db_transaction
          execute "ROLLBACK"
        end

        def outside_transaction?
          message = "#outside_transaction? is deprecated. This method was only really used " \
                    "internally, but you can use #transaction_open? instead."
          ActiveSupport::Deprecation.warn message
          @connection.transaction_status == PGconn::PQTRANS_IDLE
        end

        def create_savepoint
          execute("SAVEPOINT #{current_savepoint_name}")
        end

        def rollback_to_savepoint
          execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
        end

        def release_savepoint
          execute("RELEASE SAVEPOINT #{current_savepoint_name}")
        end
      end
    end
  end
end
require 'active_record/connection_adapters/abstract_adapter'

module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      module OID
        class Type
          def type; end

          def type_cast_for_write(value)
            value
          end
        end

        class Identity < Type
          def type_cast(value)
            value
          end
        end

        class Bytea < Type
          def type_cast(value)
            PGconn.unescape_bytea value
          end
        end

        class Money < Type
          def type_cast(value)
            return if value.nil?

            # Because money output is formatted according to the locale, there are two
            # cases to consider (note the decimal separators):
            #  (1) $12,345,678.12
            #  (2) $12.345.678,12

            case value
            when /^-?\D+[\d,]+\.\d{2}$/  # (1)
              value.gsub!(/[^-\d.]/, '')
            when /^-?\D+[\d.]+,\d{2}$/  # (2)
              value.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
            end

            ConnectionAdapters::Column.value_to_decimal value
          end
        end

        class Vector < Type
          attr_reader :delim, :subtype

          # +delim+ corresponds to the `typdelim` column in the pg_types
          # table.  +subtype+ is derived from the `typelem` column in the
          # pg_types table.
          def initialize(delim, subtype)
            @delim   = delim
            @subtype = subtype
          end

          # FIXME: this should probably split on +delim+ and use +subtype+
          # to cast the values.  Unfortunately, the current Rails behavior
          # is to just return the string.
          def type_cast(value)
            value
          end
        end

        class Array < Type
          attr_reader :subtype
          def initialize(subtype)
            @subtype = subtype
          end

          def type_cast(value)
            if String === value
              ConnectionAdapters::PostgreSQLColumn.string_to_array value, @subtype
            else
              value
            end
          end
        end

        class Range < Type
          attr_reader :subtype
          def initialize(subtype)
            @subtype = subtype
          end

          def extract_bounds(value)
            from, to = value[1..-2].split(',')
            {
              from:          (value[1] == ',' || from == '-infinity') ? infinity(:negative => true) : from,
              to:            (value[-2] == ',' || to == 'infinity') ? infinity : to,
              exclude_start: (value[0] == '('),
              exclude_end:   (value[-1] == ')')
            }
          end

          def infinity(options = {})
            ::Float::INFINITY * (options[:negative] ? -1 : 1)
          end

          def infinity?(value)
            value.respond_to?(:infinite?) && value.infinite?
          end

          def to_integer(value)
            infinity?(value) ? value : value.to_i
          end

          def type_cast(value)
            return if value.nil? || value == 'empty'
            return value if value.is_a?(::Range)

            extracted = extract_bounds(value)

            case @subtype
            when :date
              from  = ConnectionAdapters::Column.value_to_date(extracted[:from])
              from -= 1.day if extracted[:exclude_start]
              to    = ConnectionAdapters::Column.value_to_date(extracted[:to])
            when :decimal
              from  = BigDecimal.new(extracted[:from].to_s)
              # FIXME: add exclude start for ::Range, same for timestamp ranges
              to    = BigDecimal.new(extracted[:to].to_s)
            when :time
              from = ConnectionAdapters::Column.string_to_time(extracted[:from])
              to   = ConnectionAdapters::Column.string_to_time(extracted[:to])
            when :integer
              from = to_integer(extracted[:from]) rescue value ? 1 : 0
              from -= 1 if extracted[:exclude_start]
              to   = to_integer(extracted[:to]) rescue value ? 1 : 0
            else
              return value
            end

            ::Range.new(from, to, extracted[:exclude_end])
          end
        end

        class Integer < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::Column.value_to_integer value
          end
        end

        class Boolean < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::Column.value_to_boolean value
          end
        end

        class Timestamp < Type
          def type; :timestamp; end

          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is PG
            # specific
            ConnectionAdapters::PostgreSQLColumn.string_to_time value
          end
        end

        class Date < Type
          def type; :datetime; end

          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is PG
            # specific
            ConnectionAdapters::Column.value_to_date value
          end
        end

        class Time < Type
          def type_cast(value)
            return if value.nil?

            # FIXME: probably we can improve this since we know it is PG
            # specific
            ConnectionAdapters::Column.string_to_dummy_time value
          end
        end

        class Float < Type
          def type_cast(value)
            return if value.nil?

            value.to_f
          end
        end

        class Decimal < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::Column.value_to_decimal value
          end
        end

        class Hstore < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::PostgreSQLColumn.string_to_hstore value
          end
        end

        class Cidr < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::PostgreSQLColumn.string_to_cidr value
          end
        end

        class Json < Type
          def type_cast(value)
            return if value.nil?

            ConnectionAdapters::PostgreSQLColumn.string_to_json value
          end
        end

        class TypeMap
          def initialize
            @mapping = {}
          end

          def []=(oid, type)
            @mapping[oid] = type
          end

          def [](oid)
            @mapping[oid]
          end

          def clear
            @mapping.clear
          end

          def key?(oid)
            @mapping.key? oid
          end

          def fetch(ftype, fmod)
            # The type for the numeric depends on the width of the field,
            # so we'll do something special here.
            #
            # When dealing with decimal columns:
            #
            # places after decimal  = fmod - 4 & 0xffff
            # places before decimal = (fmod - 4) >> 16 & 0xffff
            if ftype == 1700 && (fmod - 4 & 0xffff).zero?
              ftype = 23
            end

            @mapping.fetch(ftype) { |oid| yield oid, fmod }
          end
        end

        TYPE_MAP = TypeMap.new # :nodoc:

        # When the PG adapter connects, the pg_type table is queried.  The
        # key of this hash maps to the `typname` column from the table.
        # TYPE_MAP is then dynamically built with oids as the key and type
        # objects as values.
        NAMES = Hash.new { |h,k| # :nodoc:
          h[k] = OID::Identity.new
        }

        # Register an OID type named +name+ with a typcasting object in
        # +type+.  +name+ should correspond to the `typname` column in
        # the `pg_type` table.
        def self.register_type(name, type)
          NAMES[name] = type
        end

        # Alias the +old+ type to the +new+ type.
        def self.alias_type(new, old)
          NAMES[new] = NAMES[old]
        end

        # Is +name+ a registered type?
        def self.registered_type?(name)
          NAMES.key? name
        end

        register_type 'int2', OID::Integer.new
        alias_type    'int4', 'int2'
        alias_type    'int8', 'int2'
        alias_type    'oid',  'int2'

        register_type 'daterange', OID::Range.new(:date)
        register_type 'numrange', OID::Range.new(:decimal)
        register_type 'tsrange', OID::Range.new(:time)
        register_type 'int4range', OID::Range.new(:integer)
        alias_type    'tstzrange', 'tsrange'
        alias_type    'int8range', 'int4range'

        register_type 'numeric', OID::Decimal.new
        register_type 'text', OID::Identity.new
        alias_type 'varchar', 'text'
        alias_type 'char', 'text'
        alias_type 'bpchar', 'text'
        alias_type 'xml', 'text'

        # FIXME: why are we keeping these types as strings?
        alias_type 'tsvector', 'text'
        alias_type 'interval', 'text'
        alias_type 'bit',      'text'
        alias_type 'varbit',   'text'
        alias_type 'macaddr',  'text'
        alias_type 'uuid',     'text'

        # FIXME: I don't think this is correct. We should probably be returning a parsed date,
        # but the tests pass with a string returned.
        register_type 'timestamptz', OID::Identity.new

        register_type 'money', OID::Money.new
        register_type 'bytea', OID::Bytea.new
        register_type 'bool', OID::Boolean.new

        register_type 'float4', OID::Float.new
        alias_type 'float8', 'float4'

        register_type 'timestamp', OID::Timestamp.new
        register_type 'date', OID::Date.new
        register_type 'time', OID::Time.new

        register_type 'path', OID::Identity.new
        register_type 'polygon', OID::Identity.new
        register_type 'circle', OID::Identity.new
        register_type 'hstore', OID::Hstore.new
        register_type 'json', OID::Json.new
        register_type 'ltree', OID::Identity.new

        register_type 'cidr', OID::Cidr.new
        alias_type 'inet', 'cidr'
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      module Quoting
        # Escapes binary strings for bytea input to the database.
        def escape_bytea(value)
          PGconn.escape_bytea(value) if value
        end

        # Unescapes bytea output from a database to the binary string it represents.
        # NOTE: This is NOT an inverse of escape_bytea! This is only to be used
        # on escaped binary output from database drive.
        def unescape_bytea(value)
          PGconn.unescape_bytea(value) if value
        end

        # Quotes PostgreSQL-specific data types for SQL input.
        def quote(value, column = nil) #:nodoc:
          return super unless column

          case value
          when Range
            if /range$/ =~ column.sql_type
              "'#{PostgreSQLColumn.range_to_string(value)}'::#{column.sql_type}"
            else
              super
            end
          when Array
            if column.array
              "'#{PostgreSQLColumn.array_to_string(value, column, self)}'"
            else
              super
            end
          when Hash
            case column.sql_type
            when 'hstore' then super(PostgreSQLColumn.hstore_to_string(value), column)
            when 'json' then super(PostgreSQLColumn.json_to_string(value), column)
            else super
            end
          when IPAddr
            case column.sql_type
            when 'inet', 'cidr' then super(PostgreSQLColumn.cidr_to_string(value), column)
            else super
            end
          when Float
            if value.infinite? && column.type == :datetime
              "'#{value.to_s.downcase}'"
            elsif value.infinite? || value.nan?
              "'#{value.to_s}'"
            else
              super
            end
          when Numeric
            return super unless column.sql_type == 'money'
            # Not truly string input, so doesn't require (or allow) escape string syntax.
            "'#{value}'"
          when String
            case column.sql_type
            when 'bytea' then "'#{escape_bytea(value)}'"
            when 'xml'   then "xml '#{quote_string(value)}'"
            when /^bit/
              case value
              when /^[01]*$/      then "B'#{value}'" # Bit-string notation
              when /^[0-9A-F]*$/i then "X'#{value}'" # Hexadecimal notation
              end
            else
              super
            end
          else
            super
          end
        end

        def type_cast(value, column, array_member = false)
          return super(value, column) unless column

          case value
          when Range
            return super(value, column) unless /range$/ =~ column.sql_type
            PostgreSQLColumn.range_to_string(value)
          when NilClass
            if column.array && array_member
              'NULL'
            elsif column.array
              value
            else
              super(value, column)
            end
          when Array
            return super(value, column) unless column.array
            PostgreSQLColumn.array_to_string(value, column, self)
          when String
            return super(value, column) unless 'bytea' == column.sql_type
            { :value => value, :format => 1 }
          when Hash
            case column.sql_type
            when 'hstore' then PostgreSQLColumn.hstore_to_string(value)
            when 'json' then PostgreSQLColumn.json_to_string(value)
            else super(value, column)
            end
          when IPAddr
            return super(value, column) unless ['inet','cidr'].include? column.sql_type
            PostgreSQLColumn.cidr_to_string(value)
          else
            super(value, column)
          end
        end

        # Quotes strings for use in SQL input.
        def quote_string(s) #:nodoc:
          @connection.escape(s)
        end

        # Checks the following cases:
        #
        # - table_name
        # - "table.name"
        # - schema_name.table_name
        # - schema_name."table.name"
        # - "schema.name".table_name
        # - "schema.name"."table.name"
        def quote_table_name(name)
          schema, name_part = extract_pg_identifier_from_name(name.to_s)

          unless name_part
            quote_column_name(schema)
          else
            table_name, name_part = extract_pg_identifier_from_name(name_part)
            "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
          end
        end

        def quote_table_name_for_assignment(table, attr)
          quote_column_name(attr)
        end

        # Quotes column names for use in SQL queries.
        def quote_column_name(name) #:nodoc:
          PGconn.quote_ident(name.to_s)
        end

        # Quote date/time values for use in SQL input. Includes microseconds
        # if the value is a Time responding to usec.
        def quoted_date(value) #:nodoc:
          result = super
          if value.acts_like?(:time) && value.respond_to?(:usec)
            result = "#{result}.#{sprintf("%06d", value.usec)}"
          end

          if value.year < 0
            result = result.sub(/^-/, "") + " BC"
          end
          result
        end
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      module ReferentialIntegrity
        def supports_disable_referential_integrity? #:nodoc:
          true
        end

        def disable_referential_integrity #:nodoc:
          if supports_disable_referential_integrity?
            begin
              execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
            rescue
              execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER USER" }.join(";"))
            end
          end
          yield
        ensure
          if supports_disable_referential_integrity?
            begin
              execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
            rescue
              execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER USER" }.join(";"))
            end
          end
        end
      end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      module SchemaStatements
        # Drops the database specified on the +name+ attribute
        # and creates it again using the provided +options+.
        def recreate_database(name, options = {}) #:nodoc:
          drop_database(name)
          create_database(name, options)
        end

        # Create a new PostgreSQL database. Options include <tt>:owner</tt>, <tt>:template</tt>,
        # <tt>:encoding</tt>, <tt>:collation</tt>, <tt>:ctype</tt>,
        # <tt>:tablespace</tt>, and <tt>:connection_limit</tt> (note that MySQL uses
        # <tt>:charset</tt> while PostgreSQL uses <tt>:encoding</tt>).
        #
        # Example:
        #   create_database config[:database], config
        #   create_database 'foo_development', encoding: 'unicode'
        def create_database(name, options = {})
          options = { encoding: 'utf8' }.merge!(options.symbolize_keys)

          option_string = options.sum do |key, value|
            case key
            when :owner
              " OWNER = \"#{value}\""
            when :template
              " TEMPLATE = \"#{value}\""
            when :encoding
              " ENCODING = '#{value}'"
            when :collation
              " LC_COLLATE = '#{value}'"
            when :ctype
              " LC_CTYPE = '#{value}'"
            when :tablespace
              " TABLESPACE = \"#{value}\""
            when :connection_limit
              " CONNECTION LIMIT = #{value}"
            else
              ""
            end
          end

          execute "CREATE DATABASE #{quote_table_name(name)}#{option_string}"
        end

        # Drops a PostgreSQL database.
        #
        # Example:
        #   drop_database 'matt_development'
        def drop_database(name) #:nodoc:
          execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
        end

        # Returns the list of all tables in the schema search path or a specified schema.
        def tables(name = nil)
          query(<<-SQL, 'SCHEMA').map { |row| row[0] }
            SELECT tablename
            FROM pg_tables
            WHERE schemaname = ANY (current_schemas(false))
          SQL
        end

        # Returns true if table exists.
        # If the schema is not specified as part of +name+ then it will only find tables within
        # the current schema search path (regardless of permissions to access tables in other schemas)
        def table_exists?(name)
          schema, table = Utils.extract_schema_and_table(name.to_s)
          return false unless table

          binds = [[nil, table]]
          binds << [nil, schema] if schema

          exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
              SELECT COUNT(*)
              FROM pg_class c
              LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
              WHERE c.relkind in ('v','r')
              AND c.relname = '#{table.gsub(/(^"|"$)/,'')}'
              AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
          SQL
        end

        # Returns true if schema exists.
        def schema_exists?(name)
          exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
            SELECT COUNT(*)
            FROM pg_namespace
            WHERE nspname = '#{name}'
          SQL
        end

        # Returns an array of indexes for the given table.
        def indexes(table_name, name = nil)
           result = query(<<-SQL, 'SCHEMA')
             SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
             FROM pg_class t
             INNER JOIN pg_index d ON t.oid = d.indrelid
             INNER JOIN pg_class i ON d.indexrelid = i.oid
             WHERE i.relkind = 'i'
               AND d.indisprimary = 'f'
               AND t.relname = '#{table_name}'
               AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
            ORDER BY i.relname
          SQL

          result.map do |row|
            index_name = row[0]
            unique = row[1] == 't'
            indkey = row[2].split(" ")
            inddef = row[3]
            oid = row[4]

            columns = Hash[query(<<-SQL, "SCHEMA")]
            SELECT a.attnum, a.attname
            FROM pg_attribute a
            WHERE a.attrelid = #{oid}
            AND a.attnum IN (#{indkey.join(",")})
            SQL

            column_names = columns.values_at(*indkey).compact

            # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
            desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
            orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
            where = inddef.scan(/WHERE (.+)$/).flatten[0]

            column_names.empty? ? nil : IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where)
          end.compact
        end

        # Returns the list of all column definitions for a table.
        def columns(table_name)
          # Limit, precision, and scale are all handled by the superclass.
          column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod|
            oid = OID::TYPE_MAP.fetch(oid.to_i, fmod.to_i) {
              OID::Identity.new
            }
            PostgreSQLColumn.new(column_name, default, oid, type, notnull == 'f')
          end
        end

        # Returns the current database name.
        def current_database
          query('select current_database()', 'SCHEMA')[0][0]
        end

        # Returns the current schema name.
        def current_schema
          query('SELECT current_schema', 'SCHEMA')[0][0]
        end

        # Returns the current database encoding format.
        def encoding
          query(<<-end_sql, 'SCHEMA')[0][0]
            SELECT pg_encoding_to_char(pg_database.encoding) FROM pg_database
            WHERE pg_database.datname LIKE '#{current_database}'
          end_sql
        end

        # Returns the current database collation.
        def collation
          query(<<-end_sql, 'SCHEMA')[0][0]
            SELECT pg_database.datcollate FROM pg_database WHERE pg_database.datname LIKE '#{current_database}'
          end_sql
        end

        # Returns the current database ctype.
        def ctype
          query(<<-end_sql, 'SCHEMA')[0][0]
            SELECT pg_database.datctype FROM pg_database WHERE pg_database.datname LIKE '#{current_database}'
          end_sql
        end

        # Returns an array of schema names.
        def schema_names
          query(<<-SQL, 'SCHEMA').flatten
            SELECT nspname
              FROM pg_namespace
             WHERE nspname !~ '^pg_.*'
               AND nspname NOT IN ('information_schema')
             ORDER by nspname;
          SQL
        end

        # Creates a schema for the given schema name.
        def create_schema schema_name
          execute "CREATE SCHEMA #{schema_name}"
        end

        # Drops the schema for the given schema name.
        def drop_schema schema_name
          execute "DROP SCHEMA #{schema_name} CASCADE"
        end

        # Sets the schema search path to a string of comma-separated schema names.
        # Names beginning with $ have to be quoted (e.g. $user => '$user').
        # See: http://www.postgresql.org/docs/current/static/ddl-schemas.html
        #
        # This should be not be called manually but set in database.yml.
        def schema_search_path=(schema_csv)
          if schema_csv
            execute("SET search_path TO #{schema_csv}", 'SCHEMA')
            @schema_search_path = schema_csv
          end
        end

        # Returns the active schema search path.
        def schema_search_path
          @schema_search_path ||= query('SHOW search_path', 'SCHEMA')[0][0]
        end

        # Returns the current client message level.
        def client_min_messages
          query('SHOW client_min_messages', 'SCHEMA')[0][0]
        end

        # Set the client message level.
        def client_min_messages=(level)
          execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
        end

        # Returns the sequence name for a table's primary key or some other specified key.
        def default_sequence_name(table_name, pk = nil) #:nodoc:
          result = serial_sequence(table_name, pk || 'id')
          return nil unless result
          result.split('.').last
        rescue ActiveRecord::StatementInvalid
          "#{table_name}_#{pk || 'id'}_seq"
        end

        def serial_sequence(table, column)
          result = exec_query(<<-eosql, 'SCHEMA')
            SELECT pg_get_serial_sequence('#{table}', '#{column}')
          eosql
          result.rows.first.first
        end

        # Resets the sequence of a table's primary key to the maximum value.
        def reset_pk_sequence!(table, pk = nil, sequence = nil) #:nodoc:
          unless pk and sequence
            default_pk, default_sequence = pk_and_sequence_for(table)

            pk ||= default_pk
            sequence ||= default_sequence
          end

          if @logger && pk && !sequence
            @logger.warn "#{table} has primary key #{pk} with no default sequence"
          end

          if pk && sequence
            quoted_sequence = quote_table_name(sequence)

            select_value <<-end_sql, 'SCHEMA'
              SELECT setval('#{quoted_sequence}', (SELECT COALESCE(MAX(#{quote_column_name pk})+(SELECT increment_by FROM #{quoted_sequence}), (SELECT min_value FROM #{quoted_sequence})) FROM #{quote_table_name(table)}), false)
            end_sql
          end
        end

        # Returns a table's primary key and belonging sequence.
        def pk_and_sequence_for(table) #:nodoc:
          # First try looking for a sequence with a dependency on the
          # given table's primary key.
          result = query(<<-end_sql, 'SCHEMA')[0]
            SELECT attr.attname, seq.relname
            FROM pg_class      seq,
                 pg_attribute  attr,
                 pg_depend     dep,
                 pg_constraint cons
            WHERE seq.oid           = dep.objid
              AND seq.relkind       = 'S'
              AND attr.attrelid     = dep.refobjid
              AND attr.attnum       = dep.refobjsubid
              AND attr.attrelid     = cons.conrelid
              AND attr.attnum       = cons.conkey[1]
              AND cons.contype      = 'p'
              AND dep.refobjid      = '#{quote_table_name(table)}'::regclass
          end_sql

          if result.nil? or result.empty?
            result = query(<<-end_sql, 'SCHEMA')[0]
              SELECT attr.attname,
                CASE
                  WHEN split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2) ~ '.' THEN
                    substr(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2),
                           strpos(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2), '.')+1)
                  ELSE split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2)
                END
              FROM pg_class       t
              JOIN pg_attribute   attr ON (t.oid = attrelid)
              JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum)
              JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1])
              WHERE t.oid = '#{quote_table_name(table)}'::regclass
                AND cons.contype = 'p'
                AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval'
            end_sql
          end

          [result.first, result.last]
        rescue
          nil
        end

        # Returns just a table's primary key
        def primary_key(table)
          row = exec_query(<<-end_sql, 'SCHEMA').rows.first
            SELECT attr.attname
            FROM pg_attribute attr
            INNER JOIN pg_constraint cons ON attr.attrelid = cons.conrelid AND attr.attnum = cons.conkey[1]
            WHERE cons.contype = 'p'
              AND cons.conrelid = '#{quote_table_name(table)}'::regclass
          end_sql

          row && row.first
        end

        # Renames a table.
        # Also renames a table's primary key sequence if the sequence name matches the
        # Active Record default.
        #
        # Example:
        #   rename_table('octopuses', 'octopi')
        def rename_table(name, new_name)
          clear_cache!
          execute "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
          pk, seq = pk_and_sequence_for(new_name)
          if seq == "#{name}_#{pk}_seq"
            new_seq = "#{new_name}_#{pk}_seq"
            execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
          end
        end

        # Adds a new column to the named table.
        # See TableDefinition#column for details of the options you can use.
        def add_column(table_name, column_name, type, options = {})
          clear_cache!
          add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
          add_column_options!(add_column_sql, options)

          execute add_column_sql
        end

        # Changes the column of a table.
        def change_column(table_name, column_name, type, options = {})
          clear_cache!
          quoted_table_name = quote_table_name(table_name)

          execute "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"

          change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
          change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
        end

        # Changes the default value of a table column.
        def change_column_default(table_name, column_name, default)
          clear_cache!
          execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}"
        end

        def change_column_null(table_name, column_name, null, default = nil)
          clear_cache!
          unless null || default.nil?
            execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
          end
          execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
        end

        # Renames a column in a table.
        def rename_column(table_name, column_name, new_column_name)
          clear_cache!
          execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
        end

        def remove_index!(table_name, index_name) #:nodoc:
          execute "DROP INDEX #{quote_table_name(index_name)}"
        end

        def rename_index(table_name, old_name, new_name)
          execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
        end

        def index_name_length
          63
        end

        # Maps logical Rails types to PostgreSQL-specific data types.
        def type_to_sql(type, limit = nil, precision = nil, scale = nil)
          case type.to_s
          when 'binary'
            # PostgreSQL doesn't support limits on binary (bytea) columns.
            # The hard limit is 1Gb, because of a 32-bit size field, and TOAST.
            case limit
            when nil, 0..0x3fffffff; super(type)
            else raise(ActiveRecordError, "No binary type has byte size #{limit}.")
            end
          when 'text'
            # PostgreSQL doesn't support limits on text columns.
            # The hard limit is 1Gb, according to section 8.3 in the manual.
            case limit
            when nil, 0..0x3fffffff; super(type)
            else raise(ActiveRecordError, "The limit on text can be at most 1GB - 1byte.")
            end
          when 'integer'
            return 'integer' unless limit

            case limit
              when 1, 2; 'smallint'
              when 3, 4; 'integer'
              when 5..8; 'bigint'
              else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
            end
          when 'datetime'
            return super unless precision

            case precision
              when 0..6; "timestamp(#{precision})"
              else raise(ActiveRecordError, "No timestamp type has precision of #{precision}. The allowed range of precision is from 0 to 6")
            end
          else
            super
          end
        end

        # Returns a SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
        #
        # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and
        # requires that the ORDER BY include the distinct column.
        #
        #   distinct("posts.id", ["posts.created_at desc"])
        #   # => "DISTINCT posts.id, posts.created_at AS alias_0"
        def distinct(columns, orders) #:nodoc:
          order_columns = orders.map{ |s|
              # Convert Arel node to string
              s = s.to_sql unless s.is_a?(String)
              # Remove any ASC/DESC modifiers
              s.gsub(/\s+(ASC|DESC)\s*(NULLS\s+(FIRST|LAST)\s*)?/i, '')
            }.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }

          [super].concat(order_columns).join(', ')
        end
      end
    end
  end
end
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/statement_pool'
require 'active_record/connection_adapters/postgresql/oid'
require 'active_record/connection_adapters/postgresql/cast'
require 'active_record/connection_adapters/postgresql/array_parser'
require 'active_record/connection_adapters/postgresql/quoting'
require 'active_record/connection_adapters/postgresql/schema_statements'
require 'active_record/connection_adapters/postgresql/database_statements'
require 'active_record/connection_adapters/postgresql/referential_integrity'
require 'arel/visitors/bind_visitor'

# Make sure we're using pg high enough for PGResult#values
gem 'pg', '~> 0.11'
require 'pg'

require 'ipaddr'

module ActiveRecord
  module ConnectionHandling
    VALID_CONN_PARAMS = [:host, :hostaddr, :port, :dbname, :user, :password, :connect_timeout,
                         :client_encoding, :options, :application_name, :fallback_application_name,
                         :keepalives, :keepalives_idle, :keepalives_interval, :keepalives_count,
                         :tty, :sslmode, :requiressl, :sslcert, :sslkey, :sslrootcert, :sslcrl,
                         :requirepeer, :krbsrvname, :gsslib, :service]

    # Establishes a connection to the database that's used by all Active Record objects
    def postgresql_connection(config) # :nodoc:
      conn_params = config.symbolize_keys

      conn_params.delete_if { |_, v| v.nil? }

      # Map ActiveRecords param names to PGs.
      conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
      conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]

      # Forward only valid config params to PGconn.connect.
      conn_params.keep_if { |k, _| VALID_CONN_PARAMS.include?(k) }

      # The postgres drivers don't allow the creation of an unconnected PGconn object,
      # so just pass a nil connection object for the time being.
      ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
    end
  end

  module ConnectionAdapters
    # PostgreSQL-specific extensions to column definitions in a table.
    class PostgreSQLColumn < Column #:nodoc:
      attr_accessor :array
      # Instantiates a new PostgreSQL column definition in a table.
      def initialize(name, default, oid_type, sql_type = nil, null = true)
        @oid_type = oid_type
        if sql_type =~ /\[\]$/
          @array = true
          super(name, self.class.extract_value_from_default(default), sql_type[0..sql_type.length - 3], null)
        else
          @array = false
          super(name, self.class.extract_value_from_default(default), sql_type, null)
        end
      end

      # :stopdoc:
      class << self
        include ConnectionAdapters::PostgreSQLColumn::Cast
        include ConnectionAdapters::PostgreSQLColumn::ArrayParser
        attr_accessor :money_precision
      end
      # :startdoc:

      # Extracts the value from a PostgreSQL column default definition.
      def self.extract_value_from_default(default)
        # This is a performance optimization for Ruby 1.9.2 in development.
        # If the value is nil, we return nil straight away without checking
        # the regular expressions. If we check each regular expression,
        # Regexp#=== will call NilClass#to_str, which will trigger
        # method_missing (defined by whiny nil in ActiveSupport) which
        # makes this method very very slow.
        return default unless default

        case default
          when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
            $1
          # Numeric types
          when /\A\(?(-?\d+(\.\d*)?\)?)\z/
            $1
          # Character types
          when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
            $1
          # Binary data types
          when /\A'(.*)'::bytea\z/m
            $1
          # Date/time types
          when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
            $1
          when /\A'(.*)'::interval\z/
            $1
          # Boolean type
          when 'true'
            true
          when 'false'
            false
          # Geometric types
          when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
            $1
          # Network address types
          when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
            $1
          # Bit string types
          when /\AB'(.*)'::"?bit(?: varying)?"?\z/
            $1
          # XML type
          when /\A'(.*)'::xml\z/m
            $1
          # Arrays
          when /\A'(.*)'::"?\D+"?\[\]\z/
            $1
          # Hstore
          when /\A'(.*)'::hstore\z/
            $1
          # JSON
          when /\A'(.*)'::json\z/
            $1
          # Object identifier types
          when /\A-?\d+\z/
            $1
          else
            # Anything else is blank, some user type, or some function
            # and we can't know the value of that, so return nil.
            nil
        end
      end

      def type_cast(value)
        return if value.nil?
        return super if encoded?

        @oid_type.type_cast value
      end

      private

        def extract_limit(sql_type)
          case sql_type
          when /^bigint/i;    8
          when /^smallint/i;  2
          when /^timestamp/i; nil
          else super
          end
        end

        # Extracts the scale from PostgreSQL-specific data types.
        def extract_scale(sql_type)
          # Money type has a fixed scale of 2.
          sql_type =~ /^money/ ? 2 : super
        end

        # Extracts the precision from PostgreSQL-specific data types.
        def extract_precision(sql_type)
          if sql_type == 'money'
            self.class.money_precision
          elsif sql_type =~ /timestamp/i
            $1.to_i if sql_type =~ /\((\d+)\)/
          else
            super
          end
        end

        # Maps PostgreSQL-specific data types to logical Rails types.
        def simplified_type(field_type)
          case field_type
          # Numeric and monetary types
          when /^(?:real|double precision)$/
            :float
          # Monetary types
          when 'money'
            :decimal
          when 'hstore'
            :hstore
          when 'ltree'
            :ltree
          # Network address types
          when 'inet'
            :inet
          when 'cidr'
            :cidr
          when 'macaddr'
            :macaddr
          # Character types
          when /^(?:character varying|bpchar)(?:\(\d+\))?$/
            :string
          # Binary data types
          when 'bytea'
            :binary
          # Date/time types
          when /^timestamp with(?:out)? time zone$/
            :datetime
          when /^interval(?:|\(\d+\))$/
            :string
          # Geometric types
          when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/
            :string
          # Bit strings
          when /^bit(?: varying)?(?:\(\d+\))?$/
            :string
          # XML type
          when 'xml'
            :xml
          # tsvector type
          when 'tsvector'
            :tsvector
          # Arrays
          when /^\D+\[\]$/
            :string
          # Object identifier types
          when 'oid'
            :integer
          # UUID type
          when 'uuid'
            :uuid
          # JSON type
          when 'json'
            :json
          # Small and big integer types
          when /^(?:small|big)int$/
            :integer
          when /(num|date|tstz|ts|int4|int8)range$/
            field_type.to_sym
          # Pass through all types that are not specific to PostgreSQL.
          else
            super
          end
        end
    end

    # The PostgreSQL adapter works with the native C (https://bitbucket.org/ged/ruby-pg) driver.
    #
    # Options:
    #
    # * <tt>:host</tt> - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets,
    #   the default is to connect to localhost.
    # * <tt>:port</tt> - Defaults to 5432.
    # * <tt>:username</tt> - Defaults to be the same as the operating system name of the user running the application.
    # * <tt>:password</tt> - Password to be used if the server demands password authentication.
    # * <tt>:database</tt> - Defaults to be the same as the user name.
    # * <tt>:schema_search_path</tt> - An optional schema search path for the connection given
    #   as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option.
    # * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO
    #   <encoding></tt> call on the connection.
    # * <tt>:min_messages</tt> - An optional client min messages that is used in a
    #   <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
    # * <tt>:variables</tt> - An optional hash of additional parameters that
    #   will be used in <tt>SET SESSION key = val</tt> calls on the connection.
    # * <tt>:insert_returning</tt> - An optional boolean to control the use or <tt>RETURNING</tt> for <tt>INSERT</tt> statements
    #   defaults to true.
    #
    # Any further options are used as connection parameters to libpq. See
    # http://www.postgresql.org/docs/9.1/static/libpq-connect.html for the
    # list of parameters.
    #
    # In addition, default connection parameters of libpq can be set per environment variables.
    # See http://www.postgresql.org/docs/9.1/static/libpq-envars.html .
    class PostgreSQLAdapter < AbstractAdapter
      class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
        attr_accessor :array
      end

      class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
        def xml(*args)
          options = args.extract_options!
          column(args[0], 'xml', options)
        end

        def tsvector(*args)
          options = args.extract_options!
          column(args[0], 'tsvector', options)
        end

        def int4range(name, options = {})
          column(name, 'int4range', options)
        end

        def int8range(name, options = {})
          column(name, 'int8range', options)
        end

        def tsrange(name, options = {})
          column(name, 'tsrange', options)
        end

        def tstzrange(name, options = {})
          column(name, 'tstzrange', options)
        end

        def numrange(name, options = {})
          column(name, 'numrange', options)
        end

        def daterange(name, options = {})
          column(name, 'daterange', options)
        end

        def hstore(name, options = {})
          column(name, 'hstore', options)
        end

        def ltree(name, options = {})
          column(name, 'ltree', options)
        end

        def inet(name, options = {})
          column(name, 'inet', options)
        end

        def cidr(name, options = {})
          column(name, 'cidr', options)
        end

        def macaddr(name, options = {})
          column(name, 'macaddr', options)
        end

        def uuid(name, options = {})
          column(name, 'uuid', options)
        end

        def json(name, options = {})
          column(name, 'json', options)
        end

        def column(name, type = nil, options = {})
          super
          column = self[name]
          column.array = options[:array]

          self
        end

        private

        def new_column_definition(base, name, type)
          definition = ColumnDefinition.new base, name, type
          @columns << definition
          @columns_hash[name] = definition
          definition
        end
      end

      ADAPTER_NAME = 'PostgreSQL'

      NATIVE_DATABASE_TYPES = {
        primary_key: "serial primary key",
        string:      { name: "character varying", limit: 255 },
        text:        { name: "text" },
        integer:     { name: "integer" },
        float:       { name: "float" },
        decimal:     { name: "decimal" },
        datetime:    { name: "timestamp" },
        timestamp:   { name: "timestamp" },
        time:        { name: "time" },
        date:        { name: "date" },
        daterange:   { name: "daterange" },
        numrange:    { name: "numrange" },
        tsrange:     { name: "tsrange" },
        tstzrange:   { name: "tstzrange" },
        int4range:   { name: "int4range" },
        int8range:   { name: "int8range" },
        binary:      { name: "bytea" },
        boolean:     { name: "boolean" },
        xml:         { name: "xml" },
        tsvector:    { name: "tsvector" },
        hstore:      { name: "hstore" },
        inet:        { name: "inet" },
        cidr:        { name: "cidr" },
        macaddr:     { name: "macaddr" },
        uuid:        { name: "uuid" },
        json:        { name: "json" },
        ltree:       { name: "ltree" }
      }

      include Quoting
      include ReferentialIntegrity
      include SchemaStatements
      include DatabaseStatements

      # Returns 'PostgreSQL' as adapter name for identification purposes.
      def adapter_name
        ADAPTER_NAME
      end

      # Adds `:array` option to the default set provided by the
      # AbstractAdapter
      def prepare_column_options(column, types)
        spec = super
        spec[:array] = 'true' if column.respond_to?(:array) && column.array
        spec
      end

      # Adds `:array` as a valid migration key
      def migration_keys
        super + [:array]
      end

      # Returns +true+, since this connection adapter supports prepared statement
      # caching.
      def supports_statement_cache?
        true
      end

      def supports_index_sort_order?
        true
      end

      def supports_partial_index?
        true
      end

      def supports_transaction_isolation?
        true
      end

      class StatementPool < ConnectionAdapters::StatementPool
        def initialize(connection, max)
          super
          @counter = 0
          @cache   = Hash.new { |h,pid| h[pid] = {} }
        end

        def each(&block); cache.each(&block); end
        def key?(key);    cache.key?(key); end
        def [](key);      cache[key]; end
        def length;       cache.length; end

        def next_key
          "a#{@counter + 1}"
        end

        def []=(sql, key)
          while @max <= cache.size
            dealloc(cache.shift.last)
          end
          @counter += 1
          cache[sql] = key
        end

        def clear
          cache.each_value do |stmt_key|
            dealloc stmt_key
          end
          cache.clear
        end

        def delete(sql_key)
          dealloc cache[sql_key]
          cache.delete sql_key
        end

        private

          def cache
            @cache[Process.pid]
          end

          def dealloc(key)
            @connection.query "DEALLOCATE #{key}" if connection_active?
          end

          def connection_active?
            @connection.status == PGconn::CONNECTION_OK
          rescue PGError
            false
          end
      end

      class BindSubstitution < Arel::Visitors::PostgreSQL # :nodoc:
        include Arel::Visitors::BindVisitor
      end

      # Initializes and connects a PostgreSQL adapter.
      def initialize(connection, logger, connection_parameters, config)
        super(connection, logger)

        if config.fetch(:prepared_statements) { true }
          @visitor = Arel::Visitors::PostgreSQL.new self
        else
          @visitor = BindSubstitution.new self
        end

        @connection_parameters, @config = connection_parameters, config

        # @local_tz is initialized as nil to avoid warnings when connect tries to use it
        @local_tz = nil
        @table_alias_length = nil

        connect
        @statements = StatementPool.new @connection,
                                        config.fetch(:statement_limit) { 1000 }

        if postgresql_version < 80200
          raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
        end

        initialize_type_map
        @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
        @use_insert_returning = @config.key?(:insert_returning) ? @config[:insert_returning] : true
      end

      # Clears the prepared statements cache.
      def clear_cache!
        @statements.clear
      end

      # Is this connection alive and ready for queries?
      def active?
        @connection.query 'SELECT 1'
        true
      rescue PGError
        false
      end

      # Close then reopen the connection.
      def reconnect!
        super
        @connection.reset
        configure_connection
      end

      def reset!
        clear_cache!
        super
      end

      # Disconnects from the database if already connected. Otherwise, this
      # method does nothing.
      def disconnect!
        super
        @connection.close rescue nil
      end

      def native_database_types #:nodoc:
        NATIVE_DATABASE_TYPES
      end

      # Returns true, since this connection adapter supports migrations.
      def supports_migrations?
        true
      end

      # Does PostgreSQL support finding primary key on non-Active Record tables?
      def supports_primary_key? #:nodoc:
        true
      end

      # Enable standard-conforming strings if available.
      def set_standard_conforming_strings
        old, self.client_min_messages = client_min_messages, 'panic'
        execute('SET standard_conforming_strings = on', 'SCHEMA') rescue nil
      ensure
        self.client_min_messages = old
      end

      def supports_insert_with_returning?
        true
      end

      def supports_ddl_transactions?
        true
      end

      # Returns true, since this connection adapter supports savepoints.
      def supports_savepoints?
        true
      end

      # Returns true.
      def supports_explain?
        true
      end

      # Returns true if pg > 9.2
      def supports_extensions?
        postgresql_version >= 90200
      end

      # Range datatypes weren't introduced until PostgreSQL 9.2
      def supports_ranges?
        postgresql_version >= 90200
      end

      def enable_extension(name)
        exec_query("CREATE EXTENSION IF NOT EXISTS #{name}").tap {
          reload_type_map
        }
      end

      def disable_extension(name)
        exec_query("DROP EXTENSION IF EXISTS #{name} CASCADE").tap {
          reload_type_map
        }
      end

      def extension_enabled?(name)
        if supports_extensions?
          res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL)",
            'SCHEMA'
          res.column_types['exists'].type_cast res.rows.first.first
        end
      end

      def extensions
        if supports_extensions?
          res = exec_query "SELECT extname from pg_extension", "SCHEMA"
          res.rows.map { |r| res.column_types['extname'].type_cast r.first }
        else
          super
        end
      end

      # Returns the configured supported identifier length supported by PostgreSQL
      def table_alias_length
        @table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
      end

      def add_column_options!(sql, options)
        if options[:array] || options[:column].try(:array)
          sql << '[]'
        end
        super
      end

      # Set the authorized user for this session
      def session_auth=(user)
        clear_cache!
        exec_query "SET SESSION AUTHORIZATION #{user}"
      end

      module Utils
        extend self

        # Returns an array of <tt>[schema_name, table_name]</tt> extracted from +name+.
        # +schema_name+ is nil if not specified in +name+.
        # +schema_name+ and +table_name+ exclude surrounding quotes (regardless of whether provided in +name+)
        # +name+ supports the range of schema/table references understood by PostgreSQL, for example:
        #
        # * <tt>table_name</tt>
        # * <tt>"table.name"</tt>
        # * <tt>schema_name.table_name</tt>
        # * <tt>schema_name."table.name"</tt>
        # * <tt>"schema.name"."table name"</tt>
        def extract_schema_and_table(name)
          table, schema = name.scan(/[^".\s]+|"[^"]*"/)[0..1].collect{|m| m.gsub(/(^"|"$)/,'') }.reverse
          [schema, table]
        end
      end

      def use_insert_returning?
        @use_insert_returning
      end

      protected

        # Returns the version of the connected PostgreSQL server.
        def postgresql_version
          @connection.server_version
        end

        # See http://www.postgresql.org/docs/9.1/static/errcodes-appendix.html
        FOREIGN_KEY_VIOLATION = "23503"
        UNIQUE_VIOLATION      = "23505"

        def translate_exception(exception, message)
          case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
          when UNIQUE_VIOLATION
            RecordNotUnique.new(message, exception)
          when FOREIGN_KEY_VIOLATION
            InvalidForeignKey.new(message, exception)
          else
            super
          end
        end

      private

        def reload_type_map
          OID::TYPE_MAP.clear
          initialize_type_map
        end

        def initialize_type_map
          result = execute('SELECT oid, typname, typelem, typdelim, typinput FROM pg_type', 'SCHEMA')
          leaves, nodes = result.partition { |row| row['typelem'] == '0' }

          # populate the leaf nodes
          leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row|
            OID::TYPE_MAP[row['oid'].to_i] = OID::NAMES[row['typname']]
          end

          arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }

          # populate composite types
          nodes.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row|
            vector = OID::Vector.new row['typdelim'], OID::TYPE_MAP[row['typelem'].to_i]
            OID::TYPE_MAP[row['oid'].to_i] = vector
          end

          # populate array types
          arrays.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row|
            array = OID::Array.new  OID::TYPE_MAP[row['typelem'].to_i]
            OID::TYPE_MAP[row['oid'].to_i] = array
          end
        end

        FEATURE_NOT_SUPPORTED = "0A000" # :nodoc:

        def exec_no_cache(sql, binds)
          @connection.async_exec(sql)
        end

        def exec_cache(sql, binds)
          stmt_key = prepare_statement sql

          # Clear the queue
          @connection.get_last_result
          @connection.send_query_prepared(stmt_key, binds.map { |col, val|
            type_cast(val, col)
          })
          @connection.block
          @connection.get_last_result
        rescue PGError => e
          # Get the PG code for the failure.  Annoyingly, the code for
          # prepared statements whose return value may have changed is
          # FEATURE_NOT_SUPPORTED.  Check here for more details:
          # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
          begin
            code = e.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
          rescue
            raise e
          end
          if FEATURE_NOT_SUPPORTED == code
            @statements.delete sql_key(sql)
            retry
          else
            raise e
          end
        end

        # Returns the statement identifier for the client side cache
        # of statements
        def sql_key(sql)
          "#{schema_search_path}-#{sql}"
        end

        # Prepare the statement if it hasn't been prepared, return
        # the statement key.
        def prepare_statement(sql)
          sql_key = sql_key(sql)
          unless @statements.key? sql_key
            nextkey = @statements.next_key
            @connection.prepare nextkey, sql
            @statements[sql_key] = nextkey
          end
          @statements[sql_key]
        end

        # The internal PostgreSQL identifier of the money data type.
        MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
        # The internal PostgreSQL identifier of the BYTEA data type.
        BYTEA_COLUMN_TYPE_OID = 17 #:nodoc:

        # Connects to a PostgreSQL server and sets up the adapter depending on the
        # connected server's characteristics.
        def connect
          @connection = PGconn.connect(@connection_parameters)

          # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
          # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
          # should know about this but can't detect it there, so deal with it here.
          PostgreSQLColumn.money_precision = (postgresql_version >= 80300) ? 19 : 10

          configure_connection
        end

        # Configures the encoding, verbosity, schema search path, and time zone of the connection.
        # This is called by #connect and should not be called manually.
        def configure_connection
          if @config[:encoding]
            @connection.set_client_encoding(@config[:encoding])
          end
          self.client_min_messages = @config[:min_messages] || 'warning'
          self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]

          # Use standard-conforming strings if available so we don't have to do the E'...' dance.
          set_standard_conforming_strings

          # If using Active Record's time zone support configure the connection to return
          # TIMESTAMP WITH ZONE types in UTC.
          # (SET TIME ZONE does not use an equals sign like other SET variables)
          if ActiveRecord::Base.default_timezone == :utc
            execute("SET time zone 'UTC'", 'SCHEMA')
          elsif @local_tz
            execute("SET time zone '#{@local_tz}'", 'SCHEMA')
          end

          # SET statements from :variables config hash
          # http://www.postgresql.org/docs/8.3/static/sql-set.html
          variables = @config[:variables] || {}
          variables.map do |k, v|
            if v == ':default' || v == :default
              # Sets the value to the global or compile default
              execute("SET SESSION #{k.to_s} TO DEFAULT", 'SCHEMA')
            elsif !v.nil?
              execute("SET SESSION #{k.to_s} TO #{quote(v)}", 'SCHEMA')
            end
          end
        end

        # Returns the current ID of a table's sequence.
        def last_insert_id(sequence_name) #:nodoc:
          Integer(last_insert_id_value(sequence_name))
        end

        def last_insert_id_value(sequence_name)
          last_insert_id_result(sequence_name).rows.first.first
        end

        def last_insert_id_result(sequence_name) #:nodoc:
          exec_query("SELECT currval('#{sequence_name}')", 'SQL')
        end

        # Executes a SELECT query and returns the results, performing any data type
        # conversions that are required to be performed here instead of in PostgreSQLColumn.
        def select(sql, name = nil, binds = [])
          exec_query(sql, name, binds)
        end

        def select_raw(sql, name = nil)
          res = execute(sql, name)
          results = result_as_array(res)
          fields = res.fields
          res.clear
          return fields, results
        end

        # Returns the list of a table's column names, data types, and default values.
        #
        # The underlying query is roughly:
        #  SELECT column.name, column.type, default.value
        #    FROM column LEFT JOIN default
        #      ON column.table_id = default.table_id
        #     AND column.num = default.column_num
        #   WHERE column.table_id = get_table_id('table_name')
        #     AND column.num > 0
        #     AND NOT column.is_dropped
        #   ORDER BY column.num
        #
        # If the table name is not prefixed with a schema, the database will
        # take the first match from the schema search path.
        #
        # Query implementation notes:
        #  - format_type includes the column size constraint, e.g. varchar(50)
        #  - ::regclass is a function that gives the id for a table name
        def column_definitions(table_name) #:nodoc:
          exec_query(<<-end_sql, 'SCHEMA').rows
              SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                     pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
                FROM pg_attribute a LEFT JOIN pg_attrdef d
                  ON a.attrelid = d.adrelid AND a.attnum = d.adnum
               WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
                 AND a.attnum > 0 AND NOT a.attisdropped
               ORDER BY a.attnum
          end_sql
        end

        def extract_pg_identifier_from_name(name)
          match_data = name.start_with?('"') ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)

          if match_data
            rest = name[match_data[0].length, name.length]
            rest = rest[1, rest.length] if rest.start_with? "."
            [match_data[1], (rest.length > 0 ? rest : nil)]
          end
        end

        def extract_table_ref_from_insert_sql(sql)
          sql[/into\s+([^\(]*).*values\s*\(/i]
          $1.strip if $1
        end

        def table_definition
          TableDefinition.new(self)
        end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class SchemaCache
      attr_reader :primary_keys, :tables, :version
      attr_accessor :connection

      def initialize(conn)
        @connection = conn

        @columns      = {}
        @columns_hash = {}
        @primary_keys = {}
        @tables       = {}
        prepare_default_proc
      end

      # A cached lookup for table existence.
      def table_exists?(name)
        return @tables[name] if @tables.key? name

        @tables[name] = connection.table_exists?(name)
      end

      # Add internal cache for table with +table_name+.
      def add(table_name)
        if table_exists?(table_name)
          @primary_keys[table_name]
          @columns[table_name]
          @columns_hash[table_name]
        end
      end

      # Get the columns for a table
      def columns(table = nil)
        if table
          @columns[table]
        else
          @columns
        end
      end

      # Get the columns for a table as a hash, key is the column name
      # value is the column object.
      def columns_hash(table = nil)
        if table
          @columns_hash[table]
        else
          @columns_hash
        end
      end

      # Clears out internal caches
      def clear!
        @columns.clear
        @columns_hash.clear
        @primary_keys.clear
        @tables.clear
        @version = nil
      end

      # Clear out internal caches for table with +table_name+.
      def clear_table_cache!(table_name)
        @columns.delete table_name
        @columns_hash.delete table_name
        @primary_keys.delete table_name
        @tables.delete table_name
      end

      def marshal_dump
        # if we get current version during initialization, it happens stack over flow.
        @version = ActiveRecord::Migrator.current_version
        [@version] + [:@columns, :@columns_hash, :@primary_keys, :@tables].map do |val|
          self.instance_variable_get(val).inject({}) { |h, v| h[v[0]] = v[1]; h }
        end
      end

      def marshal_load(array)
        @version, @columns, @columns_hash, @primary_keys, @tables = array
        prepare_default_proc
      end

      private

      def prepare_default_proc
        @columns.default_proc = Proc.new do |h, table_name|
          h[table_name] = connection.columns(table_name)
        end

        @columns_hash.default_proc = Proc.new do |h, table_name|
          h[table_name] = Hash[columns[table_name].map { |col|
            [col.name, col]
          }]
        end

        @primary_keys.default_proc = Proc.new do |h, table_name|
          h[table_name] = table_exists?(table_name) ? connection.primary_key(table_name) : nil
        end
      end
    end
  end
end
require 'active_record/connection_adapters/abstract_adapter'
require 'active_record/connection_adapters/statement_pool'
require 'arel/visitors/bind_visitor'

gem 'sqlite3', '~> 1.3.6'
require 'sqlite3'

module ActiveRecord
  module ConnectionHandling
    # sqlite3 adapter reuses sqlite_connection.
    def sqlite3_connection(config) # :nodoc:
      # Require database.
      unless config[:database]
        raise ArgumentError, "No database file specified. Missing argument: database"
      end

      # Allow database path relative to Rails.root, but only if
      # the database path is not the special path that tells
      # Sqlite to build a database only in memory.
      if defined?(Rails.root) && ':memory:' != config[:database]
        config[:database] = File.expand_path(config[:database], Rails.root)
      end

      db = SQLite3::Database.new(
        config[:database],
        :results_as_hash => true
      )

      db.busy_timeout(config[:timeout]) if config[:timeout]

      ConnectionAdapters::SQLite3Adapter.new(db, logger, config)
    end
  end

  module ConnectionAdapters #:nodoc:
    class SQLite3Column < Column #:nodoc:
      class <<  self
        def binary_to_string(value)
          if value.encoding != Encoding::ASCII_8BIT
            value = value.force_encoding(Encoding::ASCII_8BIT)
          end
          value
        end
      end
    end

    # The SQLite3 adapter works SQLite 3.6.16 or newer
    # with the sqlite3-ruby drivers (available as gem from https://rubygems.org/gems/sqlite3).
    #
    # Options:
    #
    # * <tt>:database</tt> - Path to the database file.
    class SQLite3Adapter < AbstractAdapter
      class Version
        include Comparable

        def initialize(version_string)
          @version = version_string.split('.').map { |v| v.to_i }
        end

        def <=>(version_string)
          @version <=> version_string.split('.').map { |v| v.to_i }
        end
      end

      class StatementPool < ConnectionAdapters::StatementPool
        def initialize(connection, max)
          super
          @cache = Hash.new { |h,pid| h[pid] = {} }
        end

        def each(&block); cache.each(&block); end
        def key?(key);    cache.key?(key); end
        def [](key);      cache[key]; end
        def length;       cache.length; end

        def []=(sql, key)
          while @max <= cache.size
            dealloc(cache.shift.last[:stmt])
          end
          cache[sql] = key
        end

        def clear
          cache.values.each do |hash|
            dealloc hash[:stmt]
          end
          cache.clear
        end

        private
        def cache
          @cache[$$]
        end

        def dealloc(stmt)
          stmt.close unless stmt.closed?
        end
      end

      class BindSubstitution < Arel::Visitors::SQLite # :nodoc:
        include Arel::Visitors::BindVisitor
      end

      def initialize(connection, logger, config)
        super(connection, logger)

        @active     = nil
        @statements = StatementPool.new(@connection,
                                        config.fetch(:statement_limit) { 1000 })
        @config = config

        if config.fetch(:prepared_statements) { true }
          @visitor = Arel::Visitors::SQLite.new self
        else
          @visitor = BindSubstitution.new self
        end
      end

      def adapter_name #:nodoc:
        'SQLite'
      end

      # Returns true
      def supports_ddl_transactions?
        true
      end

      # Returns true if SQLite version is '3.6.8' or greater, false otherwise.
      def supports_savepoints?
        sqlite_version >= '3.6.8'
      end

      # Returns true, since this connection adapter supports prepared statement
      # caching.
      def supports_statement_cache?
        true
      end

      # Returns true, since this connection adapter supports migrations.
      def supports_migrations? #:nodoc:
        true
      end

      # Returns true.
      def supports_primary_key? #:nodoc:
        true
      end

      def requires_reloading?
        true
      end

      # Returns true
      def supports_add_column?
        true
      end

      def active?
        @active != false
      end

      # Disconnects from the database if already connected. Otherwise, this
      # method does nothing.
      def disconnect!
        super
        @active = false
        @connection.close rescue nil
      end

      # Clears the prepared statements cache.
      def clear_cache!
        @statements.clear
      end

      # Returns true
      def supports_count_distinct? #:nodoc:
        true
      end

      # Returns true
      def supports_autoincrement? #:nodoc:
        true
      end

      def supports_index_sort_order?
        true
      end

      def native_database_types #:nodoc:
        {
          :primary_key => default_primary_key_type,
          :string      => { :name => "varchar", :limit => 255 },
          :text        => { :name => "text" },
          :integer     => { :name => "integer" },
          :float       => { :name => "float" },
          :decimal     => { :name => "decimal" },
          :datetime    => { :name => "datetime" },
          :timestamp   => { :name => "datetime" },
          :time        => { :name => "time" },
          :date        => { :name => "date" },
          :binary      => { :name => "blob" },
          :boolean     => { :name => "boolean" }
        }
      end

      # Returns the current database encoding format as a string, eg: 'UTF-8'
      def encoding
        @connection.encoding.to_s
      end

      # Returns true.
      def supports_explain?
        true
      end

      # QUOTING ==================================================

      def quote(value, column = nil)
        if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
          s = column.class.string_to_binary(value).unpack("H*")[0]
          "x'#{s}'"
        else
          super
        end
      end

      def quote_string(s) #:nodoc:
        @connection.class.quote(s)
      end

      def quote_table_name_for_assignment(table, attr)
        quote_column_name(attr)
      end

      def quote_column_name(name) #:nodoc:
        %Q("#{name.to_s.gsub('"', '""')}")
      end

      # Quote date/time values for use in SQL input. Includes microseconds
      # if the value is a Time responding to usec.
      def quoted_date(value) #:nodoc:
        if value.respond_to?(:usec)
          "#{super}.#{sprintf("%06d", value.usec)}"
        else
          super
        end
      end

      def type_cast(value, column) # :nodoc:
        return value.to_f if BigDecimal === value
        return super unless String === value
        return super unless column && value

        value = super
        if column.type == :string && value.encoding == Encoding::ASCII_8BIT
          logger.error "Binary data inserted for `string` type on column `#{column.name}`" if logger
          value = value.encode Encoding::UTF_8
        end
        value
      end

      # DATABASE STATEMENTS ======================================

      def explain(arel, binds = [])
        sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
        ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
      end

      class ExplainPrettyPrinter
        # Pretty prints the result of a EXPLAIN QUERY PLAN in a way that resembles
        # the output of the SQLite shell:
        #
        #   0|0|0|SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
        #   0|1|1|SCAN TABLE posts (~100000 rows)
        #
        def pp(result) # :nodoc:
          result.rows.map do |row|
            row.join('|')
          end.join("\n") + "\n"
        end
      end

      def exec_query(sql, name = nil, binds = [])
        log(sql, name, binds) do

          # Don't cache statements without bind values
          if binds.empty?
            stmt    = @connection.prepare(sql)
            cols    = stmt.columns
            records = stmt.to_a
            stmt.close
            stmt = records
          else
            cache = @statements[sql] ||= {
              :stmt => @connection.prepare(sql)
            }
            stmt = cache[:stmt]
            cols = cache[:cols] ||= stmt.columns
            stmt.reset!
            stmt.bind_params binds.map { |col, val|
              type_cast(val, col)
            }
          end

          ActiveRecord::Result.new(cols, stmt.to_a)
        end
      end

      def exec_delete(sql, name = 'SQL', binds = [])
        exec_query(sql, name, binds)
        @connection.changes
      end
      alias :exec_update :exec_delete

      def last_inserted_id(result)
        @connection.last_insert_row_id
      end

      def execute(sql, name = nil) #:nodoc:
        log(sql, name) { @connection.execute(sql) }
      end

      def update_sql(sql, name = nil) #:nodoc:
        super
        @connection.changes
      end

      def delete_sql(sql, name = nil) #:nodoc:
        sql += " WHERE 1=1" unless sql =~ /WHERE/i
        super sql, name
      end

      def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
        super
        id_value || @connection.last_insert_row_id
      end
      alias :create :insert_sql

      def select_rows(sql, name = nil)
        exec_query(sql, name).rows
      end

      def create_savepoint
        execute("SAVEPOINT #{current_savepoint_name}")
      end

      def rollback_to_savepoint
        execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
      end

      def release_savepoint
        execute("RELEASE SAVEPOINT #{current_savepoint_name}")
      end

      def begin_db_transaction #:nodoc:
        log('begin transaction',nil) { @connection.transaction }
      end

      def commit_db_transaction #:nodoc:
        log('commit transaction',nil) { @connection.commit }
      end

      def rollback_db_transaction #:nodoc:
        log('rollback transaction',nil) { @connection.rollback }
      end

      # SCHEMA STATEMENTS ========================================

      def tables(name = nil, table_name = nil) #:nodoc:
        sql = <<-SQL
          SELECT name
          FROM sqlite_master
          WHERE type = 'table' AND NOT name = 'sqlite_sequence'
        SQL
        sql << " AND name = #{quote_table_name(table_name)}" if table_name

        exec_query(sql, 'SCHEMA').map do |row|
          row['name']
        end
      end

      def table_exists?(table_name)
        table_name && tables(nil, table_name).any?
      end

      # Returns an array of +SQLite3Column+ objects for the table specified by +table_name+.
      def columns(table_name) #:nodoc:
        table_structure(table_name).map do |field|
          case field["dflt_value"]
          when /^null$/i
            field["dflt_value"] = nil
          when /^'(.*)'$/m
            field["dflt_value"] = $1.gsub("''", "'")
          when /^"(.*)"$/m
            field["dflt_value"] = $1.gsub('""', '"')
          end

          SQLite3Column.new(field['name'], field['dflt_value'], field['type'], field['notnull'].to_i == 0)
        end
      end

      # Returns an array of indexes for the given table.
      def indexes(table_name, name = nil) #:nodoc:
        exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", 'SCHEMA').map do |row|
          IndexDefinition.new(
            table_name,
            row['name'],
            row['unique'] != 0,
            exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col|
              col['name']
            })
        end
      end

      def primary_key(table_name) #:nodoc:
        column = table_structure(table_name).find { |field|
          field['pk'] == 1
        }
        column && column['name']
      end

      def remove_index!(table_name, index_name) #:nodoc:
        exec_query "DROP INDEX #{quote_column_name(index_name)}"
      end

      # Renames a table.
      #
      # Example:
      #   rename_table('octopuses', 'octopi')
      def rename_table(name, new_name)
        exec_query "ALTER TABLE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}"
      end

      # See: http://www.sqlite.org/lang_altertable.html
      # SQLite has an additional restriction on the ALTER TABLE statement
      def valid_alter_table_options( type, options)
        type.to_sym != :primary_key
      end

      def add_column(table_name, column_name, type, options = {}) #:nodoc:
        if supports_add_column? && valid_alter_table_options( type, options )
          super(table_name, column_name, type, options)
        else
          alter_table(table_name) do |definition|
            definition.column(column_name, type, options)
          end
        end
      end

      def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
        alter_table(table_name) do |definition|
          definition.columns.delete(definition[column_name])
        end
      end

      def change_column_default(table_name, column_name, default) #:nodoc:
        alter_table(table_name) do |definition|
          definition[column_name].default = default
        end
      end

      def change_column_null(table_name, column_name, null, default = nil)
        unless null || default.nil?
          exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
        end
        alter_table(table_name) do |definition|
          definition[column_name].null = null
        end
      end

      def change_column(table_name, column_name, type, options = {}) #:nodoc:
        alter_table(table_name) do |definition|
          include_default = options_include_default?(options)
          definition[column_name].instance_eval do
            self.type    = type
            self.limit   = options[:limit] if options.include?(:limit)
            self.default = options[:default] if include_default
            self.null    = options[:null] if options.include?(:null)
            self.precision = options[:precision] if options.include?(:precision)
            self.scale   = options[:scale] if options.include?(:scale)
          end
        end
      end

      def rename_column(table_name, column_name, new_column_name) #:nodoc:
        unless columns(table_name).detect{|c| c.name == column_name.to_s }
          raise ActiveRecord::ActiveRecordError, "Missing column #{table_name}.#{column_name}"
        end
        alter_table(table_name, :rename => {column_name.to_s => new_column_name.to_s})
      end

      protected
        def select(sql, name = nil, binds = []) #:nodoc:
          exec_query(sql, name, binds)
        end

        def table_structure(table_name)
          structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", 'SCHEMA').to_hash
          raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
          structure
        end

        def alter_table(table_name, options = {}) #:nodoc:
          altered_table_name = "altered_#{table_name}"
          caller = lambda {|definition| yield definition if block_given?}

          transaction do
            move_table(table_name, altered_table_name,
              options.merge(:temporary => true))
            move_table(altered_table_name, table_name, &caller)
          end
        end

        def move_table(from, to, options = {}, &block) #:nodoc:
          copy_table(from, to, options, &block)
          drop_table(from)
        end

        def copy_table(from, to, options = {}) #:nodoc:
          from_primary_key = primary_key(from)
          options[:id] = false
          create_table(to, options) do |definition|
            @definition = definition
            @definition.primary_key(from_primary_key) if from_primary_key.present?
            columns(from).each do |column|
              column_name = options[:rename] ?
                (options[:rename][column.name] ||
                 options[:rename][column.name.to_sym] ||
                 column.name) : column.name
              next if column_name == from_primary_key

              @definition.column(column_name, column.type,
                :limit => column.limit, :default => column.default,
                :precision => column.precision, :scale => column.scale,
                :null => column.null)
            end
            yield @definition if block_given?
          end
          copy_table_indexes(from, to, options[:rename] || {})
          copy_table_contents(from, to,
            @definition.columns.map {|column| column.name},
            options[:rename] || {})
        end

        def copy_table_indexes(from, to, rename = {}) #:nodoc:
          indexes(from).each do |index|
            name = index.name
            if to == "altered_#{from}"
              name = "temp_#{name}"
            elsif from == "altered_#{to}"
              name = name[5..-1]
            end

            to_column_names = columns(to).map { |c| c.name }
            columns = index.columns.map {|c| rename[c] || c }.select do |column|
              to_column_names.include?(column)
            end

            unless columns.empty?
              # index name can't be the same
              opts = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_") }
              opts[:unique] = true if index.unique
              add_index(to, columns, opts)
            end
          end
        end

        def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
          column_mappings = Hash[columns.map {|name| [name, name]}]
          rename.each { |a| column_mappings[a.last] = a.first }
          from_columns = columns(from).collect {|col| col.name}
          columns = columns.find_all{|col| from_columns.include?(column_mappings[col])}
          quoted_columns = columns.map { |col| quote_column_name(col) } * ','

          quoted_to = quote_table_name(to)
          exec_query("SELECT * FROM #{quote_table_name(from)}").each do |row|
            sql = "INSERT INTO #{quoted_to} (#{quoted_columns}) VALUES ("
            sql << columns.map {|col| quote row[column_mappings[col]]} * ', '
            sql << ')'
            exec_query sql
          end
        end

        def sqlite_version
          @sqlite_version ||= SQLite3Adapter::Version.new(select_value('select sqlite_version(*)'))
        end

        def default_primary_key_type
          if supports_autoincrement?
            'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'
          else
            'INTEGER PRIMARY KEY NOT NULL'
          end
        end

        def translate_exception(exception, message)
          case exception.message
          when /column(s)? .* (is|are) not unique/
            RecordNotUnique.new(message, exception)
          else
            super
          end
        end
    end
  end
end
module ActiveRecord
  module ConnectionAdapters
    class StatementPool
      include Enumerable

      def initialize(connection, max = 1000)
        @connection = connection
        @max        = max
      end

      def each
        raise NotImplementedError
      end

      def key?(key)
        raise NotImplementedError
      end

      def [](key)
        raise NotImplementedError
      end

      def length
        raise NotImplementedError
      end

      def []=(sql, key)
        raise NotImplementedError
      end

      def clear
        raise NotImplementedError
      end

      def delete(key)
        raise NotImplementedError
      end
    end
  end
end
module ActiveRecord
  module ConnectionHandling
    # Establishes the connection to the database. Accepts a hash as input where
    # the <tt>:adapter</tt> key must be specified with the name of a database adapter (in lower-case)
    # example for regular databases (MySQL, Postgresql, etc):
    #
    #   ActiveRecord::Base.establish_connection(
    #     adapter:  "mysql",
    #     host:     "localhost",
    #     username: "myuser",
    #     password: "mypass",
    #     database: "somedatabase"
    #   )
    #
    # Example for SQLite database:
    #
    #   ActiveRecord::Base.establish_connection(
    #     adapter: "sqlite",
    #     database:  "path/to/dbfile"
    #   )
    #
    # Also accepts keys as strings (for parsing from YAML for example):
    #
    #   ActiveRecord::Base.establish_connection(
    #     "adapter" => "sqlite",
    #     "database"  => "path/to/dbfile"
    #   )
    #
    # Or a URL:
    #
    #   ActiveRecord::Base.establish_connection(
    #     "postgres://myuser:mypass@localhost/somedatabase"
    #   )
    #
    # The exceptions AdapterNotSpecified, AdapterNotFound and ArgumentError
    # may be returned on an error.
    def establish_connection(spec = ENV["DATABASE_URL"])
      resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new spec, configurations
      spec = resolver.spec

      unless respond_to?(spec.adapter_method)
        raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
      end

      remove_connection
      connection_handler.establish_connection self, spec
    end

    # Returns the connection currently associated with the class. This can
    # also be used to "borrow" the connection to do database work unrelated
    # to any of the specific Active Records.
    def connection
      retrieve_connection
    end

    def connection_id
      Thread.current['ActiveRecord::Base.connection_id']
    end

    def connection_id=(connection_id)
      Thread.current['ActiveRecord::Base.connection_id'] = connection_id
    end

    # Returns the configuration of the associated connection as a hash:
    #
    #  ActiveRecord::Base.connection_config
    #  # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"}
    #
    # Please use only for reading.
    def connection_config
      connection_pool.spec.config
    end

    def connection_pool
      connection_handler.retrieve_connection_pool(self) or raise ConnectionNotEstablished
    end

    def retrieve_connection
      connection_handler.retrieve_connection(self)
    end

    # Returns true if Active Record is connected.
    def connected?
      connection_handler.connected?(self)
    end

    def remove_connection(klass = self)
      connection_handler.remove_connection(klass)
    end

    def clear_cache! # :nodoc:
      connection.schema_cache.clear!
    end

    delegate :clear_active_connections!, :clear_reloadable_connections!,
      :clear_all_connections!, :to => :connection_handler
  end
end
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/object/duplicable'
require 'thread'

module ActiveRecord
  module Core
    extend ActiveSupport::Concern

    included do
      ##
      # :singleton-method:
      #
      # Accepts a logger conforming to the interface of Log4r which is then
      # passed on to any new database connections made and which can be
      # retrieved on both a class and instance level by calling +logger+.
      mattr_accessor :logger, instance_writer: false

      ##
      # :singleton-method:
      # Contains the database configuration - as is typically stored in config/database.yml -
      # as a Hash.
      #
      # For example, the following database.yml...
      #
      #   development:
      #     adapter: sqlite3
      #     database: db/development.sqlite3
      #
      #   production:
      #     adapter: sqlite3
      #     database: db/production.sqlite3
      #
      # ...would result in ActiveRecord::Base.configurations to look like this:
      #
      #   {
      #      'development' => {
      #         'adapter'  => 'sqlite3',
      #         'database' => 'db/development.sqlite3'
      #      },
      #      'production' => {
      #         'adapter'  => 'sqlite3',
      #         'database' => 'db/production.sqlite3'
      #      }
      #   }
      mattr_accessor :configurations, instance_writer: false
      self.configurations = {}

      ##
      # :singleton-method:
      # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
      # dates and times from the database. This is set to :utc by default.
      mattr_accessor :default_timezone, instance_writer: false
      self.default_timezone = :utc

      ##
      # :singleton-method:
      # Specifies the format to use when dumping the database schema with Rails'
      # Rakefile. If :sql, the schema is dumped as (potentially database-
      # specific) SQL statements. If :ruby, the schema is dumped as an
      # ActiveRecord::Schema file which can be loaded into any database that
      # supports migrations. Use :ruby if you want to have different database
      # adapters for, e.g., your development and test environments.
      mattr_accessor :schema_format, instance_writer: false
      self.schema_format = :ruby

      ##
      # :singleton-method:
      # Specify whether or not to use timestamps for migration versions
      mattr_accessor :timestamped_migrations, instance_writer: false
      self.timestamped_migrations = true

      class_attribute :connection_handler, instance_writer: false
      self.connection_handler = ConnectionAdapters::ConnectionHandler.new
    end

    module ClassMethods
      def inherited(child_class) #:nodoc:
        child_class.initialize_generated_modules
        super
      end

      def initialize_generated_modules
        @attribute_methods_mutex = Mutex.new

        # force attribute methods to be higher in inheritance hierarchy than other generated methods
        generated_attribute_methods.const_set(:AttrNames, Module.new {
          def self.const_missing(name)
            const_set(name, [name.to_s.sub(/ATTR_/, '')].pack('h*').freeze)
          end
        })

        generated_feature_methods
      end

      def generated_feature_methods
        @generated_feature_methods ||= begin
          mod = const_set(:GeneratedFeatureMethods, Module.new)
          include mod
          mod
        end
      end

      # Returns a string like 'Post(id:integer, title:string, body:text)'
      def inspect
        if self == Base
          super
        elsif abstract_class?
          "#{super}(abstract)"
        elsif table_exists?
          attr_list = columns.map { |c| "#{c.name}: #{c.type}" } * ', '
          "#{super}(#{attr_list})"
        else
          "#{super}(Table doesn't exist)"
        end
      end

      # Overwrite the default class equality method to provide support for association proxies.
      def ===(object)
        object.is_a?(self)
      end

      # Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
      #
      #   class Post < ActiveRecord::Base
      #     scope :published_and_commented, published.and(self.arel_table[:comments_count].gt(0))
      #   end
      def arel_table
        @arel_table ||= Arel::Table.new(table_name, arel_engine)
      end

      # Returns the Arel engine.
      def arel_engine
        @arel_engine ||= begin
          if Base == self || connection_handler.retrieve_connection_pool(self)
            self
          else
            superclass.arel_engine
          end
       end
      end

      private

      def relation #:nodoc:
        relation = Relation.new(self, arel_table)

        if finder_needs_type_condition?
          relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
        else
          relation
        end
      end
    end

    # New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
    # attributes but not yet saved (pass a hash with key names matching the associated table column names).
    # In both instances, valid attribute keys are determined by the column names of the associated table --
    # hence you can't have attributes that aren't part of the table columns.
    #
    # ==== Example:
    #   # Instantiates a single new object
    #   User.new(first_name: 'Jamie')
    def initialize(attributes = nil)
      defaults = self.class.column_defaults.dup
      defaults.each { |k, v| defaults[k] = v.dup if v.duplicable? }

      @attributes   = self.class.initialize_attributes(defaults)
      @columns_hash = self.class.column_types.dup

      init_internals
      ensure_proper_type
      populate_with_current_scope_attributes

      assign_attributes(attributes) if attributes

      yield self if block_given?
      run_callbacks :initialize unless _initialize_callbacks.empty?
    end

    # Initialize an empty model object from +coder+. +coder+ must contain
    # the attributes necessary for initializing an empty model object. For
    # example:
    #
    #   class Post < ActiveRecord::Base
    #   end
    #
    #   post = Post.allocate
    #   post.init_with('attributes' => { 'title' => 'hello world' })
    #   post.title # => 'hello world'
    def init_with(coder)
      @attributes   = self.class.initialize_attributes(coder['attributes'])
      @columns_hash = self.class.column_types.merge(coder['column_types'] || {})

      init_internals

      @new_record = false

      run_callbacks :find
      run_callbacks :initialize

      self
    end

    ##
    # :method: clone
    # Identical to Ruby's clone method.  This is a "shallow" copy.  Be warned that your attributes are not copied.
    # That means that modifying attributes of the clone will modify the original, since they will both point to the
    # same attributes hash. If you need a copy of your attributes hash, please use the #dup method.
    #
    #   user = User.first
    #   new_user = user.clone
    #   user.name               # => "Bob"
    #   new_user.name = "Joe"
    #   user.name               # => "Joe"
    #
    #   user.object_id == new_user.object_id            # => false
    #   user.name.object_id == new_user.name.object_id  # => true
    #
    #   user.name.object_id == user.dup.name.object_id  # => false

    ##
    # :method: dup
    # Duped objects have no id assigned and are treated as new records. Note
    # that this is a "shallow" copy as it copies the object's attributes
    # only, not its associations. The extent of a "deep" copy is application
    # specific and is therefore left to the application to implement according
    # to its need.
    # The dup method does not preserve the timestamps (created|updated)_(at|on).

    ##
    def initialize_dup(other) # :nodoc:
      cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
      self.class.initialize_attributes(cloned_attributes, :serialized => false)

      @attributes = cloned_attributes
      @attributes[self.class.primary_key] = nil

      run_callbacks(:initialize) unless _initialize_callbacks.empty?

      @changed_attributes = {}
      self.class.column_defaults.each do |attr, orig_value|
        @changed_attributes[attr] = orig_value if _field_changed?(attr, orig_value, @attributes[attr])
      end

      @aggregation_cache = {}
      @association_cache = {}
      @attributes_cache  = {}

      @new_record  = true

      ensure_proper_type
      populate_with_current_scope_attributes
      super
    end

    # Populate +coder+ with attributes about this record that should be
    # serialized. The structure of +coder+ defined in this method is
    # guaranteed to match the structure of +coder+ passed to the +init_with+
    # method.
    #
    # Example:
    #
    #   class Post < ActiveRecord::Base
    #   end
    #   coder = {}
    #   Post.new.encode_with(coder)
    #   coder # => {"attributes" => {"id" => nil, ... }}
    def encode_with(coder)
      coder['attributes'] = attributes
    end

    # Returns true if +comparison_object+ is the same exact object, or +comparison_object+
    # is of the same type and +self+ has an ID and it is equal to +comparison_object.id+.
    #
    # Note that new records are different from any other record by definition, unless the
    # other record is the receiver itself. Besides, if you fetch existing records with
    # +select+ and leave the ID out, you're on your own, this predicate will return false.
    #
    # Note also that destroying a record preserves its ID in the model instance, so deleted
    # models are still comparable.
    def ==(comparison_object)
      super ||
        comparison_object.instance_of?(self.class) &&
        id.present? &&
        comparison_object.id == id
    end
    alias :eql? :==

    # Delegates to id in order to allow two records of the same type and id to work with something like:
    #   [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
    def hash
      id.hash
    end

    # Freeze the attributes hash such that associations are still accessible, even on destroyed records.
    def freeze
      @attributes.freeze
      self
    end

    # Returns +true+ if the attributes hash has been frozen.
    def frozen?
      @attributes.frozen?
    end

    # Allows sort on objects
    def <=>(other_object)
      if other_object.is_a?(self.class)
        self.to_key <=> other_object.to_key
      end
    end

    # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
    # attributes will be marked as read only since they cannot be saved.
    def readonly?
      @readonly
    end

    # Marks this record as read only.
    def readonly!
      @readonly = true
    end

    # Returns the connection currently associated with the class. This can
    # also be used to "borrow" the connection to do database work that isn't
    # easily done without going straight to SQL.
    def connection
      self.class.connection
    end

    # Returns the contents of the record as a nicely formatted string.
    def inspect
      inspection = if @attributes
                     self.class.column_names.collect { |name|
                       if has_attribute?(name)
                         "#{name}: #{attribute_for_inspect(name)}"
                       end
                     }.compact.join(", ")
                   else
                     "not initialized"
                   end
      "#<#{self.class} #{inspection}>"
    end

    # Returns a hash of the given methods with their names as keys and returned values as values.
    def slice(*methods)
      Hash[methods.map { |method| [method, public_send(method)] }].with_indifferent_access
    end

    private

    # Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
    # of the array, and then rescues from the possible NoMethodError. If those elements are
    # ActiveRecord::Base's, then this triggers the various method_missing's that we have,
    # which significantly impacts upon performance.
    #
    # So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
    #
    # See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
    def to_ary # :nodoc:
      nil
    end

    def init_internals
      pk = self.class.primary_key
      @attributes[pk] = nil unless @attributes.key?(pk)

      @aggregation_cache        = {}
      @association_cache        = {}
      @attributes_cache         = {}
      @previously_changed       = {}
      @changed_attributes       = {}
      @readonly                 = false
      @destroyed                = false
      @marked_for_destruction   = false
      @new_record               = true
      @txn                      = nil
      @_start_transaction_state = {}
      @transaction              = nil
    end
  end
end
module ActiveRecord
  # = Active Record Counter Cache
  module CounterCache
    extend ActiveSupport::Concern

    module ClassMethods
      # Resets one or more counter caches to their correct value using an SQL
      # count query. This is useful when adding new counter caches, or if the
      # counter has been corrupted or modified directly by SQL.
      #
      # ==== Parameters
      #
      # * +id+ - The id of the object you wish to reset a counter on.
      # * +counters+ - One or more counter names to reset
      #
      # ==== Examples
      #
      #   # For Post with id #1 records reset the comments_count
      #   Post.reset_counters(1, :comments)
      def reset_counters(id, *counters)
        object = find(id)
        counters.each do |association|
          has_many_association = reflect_on_association(association.to_sym)

          if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
            has_many_association = has_many_association.through_reflection
          end

          foreign_key  = has_many_association.foreign_key.to_s
          child_class  = has_many_association.klass
          belongs_to   = child_class.reflect_on_all_associations(:belongs_to)
          reflection   = belongs_to.find { |e| e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
          counter_name = reflection.counter_cache_column

          stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({
            arel_table[counter_name] => object.send(association).count
          })
          connection.update stmt
        end
        return true
      end

      # A generic "counter updater" implementation, intended primarily to be
      # used by increment_counter and decrement_counter, but which may also
      # be useful on its own. It simply does a direct SQL update for the record
      # with the given ID, altering the given hash of counters by the amount
      # given by the corresponding value:
      #
      # ==== Parameters
      #
      # * +id+ - The id of the object you wish to update a counter on or an Array of ids.
      # * +counters+ - An Array of Hashes containing the names of the fields
      #   to update as keys and the amount to update the field by as values.
      #
      # ==== Examples
      #
      #   # For the Post with id of 5, decrement the comment_count by 1, and
      #   # increment the action_count by 1
      #   Post.update_counters 5, comment_count: -1, action_count: 1
      #   # Executes the following SQL:
      #   # UPDATE posts
      #   #    SET comment_count = COALESCE(comment_count, 0) - 1,
      #   #        action_count = COALESCE(action_count, 0) + 1
      #   #  WHERE id = 5
      #
      #   # For the Posts with id of 10 and 15, increment the comment_count by 1
      #   Post.update_counters [10, 15], comment_count: 1
      #   # Executes the following SQL:
      #   # UPDATE posts
      #   #    SET comment_count = COALESCE(comment_count, 0) + 1
      #   #  WHERE id IN (10, 15)
      def update_counters(id, counters)
        updates = counters.map do |counter_name, value|
          operator = value < 0 ? '-' : '+'
          quoted_column = connection.quote_column_name(counter_name)
          "#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}"
        end

        where(primary_key => id).update_all updates.join(', ')
      end

      # Increment a numeric field by one, via a direct SQL update.
      #
      # This method is used primarily for maintaining counter_cache columns used to
      # store aggregate values. For example, a DiscussionBoard may cache posts_count
      # and comments_count to avoid running an SQL query to calculate the number of
      # posts and comments there are each time it is displayed.
      #
      # ==== Parameters
      #
      # * +counter_name+ - The name of the field that should be incremented.
      # * +id+ - The id of the object that should be incremented or an Array of ids.
      #
      # ==== Examples
      #
      #   # Increment the post_count column for the record with an id of 5
      #   DiscussionBoard.increment_counter(:post_count, 5)
      def increment_counter(counter_name, id)
        update_counters(id, counter_name => 1)
      end

      # Decrement a numeric field by one, via a direct SQL update.
      #
      # This works the same as increment_counter but reduces the column value by
      # 1 instead of increasing it.
      #
      # ==== Parameters
      #
      # * +counter_name+ - The name of the field that should be decremented.
      # * +id+ - The id of the object that should be decremented or an Array of ids.
      #
      # ==== Examples
      #
      #   # Decrement the post_count column for the record with an id of 5
      #   DiscussionBoard.decrement_counter(:post_count, 5)
      def decrement_counter(counter_name, id)
        update_counters(id, counter_name => -1)
      end
    end
  end
end
module ActiveRecord
  module DynamicMatchers #:nodoc:
    # This code in this file seems to have a lot of indirection, but the indirection
    # is there to provide extension points for the activerecord-deprecated_finders
    # gem. When we stop supporting activerecord-deprecated_finders (from Rails 5),
    # then we can remove the indirection.

    def respond_to?(name, include_private = false)
      match = Method.match(self, name)
      match && match.valid? || super
    end

    private

    def method_missing(name, *arguments, &block)
      match = Method.match(self, name)

      if match && match.valid?
        match.define
        send(name, *arguments, &block)
      else
        super
      end
    end

    class Method
      @matchers = []

      class << self
        attr_reader :matchers

        def match(model, name)
          klass = matchers.find { |k| name =~ k.pattern }
          klass.new(model, name) if klass
        end

        def pattern
          /^#{prefix}_([_a-zA-Z]\w*)#{suffix}$/
        end

        def prefix
          raise NotImplementedError
        end

        def suffix
          ''
        end
      end

      attr_reader :model, :name, :attribute_names

      def initialize(model, name)
        @model           = model
        @name            = name.to_s
        @attribute_names = @name.match(self.class.pattern)[1].split('_and_')
        @attribute_names.map! { |n| @model.attribute_aliases[n] || n }
      end

      def valid?
        attribute_names.all? { |name| model.columns_hash[name] || model.reflect_on_aggregation(name.to_sym) }
      end

      def define
        model.class_eval <<-CODE, __FILE__, __LINE__ + 1
          def self.#{name}(#{signature})
            #{body}
          end
        CODE
      end

      def body
        raise NotImplementedError
      end
    end

    module Finder
      # Extended in activerecord-deprecated_finders
      def body
        result
      end

      # Extended in activerecord-deprecated_finders
      def result
        "#{finder}(#{attributes_hash})"
      end

      # Extended in activerecord-deprecated_finders
      def signature
        attribute_names.join(', ')
      end

      def attributes_hash
        "{" + attribute_names.map { |name| ":#{name} => #{name}" }.join(',') + "}"
      end

      def finder
        raise NotImplementedError
      end
    end

    class FindBy < Method
      Method.matchers << self
      include Finder

      def self.prefix
        "find_by"
      end

      def finder
        "find_by"
      end
    end

    class FindByBang < Method
      Method.matchers << self
      include Finder

      def self.prefix
        "find_by"
      end

      def self.suffix
        "!"
      end

      def finder
        "find_by!"
      end
    end
  end
end
module ActiveRecord

  # = Active Record Errors
  #
  # Generic Active Record exception class.
  class ActiveRecordError < StandardError
  end

  # Raised when the single-table inheritance mechanism fails to locate the subclass
  # (for example due to improper usage of column that +inheritance_column+ points to).
  class SubclassNotFound < ActiveRecordError #:nodoc:
  end

  # Raised when an object assigned to an association has an incorrect type.
  #
  #   class Ticket < ActiveRecord::Base
  #     has_many :patches
  #   end
  #
  #   class Patch < ActiveRecord::Base
  #     belongs_to :ticket
  #   end
  #
  #   # Comments are not patches, this assignment raises AssociationTypeMismatch.
  #   @ticket.patches << Comment.new(content: "Please attach tests to your patch.")
  class AssociationTypeMismatch < ActiveRecordError
  end

  # Raised when unserialized object's type mismatches one specified for serializable field.
  class SerializationTypeMismatch < ActiveRecordError
  end

  # Raised when adapter not specified on connection (or configuration file <tt>config/database.yml</tt>
  # misses adapter field).
  class AdapterNotSpecified < ActiveRecordError
  end

  # Raised when Active Record cannot find database adapter specified in <tt>config/database.yml</tt> or programmatically.
  class AdapterNotFound < ActiveRecordError
  end

  # Raised when connection to the database could not been established (for example when <tt>connection=</tt>
  # is given a nil object).
  class ConnectionNotEstablished < ActiveRecordError
  end

  # Raised when Active Record cannot find record by given id or set of ids.
  class RecordNotFound < ActiveRecordError
  end

  # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
  # saved because record is invalid.
  class RecordNotSaved < ActiveRecordError
  end

  # Raised by ActiveRecord::Base.destroy! when a call to destroy would return false.
  class RecordNotDestroyed < ActiveRecordError
  end

  # Raised when SQL statement cannot be executed by the database (for example, it's often the case for
  # MySQL when Ruby driver used is too old).
  class StatementInvalid < ActiveRecordError
  end

  # Raised when SQL statement is invalid and the application gets a blank result.
  class ThrowResult < ActiveRecordError
  end

  # Parent class for all specific exceptions which wrap database driver exceptions
  # provides access to the original exception also.
  class WrappedDatabaseException < StatementInvalid
    attr_reader :original_exception

    def initialize(message, original_exception)
      super(message)
      @original_exception = original_exception
    end
  end

  # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
  class RecordNotUnique < WrappedDatabaseException
  end

  # Raised when a record cannot be inserted or updated because it references a non-existent record.
  class InvalidForeignKey < WrappedDatabaseException
  end

  # Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example,
  # when using +find+ method)
  # does not match number of expected variables.
  #
  # For example, in
  #
  #   Location.where("lat = ? AND lng = ?", 53.7362)
  #
  # two placeholders are given but only one variable to fill them.
  class PreparedStatementInvalid < ActiveRecordError
  end

  # Raised on attempt to save stale record. Record is stale when it's being saved in another query after
  # instantiation, for example, when two users edit the same wiki page and one starts editing and saves
  # the page before the other.
  #
  # Read more about optimistic locking in ActiveRecord::Locking module RDoc.
  class StaleObjectError < ActiveRecordError
    attr_reader :record, :attempted_action

    def initialize(record, attempted_action)
      super("Attempted to #{attempted_action} a stale object: #{record.class.name}")
      @record = record
      @attempted_action = attempted_action
    end

  end

  # Raised when association is being configured improperly or
  # user tries to use offset and limit together with has_many or has_and_belongs_to_many associations.
  class ConfigurationError < ActiveRecordError
  end

  # Raised on attempt to update record that is instantiated as read only.
  class ReadOnlyRecord < ActiveRecordError
  end

  # ActiveRecord::Transactions::ClassMethods.transaction uses this exception
  # to distinguish a deliberate rollback from other exceptional situations.
  # Normally, raising an exception will cause the +transaction+ method to rollback
  # the database transaction *and* pass on the exception. But if you raise an
  # ActiveRecord::Rollback exception, then the database transaction will be rolled back,
  # without passing on the exception.
  #
  # For example, you could do this in your controller to rollback a transaction:
  #
  #   class BooksController < ActionController::Base
  #     def create
  #       Book.transaction do
  #         book = Book.new(params[:book])
  #         book.save!
  #         if today_is_friday?
  #           # The system must fail on Friday so that our support department
  #           # won't be out of job. We silently rollback this transaction
  #           # without telling the user.
  #           raise ActiveRecord::Rollback, "Call tech support!"
  #         end
  #       end
  #       # ActiveRecord::Rollback is the only exception that won't be passed on
  #       # by ActiveRecord::Base.transaction, so this line will still be reached
  #       # even on Friday.
  #       redirect_to root_url
  #     end
  #   end
  class Rollback < ActiveRecordError
  end

  # Raised when attribute has a name reserved by Active Record (when attribute has name of one of Active Record instance methods).
  class DangerousAttributeError < ActiveRecordError
  end

  # Raised when unknown attributes are supplied via mass assignment.
  class UnknownAttributeError < NoMethodError
  end

  # Raised when an error occurred while doing a mass assignment to an attribute through the
  # <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
  # offending attribute.
  class AttributeAssignmentError < ActiveRecordError
    attr_reader :exception, :attribute
    def initialize(message, exception, attribute)
      super(message)
      @exception = exception
      @attribute = attribute
    end
  end

  # Raised when there are multiple errors while doing a mass assignment through the +attributes+
  # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
  # objects, each corresponding to the error while assigning to an attribute.
  class MultiparameterAssignmentErrors < ActiveRecordError
    attr_reader :errors
    def initialize(errors)
      @errors = errors
    end
  end

  # Raised when a primary key is needed, but there is not one specified in the schema or model.
  class UnknownPrimaryKey < ActiveRecordError
    attr_reader :model

    def initialize(model)
      super("Unknown primary key for table #{model.table_name} in model #{model}.")
      @model = model
    end

  end

  # Raised when a relation cannot be mutated because it's already loaded.
  #
  #   class Task < ActiveRecord::Base
  #   end
  #
  #   relation = Task.all
  #   relation.loaded? # => true
  #
  #   # Methods which try to mutate a loaded relation fail.
  #   relation.where!(title: 'TODO')  # => ActiveRecord::ImmutableRelation
  #   relation.limit!(5)              # => ActiveRecord::ImmutableRelation
  class ImmutableRelation < ActiveRecordError
  end

  class TransactionIsolationError < ActiveRecordError
  end
end
require 'active_support/lazy_load_hooks'

module ActiveRecord
  module Explain
    def self.extended(base)
      base.mattr_accessor :auto_explain_threshold_in_seconds, instance_accessor: false
    end

    # If the database adapter supports explain and auto explain is enabled,
    # this method triggers EXPLAIN logging for the queries triggered by the
    # block if it takes more than the threshold as a whole. That is, the
    # threshold is not checked against each individual query, but against the
    # duration of the entire block. This approach is convenient for relations.

    #
    # The available_queries_for_explain thread variable collects the queries
    # to be explained. If the value is nil, it means queries are not being
    # currently collected. A false value indicates collecting is turned
    # off. Otherwise it is an array of queries.
    def logging_query_plan # :nodoc:
      return yield unless logger

      threshold = auto_explain_threshold_in_seconds
      current   = Thread.current
      if connection.supports_explain? && threshold && current[:available_queries_for_explain].nil?
        begin
          queries = current[:available_queries_for_explain] = []
          start = Time.now
          result = yield
          logger.warn(exec_explain(queries)) if Time.now - start > threshold
          result
        ensure
          current[:available_queries_for_explain] = nil
        end
      else
        yield
      end
    end

    # Relation#explain needs to be able to collect the queries regardless of
    # whether auto explain is enabled. This method serves that purpose.
    def collecting_queries_for_explain # :nodoc:
      current = Thread.current
      original, current[:available_queries_for_explain] = current[:available_queries_for_explain], []
      return yield, current[:available_queries_for_explain]
    ensure
      # Note that the return value above does not depend on this assigment.
      current[:available_queries_for_explain] = original
    end

    # Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
    # Returns a formatted string ready to be logged.
    def exec_explain(queries) # :nodoc:
      str = queries && queries.map do |sql, bind|
        [].tap do |msg|
          msg << "EXPLAIN for: #{sql}"
          unless bind.empty?
            bind_msg = bind.map {|col, val| [col.name, val]}.inspect
            msg.last << " #{bind_msg}"
          end
          msg << connection.explain(sql, bind)
        end.join("\n")
      end.join("\n")

      # Overriding inspect to be more human readable, specially in the console.
      def str.inspect
        self
      end
      str
    end

    # Silences automatic EXPLAIN logging for the duration of the block.
    #
    # This has high priority, no EXPLAINs will be run even if downwards
    # the threshold is set to 0.
    #
    # As the name of the method suggests this only applies to automatic
    # EXPLAINs, manual calls to <tt>ActiveRecord::Relation#explain</tt> run.
    def silence_auto_explain
      current = Thread.current
      original, current[:available_queries_for_explain] = current[:available_queries_for_explain], false
      yield
    ensure
      current[:available_queries_for_explain] = original
    end
  end
end
require 'active_support/notifications'

module ActiveRecord
  class ExplainSubscriber # :nodoc:
    def start(name, id, payload)
      # unused
    end

    def finish(name, id, payload)
      if queries = Thread.current[:available_queries_for_explain]
        queries << payload.values_at(:sql, :binds) unless ignore_payload?(payload)
      end
    end

    # SCHEMA queries cannot be EXPLAINed, also we do not want to run EXPLAIN on
    # our own EXPLAINs now matter how loopingly beautiful that would be.
    #
    # On the other hand, we want to monitor the performance of our real database
    # queries, not the performance of the access to the query cache.
    IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE)
    EXPLAINED_SQLS = /\A\s*(select|update|delete|insert)/i
    def ignore_payload?(payload)
      payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ EXPLAINED_SQLS
    end

    ActiveSupport::Notifications.subscribe("sql.active_record", new)
  end
end
require 'erb'
require 'yaml'

module ActiveRecord
  class FixtureSet
    class File # :nodoc:
      include Enumerable

      ##
      # Open a fixture file named +file+.  When called with a block, the block
      # is called with the filehandle and the filehandle is automatically closed
      # when the block finishes.
      def self.open(file)
        x = new file
        block_given? ? yield(x) : x
      end

      def initialize(file)
        @file = file
        @rows = nil
      end

      def each(&block)
        rows.each(&block)
      end

      RESCUE_ERRORS = [ ArgumentError, Psych::SyntaxError ] # :nodoc:

      private
        def rows
          return @rows if @rows

          begin
            data = YAML.load(render(IO.read(@file)))
          rescue *RESCUE_ERRORS => error
            raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n  #{error.class}: #{error}", error.backtrace
          end
          @rows = data ? validate(data).to_a : []
        end

        def render(content)
          ERB.new(content).result
        end

        # Validate our unmarshalled data.
        def validate(data)
          unless Hash === data || YAML::Omap === data
            raise Fixture::FormatError, 'fixture is not a hash'
          end

          raise Fixture::FormatError unless data.all? { |name, row| Hash === row }
          data
        end
    end
  end
end
require 'erb'
require 'yaml'
require 'zlib'
require 'active_support/dependencies'
require 'active_record/fixture_set/file'
require 'active_record/errors'

module ActiveRecord
  class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
  end

  # \Fixtures are a way of organizing data that you want to test against; in short, sample data.
  #
  # They are stored in YAML files, one file per model, which are placed in the directory
  # appointed by <tt>ActiveSupport::TestCase.fixture_path=(path)</tt> (this is automatically
  # configured for Rails, so you can just put your files in <tt><your-rails-app>/test/fixtures/</tt>).
  # The fixture file ends with the <tt>.yml</tt> file extension (Rails example:
  # <tt><your-rails-app>/test/fixtures/web_sites.yml</tt>). The format of a fixture file looks
  # like this:
  #
  #   rubyonrails:
  #     id: 1
  #     name: Ruby on Rails
  #     url: http://www.rubyonrails.org
  #
  #   google:
  #     id: 2
  #     name: Google
  #     url: http://www.google.com
  #
  # This fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and
  # is followed by an indented list of key/value pairs in the "key: value" format. Records are
  # separated by a blank line for your viewing pleasure.
  #
  # Note that fixtures are unordered. If you want ordered fixtures, use the omap YAML type.
  # See http://yaml.org/type/omap.html
  # for the specification. You will need ordered fixtures when you have foreign key constraints
  # on keys in the same table. This is commonly needed for tree structures. Example:
  #
  #    --- !omap
  #    - parent:
  #        id:         1
  #        parent_id:  NULL
  #        title:      Parent
  #    - child:
  #        id:         2
  #        parent_id:  1
  #        title:      Child
  #
  # = Using Fixtures in Test Cases
  #
  # Since fixtures are a testing construct, we use them in our unit and functional tests. There
  # are two ways to use the fixtures, but first let's take a look at a sample unit test:
  #
  #   require 'test_helper'
  #
  #   class WebSiteTest < ActiveSupport::TestCase
  #     test "web_site_count" do
  #       assert_equal 2, WebSite.count
  #     end
  #   end
  #
  # By default, <tt>test_helper.rb</tt> will load all of your fixtures into your test database,
  # so this test will succeed.
  #
  # The testing environment will automatically load the all fixtures into the database before each
  # test. To ensure consistent data, the environment deletes the fixtures before running the load.
  #
  # In addition to being available in the database, the fixture's data may also be accessed by
  # using a special dynamic method, which has the same name as the model, and accepts the
  # name of the fixture to instantiate:
  #
  #   test "find" do
  #     assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
  #   end
  #
  # Alternatively, you may enable auto-instantiation of the fixture data. For instance, take the
  # following tests:
  #
  #   test "find_alt_method_1" do
  #     assert_equal "Ruby on Rails", @web_sites['rubyonrails']['name']
  #   end
  #
  #   test "find_alt_method_2" do
  #     assert_equal "Ruby on Rails", @rubyonrails.name
  #   end
  #
  # In order to use these methods to access fixtured data within your testcases, you must specify one of the
  # following in your <tt>ActiveSupport::TestCase</tt>-derived class:
  #
  # - to fully enable instantiated fixtures (enable alternate methods #1 and #2 above)
  #     self.use_instantiated_fixtures = true
  #
  # - create only the hash for the fixtures, do not 'find' each instance (enable alternate method #1 only)
  #     self.use_instantiated_fixtures = :no_instances
  #
  # Using either of these alternate methods incurs a performance hit, as the fixtured data must be fully
  # traversed in the database to create the fixture hash and/or instance variables. This is expensive for
  # large sets of fixtured data.
  #
  # = Dynamic fixtures with ERB
  #
  # Some times you don't care about the content of the fixtures as much as you care about the volume.
  # In these cases, you can mix ERB in with your YAML fixtures to create a bunch of fixtures for load
  # testing, like:
  #
  #   <% 1.upto(1000) do |i| %>
  #   fix_<%= i %>:
  #     id: <%= i %>
  #     name: guy_<%= 1 %>
  #   <% end %>
  #
  # This will create 1000 very simple fixtures.
  #
  # Using ERB, you can also inject dynamic values into your fixtures with inserts like
  # <tt><%= Date.today.strftime("%Y-%m-%d") %></tt>.
  # This is however a feature to be used with some caution. The point of fixtures are that they're
  # stable units of predictable sample data. If you feel that you need to inject dynamic values, then
  # perhaps you should reexamine whether your application is properly testable. Hence, dynamic values
  # in fixtures are to be considered a code smell.
  #
  # = Transactional Fixtures
  #
  # Test cases can use begin+rollback to isolate their changes to the database instead of having to
  # delete+insert for every test case.
  #
  #   class FooTest < ActiveSupport::TestCase
  #     self.use_transactional_fixtures = true
  #
  #     test "godzilla" do
  #       assert !Foo.all.empty?
  #       Foo.destroy_all
  #       assert Foo.all.empty?
  #     end
  #
  #     test "godzilla aftermath" do
  #       assert !Foo.all.empty?
  #     end
  #   end
  #
  # If you preload your test database with all fixture data (probably in the rake task) and use
  # transactional fixtures, then you may omit all fixtures declarations in your test cases since
  # all the data's already there and every case rolls back its changes.
  #
  # In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to
  # true. This will provide access to fixture data for every table that has been loaded through
  # fixtures (depending on the value of +use_instantiated_fixtures+).
  #
  # When *not* to use transactional fixtures:
  #
  # 1. You're testing whether a transaction works correctly. Nested transactions don't commit until
  #    all parent transactions commit, particularly, the fixtures transaction which is begun in setup
  #    and rolled back in teardown. Thus, you won't be able to verify
  #    the results of your transaction until Active Record supports nested transactions or savepoints (in progress).
  # 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
  #    Use InnoDB, MaxDB, or NDB instead.
  #
  # = Advanced Fixtures
  #
  # Fixtures that don't specify an ID get some extra features:
  #
  # * Stable, autogenerated IDs
  # * Label references for associations (belongs_to, has_one, has_many)
  # * HABTM associations as inline lists
  # * Autofilled timestamp columns
  # * Fixture label interpolation
  # * Support for YAML defaults
  #
  # == Stable, Autogenerated IDs
  #
  # Here, have a monkey fixture:
  #
  #   george:
  #     id: 1
  #     name: George the Monkey
  #
  #   reginald:
  #     id: 2
  #     name: Reginald the Pirate
  #
  # Each of these fixtures has two unique identifiers: one for the database
  # and one for the humans. Why don't we generate the primary key instead?
  # Hashing each fixture's label yields a consistent ID:
  #
  #   george: # generated id: 503576764
  #     name: George the Monkey
  #
  #   reginald: # generated id: 324201669
  #     name: Reginald the Pirate
  #
  # Active Record looks at the fixture's model class, discovers the correct
  # primary key, and generates it right before inserting the fixture
  # into the database.
  #
  # The generated ID for a given label is constant, so we can discover
  # any fixture's ID without loading anything, as long as we know the label.
  #
  # == Label references for associations (belongs_to, has_one, has_many)
  #
  # Specifying foreign keys in fixtures can be very fragile, not to
  # mention difficult to read. Since Active Record can figure out the ID of
  # any fixture from its label, you can specify FK's by label instead of ID.
  #
  # === belongs_to
  #
  # Let's break out some more monkeys and pirates.
  #
  #   ### in pirates.yml
  #
  #   reginald:
  #     id: 1
  #     name: Reginald the Pirate
  #     monkey_id: 1
  #
  #   ### in monkeys.yml
  #
  #   george:
  #     id: 1
  #     name: George the Monkey
  #     pirate_id: 1
  #
  # Add a few more monkeys and pirates and break this into multiple files,
  # and it gets pretty hard to keep track of what's going on. Let's
  # use labels instead of IDs:
  #
  #   ### in pirates.yml
  #
  #   reginald:
  #     name: Reginald the Pirate
  #     monkey: george
  #
  #   ### in monkeys.yml
  #
  #   george:
  #     name: George the Monkey
  #     pirate: reginald
  #
  # Pow! All is made clear. Active Record reflects on the fixture's model class,
  # finds all the +belongs_to+ associations, and allows you to specify
  # a target *label* for the *association* (monkey: george) rather than
  # a target *id* for the *FK* (<tt>monkey_id: 1</tt>).
  #
  # ==== Polymorphic belongs_to
  #
  # Supporting polymorphic relationships is a little bit more complicated, since
  # Active Record needs to know what type your association is pointing at. Something
  # like this should look familiar:
  #
  #   ### in fruit.rb
  #
  #   belongs_to :eater, polymorphic: true
  #
  #   ### in fruits.yml
  #
  #   apple:
  #     id: 1
  #     name: apple
  #     eater_id: 1
  #     eater_type: Monkey
  #
  # Can we do better? You bet!
  #
  #   apple:
  #     eater: george (Monkey)
  #
  # Just provide the polymorphic target type and Active Record will take care of the rest.
  #
  # === has_and_belongs_to_many
  #
  # Time to give our monkey some fruit.
  #
  #   ### in monkeys.yml
  #
  #   george:
  #     id: 1
  #     name: George the Monkey
  #
  #   ### in fruits.yml
  #
  #   apple:
  #     id: 1
  #     name: apple
  #
  #   orange:
  #     id: 2
  #     name: orange
  #
  #   grape:
  #     id: 3
  #     name: grape
  #
  #   ### in fruits_monkeys.yml
  #
  #   apple_george:
  #     fruit_id: 1
  #     monkey_id: 1
  #
  #   orange_george:
  #     fruit_id: 2
  #     monkey_id: 1
  #
  #   grape_george:
  #     fruit_id: 3
  #     monkey_id: 1
  #
  # Let's make the HABTM fixture go away.
  #
  #   ### in monkeys.yml
  #
  #   george:
  #     id: 1
  #     name: George the Monkey
  #     fruits: apple, orange, grape
  #
  #   ### in fruits.yml
  #
  #   apple:
  #     name: apple
  #
  #   orange:
  #     name: orange
  #
  #   grape:
  #     name: grape
  #
  # Zap! No more fruits_monkeys.yml file. We've specified the list of fruits
  # on George's fixture, but we could've just as easily specified a list
  # of monkeys on each fruit. As with +belongs_to+, Active Record reflects on
  # the fixture's model class and discovers the +has_and_belongs_to_many+
  # associations.
  #
  # == Autofilled Timestamp Columns
  #
  # If your table/model specifies any of Active Record's
  # standard timestamp columns (+created_at+, +created_on+, +updated_at+, +updated_on+),
  # they will automatically be set to <tt>Time.now</tt>.
  #
  # If you've set specific values, they'll be left alone.
  #
  # == Fixture label interpolation
  #
  # The label of the current fixture is always available as a column value:
  #
  #   geeksomnia:
  #     name: Geeksomnia's Account
  #     subdomain: $LABEL
  #
  # Also, sometimes (like when porting older join table fixtures) you'll need
  # to be able to get a hold of the identifier for a given label. ERB
  # to the rescue:
  #
  #   george_reginald:
  #     monkey_id: <%= ActiveRecord::FixtureSet.identify(:reginald) %>
  #     pirate_id: <%= ActiveRecord::FixtureSet.identify(:george) %>
  #
  # == Support for YAML defaults
  #
  # You probably already know how to use YAML to set and reuse defaults in
  # your <tt>database.yml</tt> file. You can use the same technique in your fixtures:
  #
  #   DEFAULTS: &DEFAULTS
  #     created_on: <%= 3.weeks.ago.to_s(:db) %>
  #
  #   first:
  #     name: Smurf
  #     <<: *DEFAULTS
  #
  #   second:
  #     name: Fraggle
  #     <<: *DEFAULTS
  #
  # Any fixture labeled "DEFAULTS" is safely ignored.
  class FixtureSet
    #--
    # An instance of FixtureSet is normally stored in a single YAML file and possibly in a folder with the same name.
    #++

    MAX_ID = 2 ** 30 - 1

    @@all_cached_fixtures = Hash.new { |h,k| h[k] = {} }

    def self.find_table_name(fixture_set_name) # :nodoc:
      ActiveSupport::Deprecation.warn(
        "ActiveRecord::Fixtures.find_table_name is deprecated and shall be removed from future releases.  Use ActiveRecord::Fixtures.default_fixture_model_name instead.")
      default_fixture_model_name(fixture_set_name)
    end

    def self.default_fixture_model_name(fixture_set_name) # :nodoc:
      ActiveRecord::Base.pluralize_table_names ?
        fixture_set_name.singularize.camelize :
        fixture_set_name.camelize
    end

    def self.default_fixture_table_name(fixture_set_name) # :nodoc:
       "#{ ActiveRecord::Base.table_name_prefix }"\
       "#{ fixture_set_name.tr('/', '_') }"\
       "#{ ActiveRecord::Base.table_name_suffix }".to_sym
    end

    def self.reset_cache
      @@all_cached_fixtures.clear
    end

    def self.cache_for_connection(connection)
      @@all_cached_fixtures[connection]
    end

    def self.fixture_is_cached?(connection, table_name)
      cache_for_connection(connection)[table_name]
    end

    def self.cached_fixtures(connection, keys_to_fetch = nil)
      if keys_to_fetch
        cache_for_connection(connection).values_at(*keys_to_fetch)
      else
        cache_for_connection(connection).values
      end
    end

    def self.cache_fixtures(connection, fixtures_map)
      cache_for_connection(connection).update(fixtures_map)
    end

    def self.instantiate_fixtures(object, fixture_set, load_instances = true)
      if load_instances
        fixture_set.each do |fixture_name, fixture|
          begin
            object.instance_variable_set "@#{fixture_name}", fixture.find
          rescue FixtureClassNotFound
            nil
          end
        end
      end
    end

    def self.instantiate_all_loaded_fixtures(object, load_instances = true)
      all_loaded_fixtures.each_value do |fixture_set|
        instantiate_fixtures(object, fixture_set, load_instances)
      end
    end

    cattr_accessor :all_loaded_fixtures
    self.all_loaded_fixtures = {}

    def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {})
      fixture_set_names = Array(fixture_set_names).map(&:to_s)
      class_names = class_names.stringify_keys

      # FIXME: Apparently JK uses this.
      connection = block_given? ? yield : ActiveRecord::Base.connection

      files_to_read = fixture_set_names.reject { |fs_name|
        fixture_is_cached?(connection, fs_name)
      }

      unless files_to_read.empty?
        connection.disable_referential_integrity do
          fixtures_map = {}

          fixture_sets = files_to_read.map do |fs_name|
            fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new
              connection,
              fs_name,
              class_names[fs_name] || default_fixture_model_name(fs_name),
              ::File.join(fixtures_directory, fs_name))
          end

          all_loaded_fixtures.update(fixtures_map)

          connection.transaction(:requires_new => true) do
            fixture_sets.each do |fs|
              conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection
              table_rows = fs.table_rows

              table_rows.keys.each do |table|
                conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete'
              end

              table_rows.each do |fixture_set_name, rows|
                rows.each do |row|
                  conn.insert_fixture(row, fixture_set_name)
                end
              end
            end

            # Cap primary key sequences to max(pk).
            if connection.respond_to?(:reset_pk_sequence!)
              fixture_sets.each do |fs|
                connection.reset_pk_sequence!(fs.table_name)
              end
            end
          end

          cache_fixtures(connection, fixtures_map)
        end
      end
      cached_fixtures(connection, fixture_set_names)
    end

    # Returns a consistent, platform-independent identifier for +label+.
    # Identifiers are positive integers less than 2^32.
    def self.identify(label)
      Zlib.crc32(label.to_s) % MAX_ID
    end

    attr_reader :table_name, :name, :fixtures, :model_class

    def initialize(connection, name, class_name, path)
      @fixtures = {} # Ordered hash
      @name     = name
      @path     = path

      if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
        @model_class = class_name
      else
        @model_class = class_name.constantize rescue nil
      end

      @connection  = ( model_class.respond_to?(:connection) ?
                       model_class.connection : connection )

      @table_name = ( model_class.respond_to?(:table_name) ?
                      model_class.table_name :
                      self.class.default_fixture_table_name(name) )

      read_fixture_files
    end

    def [](x)
      fixtures[x]
    end

    def []=(k,v)
      fixtures[k] = v
    end

    def each(&block)
      fixtures.each(&block)
    end

    def size
      fixtures.size
    end

    # Return a hash of rows to be inserted. The key is the table, the value is
    # a list of rows to insert to that table.
    def table_rows
      now = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
      now = now.to_s(:db)

      # allow a standard key to be used for doing defaults in YAML
      fixtures.delete('DEFAULTS')

      # track any join tables we need to insert later
      rows = Hash.new { |h,table| h[table] = [] }

      rows[table_name] = fixtures.map do |label, fixture|
        row = fixture.to_hash

        if model_class && model_class < ActiveRecord::Base
          # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
          if model_class.record_timestamps
            timestamp_column_names.each do |c_name|
              row[c_name] = now unless row.key?(c_name)
            end
          end

          # interpolate the fixture label
          row.each do |key, value|
            row[key] = label if value == "$LABEL"
          end

          # generate a primary key if necessary
          if has_primary_key_column? && !row.include?(primary_key_name)
            row[primary_key_name] = ActiveRecord::FixtureSet.identify(label)
          end

          # If STI is used, find the correct subclass for association reflection
          reflection_class =
            if row.include?(inheritance_column_name)
              row[inheritance_column_name].constantize rescue model_class
            else
              model_class
            end

          reflection_class.reflect_on_all_associations.each do |association|
            case association.macro
            when :belongs_to
              # Do not replace association name with association foreign key if they are named the same
              fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s

              if association.name.to_s != fk_name && value = row.delete(association.name.to_s)
                if association.options[:polymorphic] && value.sub!(/\s*\(([^\)]*)\)\s*$/, "")
                  # support polymorphic belongs_to as "label (Type)"
                  row[association.foreign_type] = $1
                end

                row[fk_name] = ActiveRecord::FixtureSet.identify(value)
              end
            when :has_and_belongs_to_many
              if (targets = row.delete(association.name.to_s))
                targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
                table_name = association.join_table
                rows[table_name].concat targets.map { |target|
                  { association.foreign_key             => row[primary_key_name],
                    association.association_foreign_key => ActiveRecord::FixtureSet.identify(target) }
                }
              end
            end
          end
        end

        row
      end
      rows
    end

    private
      def primary_key_name
        @primary_key_name ||= model_class && model_class.primary_key
      end

      def has_primary_key_column?
        @has_primary_key_column ||= primary_key_name &&
          model_class.columns.any? { |c| c.name == primary_key_name }
      end

      def timestamp_column_names
        @timestamp_column_names ||=
          %w(created_at created_on updated_at updated_on) & column_names
      end

      def inheritance_column_name
        @inheritance_column_name ||= model_class && model_class.inheritance_column
      end

      def column_names
        @column_names ||= @connection.columns(@table_name).collect { |c| c.name }
      end

      def read_fixture_files
        yaml_files = Dir["#{@path}/**/*.yml"].select { |f|
          ::File.file?(f)
        } + [yaml_file_path]

        yaml_files.each do |file|
          FixtureSet::File.open(file) do |fh|
            fh.each do |fixture_name, row|
              fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class)
            end
          end
        end
      end

      def yaml_file_path
        "#{@path}.yml"
      end

  end

  #--
  # Deprecate 'Fixtures' in favor of 'FixtureSet'.
  #++
  # :nodoc:
  Fixtures = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('ActiveRecord::Fixtures', 'ActiveRecord::FixtureSet')

  class Fixture #:nodoc:
    include Enumerable

    class FixtureError < StandardError #:nodoc:
    end

    class FormatError < FixtureError #:nodoc:
    end

    attr_reader :model_class, :fixture

    def initialize(fixture, model_class)
      @fixture     = fixture
      @model_class = model_class
    end

    def class_name
      model_class.name if model_class
    end

    def each
      fixture.each { |item| yield item }
    end

    def [](key)
      fixture[key]
    end

    alias :to_hash :fixture

    def find
      if model_class
        model_class.find(fixture[model_class.primary_key])
      else
        raise FixtureClassNotFound, "No class attached to find."
      end
    end
  end
end

module ActiveRecord
  module TestFixtures
    extend ActiveSupport::Concern

    included do
      setup :setup_fixtures
      teardown :teardown_fixtures

      class_attribute :fixture_path
      class_attribute :fixture_table_names
      class_attribute :fixture_class_names
      class_attribute :use_transactional_fixtures
      class_attribute :use_instantiated_fixtures # true, false, or :no_instances
      class_attribute :pre_loaded_fixtures

      self.fixture_table_names = []
      self.use_transactional_fixtures = true
      self.use_instantiated_fixtures = false
      self.pre_loaded_fixtures = false

      self.fixture_class_names = Hash.new do |h, fixture_set_name|
        h[fixture_set_name] = ActiveRecord::FixtureSet.default_fixture_model_name(fixture_set_name)
      end
    end

    module ClassMethods
      # Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
      #
      # Examples:
      #
      #   set_fixture_class some_fixture:        SomeModel,
      #                     'namespaced/fixture' => Another::Model
      #
      # The keys must be the fixture names, that coincide with the short paths to the fixture files.
      #--
      # It is also possible to pass the class name instead of the class:
      #   set_fixture_class 'some_fixture' => 'SomeModel'
      # I think this option is redundant, i propose to deprecate it.
      # Isn't it easier to always pass the class itself?
      # (2011-12-20 alexeymuranov)
      #++
      def set_fixture_class(class_names = {})
        self.fixture_class_names = self.fixture_class_names.merge(class_names.stringify_keys)
      end

      def fixtures(*fixture_set_names)
        if fixture_set_names.first == :all
          fixture_set_names = Dir["#{fixture_path}/**/*.{yml}"]
          fixture_set_names.map! { |f| f[(fixture_path.size + 1)..-5] }
        else
          fixture_set_names = fixture_set_names.flatten.map { |n| n.to_s }
        end

        self.fixture_table_names |= fixture_set_names
        require_fixture_classes(fixture_set_names)
        setup_fixture_accessors(fixture_set_names)
      end

      def try_to_load_dependency(file_name)
        require_dependency file_name
      rescue LoadError => e
        # Let's hope the developer has included it himself

        # Let's warn in case this is a subdependency, otherwise
        # subdependency error messages are totally cryptic
        if ActiveRecord::Base.logger
          ActiveRecord::Base.logger.warn("Unable to load #{file_name}, underlying cause #{e.message} \n\n #{e.backtrace.join("\n")}")
        end
      end

      def require_fixture_classes(fixture_set_names = nil)
        if fixture_set_names
          fixture_set_names = fixture_set_names.map { |n| n.to_s }
        else
          fixture_set_names = fixture_table_names
        end

        fixture_set_names.each do |file_name|
          file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
          try_to_load_dependency(file_name)
        end
      end

      def setup_fixture_accessors(fixture_set_names = nil)
        fixture_set_names = Array(fixture_set_names || fixture_table_names)
        methods = Module.new do
          fixture_set_names.each do |fs_name|
            fs_name = fs_name.to_s
            accessor_name = fs_name.tr('/', '_').to_sym

            define_method(accessor_name) do |*fixture_names|
              force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload

              @fixture_cache[fs_name] ||= {}

              instances = fixture_names.map do |f_name|
                f_name = f_name.to_s
                @fixture_cache[fs_name].delete(f_name) if force_reload

                if @loaded_fixtures[fs_name][f_name]
                  @fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
                else
                  raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
                end
              end

              instances.size == 1 ? instances.first : instances
            end
            private accessor_name
          end
        end
        include methods
      end

      def uses_transaction(*methods)
        @uses_transaction = [] unless defined?(@uses_transaction)
        @uses_transaction.concat methods.map { |m| m.to_s }
      end

      def uses_transaction?(method)
        @uses_transaction = [] unless defined?(@uses_transaction)
        @uses_transaction.include?(method.to_s)
      end
    end

    def run_in_transaction?
      use_transactional_fixtures &&
        !self.class.uses_transaction?(method_name)
    end

    def setup_fixtures
      return if ActiveRecord::Base.configurations.blank?

      if pre_loaded_fixtures && !use_transactional_fixtures
        raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
      end

      @fixture_cache = {}
      @fixture_connections = []
      @@already_loaded_fixtures ||= {}

      # Load fixtures once and begin transaction.
      if run_in_transaction?
        if @@already_loaded_fixtures[self.class]
          @loaded_fixtures = @@already_loaded_fixtures[self.class]
        else
          @loaded_fixtures = load_fixtures
          @@already_loaded_fixtures[self.class] = @loaded_fixtures
        end
        @fixture_connections = enlist_fixture_connections
        @fixture_connections.each do |connection|
          connection.begin_transaction joinable: false
        end
      # Load fixtures for every test.
      else
        ActiveRecord::FixtureSet.reset_cache
        @@already_loaded_fixtures[self.class] = nil
        @loaded_fixtures = load_fixtures
      end

      # Instantiate fixtures for every test if requested.
      instantiate_fixtures if use_instantiated_fixtures
    end

    def teardown_fixtures
      return if ActiveRecord::Base.configurations.blank?

      # Rollback changes if a transaction is active.
      if run_in_transaction?
        @fixture_connections.each do |connection|
          connection.rollback_transaction if connection.transaction_open?
        end
        @fixture_connections.clear
      else
        ActiveRecord::FixtureSet.reset_cache
      end

      ActiveRecord::Base.clear_active_connections!
    end

    def enlist_fixture_connections
      ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
    end

    private
      def load_fixtures
        fixtures = ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
        Hash[fixtures.map { |f| [f.name, f] }]
      end

      # for pre_loaded_fixtures, only require the classes once. huge speed improvement
      @@required_fixture_classes = false

      def instantiate_fixtures
        if pre_loaded_fixtures
          raise RuntimeError, 'Load fixtures before instantiating them.' if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
          unless @@required_fixture_classes
            self.class.require_fixture_classes ActiveRecord::FixtureSet.all_loaded_fixtures.keys
            @@required_fixture_classes = true
          end
          ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
        else
          raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
          @loaded_fixtures.each_value do |fixture_set|
            ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?)
          end
        end
      end

      def load_instances?
        use_instantiated_fixtures != :no_instances
      end
  end
end
require 'active_support/core_ext/hash/indifferent_access'

module ActiveRecord
  module Inheritance
    extend ActiveSupport::Concern

    included do
      # Determine whether to store the full constant name including namespace when using STI
      class_attribute :store_full_sti_class, instance_writer: false
      self.store_full_sti_class = true
    end

    module ClassMethods
      # Determines if one of the attributes passed in is the inheritance column,
      # and if the inheritance column is attr accessible, it initializes an
      # instance of the given subclass instead of the base class
      def new(*args, &block)
        if (attrs = args.first).is_a?(Hash)
          if subclass = subclass_from_attrs(attrs)
            return subclass.new(*args, &block)
          end
        end
        # Delegate to the original .new
        super
      end

      # True if this isn't a concrete subclass needing a STI type condition.
      def descends_from_active_record?
        if self == Base
          false
        elsif superclass.abstract_class?
          superclass.descends_from_active_record?
        else
          superclass == Base || !columns_hash.include?(inheritance_column)
        end
      end

      def finder_needs_type_condition? #:nodoc:
        # This is like this because benchmarking justifies the strange :false stuff
        :true == (@finder_needs_type_condition ||= descends_from_active_record? ? :false : :true)
      end

      def symbolized_base_class
        @symbolized_base_class ||= base_class.to_s.to_sym
      end

      def symbolized_sti_name
        @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
      end

      # Returns the class descending directly from ActiveRecord::Base, or
      # an abstract class, if any, in the inheritance hierarchy.
      #
      # If A extends AR::Base, A.base_class will return A. If B descends from A
      # through some arbitrarily deep hierarchy, B.base_class will return A.
      #
      # If B < A and C < B and if A is an abstract_class then both B.base_class
      # and C.base_class would return B as the answer since A is an abstract_class.
      def base_class
        unless self < Base
          raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
        end

        if superclass == Base || superclass.abstract_class?
          self
        else
          superclass.base_class
        end
      end

      # Set this to true if this is an abstract class (see <tt>abstract_class?</tt>).
      # If you are using inheritance with ActiveRecord and don't want child classes
      # to utilize the implied STI table name of the parent class, this will need to be true.
      # For example, given the following:
      #
      #   class SuperClass < ActiveRecord::Base
      #     self.abstract_class = true
      #   end
      #   class Child < SuperClass
      #     self.table_name = 'the_table_i_really_want'
      #   end
      #
      #
      # <tt>self.abstract_class = true</tt> is required to make <tt>Child<.find,.create, or any Arel method></tt> use <tt>the_table_i_really_want</tt> instead of a table called <tt>super_classes</tt>
      #
      attr_accessor :abstract_class

      # Returns whether this class is an abstract class or not.
      def abstract_class?
        defined?(@abstract_class) && @abstract_class == true
      end

      def sti_name
        store_full_sti_class ? name : name.demodulize
      end

      protected

      # Returns the class type of the record using the current module as a prefix. So descendants of
      # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
      def compute_type(type_name)
        if type_name.match(/^::/)
          # If the type is prefixed with a scope operator then we assume that
          # the type_name is an absolute reference.
          ActiveSupport::Dependencies.constantize(type_name)
        else
          # Build a list of candidates to search for
          candidates = []
          name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
          candidates << type_name

          candidates.each do |candidate|
            begin
              constant = ActiveSupport::Dependencies.constantize(candidate)
              return constant if candidate == constant.to_s
            rescue NameError => e
              # We don't want to swallow NoMethodError < NameError errors
              raise e unless e.instance_of?(NameError)
            end
          end

          raise NameError, "uninitialized constant #{candidates.first}"
        end
      end

      private

      # Called by +instantiate+ to decide which class to use for a new
      # record instance. For single-table inheritance, we check the record
      # for a +type+ column and return the corresponding class.
      def discriminate_class_for_record(record)
        if using_single_table_inheritance?(record)
          find_sti_class(record[inheritance_column])
        else
          super
        end
      end

      def using_single_table_inheritance?(record)
        record[inheritance_column].present? && columns_hash.include?(inheritance_column)
      end

      def find_sti_class(type_name)
        if store_full_sti_class
          ActiveSupport::Dependencies.constantize(type_name)
        else
          compute_type(type_name)
        end
      rescue NameError
        raise SubclassNotFound,
          "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
          "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
          "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
          "or overwrite #{name}.inheritance_column to use another column for that information."
      end

      def type_condition(table = arel_table)
        sti_column = table[inheritance_column.to_sym]
        sti_names  = ([self] + descendants).map { |model| model.sti_name }

        sti_column.in(sti_names)
      end

      # Detect the subclass from the inheritance column of attrs. If the inheritance column value
      # is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
      # If this is a StrongParameters hash, and access to inheritance_column is not permitted,
      # this will ignore the inheritance column and return nil
      def subclass_from_attrs(attrs)
        subclass_name = attrs.with_indifferent_access[inheritance_column]
        return nil if subclass_name.blank? || subclass_name == self.name
        unless subclass = subclasses.detect { |sub| sub.name == subclass_name }
          raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
        end
        subclass
      end
    end

    private

    # Sets the attribute used for single table inheritance to this class name if this is not the
    # ActiveRecord::Base descendant.
    # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
    # do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
    # No such attribute would be set for objects of the Message class in that example.
    def ensure_proper_type
      klass = self.class
      if klass.finder_needs_type_condition?
        write_attribute(klass.inheritance_column, klass.sti_name)
      end
    end
  end
end
module ActiveRecord
  module Integration
    extend ActiveSupport::Concern

    included do
      ##
      # :singleton-method:
      # Indicates the format used to generate the timestamp format in the cache key.
      # This is +:number+, by default.
      class_attribute :cache_timestamp_format, :instance_writer => false
      self.cache_timestamp_format = :nsec
    end

    # Returns a String, which Action Pack uses for constructing an URL to this
    # object. The default implementation returns this record's id as a String,
    # or nil if this record's unsaved.
    #
    # For example, suppose that you have a User model, and that you have a
    # <tt>resources :users</tt> route. Normally, +user_path+ will
    # construct a path with the user object's 'id' in it:
    #
    #   user = User.find_by_name('Phusion')
    #   user_path(user)  # => "/users/1"
    #
    # You can override +to_param+ in your model to make +user_path+ construct
    # a path using the user's name instead of the user's id:
    #
    #   class User < ActiveRecord::Base
    #     def to_param  # overridden
    #       name
    #     end
    #   end
    #
    #   user = User.find_by_name('Phusion')
    #   user_path(user)  # => "/users/Phusion"
    def to_param
      # We can't use alias_method here, because method 'id' optimizes itself on the fly.
      id && id.to_s # Be sure to stringify the id for routes
    end

    # Returns a cache key that can be used to identify this record.
    #
    #   Product.new.cache_key     # => "products/new"
    #   Product.find(5).cache_key # => "products/5" (updated_at not available)
    #   Person.find(5).cache_key  # => "people/5-20071224150000" (updated_at available)
    def cache_key
      case
      when new_record?
        "#{self.class.model_name.cache_key}/new"
      when timestamp = self[:updated_at]
        timestamp = timestamp.utc.to_s(cache_timestamp_format)
        "#{self.class.model_name.cache_key}/#{id}-#{timestamp}"
      else
        "#{self.class.model_name.cache_key}/#{id}"
      end
    end
  end
end
module ActiveRecord
  module Locking
    # == What is Optimistic Locking
    #
    # Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of
    # conflicts with the data. It does this by checking whether another process has made changes to a record since
    # it was opened, an <tt>ActiveRecord::StaleObjectError</tt> exception is thrown if that has occurred
    # and the update is ignored.
    #
    # Check out <tt>ActiveRecord::Locking::Pessimistic</tt> for an alternative.
    #
    # == Usage
    #
    # Active Records support optimistic locking if the field +lock_version+ is present. Each update to the
    # record increments the +lock_version+ column and the locking facilities ensure that records instantiated twice
    # will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example:
    #
    #   p1 = Person.find(1)
    #   p2 = Person.find(1)
    #
    #   p1.first_name = "Michael"
    #   p1.save
    #
    #   p2.first_name = "should fail"
    #   p2.save # Raises a ActiveRecord::StaleObjectError
    #
    # Optimistic locking will also check for stale data when objects are destroyed. Example:
    #
    #   p1 = Person.find(1)
    #   p2 = Person.find(1)
    #
    #   p1.first_name = "Michael"
    #   p1.save
    #
    #   p2.destroy # Raises a ActiveRecord::StaleObjectError
    #
    # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
    # or otherwise apply the business logic needed to resolve the conflict.
    #
    # This locking mechanism will function inside a single Ruby process. To make it work across all
    # web requests, the recommended approach is to add +lock_version+ as a hidden field to your form.
    #
    # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
    # To override the name of the +lock_version+ column, set the <tt>locking_column</tt> class attribute:
    #
    #   class Person < ActiveRecord::Base
    #     self.locking_column = :lock_person
    #   end
    #
    module Optimistic
      extend ActiveSupport::Concern

      included do
        class_attribute :lock_optimistically, instance_writer: false
        self.lock_optimistically = true
      end

      def locking_enabled? #:nodoc:
        self.class.locking_enabled?
      end

      private
        def increment_lock
          lock_col = self.class.locking_column
          previous_lock_value = send(lock_col).to_i
          send(lock_col + '=', previous_lock_value + 1)
        end

        def update_record(attribute_names = @attributes.keys) #:nodoc:
          return super unless locking_enabled?
          return 0 if attribute_names.empty?

          lock_col = self.class.locking_column
          previous_lock_value = send(lock_col).to_i
          increment_lock

          attribute_names += [lock_col]
          attribute_names.uniq!

          begin
            relation = self.class.unscoped

            stmt = relation.where(
              relation.table[self.class.primary_key].eq(id).and(
                relation.table[lock_col].eq(self.class.quote_value(previous_lock_value))
              )
            ).arel.compile_update(arel_attributes_with_values_for_update(attribute_names))

            affected_rows = connection.update stmt

            unless affected_rows == 1
              raise ActiveRecord::StaleObjectError.new(self, "update")
            end

            affected_rows

          # If something went wrong, revert the version.
          rescue Exception
            send(lock_col + '=', previous_lock_value)
            raise
          end
        end

        def destroy_row
          affected_rows = super

          if locking_enabled? && affected_rows != 1
            raise ActiveRecord::StaleObjectError.new(self, "destroy")
          end

          affected_rows
        end

        def relation_for_destroy
          relation = super

          if locking_enabled?
            column_name = self.class.locking_column
            column      = self.class.columns_hash[column_name]
            substitute  = connection.substitute_at(column, relation.bind_values.length)

            relation = relation.where(self.class.arel_table[column_name].eq(substitute))
            relation.bind_values << [column, self[column_name].to_i]
          end

          relation
        end

      module ClassMethods
        DEFAULT_LOCKING_COLUMN = 'lock_version'

        # Returns true if the +lock_optimistically+ flag is set to true
        # (which it is, by default) and the table includes the
        # +locking_column+ column (defaults to +lock_version+).
        def locking_enabled?
          lock_optimistically && columns_hash[locking_column]
        end

        # Set the column to use for optimistic locking. Defaults to +lock_version+.
        def locking_column=(value)
          @locking_column = value.to_s
        end

        # The version column used for optimistic locking. Defaults to +lock_version+.
        def locking_column
          reset_locking_column unless defined?(@locking_column)
          @locking_column
        end

        # Quote the column name used for optimistic locking.
        def quoted_locking_column
          connection.quote_column_name(locking_column)
        end

        # Reset the column used for optimistic locking back to the +lock_version+ default.
        def reset_locking_column
          self.locking_column = DEFAULT_LOCKING_COLUMN
        end

        # Make sure the lock version column gets updated when counters are
        # updated.
        def update_counters(id, counters)
          counters = counters.merge(locking_column => 1) if locking_enabled?
          super
        end

        def column_defaults
          @column_defaults ||= begin
            defaults = super

            if defaults.key?(locking_column) && lock_optimistically
              defaults[locking_column] ||= 0
            end

            defaults
          end
        end
      end
    end
  end
end
module ActiveRecord
  module Locking
    # Locking::Pessimistic provides support for row-level locking using
    # SELECT ... FOR UPDATE and other lock types.
    #
    # Pass <tt>lock: true</tt> to <tt>ActiveRecord::Base.find</tt> to obtain an exclusive
    # lock on the selected rows:
    #   # select * from accounts where id=1 for update
    #   Account.find(1, lock: true)
    #
    # Pass <tt>lock: 'some locking clause'</tt> to give a database-specific locking clause
    # of your own such as 'LOCK IN SHARE MODE' or 'FOR UPDATE NOWAIT'. Example:
    #
    #   Account.transaction do
    #     # select * from accounts where name = 'shugo' limit 1 for update
    #     shugo = Account.where("name = 'shugo'").lock(true).first
    #     yuko = Account.where("name = 'yuko'").lock(true).first
    #     shugo.balance -= 100
    #     shugo.save!
    #     yuko.balance += 100
    #     yuko.save!
    #   end
    #
    # You can also use <tt>ActiveRecord::Base#lock!</tt> method to lock one record by id.
    # This may be better if you don't need to lock every row. Example:
    #
    #   Account.transaction do
    #     # select * from accounts where ...
    #     accounts = Account.where(...)
    #     account1 = accounts.detect { |account| ... }
    #     account2 = accounts.detect { |account| ... }
    #     # select * from accounts where id=? for update
    #     account1.lock!
    #     account2.lock!
    #     account1.balance -= 100
    #     account1.save!
    #     account2.balance += 100
    #     account2.save!
    #   end
    #
    # You can start a transaction and acquire the lock in one go by calling
    # <tt>with_lock</tt> with a block. The block is called from within
    # a transaction, the object is already locked. Example:
    #
    #   account = Account.first
    #   account.with_lock do
    #     # This block is called within a transaction,
    #     # account is already locked.
    #     account.balance -= 100
    #     account.save!
    #   end
    #
    # Database-specific information on row locking:
    #   MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
    #   PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
    module Pessimistic
      # Obtain a row lock on this record. Reloads the record to obtain the requested
      # lock. Pass an SQL locking clause to append the end of the SELECT statement
      # or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns
      # the locked record.
      def lock!(lock = true)
        reload(:lock => lock) if persisted?
        self
      end

      # Wraps the passed block in a transaction, locking the object
      # before yielding. You pass can the SQL locking clause
      # as argument (see <tt>lock!</tt>).
      def with_lock(lock = true)
        transaction do
          lock!(lock)
          yield
        end
      end
    end
  end
end
module ActiveRecord
  class LogSubscriber < ActiveSupport::LogSubscriber
    IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"]

    def self.runtime=(value)
      Thread.current[:active_record_sql_runtime] = value
    end

    def self.runtime
      Thread.current[:active_record_sql_runtime] ||= 0
    end

    def self.reset_runtime
      rt, self.runtime = runtime, 0
      rt
    end

    def initialize
      super
      @odd_or_even = false
    end

    def render_bind(column, value)
      if column
        if column.binary?
          value = "<#{value.bytesize} bytes of binary data>"
        end

        [column.name, value]
      else
        [nil, value]
      end
    end

    def sql(event)
      self.class.runtime += event.duration
      return unless logger.debug?

      payload = event.payload

      return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])

      name  = "#{payload[:name]} (#{event.duration.round(1)}ms)"
      sql   = payload[:sql].squeeze(' ')
      binds = nil

      unless (payload[:binds] || []).empty?
        binds = "  " + payload[:binds].map { |col,v|
          render_bind(col, v)
        }.inspect
      end

      if odd?
        name = color(name, CYAN, true)
        sql  = color(sql, nil, true)
      else
        name = color(name, MAGENTA, true)
      end

      debug "  #{name}  #{sql}#{binds}"
    end

    def identity(event)
      return unless logger.debug?

      name = color(event.payload[:name], odd? ? CYAN : MAGENTA, true)
      line = odd? ? color(event.payload[:line], nil, true) : event.payload[:line]

      debug "  #{name}  #{line}"
    end

    def odd?
      @odd_or_even = !@odd_or_even
    end

    def logger
      ActiveRecord::Base.logger
    end
  end
end

ActiveRecord::LogSubscriber.attach_to :active_record
module ActiveRecord
  class Migration
    # <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
    # a migration and knows how to reverse those commands. The CommandRecorder
    # knows how to invert the following commands:
    #
    # * add_column
    # * add_index
    # * add_timestamps
    # * create_table
    # * create_join_table
    # * remove_timestamps
    # * rename_column
    # * rename_index
    # * rename_table
    class CommandRecorder
      include JoinTable

      attr_accessor :commands, :delegate, :reverting

      def initialize(delegate = nil)
        @commands = []
        @delegate = delegate
        @reverting = false
      end

      # While executing the given block, the recorded will be in reverting mode.
      # All commands recorded will end up being recorded reverted
      # and in reverse order.
      # For example:
      #
      #   recorder.revert{ recorder.record(:rename_table, [:old, :new]) }
      #   # same effect as recorder.record(:rename_table, [:new, :old])
      def revert
        @reverting = !@reverting
        previous = @commands
        @commands = []
        yield
      ensure
        @commands = previous.concat(@commands.reverse)
        @reverting = !@reverting
      end

      # record +command+. +command+ should be a method name and arguments.
      # For example:
      #
      #   recorder.record(:method_name, [:arg1, :arg2])
      def record(*command, &block)
        if @reverting
          @commands << inverse_of(*command, &block)
        else
          @commands << (command << block)
        end
      end

      # Returns the inverse of the given command. For example:
      #
      #   recorder.inverse_of(:rename_table, [:old, :new])
      #   # => [:rename_table, [:new, :old]]
      #
      # This method will raise an +IrreversibleMigration+ exception if it cannot
      # invert the +command+.
      def inverse_of(command, args, &block)
        method = :"invert_#{command}"
        raise IrreversibleMigration unless respond_to?(method, true)
        send(method, args, &block)
      end

      def respond_to?(*args) # :nodoc:
        super || delegate.respond_to?(*args)
      end

      [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
        :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
        :change_column_default, :add_reference, :remove_reference, :transaction,
        :drop_join_table, :drop_table, :execute_block,
        :change_column, :execute, :remove_columns, # irreversible methods need to be here too
      ].each do |method|
        class_eval <<-EOV, __FILE__, __LINE__ + 1
          def #{method}(*args, &block)          # def create_table(*args, &block)
            record(:"#{method}", args, &block)  #   record(:create_table, args, &block)
          end                                   # end
        EOV
      end
      alias :add_belongs_to :add_reference
      alias :remove_belongs_to :remove_reference

      def change_table(table_name, options = {})
        yield ConnectionAdapters::Table.new(table_name, self)
      end

      private

      module StraightReversions
        private
        { transaction:       :transaction,
          execute_block:     :execute_block,
          create_table:      :drop_table,
          create_join_table: :drop_join_table,
          add_column:        :remove_column,
          add_timestamps:    :remove_timestamps,
          add_reference:     :remove_reference,
        }.each do |cmd, inv|
          [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
            class_eval <<-EOV, __FILE__, __LINE__ + 1
              def invert_#{method}(args, &block)    # def invert_create_table(args, &block)
                [:#{inverse}, args, block]          #   [:drop_table, args, block]
              end                                   # end
            EOV
          end
        end
      end

      include StraightReversions

      def invert_drop_table(args, &block)
        if args.size == 1 && block == nil
          raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
        end
        super
      end

      def invert_rename_table(args)
        [:rename_table, args.reverse]
      end

      def invert_remove_column(args)
        raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
        super
      end

      def invert_rename_index(args)
        [:rename_index, [args.first] + args.last(2).reverse]
      end

      def invert_rename_column(args)
        [:rename_column, [args.first] + args.last(2).reverse]
      end

      def invert_add_index(args)
        table, columns, options = *args
        [:remove_index, [table, (options || {}).merge(column: columns)]]
      end

      def invert_remove_index(args)
        table, options = *args
        raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option." unless options && options[:column]

        options = options.dup
        [:add_index, [table, options.delete(:column), options]]
      end

      alias :invert_add_belongs_to :invert_add_reference
      alias :invert_remove_belongs_to :invert_remove_reference

      # Forwards any missing method call to the \target.
      def method_missing(method, *args, &block)
        @delegate.send(method, *args, &block)
      rescue NoMethodError => e
        raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@delegate}")
      end
    end
  end
end
module ActiveRecord
  class Migration
    module JoinTable #:nodoc:
      private

      def find_join_table_name(table_1, table_2, options = {})
        options.delete(:table_name) || join_table_name(table_1, table_2)
      end

      def join_table_name(table_1, table_2)
        [table_1.to_s, table_2.to_s].sort.join("_").to_sym
      end
    end
  end
end
require "active_support/core_ext/class/attribute_accessors"
require 'set'

module ActiveRecord
  # Exception that can be raised to stop migrations from going backwards.
  class IrreversibleMigration < ActiveRecordError
  end

  class DuplicateMigrationVersionError < ActiveRecordError#:nodoc:
    def initialize(version)
      super("Multiple migrations have the version number #{version}")
    end
  end

  class DuplicateMigrationNameError < ActiveRecordError#:nodoc:
    def initialize(name)
      super("Multiple migrations have the name #{name}")
    end
  end

  class UnknownMigrationVersionError < ActiveRecordError #:nodoc:
    def initialize(version)
      super("No migration with version number #{version}")
    end
  end

  class IllegalMigrationNameError < ActiveRecordError#:nodoc:
    def initialize(name)
      super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed)")
    end
  end

  class PendingMigrationError < ActiveRecordError#:nodoc:
    def initialize
      super("Migrations are pending; run 'rake db:migrate RAILS_ENV=#{Rails.env}' to resolve this issue.")
    end
  end

  # = Active Record Migrations
  #
  # Migrations can manage the evolution of a schema used by several physical
  # databases. It's a solution to the common problem of adding a field to make
  # a new feature work in your local database, but being unsure of how to
  # push that change to other developers and to the production server. With
  # migrations, you can describe the transformations in self-contained classes
  # that can be checked into version control systems and executed against
  # another database that might be one, two, or five versions behind.
  #
  # Example of a simple migration:
  #
  #   class AddSsl < ActiveRecord::Migration
  #     def up
  #       add_column :accounts, :ssl_enabled, :boolean, default: true
  #     end
  #
  #     def down
  #       remove_column :accounts, :ssl_enabled
  #     end
  #   end
  #
  # This migration will add a boolean flag to the accounts table and remove it
  # if you're backing out of the migration. It shows how all migrations have
  # two methods +up+ and +down+ that describes the transformations
  # required to implement or remove the migration. These methods can consist
  # of both the migration specific methods like +add_column+ and +remove_column+,
  # but may also contain regular Ruby code for generating data needed for the
  # transformations.
  #
  # Example of a more complex migration that also needs to initialize data:
  #
  #   class AddSystemSettings < ActiveRecord::Migration
  #     def up
  #       create_table :system_settings do |t|
  #         t.string  :name
  #         t.string  :label
  #         t.text    :value
  #         t.string  :type
  #         t.integer :position
  #       end
  #
  #       SystemSetting.create  name:  'notice',
  #                             label: 'Use notice?',
  #                             value: 1
  #     end
  #
  #     def down
  #       drop_table :system_settings
  #     end
  #   end
  #
  # This migration first adds the +system_settings+ table, then creates the very
  # first row in it using the Active Record model that relies on the table. It
  # also uses the more advanced +create_table+ syntax where you can specify a
  # complete table schema in one block call.
  #
  # == Available transformations
  #
  # * <tt>create_table(name, options)</tt>: Creates a table called +name+ and
  #   makes the table object available to a block that can then add columns to it,
  #   following the same format as +add_column+. See example above. The options hash
  #   is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create
  #   table definition.
  # * <tt>drop_table(name)</tt>: Drops the table called +name+.
  # * <tt>change_table(name, options)</tt>: Allows to make column alterations to
  #   the table called +name+. It makes the table object availabe to a block that
  #   can then add/remove columns, indexes or foreign keys to it.
  # * <tt>rename_table(old_name, new_name)</tt>: Renames the table called +old_name+
  #   to +new_name+.
  # * <tt>add_column(table_name, column_name, type, options)</tt>: Adds a new column
  #   to the table called +table_name+
  #   named +column_name+ specified to be one of the following types:
  #   <tt>:string</tt>, <tt>:text</tt>, <tt>:integer</tt>, <tt>:float</tt>,
  #   <tt>:decimal</tt>, <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>,
  #   <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>. A default value can be
  #   specified by passing an +options+ hash like <tt>{ default: 11 }</tt>.
  #   Other options include <tt>:limit</tt> and <tt>:null</tt> (e.g.
  #   <tt>{ limit: 50, null: false }</tt>) -- see
  #   ActiveRecord::ConnectionAdapters::TableDefinition#column for details.
  # * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames
  #   a column but keeps the type and content.
  # * <tt>change_column(table_name, column_name, type, options)</tt>:  Changes
  #   the column to a different type using the same parameters as add_column.
  # * <tt>remove_column(table_name, column_names)</tt>: Removes the column listed in
  #   +column_names+ from the table called +table_name+.
  # * <tt>add_index(table_name, column_names, options)</tt>: Adds a new index
  #   with the name of the column. Other options include
  #   <tt>:name</tt>, <tt>:unique</tt> (e.g.
  #   <tt>{ name: 'users_name_index', unique: true }</tt>) and <tt>:order</tt>
  #   (e.g. <tt>{ order: { name: :desc } }</tt>).
  # * <tt>remove_index(table_name, column: column_name)</tt>: Removes the index
  #   specified by +column_name+.
  # * <tt>remove_index(table_name, name: index_name)</tt>: Removes the index
  #   specified by +index_name+.
  #
  # == Irreversible transformations
  #
  # Some transformations are destructive in a manner that cannot be reversed.
  # Migrations of that kind should raise an <tt>ActiveRecord::IrreversibleMigration</tt>
  # exception in their +down+ method.
  #
  # == Running migrations from within Rails
  #
  # The Rails package has several tools to help create and apply migrations.
  #
  # To generate a new migration, you can use
  #   rails generate migration MyNewMigration
  #
  # where MyNewMigration is the name of your migration. The generator will
  # create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
  # in the <tt>db/migrate/</tt> directory where <tt>timestamp</tt> is the
  # UTC formatted date and time that the migration was generated.
  #
  # You may then edit the <tt>up</tt> and <tt>down</tt> methods of
  # MyNewMigration.
  #
  # There is a special syntactic shortcut to generate migrations that add fields to a table.
  #
  #   rails generate migration add_fieldname_to_tablename fieldname:string
  #
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename</tt>, which will look like this:
  #   class AddFieldnameToTablename < ActiveRecord::Migration
  #     def up
  #       add_column :tablenames, :fieldname, :string
  #     end
  #
  #     def down
  #       remove_column :tablenames, :fieldname
  #     end
  #   end
  #
  # To run migrations against the currently configured database, use
  # <tt>rake db:migrate</tt>. This will update the database by running all of the
  # pending migrations, creating the <tt>schema_migrations</tt> table
  # (see "About the schema_migrations table" section below) if missing. It will also
  # invoke the db:schema:dump task, which will update your db/schema.rb file
  # to match the structure of your database.
  #
  # To roll the database back to a previous migration version, use
  # <tt>rake db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which
  # you wish to downgrade. If any of the migrations throw an
  # <tt>ActiveRecord::IrreversibleMigration</tt> exception, that step will fail and you'll
  # have some manual work to do.
  #
  # == Database support
  #
  # Migrations are currently supported in MySQL, PostgreSQL, SQLite,
  # SQL Server, Sybase, and Oracle (all supported databases except DB2).
  #
  # == More examples
  #
  # Not all migrations change the schema. Some just fix the data:
  #
  #   class RemoveEmptyTags < ActiveRecord::Migration
  #     def up
  #       Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
  #     end
  #
  #     def down
  #       # not much we can do to restore deleted data
  #       raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags"
  #     end
  #   end
  #
  # Others remove columns when they migrate up instead of down:
  #
  #   class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration
  #     def up
  #       remove_column :items, :incomplete_items_count
  #       remove_column :items, :completed_items_count
  #     end
  #
  #     def down
  #       add_column :items, :incomplete_items_count
  #       add_column :items, :completed_items_count
  #     end
  #   end
  #
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
  #
  #   class MakeJoinUnique < ActiveRecord::Migration
  #     def up
  #       execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
  #     end
  #
  #     def down
  #       execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`"
  #     end
  #   end
  #
  # == Using a model after changing its table
  #
  # Sometimes you'll want to add a column in a migration and populate it
  # immediately after. In that case, you'll need to make a call to
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
  # latest column data from after the new column was added. Example:
  #
  #   class AddPeopleSalary < ActiveRecord::Migration
  #     def up
  #       add_column :people, :salary, :integer
  #       Person.reset_column_information
  #       Person.all.each do |p|
  #         p.update_attribute :salary, SalaryCalculator.compute(p)
  #       end
  #     end
  #   end
  #
  # == Controlling verbosity
  #
  # By default, migrations will describe the actions they are taking, writing
  # them to the console as they happen, along with benchmarks describing how
  # long each step took.
  #
  # You can quiet them down by setting ActiveRecord::Migration.verbose = false.
  #
  # You can also insert your own messages and benchmarks by using the +say_with_time+
  # method:
  #
  #   def up
  #     ...
  #     say_with_time "Updating salaries..." do
  #       Person.all.each do |p|
  #         p.update_attribute :salary, SalaryCalculator.compute(p)
  #       end
  #     end
  #     ...
  #   end
  #
  # The phrase "Updating salaries..." would then be printed, along with the
  # benchmark for the block when the block completes.
  #
  # == About the schema_migrations table
  #
  # Rails versions 2.0 and prior used to create a table called
  # <tt>schema_info</tt> when using migrations. This table contained the
  # version of the schema as of the last applied migration.
  #
  # Starting with Rails 2.1, the <tt>schema_info</tt> table is
  # (automatically) replaced by the <tt>schema_migrations</tt> table, which
  # contains the version numbers of all the migrations applied.
  #
  # As a result, it is now possible to add migration files that are numbered
  # lower than the current schema version: when migrating up, those
  # never-applied "interleaved" migrations will be automatically applied, and
  # when migrating down, never-applied "interleaved" migrations will be skipped.
  #
  # == Timestamped Migrations
  #
  # By default, Rails generates migrations that look like:
  #
  #    20080717013526_your_migration_name.rb
  #
  # The prefix is a generation timestamp (in UTC).
  #
  # If you'd prefer to use numeric prefixes, you can turn timestamped migrations
  # off by setting:
  #
  #    config.active_record.timestamped_migrations = false
  #
  # In application.rb.
  #
  # == Reversible Migrations
  #
  # Starting with Rails 3.1, you will be able to define reversible migrations.
  # Reversible migrations are migrations that know how to go +down+ for you.
  # You simply supply the +up+ logic, and the Migration system will figure out
  # how to execute the down commands for you.
  #
  # To define a reversible migration, define the +change+ method in your
  # migration like this:
  #
  #   class TenderloveMigration < ActiveRecord::Migration
  #     def change
  #       create_table(:horses) do |t|
  #         t.column :content, :text
  #         t.column :remind_at, :datetime
  #       end
  #     end
  #   end
  #
  # This migration will create the horses table for you on the way up, and
  # automatically figure out how to drop the table on the way down.
  #
  # Some commands like +remove_column+ cannot be reversed.  If you care to
  # define how to move up and down in these cases, you should define the +up+
  # and +down+ methods as before.
  #
  # If a command cannot be reversed, an
  # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
  # the migration is moving down.
  #
  # For a list of commands that are reversible, please see
  # <tt>ActiveRecord::Migration::CommandRecorder</tt>.
  class Migration
    autoload :CommandRecorder, 'active_record/migration/command_recorder'


    # This class is used to verify that all migrations have been run before
    # loading a web page if config.active_record.migration_error is set to :page_load
    class CheckPending
      def initialize(app)
        @app = app
      end

      def call(env)
        ActiveRecord::Base.logger.silence do
          ActiveRecord::Migration.check_pending!
        end
        @app.call(env)
      end
    end

    class << self
      attr_accessor :delegate # :nodoc:
    end

    def self.check_pending!
      raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?
    end

    def self.method_missing(name, *args, &block) # :nodoc:
      (delegate || superclass.delegate).send(name, *args, &block)
    end

    def self.migrate(direction)
      new.migrate direction
    end

    cattr_accessor :verbose

    attr_accessor :name, :version

    def initialize(name = self.class.name, version = nil)
      @name       = name
      @version    = version
      @connection = nil
    end

    # instantiate the delegate object after initialize is defined
    self.verbose  = true
    self.delegate = new

    # Reverses the migration commands for the given block and
    # the given migrations.
    #
    # The following migration will remove the table 'horses'
    # and create the table 'apples' on the way up, and the reverse
    # on the way down.
    #
    #   class FixTLMigration < ActiveRecord::Migration
    #     def change
    #       revert do
    #         create_table(:horses) do |t|
    #           t.text :content
    #           t.datetime :remind_at
    #         end
    #       end
    #       create_table(:apples) do |t|
    #         t.string :variety
    #       end
    #     end
    #   end
    #
    # Or equivalently, if +TenderloveMigration+ is defined as in the
    # documentation for Migration:
    #
    #   require_relative '2012121212_tenderlove_migration'
    #
    #   class FixupTLMigration < ActiveRecord::Migration
    #     def change
    #       revert TenderloveMigration
    #
    #       create_table(:apples) do |t|
    #         t.string :variety
    #       end
    #     end
    #   end
    #
    # This command can be nested.
    def revert(*migration_classes)
      run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
      if block_given?
        if @connection.respond_to? :revert
          @connection.revert { yield }
        else
          recorder = CommandRecorder.new(@connection)
          @connection = recorder
          suppress_messages do
            @connection.revert { yield }
          end
          @connection = recorder.delegate
          recorder.commands.each do |cmd, args, block|
            send(cmd, *args, &block)
          end
        end
      end
    end

    def reverting?
      @connection.respond_to?(:reverting) && @connection.reverting
    end

    class ReversibleBlockHelper < Struct.new(:reverting)
      def up
        yield unless reverting
      end

      def down
        yield if reverting
      end
    end

    # Used to specify an operation that can be run in one direction or another.
    # Call the methods +up+ and +down+ of the yielded object to run a block
    # only in one given direction.
    # The whole block will be called in the right order within the migration.
    #
    # In the following example, the looping on users will always be done
    # when the three columns 'first_name', 'last_name' and 'full_name' exist,
    # even when migrating down:
    #
    #    class SplitNameMigration < ActiveRecord::Migration
    #      def change
    #        add_column :users, :first_name, :string
    #        add_column :users, :last_name, :string
    #
    #        reversible do |dir|
    #          User.reset_column_information
    #          User.all.each do |u|
    #            dir.up   { u.first_name, u.last_name = u.full_name.split(' ') }
    #            dir.down { u.full_name = "#{u.first_name} #{u.last_name}" }
    #            u.save
    #          end
    #        end
    #
    #        revert { add_column :users, :full_name, :string }
    #      end
    #    end
    def reversible
      helper = ReversibleBlockHelper.new(reverting?)
      execute_block{ yield helper }
    end

    # Runs the given migration classes.
    # Last argument can specify options:
    # - :direction (default is :up)
    # - :revert (default is false)
    def run(*migration_classes)
      opts = migration_classes.extract_options!
      dir = opts[:direction] || :up
      dir = (dir == :down ? :up : :down) if opts[:revert]
      if reverting?
        # If in revert and going :up, say, we want to execute :down without reverting, so
        revert { run(*migration_classes, direction: dir, revert: true) }
      else
        migration_classes.each do |migration_class|
          migration_class.new.exec_migration(@connection, dir)
        end
      end
    end

    def up
      self.class.delegate = self
      return unless self.class.respond_to?(:up)
      self.class.up
    end

    def down
      self.class.delegate = self
      return unless self.class.respond_to?(:down)
      self.class.down
    end

    # Execute this migration in the named direction
    def migrate(direction)
      return unless respond_to?(direction)

      case direction
      when :up   then announce "migrating"
      when :down then announce "reverting"
      end

      time   = nil
      ActiveRecord::Base.connection_pool.with_connection do |conn|
        time = Benchmark.measure do
          exec_migration(conn, direction)
        end
      end

      case direction
      when :up   then announce "migrated (%.4fs)" % time.real; write
      when :down then announce "reverted (%.4fs)" % time.real; write
      end
    end

    def exec_migration(conn, direction)
      @connection = conn
      if respond_to?(:change)
        if direction == :down
          revert { change }
        else
          change
        end
      else
        send(direction)
      end
    ensure
      @connection = nil
    end

    def write(text="")
      puts(text) if verbose
    end

    def announce(message)
      text = "#{version} #{name}: #{message}"
      length = [0, 75 - text.length].max
      write "== %s %s" % [text, "=" * length]
    end

    def say(message, subitem=false)
      write "#{subitem ? "   ->" : "--"} #{message}"
    end

    def say_with_time(message)
      say(message)
      result = nil
      time = Benchmark.measure { result = yield }
      say "%.4fs" % time.real, :subitem
      say("#{result} rows", :subitem) if result.is_a?(Integer)
      result
    end

    def suppress_messages
      save, self.verbose = verbose, false
      yield
    ensure
      self.verbose = save
    end

    def connection
      @connection || ActiveRecord::Base.connection
    end

    def method_missing(method, *arguments, &block)
      arg_list = arguments.map{ |a| a.inspect } * ', '

      say_with_time "#{method}(#{arg_list})" do
        unless @connection.respond_to? :revert
          unless arguments.empty? || method == :execute
            arguments[0] = Migrator.proper_table_name(arguments.first)
            arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
          end
        end
        return super unless connection.respond_to?(method)
        connection.send(method, *arguments, &block)
      end
    end

    def copy(destination, sources, options = {})
      copied = []

      FileUtils.mkdir_p(destination) unless File.exists?(destination)

      destination_migrations = ActiveRecord::Migrator.migrations(destination)
      last = destination_migrations.last
      sources.each do |scope, path|
        source_migrations = ActiveRecord::Migrator.migrations(path)

        source_migrations.each do |migration|
          source = File.read(migration.filename)
          source = "# This migration comes from #{scope} (originally #{migration.version})\n#{source}"

          if duplicate = destination_migrations.detect { |m| m.name == migration.name }
            if options[:on_skip] && duplicate.scope != scope.to_s
              options[:on_skip].call(scope, migration)
            end
            next
          end

          migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
          new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
          old_path, migration.filename = migration.filename, new_path
          last = migration

          File.open(migration.filename, "w") { |f| f.write source }
          copied << migration
          options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
          destination_migrations << migration
        end
      end

      copied
    end

    def next_migration_number(number)
      if ActiveRecord::Base.timestamped_migrations
        [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
      else
        "%.3d" % number
      end
    end

    private
    def execute_block
      if connection.respond_to? :execute_block
        super # use normal delegation to record the block
      else
        yield
      end
    end
  end

  # MigrationProxy is used to defer loading of the actual migration classes
  # until they are needed
  class MigrationProxy < Struct.new(:name, :version, :filename, :scope)

    def initialize(name, version, filename, scope)
      super
      @migration = nil
    end

    def basename
      File.basename(filename)
    end

    delegate :migrate, :announce, :write, :to => :migration

    private

      def migration
        @migration ||= load_migration
      end

      def load_migration
        require(File.expand_path(filename))
        name.constantize.new
      end

  end

  class Migrator#:nodoc:
    class << self
      attr_writer :migrations_paths
      alias :migrations_path= :migrations_paths=

      def migrate(migrations_paths, target_version = nil, &block)
        case
        when target_version.nil?
          up(migrations_paths, target_version, &block)
        when current_version == 0 && target_version == 0
          []
        when current_version > target_version
          down(migrations_paths, target_version, &block)
        else
          up(migrations_paths, target_version, &block)
        end
      end

      def rollback(migrations_paths, steps=1)
        move(:down, migrations_paths, steps)
      end

      def forward(migrations_paths, steps=1)
        move(:up, migrations_paths, steps)
      end

      def up(migrations_paths, target_version = nil)
        migrations = migrations(migrations_paths)
        migrations.select! { |m| yield m } if block_given?

        self.new(:up, migrations, target_version).migrate
      end

      def down(migrations_paths, target_version = nil, &block)
        migrations = migrations(migrations_paths)
        migrations.select! { |m| yield m } if block_given?

        self.new(:down, migrations, target_version).migrate
      end

      def run(direction, migrations_paths, target_version)
        self.new(direction, migrations(migrations_paths), target_version).run
      end

      def open(migrations_paths)
        self.new(:up, migrations(migrations_paths), nil)
      end

      def schema_migrations_table_name
        SchemaMigration.table_name
      end

      def get_all_versions
        SchemaMigration.all.map { |x| x.version.to_i }.sort
      end

      def current_version
        sm_table = schema_migrations_table_name
        if Base.connection.table_exists?(sm_table)
          get_all_versions.max || 0
        else
          0
        end
      end

      def needs_migration?
        current_version < last_version
      end

      def last_version
        migrations(migrations_paths).last.try(:version)||0
      end

      def proper_table_name(name)
        # Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string
        if name.respond_to? :table_name
          name.table_name
        else
          "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
        end
      end

      def migrations_paths
        @migrations_paths ||= ['db/migrate']
        # just to not break things if someone uses: migration_path = some_string
        Array(@migrations_paths)
      end

      def migrations_path
        migrations_paths.first
      end

      def migrations(paths)
        paths = Array(paths)

        files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }]

        migrations = files.map do |file|
          version, name, scope = file.scan(/([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first

          raise IllegalMigrationNameError.new(file) unless version
          version = version.to_i
          name = name.camelize

          MigrationProxy.new(name, version, file, scope)
        end

        migrations.sort_by(&:version)
      end

      private

      def move(direction, migrations_paths, steps)
        migrator = self.new(direction, migrations(migrations_paths))
        start_index = migrator.migrations.index(migrator.current_migration)

        if start_index
          finish = migrator.migrations[start_index + steps]
          version = finish ? finish.version : 0
          send(direction, migrations_paths, version)
        end
      end
    end

    def initialize(direction, migrations, target_version = nil)
      raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?

      @direction         = direction
      @target_version    = target_version
      @migrated_versions = nil

      if Array(migrations).grep(String).empty?
        @migrations = migrations
      else
        ActiveSupport::Deprecation.warn "instantiate this class with a list of migrations"
        @migrations = self.class.migrations(migrations)
      end

      validate(@migrations)

      ActiveRecord::SchemaMigration.create_table
    end

    def current_version
      migrated.sort.last || 0
    end

    def current_migration
      migrations.detect { |m| m.version == current_version }
    end
    alias :current :current_migration

    def run
      target = migrations.detect { |m| m.version == @target_version }
      raise UnknownMigrationVersionError.new(@target_version) if target.nil?
      unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
        target.migrate(@direction)
        record_version_state_after_migrating(target.version)
      end
    end

    def migrate
      if !target && @target_version && @target_version > 0
        raise UnknownMigrationVersionError.new(@target_version)
      end

      running = runnable

      if block_given?
        message = "block argument to migrate is deprecated, please filter migrations before constructing the migrator"
        ActiveSupport::Deprecation.warn message
        running.select! { |m| yield m }
      end

      running.each do |migration|
        Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger

        begin
          ddl_transaction do
            migration.migrate(@direction)
            record_version_state_after_migrating(migration.version)
          end
        rescue => e
          canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
          raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace
        end
      end
    end

    def runnable
      runnable = migrations[start..finish]
      if up?
        runnable.reject { |m| ran?(m) }
      else
        # skip the last migration if we're headed down, but not ALL the way down
        runnable.pop if target
        runnable.find_all { |m| ran?(m) }
      end
    end

    def migrations
      down? ? @migrations.reverse : @migrations.sort_by(&:version)
    end

    def pending_migrations
      already_migrated = migrated
      migrations.reject { |m| already_migrated.include?(m.version) }
    end

    def migrated
      @migrated_versions ||= Set.new(self.class.get_all_versions)
    end

    private
    def ran?(migration)
      migrated.include?(migration.version.to_i)
    end

    def target
      migrations.detect { |m| m.version == @target_version }
    end

    def finish
      migrations.index(target) || migrations.size - 1
    end

    def start
      up? ? 0 : (migrations.index(current) || 0)
    end

    def validate(migrations)
      name ,= migrations.group_by(&:name).find { |_,v| v.length > 1 }
      raise DuplicateMigrationNameError.new(name) if name

      version ,= migrations.group_by(&:version).find { |_,v| v.length > 1 }
      raise DuplicateMigrationVersionError.new(version) if version
    end

    def record_version_state_after_migrating(version)
      if down?
        migrated.delete(version)
        ActiveRecord::SchemaMigration.where(:version => version.to_s).delete_all
      else
        migrated << version
        ActiveRecord::SchemaMigration.create!(:version => version.to_s)
      end
    end

    def up?
      @direction == :up
    end

    def down?
      @direction == :down
    end

    # Wrap the migration in a transaction only if supported by the adapter.
    def ddl_transaction
      if Base.connection.supports_ddl_transactions?
        Base.transaction { yield }
      else
        yield
      end
    end
  end
end
module ActiveRecord
  module ModelSchema
    extend ActiveSupport::Concern

    included do
      ##
      # :singleton-method:
      # Accessor for the prefix type that will be prepended to every primary key column name.
      # The options are :table_name and :table_name_with_underscore. If the first is specified,
      # the Product class will look for "productid" instead of "id" as the primary column. If the
      # latter is specified, the Product class will look for "product_id" instead of "id". Remember
      # that this is a global setting for all Active Records.
      mattr_accessor :primary_key_prefix_type, instance_writer: false

      ##
      # :singleton-method:
      # Accessor for the name of the prefix string to prepend to every table name. So if set
      # to "basecamp_", all table names will be named like "basecamp_projects", "basecamp_people",
      # etc. This is a convenient way of creating a namespace for tables in a shared database.
      # By default, the prefix is the empty string.
      #
      # If you are organising your models within modules you can add a prefix to the models within
      # a namespace by defining a singleton method in the parent module called table_name_prefix which
      # returns your chosen prefix.
      class_attribute :table_name_prefix, instance_writer: false
      self.table_name_prefix = ""

      ##
      # :singleton-method:
      # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
      # "people_basecamp"). By default, the suffix is the empty string.
      class_attribute :table_name_suffix, instance_writer: false
      self.table_name_suffix = ""

      ##
      # :singleton-method:
      # Indicates whether table names should be the pluralized versions of the corresponding class names.
      # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
      # See table_name for the full rules on table/class naming. This is true, by default.
      class_attribute :pluralize_table_names, instance_writer: false
      self.pluralize_table_names = true

      self.inheritance_column = 'type'
    end

    module ClassMethods
      # Guesses the table name (in forced lower-case) based on the name of the class in the
      # inheritance hierarchy descending directly from ActiveRecord::Base. So if the hierarchy
      # looks like: Reply < Message < ActiveRecord::Base, then Message is used
      # to guess the table name even when called on Reply. The rules used to do the guess
      # are handled by the Inflector class in Active Support, which knows almost all common
      # English inflections. You can add new inflections in config/initializers/inflections.rb.
      #
      # Nested classes are given table names prefixed by the singular form of
      # the parent's table name. Enclosing modules are not considered.
      #
      # ==== Examples
      #
      #   class Invoice < ActiveRecord::Base
      #   end
      #
      #   file                  class               table_name
      #   invoice.rb            Invoice             invoices
      #
      #   class Invoice < ActiveRecord::Base
      #     class Lineitem < ActiveRecord::Base
      #     end
      #   end
      #
      #   file                  class               table_name
      #   invoice.rb            Invoice::Lineitem   invoice_lineitems
      #
      #   module Invoice
      #     class Lineitem < ActiveRecord::Base
      #     end
      #   end
      #
      #   file                  class               table_name
      #   invoice/lineitem.rb   Invoice::Lineitem   lineitems
      #
      # Additionally, the class-level +table_name_prefix+ is prepended and the
      # +table_name_suffix+ is appended. So if you have "myapp_" as a prefix,
      # the table name guess for an Invoice class becomes "myapp_invoices".
      # Invoice::Lineitem becomes "myapp_invoice_lineitems".
      #
      # You can also set your own table name explicitly:
      #
      #   class Mouse < ActiveRecord::Base
      #     self.table_name = "mice"
      #   end
      #
      # Alternatively, you can override the table_name method to define your
      # own computation. (Possibly using <tt>super</tt> to manipulate the default
      # table name.) Example:
      #
      #   class Post < ActiveRecord::Base
      #     def self.table_name
      #       "special_" + super
      #     end
      #   end
      #   Post.table_name # => "special_posts"
      def table_name
        reset_table_name unless defined?(@table_name)
        @table_name
      end

      # Sets the table name explicitly. Example:
      #
      #   class Project < ActiveRecord::Base
      #     self.table_name = "project"
      #   end
      #
      # You can also just define your own <tt>self.table_name</tt> method; see
      # the documentation for ActiveRecord::Base#table_name.
      def table_name=(value)
        value = value && value.to_s

        if defined?(@table_name)
          return if value == @table_name
          reset_column_information if connected?
        end

        @table_name        = value
        @quoted_table_name = nil
        @arel_table        = nil
        @sequence_name     = nil unless defined?(@explicit_sequence_name) && @explicit_sequence_name
        @relation          = Relation.new(self, arel_table)
      end

      # Returns a quoted version of the table name, used to construct SQL statements.
      def quoted_table_name
        @quoted_table_name ||= connection.quote_table_name(table_name)
      end

      # Computes the table name, (re)sets it internally, and returns it.
      def reset_table_name #:nodoc:
        self.table_name = if abstract_class?
          superclass == Base ? nil : superclass.table_name
        elsif superclass.abstract_class?
          superclass.table_name || compute_table_name
        else
          compute_table_name
        end
      end

      def full_table_name_prefix #:nodoc:
        (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
      end

      # Defines the name of the table column which will store the class name on single-table
      # inheritance situations.
      #
      # The default inheritance column name is +type+, which means it's a
      # reserved word inside Active Record. To be able to use single-table
      # inheritance with another column name, or to use the column +type+ in
      # your own model for something else, you can set +inheritance_column+:
      #
      #     self.inheritance_column = 'zoink'
      def inheritance_column
        (@inheritance_column ||= nil) || superclass.inheritance_column
      end

      # Sets the value of inheritance_column
      def inheritance_column=(value)
        @inheritance_column = value.to_s
        @explicit_inheritance_column = true
      end

      def sequence_name
        if base_class == self
          @sequence_name ||= reset_sequence_name
        else
          (@sequence_name ||= nil) || base_class.sequence_name
        end
      end

      def reset_sequence_name #:nodoc:
        @explicit_sequence_name = false
        @sequence_name          = connection.default_sequence_name(table_name, primary_key)
      end

      # Sets the name of the sequence to use when generating ids to the given
      # value, or (if the value is nil or false) to the value returned by the
      # given block. This is required for Oracle and is useful for any
      # database which relies on sequences for primary key generation.
      #
      # If a sequence name is not explicitly set when using Oracle or Firebird,
      # it will default to the commonly used pattern of: #{table_name}_seq
      #
      # If a sequence name is not explicitly set when using PostgreSQL, it
      # will discover the sequence corresponding to your primary key for you.
      #
      #   class Project < ActiveRecord::Base
      #     self.sequence_name = "projectseq"   # default would have been "project_seq"
      #   end
      def sequence_name=(value)
        @sequence_name          = value.to_s
        @explicit_sequence_name = true
      end

      # Indicates whether the table associated with this class exists
      def table_exists?
        connection.schema_cache.table_exists?(table_name)
      end

      # Returns an array of column objects for the table associated with this class.
      def columns
        @columns ||= connection.schema_cache.columns[table_name].map do |col|
          col = col.dup
          col.primary = (col.name == primary_key)
          col
        end
      end

      # Returns a hash of column objects for the table associated with this class.
      def columns_hash
        @columns_hash ||= Hash[columns.map { |c| [c.name, c] }]
      end

      def column_types # :nodoc:
        @column_types ||= decorate_columns(columns_hash.dup)
      end

      def decorate_columns(columns_hash) # :nodoc:
        return if columns_hash.empty?

        columns_hash.each do |name, col|
          if serialized_attributes.key?(name)
            columns_hash[name] = AttributeMethods::Serialization::Type.new(col)
          end
          if create_time_zone_conversion_attribute?(name, col)
            columns_hash[name] = AttributeMethods::TimeZoneConversion::Type.new(col)
          end
        end

        columns_hash
      end

      # Returns a hash where the keys are column names and the values are
      # default values when instantiating the AR object for this table.
      def column_defaults
        @column_defaults ||= Hash[columns.map { |c| [c.name, c.default] }]
      end

      # Returns an array of column names as strings.
      def column_names
        @column_names ||= columns.map { |column| column.name }
      end

      # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
      # and columns used for single table inheritance have been removed.
      def content_columns
        @content_columns ||= columns.reject { |c| c.primary || c.name =~ /(_id|_count)$/ || c.name == inheritance_column }
      end

      # Returns a hash of all the methods added to query each of the columns in the table with the name of the method as the key
      # and true as the value. This makes it possible to do O(1) lookups in respond_to? to check if a given method for attribute
      # is available.
      def column_methods_hash #:nodoc:
        @dynamic_methods_hash ||= column_names.each_with_object(Hash.new(false)) do |attr, methods|
          attr_name = attr.to_s
          methods[attr.to_sym]       = attr_name
          methods["#{attr}=".to_sym] = attr_name
          methods["#{attr}?".to_sym] = attr_name
          methods["#{attr}_before_type_cast".to_sym] = attr_name
        end
      end

      # Resets all the cached information about columns, which will cause them
      # to be reloaded on the next request.
      #
      # The most common usage pattern for this method is probably in a migration,
      # when just after creating a table you want to populate it with some default
      # values, eg:
      #
      #  class CreateJobLevels < ActiveRecord::Migration
      #    def up
      #      create_table :job_levels do |t|
      #        t.integer :id
      #        t.string :name
      #
      #        t.timestamps
      #      end
      #
      #      JobLevel.reset_column_information
      #      %w{assistant executive manager director}.each do |type|
      #        JobLevel.create(name: type)
      #      end
      #    end
      #
      #    def down
      #      drop_table :job_levels
      #    end
      #  end
      def reset_column_information
        connection.clear_cache!
        undefine_attribute_methods
        connection.schema_cache.clear_table_cache!(table_name) if table_exists?

        @arel_engine          = nil
        @column_defaults      = nil
        @column_names         = nil
        @columns              = nil
        @columns_hash         = nil
        @column_types         = nil
        @content_columns      = nil
        @dynamic_methods_hash = nil
        @inheritance_column   = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
        @relation             = nil
      end

      # This is a hook for use by modules that need to do extra stuff to
      # attributes when they are initialized. (e.g. attribute
      # serialization)
      def initialize_attributes(attributes, options = {}) #:nodoc:
        attributes
      end

      private

      # Guesses the table name, but does not decorate it with prefix and suffix information.
      def undecorated_table_name(class_name = base_class.name)
        table_name = class_name.to_s.demodulize.underscore
        pluralize_table_names ? table_name.pluralize : table_name
      end

      # Computes and returns a table name according to default conventions.
      def compute_table_name
        base = base_class
        if self == base
          # Nested classes are prefixed with singular parent table name.
          if parent < Base && !parent.abstract_class?
            contained = parent.table_name
            contained = contained.singularize if parent.pluralize_table_names
            contained += '_'
          end
          "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{table_name_suffix}"
        else
          # STI subclasses always use their superclass' table.
          base.table_name
        end
      end
    end
  end
end
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/try'
require 'active_support/core_ext/hash/indifferent_access'

module ActiveRecord
  module NestedAttributes #:nodoc:
    class TooManyRecords < ActiveRecordError
    end

    extend ActiveSupport::Concern

    included do
      class_attribute :nested_attributes_options, instance_writer: false
      self.nested_attributes_options = {}
    end

    # = Active Record Nested Attributes
    #
    # Nested attributes allow you to save attributes on associated records
    # through the parent. By default nested attribute updating is turned off
    # and you can enable it using the accepts_nested_attributes_for class
    # method. When you enable nested attributes an attribute writer is
    # defined on the model.
    #
    # The attribute writer is named after the association, which means that
    # in the following example, two new methods are added to your model:
    #
    # <tt>author_attributes=(attributes)</tt> and
    # <tt>pages_attributes=(attributes)</tt>.
    #
    #   class Book < ActiveRecord::Base
    #     has_one :author
    #     has_many :pages
    #
    #     accepts_nested_attributes_for :author, :pages
    #   end
    #
    # Note that the <tt>:autosave</tt> option is automatically enabled on every
    # association that accepts_nested_attributes_for is used for.
    #
    # === One-to-one
    #
    # Consider a Member model that has one Avatar:
    #
    #   class Member < ActiveRecord::Base
    #     has_one :avatar
    #     accepts_nested_attributes_for :avatar
    #   end
    #
    # Enabling nested attributes on a one-to-one association allows you to
    # create the member and avatar in one go:
    #
    #   params = { member: { name: 'Jack', avatar_attributes: { icon: 'smiling' } } }
    #   member = Member.create(params[:member])
    #   member.avatar.id # => 2
    #   member.avatar.icon # => 'smiling'
    #
    # It also allows you to update the avatar through the member:
    #
    #   params = { member: { avatar_attributes: { id: '2', icon: 'sad' } } }
    #   member.update params[:member]
    #   member.avatar.icon # => 'sad'
    #
    # By default you will only be able to set and update attributes on the
    # associated model. If you want to destroy the associated model through the
    # attributes hash, you have to enable it first using the
    # <tt>:allow_destroy</tt> option.
    #
    #   class Member < ActiveRecord::Base
    #     has_one :avatar
    #     accepts_nested_attributes_for :avatar, allow_destroy: true
    #   end
    #
    # Now, when you add the <tt>_destroy</tt> key to the attributes hash, with a
    # value that evaluates to +true+, you will destroy the associated model:
    #
    #   member.avatar_attributes = { id: '2', _destroy: '1' }
    #   member.avatar.marked_for_destruction? # => true
    #   member.save
    #   member.reload.avatar # => nil
    #
    # Note that the model will _not_ be destroyed until the parent is saved.
    #
    # === One-to-many
    #
    # Consider a member that has a number of posts:
    #
    #   class Member < ActiveRecord::Base
    #     has_many :posts
    #     accepts_nested_attributes_for :posts
    #   end
    #
    # You can now set or update attributes on an associated post model through
    # the attribute hash.
    #
    # For each hash that does _not_ have an <tt>id</tt> key a new record will
    # be instantiated, unless the hash also contains a <tt>_destroy</tt> key
    # that evaluates to +true+.
    #
    #   params = { member: {
    #     name: 'joe', posts_attributes: [
    #       { title: 'Kari, the awesome Ruby documentation browser!' },
    #       { title: 'The egalitarian assumption of the modern citizen' },
    #       { title: '', _destroy: '1' } # this will be ignored
    #     ]
    #   }}
    #
    #   member = Member.create(params[:member])
    #   member.posts.length # => 2
    #   member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
    #   member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
    #
    # You may also set a :reject_if proc to silently ignore any new record
    # hashes if they fail to pass your criteria. For example, the previous
    # example could be rewritten as:
    #
    #    class Member < ActiveRecord::Base
    #      has_many :posts
    #      accepts_nested_attributes_for :posts, reject_if: proc { |attributes| attributes['title'].blank? }
    #    end
    #
    #   params = { member: {
    #     name: 'joe', posts_attributes: [
    #       { title: 'Kari, the awesome Ruby documentation browser!' },
    #       { title: 'The egalitarian assumption of the modern citizen' },
    #       { title: '' } # this will be ignored because of the :reject_if proc
    #     ]
    #   }}
    #
    #   member = Member.create(params[:member])
    #   member.posts.length # => 2
    #   member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
    #   member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
    #
    # Alternatively, :reject_if also accepts a symbol for using methods:
    #
    #    class Member < ActiveRecord::Base
    #      has_many :posts
    #      accepts_nested_attributes_for :posts, reject_if: :new_record?
    #    end
    #
    #    class Member < ActiveRecord::Base
    #      has_many :posts
    #      accepts_nested_attributes_for :posts, reject_if: :reject_posts
    #
    #      def reject_posts(attributed)
    #        attributed['title'].blank?
    #      end
    #    end
    #
    # If the hash contains an <tt>id</tt> key that matches an already
    # associated record, the matching record will be modified:
    #
    #   member.attributes = {
    #     name: 'Joe',
    #     posts_attributes: [
    #       { id: 1, title: '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!' },
    #       { id: 2, title: '[UPDATED] other post' }
    #     ]
    #   }
    #
    #   member.posts.first.title # => '[UPDATED] An, as of yet, undisclosed awesome Ruby documentation browser!'
    #   member.posts.second.title # => '[UPDATED] other post'
    #
    # By default the associated records are protected from being destroyed. If
    # you want to destroy any of the associated records through the attributes
    # hash, you have to enable it first using the <tt>:allow_destroy</tt>
    # option. This will allow you to also use the <tt>_destroy</tt> key to
    # destroy existing records:
    #
    #   class Member < ActiveRecord::Base
    #     has_many :posts
    #     accepts_nested_attributes_for :posts, allow_destroy: true
    #   end
    #
    #   params = { member: {
    #     posts_attributes: [{ id: '2', _destroy: '1' }]
    #   }}
    #
    #   member.attributes = params[:member]
    #   member.posts.detect { |p| p.id == 2 }.marked_for_destruction? # => true
    #   member.posts.length # => 2
    #   member.save
    #   member.reload.posts.length # => 1
    #
    # === Saving
    #
    # All changes to models, including the destruction of those marked for
    # destruction, are saved and destroyed automatically and atomically when
    # the parent model is saved. This happens inside the transaction initiated
    # by the parents save method. See ActiveRecord::AutosaveAssociation.
    #
    # === Validating the presence of a parent model
    #
    # If you want to validate that a child record is associated with a parent
    # record, you can use <tt>validates_presence_of</tt> and
    # <tt>inverse_of</tt> as this example illustrates:
    #
    #   class Member < ActiveRecord::Base
    #     has_many :posts, inverse_of: :member
    #     accepts_nested_attributes_for :posts
    #   end
    #
    #   class Post < ActiveRecord::Base
    #     belongs_to :member, inverse_of: :posts
    #     validates_presence_of :member
    #   end
    module ClassMethods
      REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == '_destroy' || value.blank? } }

      # Defines an attributes writer for the specified association(s).
      #
      # Supported options:
      # [:allow_destroy]
      #   If true, destroys any members from the attributes hash with a
      #   <tt>_destroy</tt> key and a value that evaluates to +true+
      #   (eg. 1, '1', true, or 'true'). This option is off by default.
      # [:reject_if]
      #   Allows you to specify a Proc or a Symbol pointing to a method
      #   that checks whether a record should be built for a certain attribute
      #   hash. The hash is passed to the supplied Proc or the method
      #   and it should return either +true+ or +false+. When no :reject_if
      #   is specified, a record will be built for all attribute hashes that
      #   do not have a <tt>_destroy</tt> value that evaluates to true.
      #   Passing <tt>:all_blank</tt> instead of a Proc will create a proc
      #   that will reject a record where all the attributes are blank excluding
      #   any value for _destroy.
      # [:limit]
      #   Allows you to specify the maximum number of the associated records that
      #   can be processed with the nested attributes. Limit also can be specified as a
      #   Proc or a Symbol pointing to a method that should return number. If the size of the
      #   nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords
      #   exception is raised. If omitted, any number associations can be processed.
      #   Note that the :limit option is only applicable to one-to-many associations.
      # [:update_only]
      #   For a one-to-one association, this option allows you to specify how
      #   nested attributes are to be used when an associated record already
      #   exists. In general, an existing record may either be updated with the
      #   new set of attribute values or be replaced by a wholly new record
      #   containing those values. By default the :update_only option is +false+
      #   and the nested attributes are used to update the existing record only
      #   if they include the record's <tt>:id</tt> value. Otherwise a new
      #   record will be instantiated and used to replace the existing one.
      #   However if the :update_only option is +true+, the nested attributes
      #   are used to update the record's attributes always, regardless of
      #   whether the <tt>:id</tt> is present. The option is ignored for collection
      #   associations.
      #
      # Examples:
      #   # creates avatar_attributes=
      #   accepts_nested_attributes_for :avatar, reject_if: proc { |attributes| attributes['name'].blank? }
      #   # creates avatar_attributes=
      #   accepts_nested_attributes_for :avatar, reject_if: :all_blank
      #   # creates avatar_attributes= and posts_attributes=
      #   accepts_nested_attributes_for :avatar, :posts, allow_destroy: true
      def accepts_nested_attributes_for(*attr_names)
        options = { :allow_destroy => false, :update_only => false }
        options.update(attr_names.extract_options!)
        options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
        options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank

        attr_names.each do |association_name|
          if reflection = reflect_on_association(association_name)
            reflection.options[:autosave] = true
            add_autosave_association_callbacks(reflection)

            nested_attributes_options = self.nested_attributes_options.dup
            nested_attributes_options[association_name.to_sym] = options
            self.nested_attributes_options = nested_attributes_options

            type = (reflection.collection? ? :collection : :one_to_one)

            # def pirate_attributes=(attributes)
            #   assign_nested_attributes_for_one_to_one_association(:pirate, attributes, mass_assignment_options)
            # end
            generated_feature_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
              if method_defined?(:#{association_name}_attributes=)
                remove_method(:#{association_name}_attributes=)
              end
              def #{association_name}_attributes=(attributes)
                assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
              end
            eoruby
          else
            raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
          end
        end
      end
    end

    # Returns ActiveRecord::AutosaveAssociation::marked_for_destruction? It's
    # used in conjunction with fields_for to build a form element for the
    # destruction of this association.
    #
    # See ActionView::Helpers::FormHelper::fields_for for more info.
    def _destroy
      marked_for_destruction?
    end

    private

    # Attribute hash keys that should not be assigned as normal attributes.
    # These hash keys are nested attributes implementation details.
    UNASSIGNABLE_KEYS = %w( id _destroy )

    # Assigns the given attributes to the association.
    #
    # If an associated record does not yet exist, one will be instantiated. If
    # an associated record already exists, the method's behavior depends on
    # the value of the update_only option. If update_only is +false+ and the
    # given attributes include an <tt>:id</tt> that matches the existing record's
    # id, then the existing record will be modified. If no <tt>:id</tt> is provided
    # it will be replaced with a new record. If update_only is +true+ the existing
    # record will be modified regardless of whether an <tt>:id</tt> is provided.
    #
    # If the given attributes include a matching <tt>:id</tt> attribute, or
    # update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
    # then the existing record will be marked for destruction.
    def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
      options = self.nested_attributes_options[association_name]
      attributes = attributes.with_indifferent_access

      if (options[:update_only] || !attributes['id'].blank?) && (record = send(association_name)) &&
          (options[:update_only] || record.id.to_s == attributes['id'].to_s)
        assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)

      elsif attributes['id'].present?
        raise_nested_attributes_record_not_found(association_name, attributes['id'])

      elsif !reject_new_record?(association_name, attributes)
        method = "build_#{association_name}"
        if respond_to?(method)
          send(method, attributes.except(*UNASSIGNABLE_KEYS))
        else
          raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?"
        end
      end
    end

    # Assigns the given attributes to the collection association.
    #
    # Hashes with an <tt>:id</tt> value matching an existing associated record
    # will update that record. Hashes without an <tt>:id</tt> value will build
    # a new record for the association. Hashes with a matching <tt>:id</tt>
    # value and a <tt>:_destroy</tt> key set to a truthy value will mark the
    # matched record for destruction.
    #
    # For example:
    #
    #   assign_nested_attributes_for_collection_association(:people, {
    #     '1' => { id: '1', name: 'Peter' },
    #     '2' => { name: 'John' },
    #     '3' => { id: '2', _destroy: true }
    #   })
    #
    # Will update the name of the Person with ID 1, build a new associated
    # person with the name 'John', and mark the associated Person with ID 2
    # for destruction.
    #
    # Also accepts an Array of attribute hashes:
    #
    #   assign_nested_attributes_for_collection_association(:people, [
    #     { id: '1', name: 'Peter' },
    #     { name: 'John' },
    #     { id: '2', _destroy: true }
    #   ])
    def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
      options = self.nested_attributes_options[association_name]

      unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
        raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
      end

      if limit = options[:limit]
        limit = case limit
        when Symbol
          send(limit)
        when Proc
          limit.call
        else
          limit
        end

        if limit && attributes_collection.size > limit
          raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead."
        end
      end

      if attributes_collection.is_a? Hash
        keys = attributes_collection.keys
        attributes_collection = if keys.include?('id') || keys.include?(:id)
          [attributes_collection]
        else
          attributes_collection.values
        end
      end

      association = association(association_name)

      existing_records = if association.loaded?
        association.target
      else
        attribute_ids = attributes_collection.map {|a| a['id'] || a[:id] }.compact
        attribute_ids.empty? ? [] : association.scope.where(association.klass.primary_key => attribute_ids)
      end

      attributes_collection.each do |attributes|
        attributes = attributes.with_indifferent_access

        if attributes['id'].blank?
          unless reject_new_record?(association_name, attributes)
            association.build(attributes.except(*UNASSIGNABLE_KEYS))
          end
        elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s }
          unless association.loaded? || call_reject_if(association_name, attributes)
            # Make sure we are operating on the actual object which is in the association's
            # proxy_target array (either by finding it, or adding it if not found)
            target_record = association.target.detect { |record| record == existing_record }

            if target_record
              existing_record = target_record
            else
              association.add_to_target(existing_record)
            end
          end

          if !call_reject_if(association_name, attributes)
            assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
          end
        else
          raise_nested_attributes_record_not_found(association_name, attributes['id'])
        end
      end
    end

    # Updates a record with the +attributes+ or marks it for destruction if
    # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
    def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
      record.assign_attributes(attributes.except(*UNASSIGNABLE_KEYS))
      record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
    end

    # Determines if a hash contains a truthy _destroy key.
    def has_destroy_flag?(hash)
      ConnectionAdapters::Column.value_to_boolean(hash['_destroy'])
    end

    # Determines if a new record should be build by checking for
    # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
    # association and evaluates to +true+.
    def reject_new_record?(association_name, attributes)
      has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
    end

    def call_reject_if(association_name, attributes)
      return false if has_destroy_flag?(attributes)
      case callback = self.nested_attributes_options[association_name][:reject_if]
      when Symbol
        method(callback).arity == 0 ? send(callback) : send(callback, attributes)
      when Proc
        callback.call(attributes)
      end
    end

    def raise_nested_attributes_record_not_found(association_name, record_id)
      raise RecordNotFound, "Couldn't find #{self.class.reflect_on_association(association_name).klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
    end
  end
end
# -*- coding: utf-8 -*-

module ActiveRecord
  module NullRelation # :nodoc:
    def exec_queries
      @records = []
    end

    def pluck(_column_name)
      []
    end

    def delete_all(_conditions = nil)
      0
    end

    def update_all(_updates, _conditions = nil, _options = {})
      0
    end

    def delete(_id_or_array)
      0
    end

    def size
      0
    end

    def empty?
      true
    end

    def any?
      false
    end

    def many?
      false
    end

    def to_sql
      @to_sql ||= ""
    end

    def where_values_hash
      {}
    end

    def count(*)
      0
    end

    def sum(*)
      0
    end

    def calculate(_operation, _column_name, _options = {})
      nil
    end

    def exists?(_id = false)
      false
    end
  end
end
module ActiveRecord
  # = Active Record Persistence
  module Persistence
    extend ActiveSupport::Concern

    module ClassMethods
      # Creates an object (or multiple objects) and saves it to the database, if validations pass.
      # The resulting object is returned whether the object was saved successfully to the database or not.
      #
      # The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the
      # attributes on the objects that are to be created.
      #
      # +create+ respects mass-assignment security and accepts either +:as+ or +:without_protection+ options
      # in the +options+ parameter.
      #
      # ==== Examples
      #   # Create a single new object
      #   User.create(first_name: 'Jamie')
      #
      #   # Create an Array of new objects
      #   User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
      #
      #   # Create a single object and pass it into a block to set other attributes.
      #   User.create(first_name: 'Jamie') do |u|
      #     u.is_admin = false
      #   end
      #
      #   # Creating an Array of new objects using a block, where the block is executed for each object:
      #   User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
      #     u.is_admin = false
      #   end
      def create(attributes = nil, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| create(attr, &block) }
        else
          object = new(attributes, &block)
          object.save
          object
        end
      end

      # Given an attributes hash, +instantiate+ returns a new instance of
      # the appropriate class.
      #
      # For example, +Post.all+ may return Comments, Messages, and Emails
      # by storing the record's subclass in a +type+ attribute. By calling
      # +instantiate+ instead of +new+, finder methods ensure they get new
      # instances of the appropriate class for each record.
      #
      # See +ActiveRecord::Inheritance#discriminate_class_for_record+ to see
      # how this "single-table" inheritance mapping is implemented.
      def instantiate(record, column_types = {})
        klass = discriminate_class_for_record(record)
        column_types = klass.decorate_columns(column_types)
        klass.allocate.init_with('attributes' => record, 'column_types' => column_types)
      end

      private
        # Called by +instantiate+ to decide which class to use for a new
        # record instance.
        #
        # See +ActiveRecord::Inheritance#discriminate_class_for_record+ for
        # the single-table inheritance discriminator.
        def discriminate_class_for_record(record)
          self
        end
    end

    # Returns true if this object hasn't been saved yet -- that is, a record
    # for the object doesn't exist in the data store yet; otherwise, returns false.
    def new_record?
      @new_record
    end

    # Returns true if this object has been destroyed, otherwise returns false.
    def destroyed?
      @destroyed
    end

    # Returns true if the record is persisted, i.e. it's not a new record and it was
    # not destroyed, otherwise returns false.
    def persisted?
      !(new_record? || destroyed?)
    end

    # Saves the model.
    #
    # If the model is new a record gets created in the database, otherwise
    # the existing record gets updated.
    #
    # By default, save always run validations. If any of them fail the action
    # is cancelled and +save+ returns +false+. However, if you supply
    # validate: false, validations are bypassed altogether. See
    # ActiveRecord::Validations for more information.
    #
    # There's a series of callbacks associated with +save+. If any of the
    # <tt>before_*</tt> callbacks return +false+ the action is cancelled and
    # +save+ returns +false+. See ActiveRecord::Callbacks for further
    # details.
    def save(*)
      create_or_update
    rescue ActiveRecord::RecordInvalid
      false
    end

    # Saves the model.
    #
    # If the model is new a record gets created in the database, otherwise
    # the existing record gets updated.
    #
    # With <tt>save!</tt> validations always run. If any of them fail
    # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations
    # for more information.
    #
    # There's a series of callbacks associated with <tt>save!</tt>. If any of
    # the <tt>before_*</tt> callbacks return +false+ the action is cancelled
    # and <tt>save!</tt> raises ActiveRecord::RecordNotSaved. See
    # ActiveRecord::Callbacks for further details.
    def save!(*)
      create_or_update || raise(RecordNotSaved)
    end

    # Deletes the record in the database and freezes this instance to
    # reflect that no changes should be made (since they can't be
    # persisted). Returns the frozen instance.
    #
    # The row is simply removed with an SQL +DELETE+ statement on the
    # record's primary key, and no callbacks are executed.
    #
    # To enforce the object's +before_destroy+ and +after_destroy+
    # callbacks or any <tt>:dependent</tt> association
    # options, use <tt>#destroy</tt>.
    def delete
      self.class.delete(id) if persisted?
      @destroyed = true
      freeze
    end

    # Deletes the record in the database and freezes this instance to reflect
    # that no changes should be made (since they can't be persisted).
    #
    # There's a series of callbacks associated with <tt>destroy</tt>. If
    # the <tt>before_destroy</tt> callback return +false+ the action is cancelled
    # and <tt>destroy</tt> returns +false+. See
    # ActiveRecord::Callbacks for further details.
    def destroy
      raise ReadOnlyRecord if readonly?
      destroy_associations
      destroy_row if persisted?
      @destroyed = true
      freeze
    end

    # Deletes the record in the database and freezes this instance to reflect
    # that no changes should be made (since they can't be persisted).
    #
    # There's a series of callbacks associated with <tt>destroy!</tt>. If
    # the <tt>before_destroy</tt> callback return +false+ the action is cancelled
    # and <tt>destroy!</tt> raises ActiveRecord::RecordNotDestroyed. See
    # ActiveRecord::Callbacks for further details.
    def destroy!
      destroy || raise(ActiveRecord::RecordNotDestroyed)
    end

    # Returns an instance of the specified +klass+ with the attributes of the
    # current record. This is mostly useful in relation to single-table
    # inheritance structures where you want a subclass to appear as the
    # superclass. This can be used along with record identification in
    # Action Pack to allow, say, <tt>Client < Company</tt> to do something
    # like render <tt>partial: @client.becomes(Company)</tt> to render that
    # instance using the companies/company partial instead of clients/client.
    #
    # Note: The new instance will share a link to the same attributes as the original class.
    # So any change to the attributes in either instance will affect the other.
    def becomes(klass)
      became = klass.new
      became.instance_variable_set("@attributes", @attributes)
      became.instance_variable_set("@attributes_cache", @attributes_cache)
      became.instance_variable_set("@new_record", new_record?)
      became.instance_variable_set("@destroyed", destroyed?)
      became.instance_variable_set("@errors", errors)
      became
    end

    # Wrapper around +becomes+ that also changes the instance's sti column value.
    # This is especially useful if you want to persist the changed class in your
    # database.
    #
    # Note: The old instance's sti column value will be changed too, as both objects
    # share the same set of attributes.
    def becomes!(klass)
      became = becomes(klass)
      became.public_send("#{klass.inheritance_column}=", klass.sti_name) unless self.class.descends_from_active_record?
      became
    end

    # Updates a single attribute and saves the record.
    # This is especially useful for boolean flags on existing records. Also note that
    #
    # * Validation is skipped.
    # * Callbacks are invoked.
    # * updated_at/updated_on column is updated if that column is available.
    # * Updates all the attributes that are dirty in this object.
    #
    def update_attribute(name, value)
      name = name.to_s
      verify_readonly_attribute(name)
      send("#{name}=", value)
      save(validate: false)
    end

    # Updates the attributes of the model from the passed-in hash and saves the
    # record, all wrapped in a transaction. If the object is invalid, the saving
    # will fail and false will be returned.
    def update(attributes)
      # The following transaction covers any possible database side-effects of the
      # attributes assignment. For example, setting the IDs of a child collection.
      with_transaction_returning_status do
        assign_attributes(attributes)
        save
      end
    end

    alias update_attributes update

    # Updates its receiver just like +update+ but calls <tt>save!</tt> instead
    # of +save+, so an exception is raised if the record is invalid.
    def update!(attributes)
      # The following transaction covers any possible database side-effects of the
      # attributes assignment. For example, setting the IDs of a child collection.
      with_transaction_returning_status do
        assign_attributes(attributes)
        save!
      end
    end

    alias update_attributes! update!

    # Equivalent to <code>update_columns(name => value)</code>.
    def update_column(name, value)
      update_columns(name => value)
    end

    # Updates the attributes directly in the database issuing an UPDATE SQL
    # statement and sets them in the receiver:
    #
    #   user.update_columns(last_request_at: Time.current)
    #
    # This is the fastest way to update attributes because it goes straight to
    # the database, but take into account that in consequence the regular update
    # procedures are totally bypassed. In particular:
    #
    # * Validations are skipped.
    # * Callbacks are skipped.
    # * +updated_at+/+updated_on+ are not updated.
    #
    # This method raises an +ActiveRecord::ActiveRecordError+ when called on new
    # objects, or when at least one of the attributes is marked as readonly.
    def update_columns(attributes)
      raise ActiveRecordError, "can not update on a new record object" unless persisted?

      attributes.each_key do |key|
        verify_readonly_attribute(key.to_s)
      end

      updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)

      attributes.each do |k, v|
        raw_write_attribute(k, v)
      end

      updated_count == 1
    end

    # Initializes +attribute+ to zero if +nil+ and adds the value passed as +by+ (default is 1).
    # The increment is performed directly on the underlying attribute, no setter is invoked.
    # Only makes sense for number-based attributes. Returns +self+.
    def increment(attribute, by = 1)
      self[attribute] ||= 0
      self[attribute] += by
      self
    end

    # Wrapper around +increment+ that saves the record. This method differs from
    # its non-bang version in that it passes through the attribute setter.
    # Saving is not subjected to validation checks. Returns +true+ if the
    # record could be saved.
    def increment!(attribute, by = 1)
      increment(attribute, by).update_attribute(attribute, self[attribute])
    end

    # Initializes +attribute+ to zero if +nil+ and subtracts the value passed as +by+ (default is 1).
    # The decrement is performed directly on the underlying attribute, no setter is invoked.
    # Only makes sense for number-based attributes. Returns +self+.
    def decrement(attribute, by = 1)
      self[attribute] ||= 0
      self[attribute] -= by
      self
    end

    # Wrapper around +decrement+ that saves the record. This method differs from
    # its non-bang version in that it passes through the attribute setter.
    # Saving is not subjected to validation checks. Returns +true+ if the
    # record could be saved.
    def decrement!(attribute, by = 1)
      decrement(attribute, by).update_attribute(attribute, self[attribute])
    end

    # Assigns to +attribute+ the boolean opposite of <tt>attribute?</tt>. So
    # if the predicate returns +true+ the attribute will become +false+. This
    # method toggles directly the underlying value without calling any setter.
    # Returns +self+.
    def toggle(attribute)
      self[attribute] = !send("#{attribute}?")
      self
    end

    # Wrapper around +toggle+ that saves the record. This method differs from
    # its non-bang version in that it passes through the attribute setter.
    # Saving is not subjected to validation checks. Returns +true+ if the
    # record could be saved.
    def toggle!(attribute)
      toggle(attribute).update_attribute(attribute, self[attribute])
    end

    # Reloads the attributes of this object from the database.
    # The optional options argument is passed to find when reloading so you
    # may do e.g. record.reload(lock: true) to reload the same record with
    # an exclusive row lock.
    def reload(options = nil)
      clear_aggregation_cache
      clear_association_cache

      fresh_object =
        if options && options[:lock]
          self.class.unscoped { self.class.lock.find(id) }
        else
          self.class.unscoped { self.class.find(id) }
        end

      @attributes.update(fresh_object.instance_variable_get('@attributes'))
      @columns_hash = fresh_object.instance_variable_get('@columns_hash')

      @attributes_cache = {}
      self
    end

    # Saves the record with the updated_at/on attributes set to the current time.
    # Please note that no validation is performed and no callbacks are executed.
    # If an attribute name is passed, that attribute is updated along with
    # updated_at/on attributes.
    #
    #   product.touch               # updates updated_at/on
    #   product.touch(:designed_at) # updates the designed_at attribute and updated_at/on
    #
    # If used along with +belongs_to+ then +touch+ will invoke +touch+ method on associated object.
    #
    #   class Brake < ActiveRecord::Base
    #     belongs_to :car, touch: true
    #   end
    #
    #   class Car < ActiveRecord::Base
    #     belongs_to :corporation, touch: true
    #   end
    #
    #   # triggers @brake.car.touch and @brake.car.corporation.touch
    #   @brake.touch
    def touch(name = nil)
      attributes = timestamp_attributes_for_update_in_model
      attributes << name if name

      unless attributes.empty?
        current_time = current_time_from_proper_timezone
        changes = {}

        attributes.each do |column|
          column = column.to_s
          changes[column] = write_attribute(column, current_time)
        end

        changes[self.class.locking_column] = increment_lock if locking_enabled?

        @changed_attributes.except!(*changes.keys)
        primary_key = self.class.primary_key
        self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
      end
    end

  private

    # A hook to be overridden by association modules.
    def destroy_associations
    end

    def destroy_row
      relation_for_destroy.delete_all
    end

    def relation_for_destroy
      pk         = self.class.primary_key
      column     = self.class.columns_hash[pk]
      substitute = connection.substitute_at(column, 0)

      relation = self.class.unscoped.where(
        self.class.arel_table[pk].eq(substitute))

      relation.bind_values = [[column, id]]
      relation
    end

    def create_or_update
      raise ReadOnlyRecord if readonly?
      result = new_record? ? create_record : update_record
      result != false
    end

    # Updates the associated record with values matching those of the instance attributes.
    # Returns the number of affected rows.
    def update_record(attribute_names = @attributes.keys)
      attributes_with_values = arel_attributes_with_values_for_update(attribute_names)

      if attributes_with_values.empty?
        0
      else
        klass = self.class
        stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(attributes_with_values)
        klass.connection.update stmt
      end
    end

    # Creates a record with values matching those of the instance attributes
    # and returns its id.
    def create_record(attribute_names = @attributes.keys)
      attributes_values = arel_attributes_with_values_for_create(attribute_names)

      new_id = self.class.unscoped.insert attributes_values
      self.id ||= new_id if self.class.primary_key

      @new_record = false
      id
    end

    def verify_readonly_attribute(name)
      raise ActiveRecordError, "#{name} is marked as readonly" if self.class.readonly_attributes.include?(name)
    end
  end
end

module ActiveRecord
  # = Active Record Query Cache
  class QueryCache
    module ClassMethods
      # Enable the query cache within the block if Active Record is configured.
      # If it's not, it will execute the given block.
      def cache(&block)
        if ActiveRecord::Base.connected?
          connection.cache(&block)
        else
          yield
        end
      end

      # Disable the query cache within the block if Active Record is configured.
      # If it's not, it will execute the given block.
      def uncached(&block)
        if ActiveRecord::Base.connected?
          connection.uncached(&block)
        else
          yield
        end
      end
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      enabled       = ActiveRecord::Base.connection.query_cache_enabled
      connection_id = ActiveRecord::Base.connection_id
      ActiveRecord::Base.connection.enable_query_cache!

      response = @app.call(env)
      response[2] = Rack::BodyProxy.new(response[2]) do
        restore_query_cache_settings(connection_id, enabled)
      end

      response
    rescue Exception => e
      restore_query_cache_settings(connection_id, enabled)
      raise e
    end

    private

    def restore_query_cache_settings(connection_id, enabled)
      ActiveRecord::Base.connection_id = connection_id
      ActiveRecord::Base.connection.clear_query_cache
      ActiveRecord::Base.connection.disable_query_cache! unless enabled
    end

  end
end
module ActiveRecord
  module Querying
    delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :to => :all
    delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :all
    delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :to => :all
    delegate :find_by, :find_by!, :to => :all
    delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :all
    delegate :find_each, :find_in_batches, :to => :all
    delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
             :where, :preload, :eager_load, :includes, :from, :lock, :readonly,
             :having, :create_with, :uniq, :references, :none, :to => :all
    delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :ids, :to => :all

    # Executes a custom SQL query against your database and returns all the results. The results will
    # be returned as an array with columns requested encapsulated as attributes of the model you call
    # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
    # a Product object with the attributes you specified in the SQL query.
    #
    # If you call a complicated SQL query which spans multiple tables the columns specified by the
    # SELECT will be attributes of the model, whether or not they are columns of the corresponding
    # table.
    #
    # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be
    # no database agnostic conversions performed. This should be a last resort because using, for example,
    # MySQL specific terms will lock you to using that particular database engine or require you to
    # change your call if you switch engines.
    #
    #   # A simple SQL query spanning multiple tables
    #   Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
    #   # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
    #
    #   # You can use the same string replacement techniques as you can with ActiveRecord#find
    #   Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
    #   # => [#<Post:0x36bff9c @attributes={"title"=>"The Cheap Man Buys Twice"}>, ...]
    def find_by_sql(sql, binds = [])
      logging_query_plan do
        result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
        column_types = {}

        if result_set.respond_to? :column_types
          column_types = result_set.column_types
        else
          ActiveSupport::Deprecation.warn "the object returned from `select_all` must respond to `column_types`"
        end

        result_set.map { |record| instantiate(record, column_types) }
      end
    end

    # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
    # The use of this method should be restricted to complicated SQL queries that can't be executed
    # using the ActiveRecord::Calculations class methods. Look into those before using this.
    #
    # ==== Parameters
    #
    # * +sql+ - An SQL statement which should return a count query from the database, see the example below.
    #
    #   Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
    def count_by_sql(sql)
      logging_query_plan do
        sql = sanitize_conditions(sql)
        connection.select_value(sql, "#{name} Count").to_i
      end
    end
  end
end
require "active_record"
require "rails"
require "active_model/railtie"

# For now, action_controller must always be present with
# rails, so let's make sure that it gets required before
# here. This is needed for correctly setting up the middleware.
# In the future, this might become an optional require.
require "action_controller/railtie"

module ActiveRecord
  # = Active Record Railtie
  class Railtie < Rails::Railtie # :nodoc:
    config.active_record = ActiveSupport::OrderedOptions.new

    config.app_generators.orm :active_record, :migration => true,
                                              :timestamps => true

    config.app_middleware.insert_after "::ActionDispatch::Callbacks",
      "ActiveRecord::QueryCache"

    config.app_middleware.insert_after "::ActionDispatch::Callbacks",
      "ActiveRecord::ConnectionAdapters::ConnectionManagement"

    config.action_dispatch.rescue_responses.merge!(
      'ActiveRecord::RecordNotFound'   => :not_found,
      'ActiveRecord::StaleObjectError' => :conflict,
      'ActiveRecord::RecordInvalid'    => :unprocessable_entity,
      'ActiveRecord::RecordNotSaved'   => :unprocessable_entity
    )


    config.active_record.use_schema_cache_dump = true

    config.eager_load_namespaces << ActiveRecord

    rake_tasks do
      require "active_record/base"
      load "active_record/railties/databases.rake"
    end

    # When loading console, force ActiveRecord::Base to be loaded
    # to avoid cross references when loading a constant for the
    # first time. Also, make it output to STDERR.
    console do |app|
      require "active_record/railties/console_sandbox" if app.sandbox?
      require "active_record/base"
      console = ActiveSupport::Logger.new(STDERR)
      Rails.logger.extend ActiveSupport::Logger.broadcast console
    end

    runner do |app|
      require "active_record/base"
    end

    initializer "active_record.initialize_timezone" do
      ActiveSupport.on_load(:active_record) do
        self.time_zone_aware_attributes = true
        self.default_timezone = :utc
      end
    end

    initializer "active_record.logger" do
      ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
    end

    initializer "active_record.migration_error" do |app|
      if config.active_record.delete(:migration_error) == :page_load
        config.app_middleware.insert_after "::ActionDispatch::Callbacks",
          "ActiveRecord::Migration::CheckPending"
      end
    end

    initializer "active_record.check_schema_cache_dump" do
      if config.active_record.delete(:use_schema_cache_dump)
        config.after_initialize do |app|
          ActiveSupport.on_load(:active_record) do
            filename = File.join(app.config.paths["db"].first, "schema_cache.dump")

            if File.file?(filename)
              cache = Marshal.load File.binread filename
              if cache.version == ActiveRecord::Migrator.current_version
                self.connection.schema_cache = cache
              else
                warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
              end
            end
          end
        end
      end
    end

    initializer "active_record.set_configs" do |app|
      ActiveSupport.on_load(:active_record) do
        begin
          old_behavior, ActiveSupport::Deprecation.behavior = ActiveSupport::Deprecation.behavior, :stderr
          whitelist_attributes = app.config.active_record.delete(:whitelist_attributes)

          if respond_to?(:mass_assignment_sanitizer=)
            mass_assignment_sanitizer = nil
          else
            mass_assignment_sanitizer = app.config.active_record.delete(:mass_assignment_sanitizer)
          end

          unless whitelist_attributes.nil? && mass_assignment_sanitizer.nil?
            ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
              Model based mass assignment security has been extracted
              out of Rails into a gem. Please use the new recommended protection model for
              params or add `protected_attributes` to your Gemfile to use the old one.

              To disable this message remove the `whitelist_attributes` option from your
              `config/application.rb` file and any `mass_assignment_sanitizer` options
              from your `config/environments/*.rb` files.

              See http://guides.rubyonrails.org/security.html#mass-assignment for more information
            EOF
          end

          unless app.config.active_record.delete(:observers).nil?
            ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
              Active Record Observers has been extracted out of Rails into a gem.
              Please use callbacks or add `rails-observers` to your Gemfile to use observers.

              To disable this message remove the `observers` option from your
              `config/application.rb` or from your initializers.

              See http://guides.rubyonrails.org/4_0_release_notes.html for more information
            EOF
          end
        ensure
          ActiveSupport::Deprecation.behavior = old_behavior
        end

        app.config.active_record.each do |k,v|
          send "#{k}=", v
        end
      end
    end

    # This sets the database configuration from Configuration#database_configuration
    # and then establishes the connection.
    initializer "active_record.initialize_database" do |app|
      ActiveSupport.on_load(:active_record) do
        unless ENV['DATABASE_URL']
          self.configurations = app.config.database_configuration
        end
        establish_connection
      end
    end

    initializer "active_record.validate_explain_support" do |app|
      if app.config.active_record[:auto_explain_threshold_in_seconds] &&
        !ActiveRecord::Base.connection.supports_explain?
        warn "auto_explain_threshold_in_seconds is set but will be ignored because your adapter does not support this feature. Please unset the configuration to avoid this warning."
      end
    end

    # Expose database runtime to controller for logging.
    initializer "active_record.log_runtime" do |app|
      require "active_record/railties/controller_runtime"
      ActiveSupport.on_load(:action_controller) do
        include ActiveRecord::Railties::ControllerRuntime
      end
    end

    initializer "active_record.set_reloader_hooks" do |app|
      hook = app.config.reload_classes_only_on_change ? :to_prepare : :to_cleanup

      ActiveSupport.on_load(:active_record) do
        ActionDispatch::Reloader.send(hook) do
          if ActiveRecord::Base.connected?
            ActiveRecord::Base.clear_reloadable_connections!
            ActiveRecord::Base.clear_cache!
          end
        end
      end
    end

    initializer "active_record.add_watchable_files" do |app|
      path = app.paths["db"].first
      config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
    end
  end
end
ActiveRecord::Base.connection.begin_db_transaction
at_exit do
  ActiveRecord::Base.connection.rollback_db_transaction
end
require 'active_support/core_ext/module/attr_internal'
require 'active_record/log_subscriber'

module ActiveRecord
  module Railties # :nodoc:
    module ControllerRuntime #:nodoc:
      extend ActiveSupport::Concern

    protected

      attr_internal :db_runtime

      def process_action(action, *args)
        # We also need to reset the runtime before each action
        # because of queries in middleware or in cases we are streaming
        # and it won't be cleaned up by the method below.
        ActiveRecord::LogSubscriber.reset_runtime
        super
      end

      def cleanup_view_runtime
        if ActiveRecord::Base.connected?
          db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
          runtime = super
          db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
          self.db_runtime = db_rt_before_render + db_rt_after_render
          runtime - db_rt_after_render
        else
          super
        end
      end

      def append_info_to_payload(payload)
        super
        if ActiveRecord::Base.connected?
          payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
        end
      end

      module ClassMethods # :nodoc:
        def log_process_action(payload)
          messages, db_runtime = super, payload[:db_runtime]
          messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
          messages
        end
      end
    end
  end
end
#FIXME Remove if ArJdbcMysql will give.
module ArJdbcMySQL #:nodoc:
  class Error < StandardError #:nodoc:
    attr_accessor :error_number, :sql_state

    def initialize msg
      super
      @error_number = nil
      @sql_state    = nil
    end

    # Mysql gem compatibility
    alias_method :errno, :error_number
    alias_method :error, :message
  end
end

module ActiveRecord
  module ReadonlyAttributes
    extend ActiveSupport::Concern

    included do
      class_attribute :_attr_readonly, instance_accessor: false
      self._attr_readonly = []
    end

    module ClassMethods
      # Attributes listed as readonly will be used to create a new record but update operations will
      # ignore these fields.
      def attr_readonly(*attributes)
        self._attr_readonly = Set.new(attributes.map { |a| a.to_s }) + (self._attr_readonly || [])
      end

      # Returns an array of all the attributes that have been specified as readonly.
      def readonly_attributes
        self._attr_readonly
      end
    end

    def _attr_readonly
      message = "Instance level _attr_readonly method is deprecated, please use class level method."
      ActiveSupport::Deprecation.warn message
      defined?(@_attr_readonly) ? @_attr_readonly : self.class._attr_readonly
    end
  end
end
module ActiveRecord
  # = Active Record Reflection
  module Reflection # :nodoc:
    extend ActiveSupport::Concern

    included do
      class_attribute :reflections
      self.reflections = {}
    end

    # Reflection enables to interrogate Active Record classes and objects
    # about their associations and aggregations. This information can,
    # for example, be used in a form builder that takes an Active Record object
    # and creates input fields for all of the attributes depending on their type
    # and displays the associations to other objects.
    #
    # MacroReflection class has info for AggregateReflection and AssociationReflection
    # classes.
    module ClassMethods
      def create_reflection(macro, name, scope, options, active_record)
        case macro
        when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
          klass = options[:through] ? ThroughReflection : AssociationReflection
          reflection = klass.new(macro, name, scope, options, active_record)
        when :composed_of
          reflection = AggregateReflection.new(macro, name, scope, options, active_record)
        end

        self.reflections = self.reflections.merge(name => reflection)
        reflection
      end

      # Returns an array of AggregateReflection objects for all the aggregations in the class.
      def reflect_on_all_aggregations
        reflections.values.grep(AggregateReflection)
      end

      # Returns the AggregateReflection object for the named +aggregation+ (use the symbol).
      #
      #   Account.reflect_on_aggregation(:balance) # => the balance AggregateReflection
      #
      def reflect_on_aggregation(aggregation)
        reflection = reflections[aggregation]
        reflection if reflection.is_a?(AggregateReflection)
      end

      # Returns an array of AssociationReflection objects for all the
      # associations in the class. If you only want to reflect on a certain
      # association type, pass in the symbol (<tt>:has_many</tt>, <tt>:has_one</tt>,
      # <tt>:belongs_to</tt>) as the first parameter.
      #
      # Example:
      #
      #   Account.reflect_on_all_associations             # returns an array of all associations
      #   Account.reflect_on_all_associations(:has_many)  # returns an array of all has_many associations
      #
      def reflect_on_all_associations(macro = nil)
        association_reflections = reflections.values.grep(AssociationReflection)
        macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections
      end

      # Returns the AssociationReflection object for the +association+ (use the symbol).
      #
      #   Account.reflect_on_association(:owner)             # returns the owner AssociationReflection
      #   Invoice.reflect_on_association(:line_items).macro  # returns :has_many
      #
      def reflect_on_association(association)
        reflection = reflections[association]
        reflection if reflection.is_a?(AssociationReflection)
      end

      # Returns an array of AssociationReflection objects for all associations which have <tt>:autosave</tt> enabled.
      def reflect_on_all_autosave_associations
        reflections.values.select { |reflection| reflection.options[:autosave] }
      end
    end

    # Abstract base class for AggregateReflection and AssociationReflection. Objects of
    # AggregateReflection and AssociationReflection are returned by the Reflection::ClassMethods.
    class MacroReflection
      # Returns the name of the macro.
      #
      # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>:balance</tt>
      # <tt>has_many :clients</tt> returns <tt>:clients</tt>
      attr_reader :name

      # Returns the macro type.
      #
      # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>:composed_of</tt>
      # <tt>has_many :clients</tt> returns <tt>:has_many</tt>
      attr_reader :macro

      attr_reader :scope

      # Returns the hash of options used for the macro.
      #
      # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>{ class_name: "Money" }</tt>
      # <tt>has_many :clients</tt> returns +{}+
      attr_reader :options

      attr_reader :active_record

      attr_reader :plural_name # :nodoc:

      def initialize(macro, name, scope, options, active_record)
        @macro         = macro
        @name          = name
        @scope         = scope
        @options       = options
        @active_record = active_record
        @plural_name   = active_record.pluralize_table_names ?
                            name.to_s.pluralize : name.to_s
      end

      # Returns the class for the macro.
      #
      # <tt>composed_of :balance, class_name: 'Money'</tt> returns the Money class
      # <tt>has_many :clients</tt> returns the Client class
      def klass
        @klass ||= class_name.constantize
      end

      # Returns the class name for the macro.
      #
      # <tt>composed_of :balance, class_name: 'Money'</tt> returns <tt>'Money'</tt>
      # <tt>has_many :clients</tt> returns <tt>'Client'</tt>
      def class_name
        @class_name ||= (options[:class_name] || derive_class_name).to_s
      end

      # Returns +true+ if +self+ and +other_aggregation+ have the same +name+ attribute, +active_record+ attribute,
      # and +other_aggregation+ has an options hash assigned to it.
      def ==(other_aggregation)
        super ||
          other_aggregation.kind_of?(self.class) &&
          name == other_aggregation.name &&
          other_aggregation.options &&
          active_record == other_aggregation.active_record
      end

      private
        def derive_class_name
          name.to_s.camelize
        end
    end


    # Holds all the meta-data about an aggregation as it was specified in the
    # Active Record class.
    class AggregateReflection < MacroReflection #:nodoc:
      def mapping
        mapping = options[:mapping] || [name, name]
        mapping.first.is_a?(Array) ? mapping : [mapping]
      end
    end

    # Holds all the meta-data about an association as it was specified in the
    # Active Record class.
    class AssociationReflection < MacroReflection #:nodoc:
      # Returns the target association's class.
      #
      #   class Author < ActiveRecord::Base
      #     has_many :books
      #   end
      #
      #   Author.reflect_on_association(:books).klass
      #   # => Book
      #
      # <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
      # a new association object. Use +build_association+ or +create_association+
      # instead. This allows plugins to hook into association object creation.
      def klass
        @klass ||= active_record.send(:compute_type, class_name)
      end

      def initialize(*args)
        super
        @collection = [:has_many, :has_and_belongs_to_many].include?(macro)
      end

      # Returns a new, unsaved instance of the associated class. +attributes+ will
      # be passed to the class's constructor.
      def build_association(attributes, &block)
        klass.new(attributes, &block)
      end

      def table_name
        @table_name ||= klass.table_name
      end

      def quoted_table_name
        @quoted_table_name ||= klass.quoted_table_name
      end

      def join_table
        @join_table ||= options[:join_table] || derive_join_table
      end

      def foreign_key
        @foreign_key ||= options[:foreign_key] || derive_foreign_key
      end

      def foreign_type
        @foreign_type ||= options[:foreign_type] || "#{name}_type"
      end

      def type
        @type ||= options[:as] && "#{options[:as]}_type"
      end

      def primary_key_column
        @primary_key_column ||= klass.columns.find { |c| c.name == klass.primary_key }
      end

      def association_foreign_key
        @association_foreign_key ||= options[:association_foreign_key] || class_name.foreign_key
      end

      # klass option is necessary to support loading polymorphic associations
      def association_primary_key(klass = nil)
        options[:primary_key] || primary_key(klass || self.klass)
      end

      def active_record_primary_key
        @active_record_primary_key ||= options[:primary_key] || primary_key(active_record)
      end

      def counter_cache_column
        if options[:counter_cache] == true
          "#{active_record.name.demodulize.underscore.pluralize}_count"
        elsif options[:counter_cache]
          options[:counter_cache].to_s
        end
      end

      def columns(tbl_name)
        @columns ||= klass.connection.columns(tbl_name)
      end

      def reset_column_information
        @columns = nil
      end

      def check_validity!
        check_validity_of_inverse!

        if has_and_belongs_to_many? && association_foreign_key == foreign_key
          raise HasAndBelongsToManyAssociationForeignKeyNeeded.new(self)
        end
      end

      def check_validity_of_inverse!
        unless options[:polymorphic]
          if has_inverse? && inverse_of.nil?
            raise InverseOfAssociationNotFoundError.new(self)
          end
        end
      end

      def through_reflection
        nil
      end

      def source_reflection
        nil
      end

      # A chain of reflections from this one back to the owner. For more see the explanation in
      # ThroughReflection.
      def chain
        [self]
      end

      def nested?
        false
      end

      # An array of arrays of scopes. Each item in the outside array corresponds to a reflection
      # in the #chain.
      def scope_chain
        scope ? [[scope]] : [[]]
      end

      alias :source_macro :macro

      def has_inverse?
        @options[:inverse_of]
      end

      def inverse_of
        if has_inverse?
          @inverse_of ||= klass.reflect_on_association(options[:inverse_of])
        end
      end

      def polymorphic_inverse_of(associated_class)
        if has_inverse?
          if inverse_relationship = associated_class.reflect_on_association(options[:inverse_of])
            inverse_relationship
          else
            raise InverseOfAssociationNotFoundError.new(self, associated_class)
          end
        end
      end

      # Returns whether or not this association reflection is for a collection
      # association. Returns +true+ if the +macro+ is either +has_many+ or
      # +has_and_belongs_to_many+, +false+ otherwise.
      def collection?
        @collection
      end

      # Returns whether or not the association should be validated as part of
      # the parent's validation.
      #
      # Unless you explicitly disable validation with
      # <tt>validate: false</tt>, validation will take place when:
      #
      # * you explicitly enable validation; <tt>validate: true</tt>
      # * you use autosave; <tt>autosave: true</tt>
      # * the association is a +has_many+ association
      def validate?
        !options[:validate].nil? ? options[:validate] : (options[:autosave] == true || macro == :has_many)
      end

      # Returns +true+ if +self+ is a +belongs_to+ reflection.
      def belongs_to?
        macro == :belongs_to
      end

      def has_and_belongs_to_many?
        macro == :has_and_belongs_to_many
      end

      def association_class
        case macro
        when :belongs_to
          if options[:polymorphic]
            Associations::BelongsToPolymorphicAssociation
          else
            Associations::BelongsToAssociation
          end
        when :has_and_belongs_to_many
          Associations::HasAndBelongsToManyAssociation
        when :has_many
          if options[:through]
            Associations::HasManyThroughAssociation
          else
            Associations::HasManyAssociation
          end
        when :has_one
          if options[:through]
            Associations::HasOneThroughAssociation
          else
            Associations::HasOneAssociation
          end
        end
      end

      def polymorphic?
        options.key? :polymorphic
      end

      private
        def derive_class_name
          class_name = name.to_s.camelize
          class_name = class_name.singularize if collection?
          class_name
        end

        def derive_foreign_key
          if belongs_to?
            "#{name}_id"
          elsif options[:as]
            "#{options[:as]}_id"
          else
            active_record.name.foreign_key
          end
        end

        def derive_join_table
          [active_record.table_name, klass.table_name].sort.join("\0").gsub(/^(.*_)(.+)\0\1(.+)/, '\1\2_\3').gsub("\0", "_")
        end

        def primary_key(klass)
          klass.primary_key || raise(UnknownPrimaryKey.new(klass))
        end
    end

    # Holds all the meta-data about a :through association as it was specified
    # in the Active Record class.
    class ThroughReflection < AssociationReflection #:nodoc:
      delegate :foreign_key, :foreign_type, :association_foreign_key,
               :active_record_primary_key, :type, :to => :source_reflection

      # Gets the source of the through reflection. It checks both a singularized
      # and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
      #
      #   class Post < ActiveRecord::Base
      #     has_many :taggings
      #     has_many :tags, through: :taggings
      #   end
      #
      def source_reflection
        @source_reflection ||= source_reflection_names.collect { |name| through_reflection.klass.reflect_on_association(name) }.compact.first
      end

      # Returns the AssociationReflection object specified in the <tt>:through</tt> option
      # of a HasManyThrough or HasOneThrough association.
      #
      #   class Post < ActiveRecord::Base
      #     has_many :taggings
      #     has_many :tags, through: :taggings
      #   end
      #
      #   tags_reflection = Post.reflect_on_association(:tags)
      #   taggings_reflection = tags_reflection.through_reflection
      #
      def through_reflection
        @through_reflection ||= active_record.reflect_on_association(options[:through])
      end

      # Returns an array of reflections which are involved in this association. Each item in the
      # array corresponds to a table which will be part of the query for this association.
      #
      # The chain is built by recursively calling #chain on the source reflection and the through
      # reflection. The base case for the recursion is a normal association, which just returns
      # [self] as its #chain.
      def chain
        @chain ||= begin
          chain = source_reflection.chain + through_reflection.chain
          chain[0] = self # Use self so we don't lose the information from :source_type
          chain
        end
      end

      # Consider the following example:
      #
      #   class Person
      #     has_many :articles
      #     has_many :comment_tags, through: :articles
      #   end
      #
      #   class Article
      #     has_many :comments
      #     has_many :comment_tags, through: :comments, source: :tags
      #   end
      #
      #   class Comment
      #     has_many :tags
      #   end
      #
      # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags,
      # but only Comment.tags will be represented in the #chain. So this method creates an array
      # of scopes corresponding to the chain.
      def scope_chain
        @scope_chain ||= begin
          scope_chain = source_reflection.scope_chain.map(&:dup)

          # Add to it the scope from this reflection (if any)
          scope_chain.first << scope if scope

          through_scope_chain = through_reflection.scope_chain

          if options[:source_type]
            through_scope_chain.first <<
              through_reflection.klass.where(foreign_type => options[:source_type])
          end

          # Recursively fill out the rest of the array from the through reflection
          scope_chain + through_scope_chain
        end
      end

      # The macro used by the source association
      def source_macro
        source_reflection.source_macro
      end

      # A through association is nested if there would be more than one join table
      def nested?
        chain.length > 2 || through_reflection.macro == :has_and_belongs_to_many
      end

      # We want to use the klass from this reflection, rather than just delegate straight to
      # the source_reflection, because the source_reflection may be polymorphic. We still
      # need to respect the source_reflection's :primary_key option, though.
      def association_primary_key(klass = nil)
        # Get the "actual" source reflection if the immediate source reflection has a
        # source reflection itself
        source_reflection = self.source_reflection
        while source_reflection.source_reflection
          source_reflection = source_reflection.source_reflection
        end

        source_reflection.options[:primary_key] || primary_key(klass || self.klass)
      end

      # Gets an array of possible <tt>:through</tt> source reflection names:
      #
      #   [:singularized, :pluralized]
      #
      def source_reflection_names
        @source_reflection_names ||= (options[:source] ? [options[:source]] : [name.to_s.singularize, name]).collect { |n| n.to_sym }
      end

      def source_options
        source_reflection.options
      end

      def through_options
        through_reflection.options
      end

      def check_validity!
        if through_reflection.nil?
          raise HasManyThroughAssociationNotFoundError.new(active_record.name, self)
        end

        if through_reflection.options[:polymorphic]
          raise HasManyThroughAssociationPolymorphicThroughError.new(active_record.name, self)
        end

        if source_reflection.nil?
          raise HasManyThroughSourceAssociationNotFoundError.new(self)
        end

        if options[:source_type] && source_reflection.options[:polymorphic].nil?
          raise HasManyThroughAssociationPointlessSourceTypeError.new(active_record.name, self, source_reflection)
        end

        if source_reflection.options[:polymorphic] && options[:source_type].nil?
          raise HasManyThroughAssociationPolymorphicSourceError.new(active_record.name, self, source_reflection)
        end

        if macro == :has_one && through_reflection.collection?
          raise HasOneThroughCantAssociateThroughCollection.new(active_record.name, self, through_reflection)
        end

        check_validity_of_inverse!
      end

      private
        def derive_class_name
          # get the class_name of the belongs_to association of the through reflection
          options[:source_type] || source_reflection.class_name
        end
    end
  end
end

module ActiveRecord
  module Batches
    # Looping through a collection of records from the database
    # (using the +all+ method, for example) is very inefficient
    # since it will try to instantiate all the objects at once.
    #
    # In that case, batch processing methods allow you to work
    # with the records in batches, thereby greatly reducing memory consumption.
    #
    # The #find_each method uses #find_in_batches with a batch size of 1000 (or as
    # specified by the +:batch_size+ option).
    #
    #   Person.all.find_each do |person|
    #     person.do_awesome_stuff
    #   end
    #
    #   Person.where("age > 21").find_each do |person|
    #     person.party_all_night!
    #   end
    #
    #  You can also pass the +:start+ option to specify
    #  an offset to control the starting point.
    def find_each(options = {})
      find_in_batches(options) do |records|
        records.each { |record| yield record }
      end
    end

    # Yields each batch of records that was found by the find +options+ as
    # an array. The size of each batch is set by the +:batch_size+
    # option; the default is 1000.
    #
    # You can control the starting point for the batch processing by
    # supplying the +:start+ option. This is especially useful if you
    # want multiple workers dealing with the same processing queue. You can
    # make worker 1 handle all the records between id 0 and 10,000 and
    # worker 2 handle from 10,000 and beyond (by setting the +:start+
    # option on that worker).
    #
    # It's not possible to set the order. That is automatically set to
    # ascending on the primary key ("id ASC") to make the batch ordering
    # work. This also means that this method only works with integer-based
    # primary keys. You can't set the limit either, that's used to control
    # the batch sizes.
    #
    #   Person.where("age > 21").find_in_batches do |group|
    #     sleep(50) # Make sure it doesn't get too crowded in there!
    #     group.each { |person| person.party_all_night! }
    #   end
    #
    #   # Let's process the next 2000 records
    #   Person.all.find_in_batches(start: 2000, batch_size: 2000) do |group|
    #     group.each { |person| person.party_all_night! }
    #   end
    def find_in_batches(options = {})
      options.assert_valid_keys(:start, :batch_size)

      relation = self

      unless arel.orders.blank? && arel.taken.blank?
        ActiveRecord::Base.logger.warn("Scoped order and limit are ignored, it's forced to be batch order and batch size")
      end

      start = options.delete(:start)
      batch_size = options.delete(:batch_size) || 1000

      relation = relation.reorder(batch_order).limit(batch_size)
      records = start ? relation.where(table[primary_key].gteq(start)).to_a : relation.to_a

      while records.any?
        records_size = records.size
        primary_key_offset = records.last.id

        yield records

        break if records_size < batch_size

        if primary_key_offset
          records = relation.where(table[primary_key].gt(primary_key_offset)).to_a
        else
          raise "Primary key not included in the custom select clause"
        end
      end
    end

    private

    def batch_order
      "#{quoted_table_name}.#{quoted_primary_key} ASC"
    end
  end
end
module ActiveRecord
  module Calculations
    # Count the records.
    #
    #   Person.count
    #   # => the total count of all people
    #
    #   Person.count(:age)
    #   # => returns the total count of all people whose age is present in database
    #
    #   Person.count(:all)
    #   # => performs a COUNT(*) (:all is an alias for '*')
    #
    #   Person.count(:age, distinct: true)
    #   # => counts the number of different age values
    #
    # If +count+ is used with +group+, it returns a Hash whose keys represent the aggregated column,
    # and the values are the respective amounts:
    #
    #   Person.group(:city).count
    #   # => { 'Rome' => 5, 'Paris' => 3 }
    def count(column_name = nil, options = {})
      column_name, options = nil, column_name if column_name.is_a?(Hash)
      calculate(:count, column_name, options)
    end

    # Calculates the average value on a given column. Returns +nil+ if there's
    # no row. See +calculate+ for examples with options.
    #
    #   Person.average('age') # => 35.8
    def average(column_name, options = {})
      calculate(:average, column_name, options)
    end

    # Calculates the minimum value on a given column. The value is returned
    # with the same data type of the column, or +nil+ if there's no row. See
    # +calculate+ for examples with options.
    #
    #   Person.minimum('age') # => 7
    def minimum(column_name, options = {})
      calculate(:minimum, column_name, options)
    end

    # Calculates the maximum value on a given column. The value is returned
    # with the same data type of the column, or +nil+ if there's no row. See
    # +calculate+ for examples with options.
    #
    #   Person.maximum('age') # => 93
    def maximum(column_name, options = {})
      calculate(:maximum, column_name, options)
    end

    # Calculates the sum of values on a given column. The value is returned
    # with the same data type of the column, 0 if there's no row. See
    # +calculate+ for examples with options.
    #
    #   Person.sum('age') # => 4562
    def sum(*args)
      if block_given?
        ActiveSupport::Deprecation.warn(
          "Calling #sum with a block is deprecated and will be removed in Rails 4.1. " \
          "If you want to perform sum calculation over the array of elements, use `to_a.sum(&block)`."
        )
        self.to_a.sum(*args) {|*block_args| yield(*block_args)}
      else
        calculate(:sum, *args)
      end
    end

    # This calculates aggregate values in the given column. Methods for count, sum, average,
    # minimum, and maximum have been added as shortcuts.
    #
    # There are two basic forms of output:
    #
    #   * Single aggregate value: The single value is type cast to Fixnum for COUNT, Float
    #     for AVG, and the given column's type for everything else.
    #
    #   * Grouped values: This returns an ordered hash of the values and groups them. It
    #     takes either a column name, or the name of a belongs_to association.
    #
    #       values = Person.group('last_name').maximum(:age)
    #       puts values["Drake"]
    #       # => 43
    #
    #       drake  = Family.find_by_last_name('Drake')
    #       values = Person.group(:family).maximum(:age) # Person belongs_to :family
    #       puts values[drake]
    #       # => 43
    #
    #       values.each do |family, max_age|
    #       ...
    #       end
    #
    #   Person.calculate(:count, :all) # The same as Person.count
    #   Person.average(:age) # SELECT AVG(age) FROM people...
    #
    #   # Selects the minimum age for any family without any minors
    #   Person.group(:last_name).having("min(age) > 17").minimum(:age)
    #
    #   Person.sum("2 * age")
    def calculate(operation, column_name, options = {})
      relation = with_default_scope

      if relation.equal?(self)
        if has_include?(column_name)
          construct_relation_for_association_calculations.calculate(operation, column_name, options)
        else
          perform_calculation(operation, column_name, options)
        end
      else
        relation.calculate(operation, column_name, options)
      end
    rescue ThrowResult
      0
    end

    # Use <tt>pluck</tt> as a shortcut to select one or more attributes without
    # loading a bunch of records just to grab the attributes you want.
    #
    #   Person.pluck(:name)
    #
    # instead of
    #
    #   Person.all.map(&:name)
    #
    # Pluck returns an <tt>Array</tt> of attribute values type-casted to match
    # the plucked column names, if they can be deduced. Plucking an SQL fragment
    # returns String values by default.
    #
    #   Person.pluck(:id)
    #   # SELECT people.id FROM people
    #   # => [1, 2, 3]
    #
    #   Person.pluck(:id, :name)
    #   # SELECT people.id, people.name FROM people
    #   # => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]
    #
    #   Person.uniq.pluck(:role)
    #   # SELECT DISTINCT role FROM people
    #   # => ['admin', 'member', 'guest']
    #
    #   Person.where(age: 21).limit(5).pluck(:id)
    #   # SELECT people.id FROM people WHERE people.age = 21 LIMIT 5
    #   # => [2, 3]
    #
    #   Person.pluck('DATEDIFF(updated_at, created_at)')
    #   # SELECT DATEDIFF(updated_at, created_at) FROM people
    #   # => ['0', '27761', '173']
    #
    def pluck(*column_names)
      column_names.map! do |column_name|
        if column_name.is_a?(Symbol) && self.column_names.include?(column_name.to_s)
          "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
        else
          column_name
        end
      end

      if has_include?(column_names.first)
        construct_relation_for_association_calculations.pluck(*column_names)
      else
        relation = spawn
        relation.select_values = column_names
        result = klass.connection.select_all(relation.arel, nil, bind_values)
        columns = result.columns.map do |key|
          klass.column_types.fetch(key) {
            result.column_types.fetch(key) {
              Class.new { def type_cast(v); v; end }.new
            }
          }
        end

        result = result.map do |attributes|
          values = klass.initialize_attributes(attributes).values

          columns.zip(values).map do |column, value|
            column.type_cast(value)
          end
        end
        columns.one? ? result.map!(&:first) : result
      end
    end

    # Pluck all the ID's for the relation using the table's primary key
    #
    #   Person.ids # SELECT people.id FROM people
    #   Person.joins(:companies).ids # SELECT people.id FROM people INNER JOIN companies ON companies.person_id = people.id
    def ids
      pluck primary_key
    end

    private

    def has_include?(column_name)
      eager_loading? || (includes_values.present? && (column_name || references_eager_loaded_tables?))
    end

    def perform_calculation(operation, column_name, options = {})
      operation = operation.to_s.downcase

      # If #count is used in conjuction with #uniq it is considered distinct. (eg. relation.uniq.count)
      distinct = options[:distinct] || self.uniq_value

      if operation == "count"
        column_name ||= (select_for_count || :all)

        unless arel.ast.grep(Arel::Nodes::OuterJoin).empty?
          distinct = true
        end

        column_name = primary_key if column_name == :all && distinct

        distinct = nil if column_name =~ /\s*DISTINCT\s+/i
      end

      if group_values.any?
        execute_grouped_calculation(operation, column_name, distinct)
      else
        execute_simple_calculation(operation, column_name, distinct)
      end
    end

    def aggregate_column(column_name)
      if @klass.column_names.include?(column_name.to_s)
        Arel::Attribute.new(@klass.unscoped.table, column_name)
      else
        Arel.sql(column_name == :all ? "*" : column_name.to_s)
      end
    end

    def operation_over_aggregate_column(column, operation, distinct)
      operation == 'count' ? column.count(distinct) : column.send(operation)
    end

    def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
      # Postgresql doesn't like ORDER BY when there are no GROUP BY
      relation = reorder(nil)

      column_alias = column_name

      if operation == "count" && (relation.limit_value || relation.offset_value)
        # Shortcut when limit is zero.
        return 0 if relation.limit_value == 0

        query_builder = build_count_subquery(relation, column_name, distinct)
      else
        column = aggregate_column(column_name)

        select_value = operation_over_aggregate_column(column, operation, distinct)

        column_alias = select_value.alias
        relation.select_values = [select_value]

        query_builder = relation.arel
      end

      result = @klass.connection.select_all(query_builder, nil, relation.bind_values)
      row    = result.first
      value  = row && row.values.first
      column = result.column_types.fetch(column_alias) do
        column_for(column_name)
      end

      type_cast_calculated_value(value, column, operation)
    end

    def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
      group_attrs = group_values

      if group_attrs.first.respond_to?(:to_sym)
        association  = @klass.reflect_on_association(group_attrs.first.to_sym)
        associated   = group_attrs.size == 1 && association && association.macro == :belongs_to # only count belongs_to associations
        group_fields = Array(associated ? association.foreign_key : group_attrs)
      else
        group_fields = group_attrs
      end

      group_aliases = group_fields.map { |field|
        column_alias_for(field)
      }
      group_columns = group_aliases.zip(group_fields).map { |aliaz,field|
        [aliaz, field]
      }

      group = group_fields

      if operation == 'count' && column_name == :all
        aggregate_alias = 'count_all'
      else
        aggregate_alias = column_alias_for([operation, column_name].join(' '))
      end

      select_values = [
        operation_over_aggregate_column(
          aggregate_column(column_name),
          operation,
          distinct).as(aggregate_alias)
      ]
      select_values += select_values unless having_values.empty?

      select_values.concat group_fields.zip(group_aliases).map { |field,aliaz|
        if field.respond_to?(:as)
          field.as(aliaz)
        else
          "#{field} AS #{aliaz}"
        end
      }

      relation = except(:group)
      relation.group_values  = group
      relation.select_values = select_values

      calculated_data = @klass.connection.select_all(relation, nil, bind_values)

      if association
        key_ids     = calculated_data.collect { |row| row[group_aliases.first] }
        key_records = association.klass.base_class.find(key_ids)
        key_records = Hash[key_records.map { |r| [r.id, r] }]
      end

      Hash[calculated_data.map do |row|
        key = group_columns.map { |aliaz, col_name|
          column = calculated_data.column_types.fetch(aliaz) do
            column_for(col_name)
          end
          type_cast_calculated_value(row[aliaz], column)
        }
        key = key.first if key.size == 1
        key = key_records[key] if associated
        [key, type_cast_calculated_value(row[aggregate_alias], column_for(column_name), operation)]
      end]
    end

    # Converts the given keys to the value that the database adapter returns as
    # a usable column name:
    #
    #   column_alias_for("users.id")                 # => "users_id"
    #   column_alias_for("sum(id)")                  # => "sum_id"
    #   column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
    #   column_alias_for("count(*)")                 # => "count_all"
    #   column_alias_for("count", "id")              # => "count_id"
    def column_alias_for(keys)
      if keys.respond_to? :name
        keys = "#{keys.relation.name}.#{keys.name}"
      end

      table_name = keys.to_s.downcase
      table_name.gsub!(/\*/, 'all')
      table_name.gsub!(/\W+/, ' ')
      table_name.strip!
      table_name.gsub!(/ +/, '_')

      @klass.connection.table_alias_for(table_name)
    end

    def column_for(field)
      field_name = field.respond_to?(:name) ? field.name.to_s : field.to_s.split('.').last
      @klass.columns_hash[field_name]
    end

    def type_cast_calculated_value(value, column, operation = nil)
      case operation
        when 'count'   then value.to_i
        when 'sum'     then type_cast_using_column(value || 0, column)
        when 'average' then value.respond_to?(:to_d) ? value.to_d : value
        else type_cast_using_column(value, column)
      end
    end

    def type_cast_using_column(value, column)
      column ? column.type_cast(value) : value
    end

    def select_for_count
      if select_values.present?
        select = select_values.join(", ")
        select if select !~ /[,*]/
      end
    end

    def build_count_subquery(relation, column_name, distinct)
      column_alias = Arel.sql('count_column')
      subquery_alias = Arel.sql('subquery_for_count')

      aliased_column = aggregate_column(column_name == :all ? 1 : column_name).as(column_alias)
      relation.select_values = [aliased_column]
      subquery = relation.arel.as(subquery_alias)

      sm = Arel::SelectManager.new relation.engine
      select_value = operation_over_aggregate_column(column_alias, 'count', distinct)
      sm.project(select_value).from(subquery)
    end
  end
end
require 'thread'
require 'thread_safe'

module ActiveRecord
  module Delegation # :nodoc:
    extend ActiveSupport::Concern

    # This module creates compiled delegation methods dynamically at runtime, which makes
    # subsequent calls to that method faster by avoiding method_missing. The delegations
    # may vary depending on the klass of a relation, so we create a subclass of Relation
    # for each different klass, and the delegations are compiled into that subclass only.

    delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :to => :to_a
    delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
             :connection, :columns_hash, :auto_explain_threshold_in_seconds, :to => :klass

    module ClassSpecificRelation
      extend ActiveSupport::Concern

      included do
        @delegation_mutex = Mutex.new
      end

      module ClassMethods
        def name
          superclass.name
        end

        def delegate_to_scoped_klass(method)
          @delegation_mutex.synchronize do
            return if method_defined?(method)

            if method.to_s =~ /\A[a-zA-Z_]\w*[!?]?\z/
              module_eval <<-RUBY, __FILE__, __LINE__ + 1
                def #{method}(*args, &block)
                  scoping { @klass.#{method}(*args, &block) }
                end
              RUBY
            else
              module_eval <<-RUBY, __FILE__, __LINE__ + 1
                def #{method}(*args, &block)
                  scoping { @klass.send(#{method.inspect}, *args, &block) }
                end
              RUBY
            end
          end
        end

        def delegate(method, opts = {})
          @delegation_mutex.synchronize do
            return if method_defined?(method)
            super
          end
        end
      end

      protected

      def method_missing(method, *args, &block)
        if @klass.respond_to?(method)
          self.class.delegate_to_scoped_klass(method)
          scoping { @klass.send(method, *args, &block) }
        elsif Array.method_defined?(method)
          self.class.delegate method, :to => :to_a
          to_a.send(method, *args, &block)
        elsif arel.respond_to?(method)
          self.class.delegate method, :to => :arel
          arel.send(method, *args, &block)
        else
          super
        end
      end
    end

    module ClassMethods
      @@subclasses = ThreadSafe::Cache.new(:initial_capacity => 2)

      def new(klass, *args)
        relation = relation_class_for(klass).allocate
        relation.__send__(:initialize, klass, *args)
        relation
      end

      # This doesn't have to be thread-safe. relation_class_for guarantees that this will only be
      # called exactly once for a given const name.
      def const_missing(name)
        const_set(name, Class.new(self) { include ClassSpecificRelation })
      end

      private
      # Cache the constants in @@subclasses because looking them up via const_get
      # make instantiation significantly slower.
      def relation_class_for(klass)
        if klass && (klass_name = klass.name)
          my_cache = @@subclasses.compute_if_absent(self) { ThreadSafe::Cache.new }
          # This hash is keyed by klass.name to avoid memory leaks in development mode
          my_cache.compute_if_absent(klass_name) do
            # Cache#compute_if_absent guarantees that the block will only executed once for the given klass_name
            const_get("#{name.gsub('::', '_')}_#{klass_name.gsub('::', '_')}", false)
          end
        else
          ActiveRecord::Relation
        end
      end
    end

    def respond_to?(method, include_private = false)
      super || Array.method_defined?(method) ||
        @klass.respond_to?(method, include_private) ||
        arel.respond_to?(method, include_private)
    end

    protected

    def method_missing(method, *args, &block)
      if @klass.respond_to?(method)
        scoping { @klass.send(method, *args, &block) }
      elsif Array.method_defined?(method)
        to_a.send(method, *args, &block)
      elsif arel.respond_to?(method)
        arel.send(method, *args, &block)
      else
        super
      end
    end
  end
end
module ActiveRecord
  module FinderMethods
    # Find by id - This can either be a specific id (1), a list of ids (1, 5, 6), or an array of ids ([5, 6, 10]).
    # If no record can be found for all of the listed ids, then RecordNotFound will be raised. If the primary key
    # is an integer, find by id coerces its arguments using +to_i+.
    #
    #   Person.find(1)       # returns the object for ID = 1
    #   Person.find("1")     # returns the object for ID = 1
    #   Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
    #   Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
    #   Person.find([1])     # returns an array for the object with ID = 1
    #   Person.where("administrator = 1").order("created_on DESC").find(1)
    #
    # Note that returned records may not be in the same order as the ids you
    # provide since database rows are unordered. Give an explicit <tt>order</tt>
    # to ensure the results are sorted.
    #
    # ==== Find with lock
    #
    # Example for find with a lock: Imagine two concurrent transactions:
    # each will read <tt>person.visits == 2</tt>, add 1 to it, and save, resulting
    # in two saves of <tt>person.visits = 3</tt>. By locking the row, the second
    # transaction has to wait until the first is finished; we get the
    # expected <tt>person.visits == 4</tt>.
    #
    #   Person.transaction do
    #     person = Person.lock(true).find(1)
    #     person.visits += 1
    #     person.save!
    #   end
    def find(*args)
      if block_given?
        to_a.find { |*block_args| yield(*block_args) }
      else
        find_with_ids(*args)
      end
    end

    # Finds the first record matching the specified conditions. There
    # is no implied ording so if order matters, you should specify it
    # yourself.
    #
    # If no record is found, returns <tt>nil</tt>.
    #
    #   Post.find_by name: 'Spartacus', rating: 4
    #   Post.find_by "published_at < ?", 2.weeks.ago
    def find_by(*args)
      where(*args).take
    end

    # Like <tt>find_by</tt>, except that if no record is found, raises
    # an <tt>ActiveRecord::RecordNotFound</tt> error.
    def find_by!(*args)
      where(*args).take!
    end

    # Gives a record (or N records if a parameter is supplied) without any implied
    # order. The order will depend on the database implementation.
    # If an order is supplied it will be respected.
    #
    #   Person.take # returns an object fetched by SELECT * FROM people
    #   Person.take(5) # returns 5 objects fetched by SELECT * FROM people LIMIT 5
    #   Person.where(["name LIKE '%?'", name]).take
    def take(limit = nil)
      limit ? limit(limit).to_a : find_take
    end

    # Same as +take+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
    # is found. Note that <tt>take!</tt> accepts no arguments.
    def take!
      take or raise RecordNotFound
    end

    # Find the first record (or first N records if a parameter is supplied).
    # If no order is defined it will order by primary key.
    #
    #   Person.first # returns the first object fetched by SELECT * FROM people
    #   Person.where(["user_name = ?", user_name]).first
    #   Person.where(["user_name = :u", { u: user_name }]).first
    #   Person.order("created_on DESC").offset(5).first
    #   Person.first(3) # returns the first three objects fetched by SELECT * FROM people LIMIT 3
    def first(limit = nil)
      if limit
        if order_values.empty? && primary_key
          order(arel_table[primary_key].asc).limit(limit).to_a
        else
          limit(limit).to_a
        end
      else
        find_first
      end
    end

    # Same as +first+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
    # is found. Note that <tt>first!</tt> accepts no arguments.
    def first!
      first or raise RecordNotFound
    end

    # Find the last record (or last N records if a parameter is supplied).
    # If no order is defined it will order by primary key.
    #
    #   Person.last # returns the last object fetched by SELECT * FROM people
    #   Person.where(["user_name = ?", user_name]).last
    #   Person.order("created_on DESC").offset(5).last
    #   Person.last(3) # returns the last three objects fetched by SELECT * FROM people.
    #
    # Take note that in that last case, the results are sorted in ascending order:
    #
    #   [#<Person id:2>, #<Person id:3>, #<Person id:4>]
    #
    # and not:
    #
    #   [#<Person id:4>, #<Person id:3>, #<Person id:2>]
    def last(limit = nil)
      if limit
        if order_values.empty? && primary_key
          order(arel_table[primary_key].desc).limit(limit).reverse
        else
          to_a.last(limit)
        end
      else
        find_last
      end
    end

    # Same as +last+ but raises <tt>ActiveRecord::RecordNotFound</tt> if no record
    # is found. Note that <tt>last!</tt> accepts no arguments.
    def last!
      last or raise RecordNotFound
    end

    # Returns +true+ if a record exists in the table that matches the +id+ or
    # conditions given, or +false+ otherwise. The argument can take six forms:
    #
    # * Integer - Finds the record with this primary key.
    # * String - Finds the record with a primary key corresponding to this
    #   string (such as <tt>'5'</tt>).
    # * Array - Finds the record that matches these +find+-style conditions
    #   (such as <tt>['color = ?', 'red']</tt>).
    # * Hash - Finds the record that matches these +find+-style conditions
    #   (such as <tt>{color: 'red'}</tt>).
    # * +false+ - Returns always +false+.
    # * No args - Returns +false+ if the table is empty, +true+ otherwise.
    #
    # For more information about specifying conditions as a Hash or Array,
    # see the Conditions section in the introduction to ActiveRecord::Base.
    #
    # Note: You can't pass in a condition as a string (like <tt>name =
    # 'Jamie'</tt>), since it would be sanitized and then queried against
    # the primary key column, like <tt>id = 'name = \'Jamie\''</tt>.
    #
    #   Person.exists?(5)
    #   Person.exists?('5')
    #   Person.exists?(['name LIKE ?', "%#{query}%"])
    #   Person.exists?(name: 'David')
    #   Person.exists?(false)
    #   Person.exists?
    def exists?(conditions = :none)
      conditions = conditions.id if Base === conditions
      return false if !conditions

      join_dependency = construct_join_dependency_for_association_find
      relation = construct_relation_for_association_find(join_dependency)
      relation = relation.except(:select, :order).select("1 AS one").limit(1)

      case conditions
      when Array, Hash
        relation = relation.where(conditions)
      else
        relation = relation.where(table[primary_key].eq(conditions)) if conditions != :none
      end

      connection.select_value(relation, "#{name} Exists", relation.bind_values)
    rescue ThrowResult
      false
    end

    protected

    def find_with_associations
      join_dependency = construct_join_dependency_for_association_find
      relation = construct_relation_for_association_find(join_dependency)
      rows = connection.select_all(relation, 'SQL', relation.bind_values.dup)
      join_dependency.instantiate(rows)
    rescue ThrowResult
      []
    end

    def construct_join_dependency_for_association_find
      including = (eager_load_values + includes_values).uniq
      ActiveRecord::Associations::JoinDependency.new(@klass, including, [])
    end

    def construct_relation_for_association_calculations
      including = (eager_load_values + includes_values).uniq
      join_dependency = ActiveRecord::Associations::JoinDependency.new(@klass, including, arel.froms.first)
      relation = except(:includes, :eager_load, :preload)
      apply_join_dependency(relation, join_dependency)
    end

    def construct_relation_for_association_find(join_dependency)
      relation = except(:includes, :eager_load, :preload, :select).select(join_dependency.columns)
      apply_join_dependency(relation, join_dependency)
    end

    def apply_join_dependency(relation, join_dependency)
      join_dependency.join_associations.each do |association|
        relation = association.join_relation(relation)
      end

      limitable_reflections = using_limitable_reflections?(join_dependency.reflections)

      if !limitable_reflections && relation.limit_value
        limited_id_condition = construct_limited_ids_condition(relation.except(:select))
        relation = relation.where(limited_id_condition)
      end

      relation = relation.except(:limit, :offset) unless limitable_reflections

      relation
    end

    def construct_limited_ids_condition(relation)
      orders = relation.order_values.map { |val| val.presence }.compact
      values = @klass.connection.distinct("#{quoted_table_name}.#{primary_key}", orders)

      relation = relation.dup.select(values)

      id_rows = @klass.connection.select_all(relation.arel, 'SQL', relation.bind_values)
      ids_array = id_rows.map {|row| row[primary_key]}

      ids_array.empty? ? raise(ThrowResult) : table[primary_key].in(ids_array)
    end

    def find_with_ids(*ids)
      expects_array = ids.first.kind_of?(Array)
      return ids.first if expects_array && ids.first.empty?

      ids = ids.flatten.compact.uniq

      case ids.size
      when 0
        raise RecordNotFound, "Couldn't find #{@klass.name} without an ID"
      when 1
        result = find_one(ids.first)
        expects_array ? [ result ] : result
      else
        find_some(ids)
      end
    end

    def find_one(id)
      id = id.id if ActiveRecord::Base === id

      column = columns_hash[primary_key]
      substitute = connection.substitute_at(column, bind_values.length)
      relation = where(table[primary_key].eq(substitute))
      relation.bind_values += [[column, id]]
      record = relation.take

      unless record
        conditions = arel.where_sql
        conditions = " [#{conditions}]" if conditions
        raise RecordNotFound, "Couldn't find #{@klass.name} with #{primary_key}=#{id}#{conditions}"
      end

      record
    end

    def find_some(ids)
      result = where(table[primary_key].in(ids)).to_a

      expected_size =
        if limit_value && ids.size > limit_value
          limit_value
        else
          ids.size
        end

      # 11 ids with limit 3, offset 9 should give 2 results.
      if offset_value && (ids.size - offset_value < expected_size)
        expected_size = ids.size - offset_value
      end

      if result.size == expected_size
        result
      else
        conditions = arel.where_sql
        conditions = " [#{conditions}]" if conditions

        error = "Couldn't find all #{@klass.name.pluralize} with IDs "
        error << "(#{ids.join(", ")})#{conditions} (found #{result.size} results, but was looking for #{expected_size})"
        raise RecordNotFound, error
      end
    end

    def find_take
      if loaded?
        @records.first
      else
        @take ||= limit(1).to_a.first
      end
    end

    def find_first
      if loaded?
        @records.first
      else
        @first ||=
          if with_default_scope.order_values.empty? && primary_key
            order(arel_table[primary_key].asc).limit(1).to_a.first
          else
            limit(1).to_a.first
          end
      end
    end

    def find_last
      if loaded?
        @records.last
      else
        @last ||=
          if offset_value || limit_value
            to_a.last
          else
            reverse_order.limit(1).to_a.first
          end
      end
    end

    def using_limitable_reflections?(reflections)
      reflections.none? { |r| r.collection? }
    end
  end
end
require 'active_support/core_ext/hash/keys'
require "set"

module ActiveRecord
  class Relation
    class HashMerger # :nodoc:
      attr_reader :relation, :hash

      def initialize(relation, hash)
        hash.assert_valid_keys(*Relation::VALUE_METHODS)

        @relation = relation
        @hash     = hash
      end

      def merge
        Merger.new(relation, other).merge
      end

      # Applying values to a relation has some side effects. E.g.
      # interpolation might take place for where values. So we should
      # build a relation to merge in rather than directly merging
      # the values.
      def other
        other = Relation.new(relation.klass, relation.table)
        hash.each { |k, v|
          if k == :joins
            if Hash === v
              other.joins!(v)
            else
              other.joins!(*v)
            end
          else
            other.send("#{k}!", v)
          end
        }
        other
      end
    end

    class Merger # :nodoc:
      attr_reader :relation, :values

      def initialize(relation, other)
        if other.default_scoped? && other.klass != relation.klass
          other = other.with_default_scope
        end

        @relation = relation
        @values   = other.values
      end

      NORMAL_VALUES = Relation::SINGLE_VALUE_METHODS +
                      Relation::MULTI_VALUE_METHODS -
                      [:where, :order, :bind, :reverse_order, :lock, :create_with, :reordering, :from] # :nodoc:

      def normal_values
        NORMAL_VALUES
      end

      def merge
        normal_values.each do |name|
          value = values[name]
          relation.send("#{name}!", *value) unless value.blank?
        end

        merge_multi_values
        merge_single_values

        relation
      end

      private

      def merge_multi_values
        relation.where_values = merged_wheres
        relation.bind_values  = merged_binds

        if values[:reordering]
          # override any order specified in the original relation
          relation.reorder! values[:order]
        elsif values[:order]
          # merge in order_values from r
          relation.order! values[:order]
        end

        relation.extend(*values[:extending]) unless values[:extending].blank?
      end

      def merge_single_values
        relation.from_value          = values[:from] unless relation.from_value
        relation.lock_value          = values[:lock] unless relation.lock_value
        relation.reverse_order_value = values[:reverse_order]

        unless values[:create_with].blank?
          relation.create_with_value = (relation.create_with_value || {}).merge(values[:create_with])
        end
      end

      def merged_binds
        if values[:bind]
          (relation.bind_values + values[:bind]).uniq(&:first)
        else
          relation.bind_values
        end
      end

      def merged_wheres
        values[:where] ||= []

        if values[:where].empty? || relation.where_values.empty?
          relation.where_values + values[:where]
        else
          # Remove equalities from the existing relation with a LHS which is
          # present in the relation being merged in.

          seen = Set.new
          values[:where].each { |w|
            if w.respond_to?(:operator) && w.operator == :==
              seen << w.left
            end
          }

          relation.where_values.reject { |w|
            w.respond_to?(:operator) &&
              w.operator == :== &&
              seen.include?(w.left)
          } + values[:where]
        end
      end
    end
  end
end
module ActiveRecord
  class PredicateBuilder # :nodoc:
    def self.build_from_hash(klass, attributes, default_table)
      queries = []

      attributes.each do |column, value|
        table = default_table

        if value.is_a?(Hash)
          if value.empty?
            queries << '1=0'
          else
            table       = Arel::Table.new(column, default_table.engine)
            association = klass.reflect_on_association(column.to_sym)

            value.each do |k, v|
              queries.concat expand(association && association.klass, table, k, v)
            end
          end
        else
          column = column.to_s

          if column.include?('.')
            table_name, column = column.split('.', 2)
            table = Arel::Table.new(table_name, default_table.engine)
          end

          queries.concat expand(klass, table, column, value)
        end
      end

      queries
    end

    def self.expand(klass, table, column, value)
      queries = []

      # Find the foreign key when using queries such as:
      # Post.where(author: author)
      #
      # For polymorphic relationships, find the foreign key and type:
      # PriceEstimate.where(estimate_of: treasure)
      if klass && value.class < Base && reflection = klass.reflect_on_association(column.to_sym)
        if reflection.polymorphic?
          queries << build(table[reflection.foreign_type], value.class.base_class)
        end

        column = reflection.foreign_key
      end

      queries << build(table[column.to_sym], value)
      queries
    end

    def self.references(attributes)
      attributes.map do |key, value|
        if value.is_a?(Hash)
          key
        else
          key = key.to_s
          key.split('.').first if key.include?('.')
        end
      end.compact
    end

    private
      def self.build(attribute, value)
        case value
        when Array
          values = value.to_a.map {|x| x.is_a?(Base) ? x.id : x}
          ranges, values = values.partition {|v| v.is_a?(Range)}

          values_predicate = if values.include?(nil)
            values = values.compact

            case values.length
            when 0
              attribute.eq(nil)
            when 1
              attribute.eq(values.first).or(attribute.eq(nil))
            else
              attribute.in(values).or(attribute.eq(nil))
            end
          else
            attribute.in(values)
          end

          array_predicates = ranges.map { |range| attribute.in(range) }
          array_predicates << values_predicate
          array_predicates.inject { |composite, predicate| composite.or(predicate) }
        when ActiveRecord::Relation
          value = value.select(value.klass.arel_table[value.klass.primary_key]) if value.select_values.empty?
          attribute.in(value.arel.ast)
        when Range
          attribute.in(value)
        when ActiveRecord::Base
          attribute.eq(value.id)
        when Class
          # FIXME: I think we need to deprecate this behavior
          attribute.eq(value.name)
        when Integer, ActiveSupport::Duration
          # Arel treats integers as literals, but they should be quoted when compared with strings
          table = attribute.relation
          column = table.engine.connection.schema_cache.columns_hash(table.name)[attribute.name.to_s]
          attribute.eq(Arel::Nodes::SqlLiteral.new(table.engine.connection.quote(value, column)))
        else
          attribute.eq(value)
        end
      end
  end
end
require 'active_support/core_ext/array/wrap'

module ActiveRecord
  module QueryMethods
    extend ActiveSupport::Concern

    # WhereChain objects act as placeholder for queries in which #where does not have any parameter.
    # In this case, #where must be chained with either #not, #like, or #not_like to return a new relation.
    class WhereChain
      def initialize(scope)
        @scope = scope
      end

      # Returns a new relation expressing WHERE + NOT condition
      # according to the conditions in the arguments.
      #
      # #not accepts conditions in one of these formats: String, Array, Hash.
      # See #where for more details on each format.
      #
      #    User.where.not("name = 'Jon'")
      #    # SELECT * FROM users WHERE NOT (name = 'Jon')
      #
      #    User.where.not(["name = ?", "Jon"])
      #    # SELECT * FROM users WHERE NOT (name = 'Jon')
      #
      #    User.where.not(name: "Jon")
      #    # SELECT * FROM users WHERE name != 'Jon'
      #
      #    User.where.not(name: nil)
      #    # SELECT * FROM users WHERE name IS NOT NULL
      #
      #    User.where.not(name: %w(Ko1 Nobu))
      #    # SELECT * FROM users WHERE name NOT IN ('Ko1', 'Nobu')
      def not(opts, *rest)
        where_value = @scope.send(:build_where, opts, rest).map do |rel|
          case rel
          when Arel::Nodes::In
            Arel::Nodes::NotIn.new(rel.left, rel.right)
          when Arel::Nodes::Equality
            Arel::Nodes::NotEqual.new(rel.left, rel.right)
          when String
            Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(rel))
          else
            Arel::Nodes::Not.new(rel)
          end
        end
        @scope.where_values += where_value
        @scope
      end
    end

    Relation::MULTI_VALUE_METHODS.each do |name|
      class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name}_values                   # def select_values
          @values[:#{name}] || []            #   @values[:select] || []
        end                                  # end
                                             #
        def #{name}_values=(values)          # def select_values=(values)
          raise ImmutableRelation if @loaded #   raise ImmutableRelation if @loaded
          @values[:#{name}] = values         #   @values[:select] = values
        end                                  # end
      CODE
    end

    (Relation::SINGLE_VALUE_METHODS - [:create_with]).each do |name|
      class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name}_value                    # def readonly_value
          @values[:#{name}]                  #   @values[:readonly]
        end                                  # end
      CODE
    end

    Relation::SINGLE_VALUE_METHODS.each do |name|
      class_eval <<-CODE, __FILE__, __LINE__ + 1
        def #{name}_value=(value)            # def readonly_value=(value)
          raise ImmutableRelation if @loaded #   raise ImmutableRelation if @loaded
          @values[:#{name}] = value          #   @values[:readonly] = value
        end                                  # end
      CODE
    end

    def create_with_value # :nodoc:
      @values[:create_with] || {}
    end

    alias extensions extending_values

    # Specify relationships to be included in the result set. For
    # example:
    #
    #   users = User.includes(:address)
    #   users.each do |user|
    #     user.address.city
    #   end
    #
    # allows you to access the +address+ attribute of the +User+ model without
    # firing an additional query. This will often result in a
    # performance improvement over a simple +join+.
    #
    # === conditions
    #
    # If you want to add conditions to your included models you'll have
    # to explicitly reference them. For example:
    #
    #   User.includes(:posts).where('posts.name = ?', 'example')
    #
    # Will throw an error, but this will work:
    #
    #   User.includes(:posts).where('posts.name = ?', 'example').references(:posts)
    def includes(*args)
      args.empty? ? self : spawn.includes!(*args)
    end

    def includes!(*args) # :nodoc:
      args.reject! {|a| a.blank? }

      self.includes_values = (includes_values + args).flatten.uniq
      self
    end

    # Forces eager loading by performing a LEFT OUTER JOIN on +args+:
    #
    #   User.eager_load(:posts)
    #   => SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ...
    #   FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
    #   "users"."id"
    def eager_load(*args)
      args.blank? ? self : spawn.eager_load!(*args)
    end

    def eager_load!(*args) # :nodoc:
      self.eager_load_values += args
      self
    end

    # Allows preloading of +args+, in the same way that +includes+ does:
    #
    #   User.preload(:posts)
    #   => SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)
    def preload(*args)
      args.blank? ? self : spawn.preload!(*args)
    end

    def preload!(*args) # :nodoc:
      self.preload_values += args
      self
    end

    # Used to indicate that an association is referenced by an SQL string, and should
    # therefore be JOINed in any query rather than loaded separately.
    #
    #   User.includes(:posts).where("posts.name = 'foo'")
    #   # => Doesn't JOIN the posts table, resulting in an error.
    #
    #   User.includes(:posts).where("posts.name = 'foo'").references(:posts)
    #   # => Query now knows the string references posts, so adds a JOIN
    def references(*args)
      args.blank? ? self : spawn.references!(*args)
    end

    def references!(*args) # :nodoc:
      args.flatten!

      self.references_values = (references_values + args.map!(&:to_s)).uniq
      self
    end

    # Works in two unique ways.
    #
    # First: takes a block so it can be used just like Array#select.
    #
    #   Model.all.select { |m| m.field == value }
    #
    # This will build an array of objects from the database for the scope,
    # converting them into an array and iterating through them using Array#select.
    #
    # Second: Modifies the SELECT statement for the query so that only certain
    # fields are retrieved:
    #
    #   Model.select(:field)
    #   # => [#<Model field:value>]
    #
    # Although in the above example it looks as though this method returns an
    # array, it actually returns a relation object and can have other query
    # methods appended to it, such as the other methods in ActiveRecord::QueryMethods.
    #
    # The argument to the method can also be an array of fields.
    #
    #   Model.select(:field, :other_field, :and_one_more)
    #   # => [#<Model field: "value", other_field: "value", and_one_more: "value">]
    #
    # You can also use one or more strings, which will be used unchanged as SELECT fields.
    #
    #   Model.select('field AS field_one', 'other_field AS field_two')
    #   # => [#<Model field: "value", other_field: "value">]
    #
    # If an alias was specified, it will be accessible from the resulting objects:
    #
    #   Model.select('field AS field_one').first.field_one
    #   # => "value"
    #
    # Accessing attributes of an object that do not have fields retrieved by a select
    # will throw <tt>ActiveModel::MissingAttributeError</tt>:
    #
    #   Model.select(:field).first.other_field
    #   # => ActiveModel::MissingAttributeError: missing attribute: other_field
    def select(*fields)
      if block_given?
        to_a.select { |*block_args| yield(*block_args) }
      else
        raise ArgumentError, 'Call this with at least one field' if fields.empty?
        spawn.select!(*fields)
      end
    end

    def select!(*fields) # :nodoc:
      self.select_values += fields.flatten
      self
    end

    # Allows to specify a group attribute:
    #
    #   User.group(:name)
    #   => SELECT "users".* FROM "users" GROUP BY name
    #
    # Returns an array with distinct records based on the +group+ attribute:
    #
    #   User.select([:id, :name])
    #   => [#<User id: 1, name: "Oscar">, #<User id: 2, name: "Oscar">, #<User id: 3, name: "Foo">
    #
    #   User.group(:name)
    #   => [#<User id: 3, name: "Foo", ...>, #<User id: 2, name: "Oscar", ...>]
    #
    #   User.group('name AS grouped_name, age')
    #   => [#<User id: 3, name: "Foo", age: 21, ...>, #<User id: 2, name: "Oscar", age: 21, ...>, #<User id: 5, name: "Foo", age: 23, ...>]
    def group(*args)
      args.blank? ? self : spawn.group!(*args)
    end

    def group!(*args) # :nodoc:
      args.flatten!

      self.group_values += args
      self
    end

    # Allows to specify an order attribute:
    #
    #   User.order('name')
    #   => SELECT "users".* FROM "users" ORDER BY name
    #
    #   User.order('name DESC')
    #   => SELECT "users".* FROM "users" ORDER BY name DESC
    #
    #   User.order('name DESC, email')
    #   => SELECT "users".* FROM "users" ORDER BY name DESC, email
    #
    #   User.order(:name)
    #   => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
    #
    #   User.order(email: :desc)
    #   => SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
    #
    #   User.order(:name, email: :desc)
    #   => SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
    def order(*args)
      args.blank? ? self : spawn.order!(*args)
    end

    def order!(*args) # :nodoc:
      args.flatten!
      validate_order_args args

      references = args.reject { |arg| Arel::Node === arg }
      references.map! { |arg| arg =~ /^([a-zA-Z]\w*)\.(\w+)/ && $1 }.compact!
      references!(references) if references.any?

      self.order_values = args + self.order_values
      self
    end

    # Replaces any existing order defined on the relation with the specified order.
    #
    #   User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
    #
    # Subsequent calls to order on the same relation will be appended. For example:
    #
    #   User.order('email DESC').reorder('id ASC').order('name ASC')
    #
    # generates a query with 'ORDER BY name ASC, id ASC'.
    def reorder(*args)
      args.blank? ? self : spawn.reorder!(*args)
    end

    def reorder!(*args) # :nodoc:
      args.flatten!
      validate_order_args args

      self.reordering_value = true
      self.order_values = args
      self
    end

    # Performs a joins on +args+:
    #
    #   User.joins(:posts)
    #   => SELECT "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id"
    #
    # You can use strings in order to customize your joins:
    #
    #   User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id")
    #   => SELECT "users".* FROM "users" LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id = users.id
    def joins(*args)
      args.compact.blank? ? self : spawn.joins!(*args.flatten)
    end

    def joins!(*args) # :nodoc:
      self.joins_values += args
      self
    end

    def bind(value)
      spawn.bind!(value)
    end

    def bind!(value) # :nodoc:
      self.bind_values += [value]
      self
    end

    # Returns a new relation, which is the result of filtering the current relation
    # according to the conditions in the arguments.
    #
    # #where accepts conditions in one of several formats. In the examples below, the resulting
    # SQL is given as an illustration; the actual query generated may be different depending
    # on the database adapter.
    #
    # === string
    #
    # A single string, without additional arguments, is passed to the query
    # constructor as a SQL fragment, and used in the where clause of the query.
    #
    #    Client.where("orders_count = '2'")
    #    # SELECT * from clients where orders_count = '2';
    #
    # Note that building your own string from user input may expose your application
    # to injection attacks if not done properly. As an alternative, it is recommended
    # to use one of the following methods.
    #
    # === array
    #
    # If an array is passed, then the first element of the array is treated as a template, and
    # the remaining elements are inserted into the template to generate the condition.
    # Active Record takes care of building the query to avoid injection attacks, and will
    # convert from the ruby type to the database type where needed. Elements are inserted
    # into the string in the order in which they appear.
    #
    #   User.where(["name = ? and email = ?", "Joe", "joe@example.com"])
    #   # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
    #
    # Alternatively, you can use named placeholders in the template, and pass a hash as the
    # second element of the array. The names in the template are replaced with the corresponding
    # values from the hash.
    #
    #   User.where(["name = :name and email = :email", { name: "Joe", email: "joe@example.com" }])
    #   # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
    #
    # This can make for more readable code in complex queries.
    #
    # Lastly, you can use sprintf-style % escapes in the template. This works slightly differently
    # than the previous methods; you are responsible for ensuring that the values in the template
    # are properly quoted. The values are passed to the connector for quoting, but the caller
    # is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting,
    # the values are inserted using the same escapes as the Ruby core method <tt>Kernel::sprintf</tt>.
    #
    #   User.where(["name = '%s' and email = '%s'", "Joe", "joe@example.com"])
    #   # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
    #
    # If #where is called with multiple arguments, these are treated as if they were passed as
    # the elements of a single array.
    #
    #   User.where("name = :name and email = :email", { name: "Joe", email: "joe@example.com" })
    #   # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com';
    #
    # When using strings to specify conditions, you can use any operator available from
    # the database. While this provides the most flexibility, you can also unintentionally introduce
    # dependencies on the underlying database. If your code is intended for general consumption,
    # test with multiple database backends.
    #
    # === hash
    #
    # #where will also accept a hash condition, in which the keys are fields and the values
    # are values to be searched for.
    #
    # Fields can be symbols or strings. Values can be single values, arrays, or ranges.
    #
    #    User.where({ name: "Joe", email: "joe@example.com" })
    #    # SELECT * FROM users WHERE name = 'Joe' AND email = 'joe@example.com'
    #
    #    User.where({ name: ["Alice", "Bob"]})
    #    # SELECT * FROM users WHERE name IN ('Alice', 'Bob')
    #
    #    User.where({ created_at: (Time.now.midnight - 1.day)..Time.now.midnight })
    #    # SELECT * FROM users WHERE (created_at BETWEEN '2012-06-09 07:00:00.000000' AND '2012-06-10 07:00:00.000000')
    #
    # In the case of a belongs_to relationship, an association key can be used
    # to specify the model if an ActiveRecord object is used as the value.
    #
    #    author = Author.find(1)
    #
    #    # The following queries will be equivalent:
    #    Post.where(author: author)
    #    Post.where(author_id: author)
    #
    # This also works with polymorphic belongs_to relationships:
    #
    #    treasure = Treasure.create(name: 'gold coins')
    #    treasure.price_estimates << PriceEstimate.create(price: 125)
    #
    #    # The following queries will be equivalent:
    #    PriceEstimate.where(estimate_of: treasure)
    #    PriceEstimate.where(estimate_of_type: 'Treasure', estimate_of_id: treasure)
    #
    # === Joins
    #
    # If the relation is the result of a join, you may create a condition which uses any of the
    # tables in the join. For string and array conditions, use the table name in the condition.
    #
    #    User.joins(:posts).where("posts.created_at < ?", Time.now)
    #
    # For hash conditions, you can either use the table name in the key, or use a sub-hash.
    #
    #    User.joins(:posts).where({ "posts.published" => true })
    #    User.joins(:posts).where({ posts: { published: true } })
    #
    # === no argument
    #
    # If no argument is passed, #where returns a new instance of WhereChain, that
    # can be chained with #not to return a new relation that negates the where clause.
    #
    #    User.where.not(name: "Jon")
    #    # SELECT * FROM users WHERE name != 'Jon'
    #
    # See WhereChain for more details on #not.
    #
    # === blank condition
    #
    # If the condition is any blank-ish object, then #where is a no-op and returns
    # the current relation.
    def where(opts = :chain, *rest)
      if opts == :chain
        WhereChain.new(spawn)
      elsif opts.blank?
        self
      else
        spawn.where!(opts, *rest)
      end
    end

    # #where! is identical to #where, except that instead of returning a new relation, it adds
    # the condition to the existing relation.
    def where!(opts = :chain, *rest) # :nodoc:
      if opts == :chain
        WhereChain.new(self)
      else
        references!(PredicateBuilder.references(opts)) if Hash === opts

        self.where_values += build_where(opts, rest)
        self
      end
    end

    # Allows to specify a HAVING clause. Note that you can't use HAVING
    # without also specifying a GROUP clause.
    #
    #   Order.having('SUM(price) > 30').group('user_id')
    def having(opts, *rest)
      opts.blank? ? self : spawn.having!(opts, *rest)
    end

    def having!(opts, *rest) # :nodoc:
      references!(PredicateBuilder.references(opts)) if Hash === opts

      self.having_values += build_where(opts, rest)
      self
    end

    # Specifies a limit for the number of records to retrieve.
    #
    #   User.limit(10) # generated SQL has 'LIMIT 10'
    #
    #   User.limit(10).limit(20) # generated SQL has 'LIMIT 20'
    def limit(value)
      spawn.limit!(value)
    end

    def limit!(value) # :nodoc:
      self.limit_value = value
      self
    end

    # Specifies the number of rows to skip before returning rows.
    #
    #   User.offset(10) # generated SQL has "OFFSET 10"
    #
    # Should be used with order.
    #
    #   User.offset(10).order("name ASC")
    def offset(value)
      spawn.offset!(value)
    end

    def offset!(value) # :nodoc:
      self.offset_value = value
      self
    end

    # Specifies locking settings (default to +true+). For more information
    # on locking, please see +ActiveRecord::Locking+.
    def lock(locks = true)
      spawn.lock!(locks)
    end

    def lock!(locks = true) # :nodoc:
      case locks
      when String, TrueClass, NilClass
        self.lock_value = locks || true
      else
        self.lock_value = false
      end

      self
    end

    # Returns a chainable relation with zero records, specifically an
    # instance of the <tt>ActiveRecord::NullRelation</tt> class.
    #
    # The returned <tt>ActiveRecord::NullRelation</tt> inherits from Relation and implements the
    # Null Object pattern. It is an object with defined null behavior and always returns an empty
    # array of records without quering the database.
    #
    # Any subsequent condition chained to the returned relation will continue
    # generating an empty relation and will not fire any query to the database.
    #
    # Used in cases where a method or scope could return zero records but the
    # result needs to be chainable.
    #
    # For example:
    #
    #   @posts = current_user.visible_posts.where(name: params[:name])
    #   # => the visible_posts method is expected to return a chainable Relation
    #
    #   def visible_posts
    #     case role
    #     when 'Country Manager'
    #       Post.where(country: country)
    #     when 'Reviewer'
    #       Post.published
    #     when 'Bad User'
    #       Post.none # => returning [] instead breaks the previous code
    #     end
    #   end
    #
    def none
      extending(NullRelation)
    end

    def none! # :nodoc:
      extending!(NullRelation)
    end

    # Sets readonly attributes for the returned relation. If value is
    # true (default), attempting to update a record will result in an error.
    #
    #   users = User.readonly
    #   users.first.save
    #   => ActiveRecord::ReadOnlyRecord: ActiveRecord::ReadOnlyRecord
    def readonly(value = true)
      spawn.readonly!(value)
    end

    def readonly!(value = true) # :nodoc:
      self.readonly_value = value
      self
    end

    # Sets attributes to be used when creating new records from a
    # relation object.
    #
    #   users = User.where(name: 'Oscar')
    #   users.new.name # => 'Oscar'
    #
    #   users = users.create_with(name: 'DHH')
    #   users.new.name # => 'DHH'
    #
    # You can pass +nil+ to +create_with+ to reset attributes:
    #
    #   users = users.create_with(nil)
    #   users.new.name # => 'Oscar'
    def create_with(value)
      spawn.create_with!(value)
    end

    def create_with!(value) # :nodoc:
      self.create_with_value = value ? create_with_value.merge(value) : {}
      self
    end

    # Specifies table from which the records will be fetched. For example:
    #
    #   Topic.select('title').from('posts')
    #   #=> SELECT title FROM posts
    #
    # Can accept other relation objects. For example:
    #
    #   Topic.select('title').from(Topic.approved)
    #   # => SELECT title FROM (SELECT * FROM topics WHERE approved = 't') subquery
    #
    #   Topic.select('a.title').from(Topic.approved, :a)
    #   # => SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
    #
    def from(value, subquery_name = nil)
      spawn.from!(value, subquery_name)
    end

    # Like #from, but modifies relation in place.
    def from!(value, subquery_name = nil) # :nodoc:
      self.from_value = [value, subquery_name]
      self
    end

    # Specifies whether the records should be unique or not. For example:
    #
    #   User.select(:name)
    #   # => Might return two records with the same name
    #
    #   User.select(:name).uniq
    #   # => Returns 1 record per unique name
    #
    #   User.select(:name).uniq.uniq(false)
    #   # => You can also remove the uniqueness
    def uniq(value = true)
      spawn.uniq!(value)
    end

    # Like #uniq, but modifies relation in place.
    def uniq!(value = true) # :nodoc:
      self.uniq_value = value
      self
    end

    # Used to extend a scope with additional methods, either through
    # a module or through a block provided.
    #
    # The object returned is a relation, which can be further extended.
    #
    # === Using a module
    #
    #   module Pagination
    #     def page(number)
    #       # pagination code goes here
    #     end
    #   end
    #
    #   scope = Model.all.extending(Pagination)
    #   scope.page(params[:page])
    #
    # You can also pass a list of modules:
    #
    #   scope = Model.all.extending(Pagination, SomethingElse)
    #
    # === Using a block
    #
    #   scope = Model.all.extending do
    #     def page(number)
    #       # pagination code goes here
    #     end
    #   end
    #   scope.page(params[:page])
    #
    # You can also use a block and a module list:
    #
    #   scope = Model.all.extending(Pagination) do
    #     def per_page(number)
    #       # pagination code goes here
    #     end
    #   end
    def extending(*modules, &block)
      if modules.any? || block
        spawn.extending!(*modules, &block)
      else
        self
      end
    end

    def extending!(*modules, &block) # :nodoc:
      modules << Module.new(&block) if block_given?

      self.extending_values += modules.flatten
      extend(*extending_values) if extending_values.any?

      self
    end

    # Reverse the existing order clause on the relation.
    #
    #   User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
    def reverse_order
      spawn.reverse_order!
    end

    def reverse_order! # :nodoc:
      self.reverse_order_value = !reverse_order_value
      self
    end

    # Returns the Arel object associated with the relation.
    def arel
      @arel ||= with_default_scope.build_arel
    end

    # Like #arel, but ignores the default scope of the model.
    def build_arel
      arel = Arel::SelectManager.new(table.engine, table)

      build_joins(arel, joins_values) unless joins_values.empty?

      collapse_wheres(arel, (where_values - ['']).uniq)

      arel.having(*having_values.uniq.reject{|h| h.blank?}) unless having_values.empty?

      arel.take(connection.sanitize_limit(limit_value)) if limit_value
      arel.skip(offset_value.to_i) if offset_value

      arel.group(*group_values.uniq.reject{|g| g.blank?}) unless group_values.empty?

      build_order(arel)

      build_select(arel, select_values.uniq)

      arel.distinct(uniq_value)
      arel.from(build_from) if from_value
      arel.lock(lock_value) if lock_value

      arel
    end

    private

    def custom_join_ast(table, joins)
      joins = joins.reject { |join| join.blank? }

      return [] if joins.empty?

      @implicit_readonly = true

      joins.map do |join|
        case join
        when Array
          join = Arel.sql(join.join(' ')) if array_of_strings?(join)
        when String
          join = Arel.sql(join)
        end
        table.create_string_join(join)
      end
    end

    def collapse_wheres(arel, wheres)
      equalities = wheres.grep(Arel::Nodes::Equality)

      arel.where(Arel::Nodes::And.new(equalities)) unless equalities.empty?

      (wheres - equalities).each do |where|
        where = Arel.sql(where) if String === where
        arel.where(Arel::Nodes::Grouping.new(where))
      end
    end

    def build_where(opts, other = [])
      case opts
      when String, Array
        [@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))]
      when Hash
        attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)

        attributes.values.grep(ActiveRecord::Relation) do |rel|
          self.bind_values += rel.bind_values
        end

        PredicateBuilder.build_from_hash(klass, attributes, table)
      else
        [opts]
      end
    end

    def build_from
      opts, name = from_value
      case opts
      when Relation
        name ||= 'subquery'
        opts.arel.as(name.to_s)
      else
        opts
      end
    end

    def build_joins(manager, joins)
      buckets = joins.group_by do |join|
        case join
        when String
          :string_join
        when Hash, Symbol, Array
          :association_join
        when ActiveRecord::Associations::JoinDependency::JoinAssociation
          :stashed_join
        when Arel::Nodes::Join
          :join_node
        else
          raise 'unknown class: %s' % join.class.name
        end
      end

      association_joins         = buckets[:association_join] || []
      stashed_association_joins = buckets[:stashed_join] || []
      join_nodes                = (buckets[:join_node] || []).uniq
      string_joins              = (buckets[:string_join] || []).map { |x|
        x.strip
      }.uniq

      join_list = join_nodes + custom_join_ast(manager, string_joins)

      join_dependency = ActiveRecord::Associations::JoinDependency.new(
        @klass,
        association_joins,
        join_list
      )

      join_dependency.graft(*stashed_association_joins)

      @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?

      # FIXME: refactor this to build an AST
      join_dependency.join_associations.each do |association|
        association.join_to(manager)
      end

      manager.join_sources.concat join_list

      manager
    end

    def build_select(arel, selects)
      unless selects.empty?
        @implicit_readonly = false
        arel.project(*selects)
      else
        arel.project(@klass.arel_table[Arel.star])
      end
    end

    def reverse_sql_order(order_query)
      order_query = ["#{quoted_table_name}.#{quoted_primary_key} ASC"] if order_query.empty?

      order_query.flat_map do |o|
        case o
        when Arel::Nodes::Ordering
          o.reverse
        when String
          o.to_s.split(',').collect do |s|
            s.strip!
            s.gsub!(/\sasc\Z/i, ' DESC') || s.gsub!(/\sdesc\Z/i, ' ASC') || s.concat(' DESC')
          end
        when Symbol
          { o => :desc }
        when Hash
          o.each_with_object({}) do |(field, dir), memo|
            memo[field] = (dir == :asc ? :desc : :asc )
          end
        else
          o
        end
      end
    end

    def array_of_strings?(o)
      o.is_a?(Array) && o.all?{|obj| obj.is_a?(String)}
    end

    def build_order(arel)
      orders = order_values
      orders = reverse_sql_order(orders) if reverse_order_value

      orders = orders.uniq.reject(&:blank?).flat_map do |order|
        case order
        when Symbol
          table[order].asc
        when Hash
          order.map { |field, dir| table[field].send(dir) }
        else
          order
        end
      end

      arel.order(*orders) unless orders.empty?
    end

    def validate_order_args(args)
      args.select { |a| Hash === a  }.each do |h|
        unless (h.values - [:asc, :desc]).empty?
          raise ArgumentError, 'Direction should be :asc or :desc'
        end
      end
    end

  end
end
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
require 'active_record/relation/merger'

module ActiveRecord
  module SpawnMethods

    # This is overridden by Associations::CollectionProxy
    def spawn #:nodoc:
      clone
    end

    # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>.
    # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
    #   Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
    #   # Performs a single join query with both where conditions.
    #
    #   recent_posts = Post.order('created_at DESC').first(5)
    #   Post.where(published: true).merge(recent_posts)
    #   # Returns the intersection of all published posts with the 5 most recently created posts.
    #   # (This is just an example. You'd probably want to do this with a single query!)
    #
    # Procs will be evaluated by merge:
    #
    #   Post.where(published: true).merge(-> { joins(:comments) })
    #   # => Post.where(published: true).joins(:comments)
    #
    # This is mainly intended for sharing common conditions between multiple associations.
    def merge(other)
      if other.is_a?(Array)
        to_a & other
      elsif other
        spawn.merge!(other)
      else
        self
      end
    end

    def merge!(other) # :nodoc:
      if !other.is_a?(Relation) && other.respond_to?(:to_proc)
        instance_exec(&other)
      else
        klass = other.is_a?(Hash) ? Relation::HashMerger : Relation::Merger
        klass.new(self, other).merge
      end
    end

    # Removes from the query the condition(s) specified in +skips+.
    #
    #   Post.order('id asc').except(:order)                  # discards the order condition
    #   Post.where('id > 10').order('id asc').except(:where) # discards the where condition but keeps the order
    def except(*skips)
      relation_with values.except(*skips)
    end

    # Removes any condition from the query other than the one(s) specified in +onlies+.
    #
    #   Post.order('id asc').only(:where)         # discards the order condition
    #   Post.order('id asc').only(:where, :order) # uses the specified order
    def only(*onlies)
      relation_with values.slice(*onlies)
    end

    private

      def relation_with(values) # :nodoc:
        result = Relation.new(klass, table, values)
        result.default_scoped = default_scoped
        result.extend(*extending_values) if extending_values.any?
        result
      end
  end
end
# -*- coding: utf-8 -*-

module ActiveRecord
  # = Active Record Relation
  class Relation
    JoinOperation = Struct.new(:relation, :join_class, :on)

    MULTI_VALUE_METHODS  = [:includes, :eager_load, :preload, :select, :group,
                            :order, :joins, :where, :having, :bind, :references,
                            :extending]

    SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :from, :reordering,
                            :reverse_order, :uniq, :create_with]

    VALUE_METHODS = MULTI_VALUE_METHODS + SINGLE_VALUE_METHODS

    include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation

    attr_reader :table, :klass, :loaded
    attr_accessor :default_scoped
    alias :model :klass
    alias :loaded? :loaded
    alias :default_scoped? :default_scoped

    def initialize(klass, table, values = {})
      @klass             = klass
      @table             = table
      @values            = values
      @implicit_readonly = nil
      @loaded            = false
      @default_scoped    = false
    end

    def initialize_copy(other)
      # This method is a hot spot, so for now, use Hash[] to dup the hash.
      #   https://bugs.ruby-lang.org/issues/7166
      @values        = Hash[@values]
      @values[:bind] = @values[:bind].dup if @values.key? :bind
      reset
    end

    def insert(values)
      primary_key_value = nil

      if primary_key && Hash === values
        primary_key_value = values[values.keys.find { |k|
          k.name == primary_key
        }]

        if !primary_key_value && connection.prefetch_primary_key?(klass.table_name)
          primary_key_value = connection.next_sequence_value(klass.sequence_name)
          values[klass.arel_table[klass.primary_key]] = primary_key_value
        end
      end

      im = arel.create_insert
      im.into @table

      conn = @klass.connection

      substitutes = values.sort_by { |arel_attr,_| arel_attr.name }
      binds       = substitutes.map do |arel_attr, value|
        [@klass.columns_hash[arel_attr.name], value]
      end

      substitutes.each_with_index do |tuple, i|
        tuple[1] = conn.substitute_at(binds[i][0], i)
      end

      if values.empty? # empty insert
        im.values = Arel.sql(connection.empty_insert_statement_value)
      else
        im.insert substitutes
      end

      conn.insert(
        im,
        'SQL',
        primary_key,
        primary_key_value,
        nil,
        binds)
    end

    # Initializes new record from relation while maintaining the current
    # scope.
    #
    # Expects arguments in the same format as +Base.new+.
    #
    #   users = User.where(name: 'DHH')
    #   user = users.new # => #<User id: nil, name: "DHH", created_at: nil, updated_at: nil>
    #
    # You can also pass a block to new with the new record as argument:
    #
    #   user = users.new { |user| user.name = 'Oscar' }
    #   user.name # => Oscar
    def new(*args, &block)
      scoping { @klass.new(*args, &block) }
    end

    alias build new

    # Tries to create a new record with the same scoped attributes
    # defined in the relation. Returns the initialized object if validation fails.
    #
    # Expects arguments in the same format as +Base.create+.
    #
    # ==== Examples
    #   users = User.where(name: 'Oscar')
    #   users.create # #<User id: 3, name: "oscar", ...>
    #
    #   users.create(name: 'fxn')
    #   users.create # #<User id: 4, name: "fxn", ...>
    #
    #   users.create { |user| user.name = 'tenderlove' }
    #   # #<User id: 5, name: "tenderlove", ...>
    #
    #   users.create(name: nil) # validation on name
    #   # #<User id: nil, name: nil, ...>
    def create(*args, &block)
      scoping { @klass.create(*args, &block) }
    end

    # Similar to #create, but calls +create!+ on the base class. Raises
    # an exception if a validation error occurs.
    #
    # Expects arguments in the same format as <tt>Base.create!</tt>.
    def create!(*args, &block)
      scoping { @klass.create!(*args, &block) }
    end

    def first_or_create(attributes = nil, &block) # :nodoc:
      first || create(attributes, &block)
    end

    def first_or_create!(attributes = nil, &block) # :nodoc:
      first || create!(attributes, &block)
    end

    def first_or_initialize(attributes = nil, &block) # :nodoc:
      first || new(attributes, &block)
    end

    # Finds the first record with the given attributes, or creates a record with the attributes
    # if one is not found.
    #
    # ==== Examples
    #   # Find the first user named Penélope or create a new one.
    #   User.find_or_create_by(first_name: 'Penélope')
    #   # => <User id: 1, first_name: 'Penélope', last_name: nil>
    #
    #   # Find the first user named Penélope or create a new one.
    #   # We already have one so the existing record will be returned.
    #   User.find_or_create_by(first_name: 'Penélope')
    #   # => <User id: 1, first_name: 'Penélope', last_name: nil>
    #
    #   # Find the first user named Scarlett or create a new one with a particular last name.
    #   User.create_with(last_name: 'Johansson').find_or_create_by(first_name: 'Scarlett')
    #   # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>
    #
    #   # Find the first user named Scarlett or create a new one with a different last name.
    #   # We already have one so the existing record will be returned.
    #   User.find_or_create_by(first_name: 'Scarlett') do |user|
    #     user.last_name = "O'Hara"
    #   end
    #   # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>
    def find_or_create_by(attributes, &block)
      find_by(attributes) || create(attributes, &block)
    end

    # Like <tt>find_or_create_by</tt>, but calls <tt>create!</tt> so an exception is raised if the created record is invalid.
    def find_or_create_by!(attributes, &block)
      find_by(attributes) || create!(attributes, &block)
    end

    # Like <tt>find_or_create_by</tt>, but calls <tt>new</tt> instead of <tt>create</tt>.
    def find_or_initialize_by(attributes, &block)
      find_by(attributes) || new(attributes, &block)
    end

    # Runs EXPLAIN on the query or queries triggered by this relation and
    # returns the result as a string. The string is formatted imitating the
    # ones printed by the database shell.
    #
    # Note that this method actually runs the queries, since the results of some
    # are needed by the next ones when eager loading is going on.
    #
    # Please see further details in the
    # {Active Record Query Interface guide}[http://guides.rubyonrails.org/active_record_querying.html#running-explain].
    def explain
      _, queries = collecting_queries_for_explain { exec_queries }
      exec_explain(queries)
    end

    # Converts relation objects to Array.
    def to_a
      load
      @records
    end

    def as_json(options = nil) #:nodoc:
      to_a.as_json(options)
    end

    # Returns size of the records.
    def size
      loaded? ? @records.length : count
    end

    # Returns true if there are no records.
    def empty?
      return @records.empty? if loaded?

      c = count
      c.respond_to?(:zero?) ? c.zero? : c.empty?
    end

    # Returns true if there are any records.
    def any?
      if block_given?
        to_a.any? { |*block_args| yield(*block_args) }
      else
        !empty?
      end
    end

    # Returns true if there is more than one record.
    def many?
      if block_given?
        to_a.many? { |*block_args| yield(*block_args) }
      else
        limit_value ? to_a.many? : size > 1
      end
    end

    # Scope all queries to the current scope.
    #
    #   Comment.where(post_id: 1).scoping do
    #     Comment.first # SELECT * FROM comments WHERE post_id = 1
    #   end
    #
    # Please check unscoped if you want to remove all previous scopes (including
    # the default_scope) during the execution of a block.
    def scoping
      previous, klass.current_scope = klass.current_scope, self
      yield
    ensure
      klass.current_scope = previous
    end

    # Updates all records with details given if they match a set of conditions supplied, limits and order can
    # also be supplied. This method constructs a single SQL UPDATE statement and sends it straight to the
    # database. It does not instantiate the involved models and it does not trigger Active Record callbacks
    # or validations.
    #
    # ==== Parameters
    #
    # * +updates+ - A string, array, or hash representing the SET part of an SQL statement.
    #
    # ==== Examples
    #
    #   # Update all customers with the given attributes
    #   Customer.update_all wants_email: true
    #
    #   # Update all books with 'Rails' in their title
    #   Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')
    #
    #   # Update all books that match conditions, but limit it to 5 ordered by date
    #   Book.where('title LIKE ?', '%Rails%').order(:created_at).limit(5).update_all(author: 'David')
    def update_all(updates)
      raise ArgumentError, "Empty list of attributes to change" if updates.blank?

      stmt = Arel::UpdateManager.new(arel.engine)

      stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
      stmt.table(table)
      stmt.key = table[primary_key]

      if with_default_scope.joins_values.any?
        @klass.connection.join_to_update(stmt, arel)
      else
        stmt.take(arel.limit)
        stmt.order(*arel.orders)
        stmt.wheres = arel.constraints
      end

      @klass.connection.update stmt, 'SQL', bind_values
    end

    # Updates an object (or multiple objects) and saves it to the database, if validations pass.
    # The resulting object is returned whether the object was saved successfully to the database or not.
    #
    # ==== Parameters
    #
    # * +id+ - This should be the id or an array of ids to be updated.
    # * +attributes+ - This should be a hash of attributes or an array of hashes.
    #
    # ==== Examples
    #
    #   # Updates one record
    #   Person.update(15, user_name: 'Samuel', group: 'expert')
    #
    #   # Updates multiple records
    #   people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
    #   Person.update(people.keys, people.values)
    def update(id, attributes)
      if id.is_a?(Array)
        id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
      else
        object = find(id)
        object.update(attributes)
        object
      end
    end

    # Destroys the records matching +conditions+ by instantiating each
    # record and calling its +destroy+ method. Each object's callbacks are
    # executed (including <tt>:dependent</tt> association options). Returns the
    # collection of objects that were destroyed; each will be frozen, to
    # reflect that no changes should be made (since they can't be persisted).
    #
    # Note: Instantiation, callback execution, and deletion of each
    # record can be time consuming when you're removing many records at
    # once. It generates at least one SQL +DELETE+ query per record (or
    # possibly more, to enforce your callbacks). If you want to delete many
    # rows quickly, without concern for their associations or callbacks, use
    # +delete_all+ instead.
    #
    # ==== Parameters
    #
    # * +conditions+ - A string, array, or hash that specifies which records
    #   to destroy. If omitted, all records are destroyed. See the
    #   Conditions section in the introduction to ActiveRecord::Base for
    #   more information.
    #
    # ==== Examples
    #
    #   Person.destroy_all("last_login < '2004-04-04'")
    #   Person.destroy_all(status: "inactive")
    #   Person.where(age: 0..18).destroy_all
    def destroy_all(conditions = nil)
      if conditions
        where(conditions).destroy_all
      else
        to_a.each {|object| object.destroy }.tap { reset }
      end
    end

    # Destroy an object (or multiple objects) that has the given id. The object is instantiated first,
    # therefore all callbacks and filters are fired off before the object is deleted. This method is
    # less efficient than ActiveRecord#delete but allows cleanup methods and other actions to be run.
    #
    # This essentially finds the object (or multiple objects) with the given id, creates a new object
    # from the attributes, and then calls destroy on it.
    #
    # ==== Parameters
    #
    # * +id+ - Can be either an Integer or an Array of Integers.
    #
    # ==== Examples
    #
    #   # Destroy a single object
    #   Todo.destroy(1)
    #
    #   # Destroy multiple objects
    #   todos = [1,2,3]
    #   Todo.destroy(todos)
    def destroy(id)
      if id.is_a?(Array)
        id.map { |one_id| destroy(one_id) }
      else
        find(id).destroy
      end
    end

    # Deletes the records matching +conditions+ without instantiating the records
    # first, and hence not calling the +destroy+ method nor invoking callbacks. This
    # is a single SQL DELETE statement that goes straight to the database, much more
    # efficient than +destroy_all+. Be careful with relations though, in particular
    # <tt>:dependent</tt> rules defined on associations are not honored. Returns the
    # number of rows affected.
    #
    #   Post.delete_all("person_id = 5 AND (category = 'Something' OR category = 'Else')")
    #   Post.delete_all(["person_id = ? AND (category = ? OR category = ?)", 5, 'Something', 'Else'])
    #   Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
    #
    # Both calls delete the affected posts all at once with a single DELETE statement.
    # If you need to destroy dependent associations or call your <tt>before_*</tt> or
    # +after_destroy+ callbacks, use the +destroy_all+ method instead.
    #
    # If a limit scope is supplied, +delete_all+ raises an ActiveRecord error:
    #
    #   Post.limit(100).delete_all
    #   # => ActiveRecord::ActiveRecordError: delete_all doesn't support limit scope
    def delete_all(conditions = nil)
      raise ActiveRecordError.new("delete_all doesn't support limit scope") if self.limit_value

      if conditions
        where(conditions).delete_all
      else
        stmt = Arel::DeleteManager.new(arel.engine)
        stmt.from(table)

        if with_default_scope.joins_values.any?
          @klass.connection.join_to_delete(stmt, arel, table[primary_key])
        else
          stmt.wheres = arel.constraints
        end

        affected = @klass.connection.delete(stmt, 'SQL', bind_values)

        reset
        affected
      end
    end

    # Deletes the row with a primary key matching the +id+ argument, using a
    # SQL +DELETE+ statement, and returns the number of rows deleted. Active
    # Record objects are not instantiated, so the object's callbacks are not
    # executed, including any <tt>:dependent</tt> association options.
    #
    # You can delete multiple rows at once by passing an Array of <tt>id</tt>s.
    #
    # Note: Although it is often much faster than the alternative,
    # <tt>#destroy</tt>, skipping callbacks might bypass business logic in
    # your application that ensures referential integrity or performs other
    # essential jobs.
    #
    # ==== Examples
    #
    #   # Delete a single row
    #   Todo.delete(1)
    #
    #   # Delete multiple rows
    #   Todo.delete([2,3,4])
    def delete(id_or_array)
      where(primary_key => id_or_array).delete_all
    end

    # Causes the records to be loaded from the database if they have not
    # been loaded already. You can use this if for some reason you need
    # to explicitly load some records before actually using them. The
    # return value is the relation itself, not the records.
    #
    #   Post.where(published: true).load # => #<ActiveRecord::Relation>
    def load
      unless loaded?
        # We monitor here the entire execution rather than individual SELECTs
        # because from the point of view of the user fetching the records of a
        # relation is a single unit of work. You want to know if this call takes
        # too long, not if the individual queries take too long.
        #
        # It could be the case that none of the queries involved surpass the
        # threshold, and at the same time the sum of them all does. The user
        # should get a query plan logged in that case.
        logging_query_plan { exec_queries }
      end

      self
    end

    # Forces reloading of relation.
    def reload
      reset
      load
    end

    def reset
      @first = @last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil
      @should_eager_load = @join_dependency = nil
      @records = []
      self
    end

    # Returns sql statement for the relation.
    #
    #   User.where(name: 'Oscar').to_sql
    #   # => SELECT "users".* FROM "users"  WHERE "users"."name" = 'Oscar'
    def to_sql
      @to_sql ||= klass.connection.to_sql(arel, bind_values.dup)
    end

    # Returns a hash of where conditions.
    #
    #   User.where(name: 'Oscar').where_values_hash
    #   # => {name: "Oscar"}
    def where_values_hash
      equalities = with_default_scope.where_values.grep(Arel::Nodes::Equality).find_all { |node|
        node.left.relation.name == table_name
      }

      binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]

      Hash[equalities.map { |where|
        name = where.left.name
        [name, binds.fetch(name.to_s) { where.right }]
      }]
    end

    def scope_for_create
      @scope_for_create ||= where_values_hash.merge(create_with_value)
    end

    # Returns true if relation needs eager loading.
    def eager_loading?
      @should_eager_load ||=
        eager_load_values.any? ||
        includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?)
    end

    # Joins that are also marked for preloading. In which case we should just eager load them.
    # Note that this is a naive implementation because we could have strings and symbols which
    # represent the same association, but that aren't matched by this. Also, we could have
    # nested hashes which partially match, e.g. { a: :b } & { a: [:b, :c] }
    def joined_includes_values
      includes_values & joins_values
    end

    # Compares two relations for equality.
    def ==(other)
      case other
      when Relation
        other.to_sql == to_sql
      when Array
        to_a == other
      end
    end

    def pretty_print(q)
      q.pp(self.to_a)
    end

    def with_default_scope #:nodoc:
      if default_scoped? && default_scope = klass.send(:build_default_scope)
        default_scope = default_scope.merge(self)
        default_scope.default_scoped = false
        default_scope
      else
        self
      end
    end

    # Returns true if relation is blank.
    def blank?
      to_a.blank?
    end

    def values
      Hash[@values]
    end

    def inspect
      entries = to_a.take([limit_value, 11].compact.min).map!(&:inspect)
      entries[10] = '...' if entries.size == 11

      "#<#{self.class.name} [#{entries.join(', ')}]>"
    end

    private

    def exec_queries
      default_scoped = with_default_scope

      if default_scoped.equal?(self)
        @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel, bind_values)

        preload = preload_values
        preload +=  includes_values unless eager_loading?
        preload.each do |associations|
          ActiveRecord::Associations::Preloader.new(@records, associations).run
        end

        # @readonly_value is true only if set explicitly. @implicit_readonly is true if there
        # are JOINS and no explicit SELECT.
        readonly = readonly_value.nil? ? @implicit_readonly : readonly_value
        @records.each { |record| record.readonly! } if readonly
      else
        @records = default_scoped.to_a
      end

      @loaded = true
      @records
    end

    def references_eager_loaded_tables?
      joined_tables = arel.join_sources.map do |join|
        if join.is_a?(Arel::Nodes::StringJoin)
          tables_in_string(join.left)
        else
          [join.left.table_name, join.left.table_alias]
        end
      end

      joined_tables += [table.name, table.table_alias]

      # always convert table names to downcase as in Oracle quoted table names are in uppercase
      joined_tables = joined_tables.flatten.compact.map { |t| t.downcase }.uniq
      string_tables = tables_in_string(to_sql)

      if (references_values - joined_tables).any?
        true
      elsif (string_tables - joined_tables).any?
        ActiveSupport::Deprecation.warn(
          "It looks like you are eager loading table(s) (one of: #{string_tables.join(', ')}) " \
          "that are referenced in a string SQL snippet. For example: \n" \
          "\n" \
          "    Post.includes(:comments).where(\"comments.title = 'foo'\")\n" \
          "\n" \
          "Currently, Active Record recognises the table in the string, and knows to JOIN the " \
          "comments table to the query, rather than loading comments in a separate query. " \
          "However, doing this without writing a full-blown SQL parser is inherently flawed. " \
          "Since we don't want to write an SQL parser, we are removing this functionality. " \
          "From now on, you must explicitly tell Active Record when you are referencing a table " \
          "from a string:\n" \
          "\n" \
          "    Post.includes(:comments).where(\"comments.title = 'foo'\").references(:comments)\n\n"
        )
        true
      else
        false
      end
    end

    def tables_in_string(string)
      return [] if string.blank?
      # always convert table names to downcase as in Oracle quoted table names are in uppercase
      # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries
      string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map{ |s| s.downcase }.uniq - ['raw_sql_']
    end
  end
end
module ActiveRecord
  ###
  # This class encapsulates a Result returned from calling +exec_query+ on any
  # database connection adapter. For example:
  #
  #   x = ActiveRecord::Base.connection.exec_query('SELECT * FROM foo')
  #   x # => #<ActiveRecord::Result:0xdeadbeef>
  class Result
    include Enumerable

    attr_reader :columns, :rows, :column_types

    def initialize(columns, rows, column_types = {})
      @columns      = columns
      @rows         = rows
      @hash_rows    = nil
      @column_types = column_types
    end

    def each
      hash_rows.each { |row| yield row }
    end

    def to_hash
      hash_rows
    end

    alias :map! :map
    alias :collect! :map

    # Returns true if there are no records.
    def empty?
      rows.empty?
    end

    def to_ary
      hash_rows
    end

    def [](idx)
      hash_rows[idx]
    end

    def last
      hash_rows.last
    end

    def initialize_copy(other)
      @columns   = columns.dup
      @rows      = rows.dup
      @hash_rows = nil
    end

    private
    def hash_rows
      @hash_rows ||=
        begin
          # We freeze the strings to prevent them getting duped when
          # used as keys in ActiveRecord::Base's @attributes hash
          columns = @columns.map { |c| c.dup.freeze }
          @rows.map { |row|
            Hash[columns.zip(row)]
          }
        end
    end
  end
end
module ActiveRecord
  module Sanitization
    extend ActiveSupport::Concern

    module ClassMethods
      def quote_value(value, column = nil) #:nodoc:
        connection.quote(value,column)
      end

      # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
      def sanitize(object) #:nodoc:
        connection.quote(object)
      end

      protected

      # Accepts an array, hash, or string of SQL conditions and sanitizes
      # them into a valid SQL fragment for a WHERE clause.
      #   ["name='%s' and group_id='%s'", "foo'bar", 4]  returns  "name='foo''bar' and group_id='4'"
      #   { name: "foo'bar", group_id: 4 }  returns "name='foo''bar' and group_id='4'"
      #   "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
      def sanitize_sql_for_conditions(condition, table_name = self.table_name)
        return nil if condition.blank?

        case condition
        when Array; sanitize_sql_array(condition)
        when Hash;  sanitize_sql_hash_for_conditions(condition, table_name)
        else        condition
        end
      end
      alias_method :sanitize_sql, :sanitize_sql_for_conditions

      # Accepts an array, hash, or string of SQL conditions and sanitizes
      # them into a valid SQL fragment for a SET clause.
      #   { name: nil, group_id: 4 }  returns "name = NULL , group_id='4'"
      def sanitize_sql_for_assignment(assignments, default_table_name = self.table_name)
        case assignments
        when Array; sanitize_sql_array(assignments)
        when Hash;  sanitize_sql_hash_for_assignment(assignments, default_table_name)
        else        assignments
        end
      end

      # Accepts a hash of SQL conditions and replaces those attributes
      # that correspond to a +composed_of+ relationship with their expanded
      # aggregate attribute values.
      # Given:
      #     class Person < ActiveRecord::Base
      #       composed_of :address, class_name: "Address",
      #         mapping: [%w(address_street street), %w(address_city city)]
      #     end
      # Then:
      #     { address: Address.new("813 abc st.", "chicago") }
      #       # => { address_street: "813 abc st.", address_city: "chicago" }
      def expand_hash_conditions_for_aggregates(attrs)
        expanded_attrs = {}
        attrs.each do |attr, value|
          if aggregation = reflect_on_aggregation(attr.to_sym)
            mapping = aggregation.mapping
            mapping.each do |field_attr, aggregate_attr|
              if mapping.size == 1 && !value.respond_to?(aggregate_attr)
                expanded_attrs[field_attr] = value
              else
                expanded_attrs[field_attr] = value.send(aggregate_attr)
              end
            end
          else
            expanded_attrs[attr] = value
          end
        end
        expanded_attrs
      end

      # Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.
      #   { name: "foo'bar", group_id: 4 }
      #     # => "name='foo''bar' and group_id= 4"
      #   { status: nil, group_id: [1,2,3] }
      #     # => "status IS NULL and group_id IN (1,2,3)"
      #   { age: 13..18 }
      #     # => "age BETWEEN 13 AND 18"
      #   { 'other_records.id' => 7 }
      #     # => "`other_records`.`id` = 7"
      #   { other_records: { id: 7 } }
      #     # => "`other_records`.`id` = 7"
      # And for value objects on a composed_of relationship:
      #   { address: Address.new("123 abc st.", "chicago") }
      #     # => "address_street='123 abc st.' and address_city='chicago'"
      def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name)
        attrs = expand_hash_conditions_for_aggregates(attrs)

        table = Arel::Table.new(table_name, arel_engine).alias(default_table_name)
        PredicateBuilder.build_from_hash(self.class, attrs, table).map { |b|
          connection.visitor.accept b
        }.join(' AND ')
      end
      alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions

      # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
      #   { status: nil, group_id: 1 }
      #     # => "status = NULL , group_id = 1"
      def sanitize_sql_hash_for_assignment(attrs, table)
        attrs.map do |attr, value|
          "#{connection.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value)}"
        end.join(', ')
      end

      # Accepts an array of conditions. The array has each value
      # sanitized and interpolated into the SQL statement.
      #   ["name='%s' and group_id='%s'", "foo'bar", 4]  returns  "name='foo''bar' and group_id='4'"
      def sanitize_sql_array(ary)
        statement, *values = ary
        if values.first.is_a?(Hash) && statement =~ /:\w+/
          replace_named_bind_variables(statement, values.first)
        elsif statement.include?('?')
          replace_bind_variables(statement, values)
        elsif statement.blank?
          statement
        else
          statement % values.collect { |value| connection.quote_string(value.to_s) }
        end
      end

      alias_method :sanitize_conditions, :sanitize_sql

      def replace_bind_variables(statement, values) #:nodoc:
        raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
        bound = values.dup
        c = connection
        statement.gsub('?') { quote_bound_value(bound.shift, c) }
      end

      def replace_named_bind_variables(statement, bind_vars) #:nodoc:
        statement.gsub(/(:?):([a-zA-Z]\w*)/) do
          if $1 == ':' # skip postgresql casts
            $& # return the whole match
          elsif bind_vars.include?(match = $2.to_sym)
            quote_bound_value(bind_vars[match])
          else
            raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
          end
        end
      end

      def quote_bound_value(value, c = connection) #:nodoc:
        if value.respond_to?(:map) && !value.acts_like?(:string)
          if value.respond_to?(:empty?) && value.empty?
            c.quote(nil)
          else
            value.map { |v| c.quote(v) }.join(',')
          end
        else
          c.quote(value)
        end
      end

      def raise_if_bind_arity_mismatch(statement, expected, provided) #:nodoc:
        unless expected == provided
          raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
        end
      end
    end

    # TODO: Deprecate this
    def quoted_id
      self.class.quote_value(id, column_for_attribute(self.class.primary_key))
    end
  end
end

module ActiveRecord
  # = Active Record Schema
  #
  # Allows programmers to programmatically define a schema in a portable
  # DSL. This means you can define tables, indexes, etc. without using SQL
  # directly, so your applications can more easily support multiple
  # databases.
  #
  # Usage:
  #
  #   ActiveRecord::Schema.define do
  #     create_table :authors do |t|
  #       t.string :name, null: false
  #     end
  #
  #     add_index :authors, :name, :unique
  #
  #     create_table :posts do |t|
  #       t.integer :author_id, null: false
  #       t.string :subject
  #       t.text :body
  #       t.boolean :private, default: false
  #     end
  #
  #     add_index :posts, :author_id
  #   end
  #
  # ActiveRecord::Schema is only supported by database adapters that also
  # support migrations, the two features being very similar.
  class Schema < Migration

    # Returns the migrations paths.
    #
    #   ActiveRecord::Schema.new.migrations_paths
    #   # => ["db/migrate"] # Rails migration path by default.
    def migrations_paths
      ActiveRecord::Migrator.migrations_paths
    end

    def define(info, &block) # :nodoc:
      instance_eval(&block)

      unless info[:version].blank?
        initialize_schema_migrations_table
        assume_migrated_upto_version(info[:version], migrations_paths)
      end
    end

    # Eval the given block. All methods available to the current connection
    # adapter are available within the block, so you can easily use the
    # database definition DSL to build up your schema (+create_table+,
    # +add_index+, etc.).
    #
    # The +info+ hash is optional, and if given is used to define metadata
    # about the current schema (currently, only the schema's version):
    #
    #   ActiveRecord::Schema.define(version: 20380119000001) do
    #     ...
    #   end
    def self.define(info={}, &block)
      new.define(info, &block)
    end
  end
end
require 'stringio'
require 'active_support/core_ext/big_decimal'

module ActiveRecord
  # = Active Record Schema Dumper
  #
  # This class is used to dump the database schema for some connection to some
  # output format (i.e., ActiveRecord::Schema).
  class SchemaDumper #:nodoc:
    private_class_method :new

    ##
    # :singleton-method:
    # A list of tables which should not be dumped to the schema.
    # Acceptable values are strings as well as regexp.
    # This setting is only used if ActiveRecord::Base.schema_format == :ruby
    cattr_accessor :ignore_tables
    @@ignore_tables = []

    def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT)
      new(connection).dump(stream)
      stream
    end

    def dump(stream)
      header(stream)
      extensions(stream)
      tables(stream)
      trailer(stream)
      stream
    end

    private

      def initialize(connection)
        @connection = connection
        @types = @connection.native_database_types
        @version = Migrator::current_version rescue nil
      end

      def header(stream)
        define_params = @version ? "version: #{@version}" : ""

        if stream.respond_to?(:external_encoding) && stream.external_encoding
          stream.puts "# encoding: #{stream.external_encoding.name}"
        end

        stream.puts <<HEADER
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(#{define_params}) do

HEADER
      end

      def trailer(stream)
        stream.puts "end"
      end

      def extensions(stream)
        return unless @connection.supports_extensions?
        extensions = @connection.extensions
        if extensions.any?
          stream.puts "  # These are extensions that must be enabled in order to support this database"
          extensions.each do |extension|
            stream.puts "  enable_extension #{extension.inspect}"
          end
          stream.puts
        end
      end

      def tables(stream)
        @connection.tables.sort.each do |tbl|
          next if ['schema_migrations', ignore_tables].flatten.any? do |ignored|
            case ignored
            when String; remove_prefix_and_suffix(tbl) == ignored
            when Regexp; remove_prefix_and_suffix(tbl) =~ ignored
            else
              raise StandardError, 'ActiveRecord::SchemaDumper.ignore_tables accepts an array of String and / or Regexp values.'
            end
          end
          table(tbl, stream)
        end
      end

      def table(table, stream)
        columns = @connection.columns(table)
        begin
          tbl = StringIO.new

          # first dump primary key column
          if @connection.respond_to?(:pk_and_sequence_for)
            pk, _ = @connection.pk_and_sequence_for(table)
          elsif @connection.respond_to?(:primary_key)
            pk = @connection.primary_key(table)
          end

          tbl.print "  create_table #{remove_prefix_and_suffix(table).inspect}"
          if columns.detect { |c| c.name == pk }
            if pk != 'id'
              tbl.print %Q(, primary_key: "#{pk}")
            end
          else
            tbl.print ", id: false"
          end
          tbl.print ", force: true"
          tbl.puts " do |t|"

          # then dump all non-primary key columns
          column_specs = columns.map do |column|
            raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
            next if column.name == pk
            @connection.column_spec(column, @types)
          end.compact

          # find all migration keys used in this table
          keys = @connection.migration_keys

          # figure out the lengths for each column based on above keys
          lengths = keys.map { |key|
            column_specs.map { |spec|
              spec[key] ? spec[key].length + 2 : 0
            }.max
          }

          # the string we're going to sprintf our values against, with standardized column widths
          format_string = lengths.map{ |len| "%-#{len}s" }

          # find the max length for the 'type' column, which is special
          type_length = column_specs.map{ |column| column[:type].length }.max

          # add column type definition to our format string
          format_string.unshift "    t.%-#{type_length}s "

          format_string *= ''

          column_specs.each do |colspec|
            values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
            values.unshift colspec[:type]
            tbl.print((format_string % values).gsub(/,\s*$/, ''))
            tbl.puts
          end

          tbl.puts "  end"
          tbl.puts

          indexes(table, tbl)

          tbl.rewind
          stream.print tbl.read
        rescue => e
          stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
          stream.puts "#   #{e.message}"
          stream.puts
        end

        stream
      end

      def indexes(table, stream)
        if (indexes = @connection.indexes(table)).any?
          add_index_statements = indexes.map do |index|
            statement_parts = [
              ('add_index ' + remove_prefix_and_suffix(index.table).inspect),
              index.columns.inspect,
              ('name: ' + index.name.inspect),
            ]
            statement_parts << 'unique: true' if index.unique

            index_lengths = (index.lengths || []).compact
            statement_parts << ('length: ' + Hash[index.columns.zip(index.lengths)].inspect) unless index_lengths.empty?

            index_orders = (index.orders || {})
            statement_parts << ('order: ' + index.orders.inspect) unless index_orders.empty?

            statement_parts << ('where: ' + index.where.inspect) if index.where

            '  ' + statement_parts.join(', ')
          end

          stream.puts add_index_statements.sort.join("\n")
          stream.puts
        end
      end

      def remove_prefix_and_suffix(table)
        table.gsub(/^(#{ActiveRecord::Base.table_name_prefix})(.+)(#{ActiveRecord::Base.table_name_suffix})$/,  "\\2")
      end
  end
end
require 'active_record/scoping/default'
require 'active_record/scoping/named'
require 'active_record/base'

module ActiveRecord
  class SchemaMigration < ActiveRecord::Base

    def self.table_name
      "#{Base.table_name_prefix}schema_migrations#{Base.table_name_suffix}"
    end

    def self.index_name
      "#{Base.table_name_prefix}unique_schema_migrations#{Base.table_name_suffix}"
    end

    def self.create_table
      unless connection.table_exists?(table_name)
        connection.create_table(table_name, :id => false) do |t|
          t.column :version, :string, :null => false
        end
        connection.add_index table_name, :version, :unique => true, :name => index_name
      end
    end

    def self.drop_table
      if connection.table_exists?(table_name)
        connection.remove_index table_name, :name => index_name
        connection.drop_table(table_name)
      end
    end

    def version
      super.to_i
    end
  end
end
module ActiveRecord
  module Scoping
    module Default
      extend ActiveSupport::Concern

      included do
        # Stores the default scope for the class.
        class_attribute :default_scopes, instance_writer: false
        self.default_scopes = []
      end

      module ClassMethods
        # Returns a scope for the model without the +default_scope+.
        #
        #   class Post < ActiveRecord::Base
        #     def self.default_scope
        #       where published: true
        #     end
        #   end
        #
        #   Post.all          # Fires "SELECT * FROM posts WHERE published = true"
        #   Post.unscoped.all # Fires "SELECT * FROM posts"
        #
        # This method also accepts a block. All queries inside the block will
        # not use the +default_scope+:
        #
        #   Post.unscoped {
        #     Post.limit(10) # Fires "SELECT * FROM posts LIMIT 10"
        #   }
        #
        # It is recommended that you use the block form of unscoped because
        # chaining unscoped with +scope+ does not work. Assuming that
        # +published+ is a +scope+, the following two statements
        # are equal: the +default_scope+ is applied on both.
        #
        #   Post.unscoped.published
        #   Post.published
        def unscoped
          block_given? ? relation.scoping { yield } : relation
        end

        def before_remove_const #:nodoc:
          self.current_scope = nil
        end

        protected

        # Use this macro in your model to set a default scope for all operations on
        # the model.
        #
        #   class Article < ActiveRecord::Base
        #     default_scope { where(published: true) }
        #   end
        #
        #   Article.all # => SELECT * FROM articles WHERE published = true
        #
        # The +default_scope+ is also applied while creating/building a record.
        # It is not applied while updating a record.
        #
        #   Article.new.published    # => true
        #   Article.create.published # => true
        #
        # (You can also pass any object which responds to +call+ to the
        # +default_scope+ macro, and it will be called when building the
        # default scope.)
        #
        # If you use multiple +default_scope+ declarations in your model then
        # they will be merged together:
        #
        #   class Article < ActiveRecord::Base
        #     default_scope { where(published: true) }
        #     default_scope { where(rating: 'G') }
        #   end
        #
        #   Article.all # => SELECT * FROM articles WHERE published = true AND rating = 'G'
        #
        # This is also the case with inheritance and module includes where the
        # parent or module defines a +default_scope+ and the child or including
        # class defines a second one.
        #
        # If you need to do more complex things with a default scope, you can
        # alternatively define it as a class method:
        #
        #   class Article < ActiveRecord::Base
        #     def self.default_scope
        #       # Should return a scope, you can call 'super' here etc.
        #     end
        #   end
        def default_scope(scope = nil)
          scope = Proc.new if block_given?

          if scope.is_a?(Relation) || !scope.respond_to?(:call)
            ActiveSupport::Deprecation.warn(
              "Calling #default_scope without a block is deprecated. For example instead " \
              "of `default_scope where(color: 'red')`, please use " \
              "`default_scope { where(color: 'red') }`. (Alternatively you can just redefine " \
              "self.default_scope.)"
            )
          end

          self.default_scopes += [scope]
        end

        def build_default_scope # :nodoc:
          if !Base.is_a?(method(:default_scope).owner)
            # The user has defined their own default scope method, so call that
            evaluate_default_scope { default_scope }
          elsif default_scopes.any?
            evaluate_default_scope do
              default_scopes.inject(relation) do |default_scope, scope|
                if !scope.is_a?(Relation) && scope.respond_to?(:call)
                  default_scope.merge(unscoped { scope.call })
                else
                  default_scope.merge(scope)
                end
              end
            end
          end
        end

        def ignore_default_scope? # :nodoc:
          Thread.current["#{self}_ignore_default_scope"]
        end

        def ignore_default_scope=(ignore) # :nodoc:
          Thread.current["#{self}_ignore_default_scope"] = ignore
        end

        # The ignore_default_scope flag is used to prevent an infinite recursion
        # situation where a default scope references a scope which has a default
        # scope which references a scope...
        def evaluate_default_scope # :nodoc:
          return if ignore_default_scope?

          begin
            self.ignore_default_scope = true
            yield
          ensure
            self.ignore_default_scope = false
          end
        end
      end
    end
  end
end
require 'active_support/core_ext/array'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/kernel/singleton_class'

module ActiveRecord
  # = Active Record \Named \Scopes
  module Scoping
    module Named
      extend ActiveSupport::Concern

      module ClassMethods
        # Returns an <tt>ActiveRecord::Relation</tt> scope object.
        #
        #   posts = Post.all
        #   posts.size # Fires "select count(*) from  posts" and returns the count
        #   posts.each {|p| puts p.name } # Fires "select * from posts" and loads post objects
        #
        #   fruits = Fruit.all
        #   fruits = fruits.where(color: 'red') if options[:red_only]
        #   fruits = fruits.limit(10) if limited?
        #
        # You can define a scope that applies to all finders using
        # <tt>ActiveRecord::Base.default_scope</tt>.
        def all
          if current_scope
            current_scope.clone
          else
            scope = relation
            scope.default_scoped = true
            scope
          end
        end

        # Collects attributes from scopes that should be applied when creating
        # an AR instance for the particular class this is called on.
        def scope_attributes # :nodoc:
          if current_scope
            current_scope.scope_for_create
          else
            scope = relation
            scope.default_scoped = true
            scope.scope_for_create
          end
        end

        # Are there default attributes associated with this scope?
        def scope_attributes? # :nodoc:
          current_scope || default_scopes.any?
        end

        # Adds a class method for retrieving and querying objects. A \scope
        # represents a narrowing of a database query, such as
        # <tt>where(color: :red).select('shirts.*').includes(:washing_instructions)</tt>.
        #
        #   class Shirt < ActiveRecord::Base
        #     scope :red, -> { where(color: 'red') }
        #     scope :dry_clean_only, -> { joins(:washing_instructions).where('washing_instructions.dry_clean_only = ?', true) }
        #   end
        #
        # The above calls to +scope+ define class methods <tt>Shirt.red</tt> and
        # <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>, in effect,
        # represents the query <tt>Shirt.where(color: 'red')</tt>.
        #
        # You should always pass a callable object to the scopes defined
        # with +scope+. This ensures that the scope is re-evaluated each
        # time it is called.
        #
        # Note that this is simply 'syntactic sugar' for defining an actual
        # class method:
        #
        #   class Shirt < ActiveRecord::Base
        #     def self.red
        #       where(color: 'red')
        #     end
        #   end
        #
        # Unlike <tt>Shirt.find(...)</tt>, however, the object returned by
        # <tt>Shirt.red</tt> is not an Array; it resembles the association object
        # constructed by a +has_many+ declaration. For instance, you can invoke
        # <tt>Shirt.red.first</tt>, <tt>Shirt.red.count</tt>,
        # <tt>Shirt.red.where(size: 'small')</tt>. Also, just as with the
        # association objects, named \scopes act like an Array, implementing
        # Enumerable; <tt>Shirt.red.each(&block)</tt>, <tt>Shirt.red.first</tt>,
        # and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if
        # <tt>Shirt.red</tt> really was an Array.
        #
        # These named \scopes are composable. For instance,
        # <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are
        # both red and dry clean only. Nested finds and calculations also work
        # with these compositions: <tt>Shirt.red.dry_clean_only.count</tt>
        # returns the number of garments for which these criteria obtain.
        # Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
        #
        # All scopes are available as class methods on the ActiveRecord::Base
        # descendant upon which the \scopes were defined. But they are also
        # available to +has_many+ associations. If,
        #
        #   class Person < ActiveRecord::Base
        #     has_many :shirts
        #   end
        #
        # then <tt>elton.shirts.red.dry_clean_only</tt> will return all of
        # Elton's red, dry clean only shirts.
        #
        # \Named scopes can also have extensions, just as with +has_many+
        # declarations:
        #
        #   class Shirt < ActiveRecord::Base
        #     scope :red, -> { where(color: 'red') } do
        #       def dom_id
        #         'red_shirts'
        #       end
        #     end
        #   end
        #
        # Scopes can also be used while creating/building a record.
        #
        #   class Article < ActiveRecord::Base
        #     scope :published, -> { where(published: true) }
        #   end
        #
        #   Article.published.new.published    # => true
        #   Article.published.create.published # => true
        #
        # \Class methods on your model are automatically available
        # on scopes. Assuming the following setup:
        #
        #   class Article < ActiveRecord::Base
        #     scope :published, -> { where(published: true) }
        #     scope :featured, -> { where(featured: true) }
        #
        #     def self.latest_article
        #       order('published_at desc').first
        #     end
        #
        #     def self.titles
        #       pluck(:title)
        #     end
        #   end
        #
        # We are able to call the methods like this:
        #
        #   Article.published.featured.latest_article
        #   Article.featured.titles
        def scope(name, body, &block)
          extension = Module.new(&block) if block

          # Check body.is_a?(Relation) to prevent the relation actually being
          # loaded by respond_to?
          if body.is_a?(Relation) || !body.respond_to?(:call)
            ActiveSupport::Deprecation.warn(
              "Using #scope without passing a callable object is deprecated. For " \
              "example `scope :red, where(color: 'red')` should be changed to " \
              "`scope :red, -> { where(color: 'red') }`. There are numerous gotchas " \
              "in the former usage and it makes the implementation more complicated " \
              "and buggy. (If you prefer, you can just define a class method named " \
              "`self.red`.)"
            )
          end

          singleton_class.send(:define_method, name) do |*args|
            options  = body.respond_to?(:call) ? unscoped { body.call(*args) } : body
            relation = all.merge(options)

            extension ? relation.extending(extension) : relation
          end
        end
      end
    end
  end
end
module ActiveRecord
  module Scoping
    extend ActiveSupport::Concern

    included do
      include Default
      include Named
    end

    module ClassMethods
      def current_scope #:nodoc:
        Thread.current["#{self}_current_scope"]
      end

      def current_scope=(scope) #:nodoc:
        Thread.current["#{self}_current_scope"] = scope
      end
    end

    def populate_with_current_scope_attributes
      return unless self.class.scope_attributes?

      self.class.scope_attributes.each do |att,value|
        send("#{att}=", value) if respond_to?("#{att}=")
      end
    end
  end
end
module ActiveRecord #:nodoc:
  # = Active Record Serialization
  module Serialization
    extend ActiveSupport::Concern
    include ActiveModel::Serializers::JSON

    included do
      self.include_root_in_json = true
    end

    def serializable_hash(options = nil)
      options = options.try(:clone) || {}

      options[:except] = Array(options[:except]).map { |n| n.to_s }
      options[:except] |= Array(self.class.inheritance_column)

      super(options)
    end
  end
end

require 'active_record/serializers/xml_serializer'
require 'active_support/core_ext/hash/conversions'

module ActiveRecord #:nodoc:
  module Serialization
    include ActiveModel::Serializers::Xml

    # Builds an XML document to represent the model. Some configuration is
    # available through +options+. However more complicated cases should
    # override ActiveRecord::Base#to_xml.
    #
    # By default the generated XML document will include the processing
    # instruction and all the object's attributes. For example:
    #
    #   <?xml version="1.0" encoding="UTF-8"?>
    #   <topic>
    #     <title>The First Topic</title>
    #     <author-name>David</author-name>
    #     <id type="integer">1</id>
    #     <approved type="boolean">false</approved>
    #     <replies-count type="integer">0</replies-count>
    #     <bonus-time type="dateTime">2000-01-01T08:28:00+12:00</bonus-time>
    #     <written-on type="dateTime">2003-07-16T09:28:00+1200</written-on>
    #     <content>Have a nice day</content>
    #     <author-email-address>david@loudthinking.com</author-email-address>
    #     <parent-id></parent-id>
    #     <last-read type="date">2004-04-15</last-read>
    #   </topic>
    #
    # This behavior can be controlled with <tt>:only</tt>, <tt>:except</tt>,
    # <tt>:skip_instruct</tt>, <tt>:skip_types</tt>, <tt>:dasherize</tt> and <tt>:camelize</tt> .
    # The <tt>:only</tt> and <tt>:except</tt> options are the same as for the
    # +attributes+ method. The default is to dasherize all column names, but you
    # can disable this setting <tt>:dasherize</tt> to +false+. Setting <tt>:camelize</tt>
    # to +true+ will camelize all column names - this also overrides <tt>:dasherize</tt>.
    # To not have the column type included in the XML output set <tt>:skip_types</tt> to +true+.
    #
    # For instance:
    #
    #   topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ])
    #
    #   <topic>
    #     <title>The First Topic</title>
    #     <author-name>David</author-name>
    #     <approved type="boolean">false</approved>
    #     <content>Have a nice day</content>
    #     <author-email-address>david@loudthinking.com</author-email-address>
    #     <parent-id></parent-id>
    #     <last-read type="date">2004-04-15</last-read>
    #   </topic>
    #
    # To include first level associations use <tt>:include</tt>:
    #
    #   firm.to_xml include: [ :account, :clients ]
    #
    #   <?xml version="1.0" encoding="UTF-8"?>
    #   <firm>
    #     <id type="integer">1</id>
    #     <rating type="integer">1</rating>
    #     <name>37signals</name>
    #     <clients type="array">
    #       <client>
    #         <rating type="integer">1</rating>
    #         <name>Summit</name>
    #       </client>
    #       <client>
    #         <rating type="integer">1</rating>
    #         <name>Microsoft</name>
    #       </client>
    #     </clients>
    #     <account>
    #       <id type="integer">1</id>
    #       <credit-limit type="integer">50</credit-limit>
    #     </account>
    #   </firm>
    #
    # Additionally, the record being serialized will be passed to a Proc's second
    # parameter. This allows for ad hoc additions to the resultant document that
    # incorporate the context of the record being serialized. And by leveraging the
    # closure created by a Proc, to_xml can be used to add elements that normally fall
    # outside of the scope of the model -- for example, generating and appending URLs
    # associated with models.
    #
    #   proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
    #   firm.to_xml procs: [ proc ]
    #
    #   <firm>
    #     # ... normal attributes as shown above ...
    #     <name-reverse>slangis73</name-reverse>
    #   </firm>
    #
    # To include deeper levels of associations pass a hash like this:
    #
    #   firm.to_xml include: {account: {}, clients: {include: :address}}
    #   <?xml version="1.0" encoding="UTF-8"?>
    #   <firm>
    #     <id type="integer">1</id>
    #     <rating type="integer">1</rating>
    #     <name>37signals</name>
    #     <clients type="array">
    #       <client>
    #         <rating type="integer">1</rating>
    #         <name>Summit</name>
    #         <address>
    #           ...
    #         </address>
    #       </client>
    #       <client>
    #         <rating type="integer">1</rating>
    #         <name>Microsoft</name>
    #         <address>
    #           ...
    #         </address>
    #       </client>
    #     </clients>
    #     <account>
    #       <id type="integer">1</id>
    #       <credit-limit type="integer">50</credit-limit>
    #     </account>
    #   </firm>
    #
    # To include any methods on the model being called use <tt>:methods</tt>:
    #
    #   firm.to_xml methods: [ :calculated_earnings, :real_earnings ]
    #
    #   <firm>
    #     # ... normal attributes as shown above ...
    #     <calculated-earnings>100000000000000000</calculated-earnings>
    #     <real-earnings>5</real-earnings>
    #   </firm>
    #
    # To call any additional Procs use <tt>:procs</tt>. The Procs are passed a
    # modified version of the options hash that was given to +to_xml+:
    #
    #   proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
    #   firm.to_xml procs: [ proc ]
    #
    #   <firm>
    #     # ... normal attributes as shown above ...
    #     <abc>def</abc>
    #   </firm>
    #
    # Alternatively, you can yield the builder object as part of the +to_xml+ call:
    #
    #   firm.to_xml do |xml|
    #     xml.creator do
    #       xml.first_name "David"
    #       xml.last_name "Heinemeier Hansson"
    #     end
    #   end
    #
    #   <firm>
    #     # ... normal attributes as shown above ...
    #     <creator>
    #       <first_name>David</first_name>
    #       <last_name>Heinemeier Hansson</last_name>
    #     </creator>
    #   </firm>
    #
    # As noted above, you may override +to_xml+ in your ActiveRecord::Base
    # subclasses to have complete control about what's generated. The general
    # form of doing this is:
    #
    #   class IHaveMyOwnXML < ActiveRecord::Base
    #     def to_xml(options = {})
    #       require 'builder'
    #       options[:indent] ||= 2
    #       xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent])
    #       xml.instruct! unless options[:skip_instruct]
    #       xml.level_one do
    #         xml.tag!(:second_level, 'content')
    #       end
    #     end
    #   end
    def to_xml(options = {}, &block)
      XmlSerializer.new(self, options).serialize(&block)
    end
  end

  class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
    class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
      def compute_type
        klass = @serializable.class
        type = if klass.serialized_attributes.key?(name)
                 super
               elsif klass.columns_hash.key?(name)
                 klass.columns_hash[name].type
               else
                 NilClass
               end

        { :text => :string,
          :time => :datetime }[type] || type
      end
      protected :compute_type
    end
  end
end
require 'active_support/core_ext/hash/indifferent_access'

module ActiveRecord
  # Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column.
  # It's like a simple key/value store baked into your record when you don't care about being able to
  # query that store outside the context of a single record.
  #
  # You can then declare accessors to this store that are then accessible just like any other attribute
  # of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's
  # already built around just accessing attributes on the model.
  #
  # Make sure that you declare the database column used for the serialized store as a text, so there's
  # plenty of room.
  #
  # You can set custom coder to encode/decode your serialized attributes to/from different formats.
  # JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides +load+ and +dump+.
  #
  # Examples:
  #
  #   class User < ActiveRecord::Base
  #     store :settings, accessors: [ :color, :homepage ], coder: JSON
  #   end
  #
  #   u = User.new(color: 'black', homepage: '37signals.com')
  #   u.color                          # Accessor stored attribute
  #   u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
  #
  #   # There is no difference between strings and symbols for accessing custom attributes
  #   u.settings[:country]  # => 'Denmark'
  #   u.settings['country'] # => 'Denmark'
  #
  #   # Add additional accessors to an existing store through store_accessor
  #   class SuperUser < User
  #     store_accessor :settings, :privileges, :servants
  #   end
  #
  # The stored attribute names can be retrieved using +stored_attributes+.
  #
  #   User.stored_attributes[:settings] # [:color, :homepage]
  #
  # == Overwriting default accessors
  #
  # All stored values are automatically available through accessors on the Active Record
  # object, but sometimes you want to specialize this behavior. This can be done by overwriting
  # the default accessors (using the same name as the attribute) and calling <tt>super</tt>
  # to actually change things.
  #
  #   class Song < ActiveRecord::Base
  #     # Uses a stored integer to hold the volume adjustment of the song
  #     store :settings, accessors: [:volume_adjustment]
  #
  #     def volume_adjustment=(decibels)
  #       super(decibels.to_i)
  #     end
  #
  #     def volume_adjustment
  #       super.to_i
  #     end
  #   end
  module Store
    extend ActiveSupport::Concern

    included do
      class_attribute :stored_attributes, instance_accessor: false
      self.stored_attributes = {}
    end

    module ClassMethods
      def store(store_attribute, options = {})
        serialize store_attribute, IndifferentCoder.new(options[:coder])
        store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors
      end

      def store_accessor(store_attribute, *keys)
        keys = keys.flatten

        _store_accessors_module.module_eval do
          keys.each do |key|
            define_method("#{key}=") do |value|
              write_store_attribute(store_attribute, key, value)
            end

            define_method(key) do
              read_store_attribute(store_attribute, key)
            end
          end
        end

        self.stored_attributes[store_attribute] ||= []
        self.stored_attributes[store_attribute] |= keys
      end

      def _store_accessors_module
        @_store_accessors_module ||= begin
          mod = Module.new
          include mod
          mod
        end
      end
    end

    protected
      def read_store_attribute(store_attribute, key)
        attribute = initialize_store_attribute(store_attribute)
        attribute[key]
      end

      def write_store_attribute(store_attribute, key, value)
        attribute = initialize_store_attribute(store_attribute)
        if value != attribute[key]
          send :"#{store_attribute}_will_change!"
          attribute[key] = value
        end
      end

    private
      def initialize_store_attribute(store_attribute)
        attribute = send(store_attribute)
        unless attribute.is_a?(ActiveSupport::HashWithIndifferentAccess)
          attribute = IndifferentCoder.as_indifferent_hash(attribute)
          send :"#{store_attribute}=", attribute
        end
        attribute
      end

    class IndifferentCoder # :nodoc:
      def initialize(coder_or_class_name)
        @coder =
          if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
            coder_or_class_name
          else
            ActiveRecord::Coders::YAMLColumn.new(coder_or_class_name || Object)
          end
      end

      def dump(obj)
        @coder.dump self.class.as_indifferent_hash(obj)
      end

      def load(yaml)
        self.class.as_indifferent_hash @coder.load(yaml)
      end

      def self.as_indifferent_hash(obj)
        case obj
        when ActiveSupport::HashWithIndifferentAccess
          obj
        when Hash
          obj.with_indifferent_access
        else
          ActiveSupport::HashWithIndifferentAccess.new
        end
      end
    end
  end
end
module ActiveRecord
  module Tasks # :nodoc:
    class DatabaseAlreadyExists < StandardError; end # :nodoc:
    class DatabaseNotSupported < StandardError; end # :nodoc:

    module DatabaseTasks # :nodoc:
      extend self

      attr_writer :current_config

      LOCAL_HOSTS    = ['127.0.0.1', 'localhost']

      def register_task(pattern, task)
        @tasks ||= {}
        @tasks[pattern] = task
      end

      register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
      register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
      register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)

      def current_config(options = {})
        options.reverse_merge! :env => Rails.env
        if options.has_key?(:config)
          @current_config = options[:config]
        else
          @current_config ||= if ENV['DATABASE_URL']
                                database_url_config
                              else
                                ActiveRecord::Base.configurations[options[:env]]
                              end
        end
      end

      def create(*arguments)
        configuration = arguments.first
        class_for_adapter(configuration['adapter']).new(*arguments).create
      rescue DatabaseAlreadyExists
        $stderr.puts "#{configuration['database']} already exists"
      rescue Exception => error
        $stderr.puts error, *(error.backtrace)
        $stderr.puts "Couldn't create database for #{configuration.inspect}"
      end

      def create_all
        each_local_configuration { |configuration| create configuration }
      end

      def create_current(environment = Rails.env)
        each_current_configuration(environment) { |configuration|
          create configuration
        }
        ActiveRecord::Base.establish_connection environment
      end

      def create_database_url
        create database_url_config
      end

      def drop(*arguments)
        configuration = arguments.first
        class_for_adapter(configuration['adapter']).new(*arguments).drop
      rescue Exception => error
        $stderr.puts error, *(error.backtrace)
        $stderr.puts "Couldn't drop #{configuration['database']}"
      end

      def drop_all
        each_local_configuration { |configuration| drop configuration }
      end

      def drop_current(environment = Rails.env)
        each_current_configuration(environment) { |configuration|
          drop configuration
        }
      end

      def drop_database_url
        drop database_url_config
      end

      def charset_current(environment = Rails.env)
        charset ActiveRecord::Base.configurations[environment]
      end

      def charset(*arguments)
        configuration = arguments.first
        class_for_adapter(configuration['adapter']).new(*arguments).charset
      end

      def collation_current(environment = Rails.env)
        collation ActiveRecord::Base.configurations[environment]
      end

      def collation(*arguments)
        configuration = arguments.first
        class_for_adapter(configuration['adapter']).new(*arguments).collation
      end

      def purge(configuration)
        class_for_adapter(configuration['adapter']).new(configuration).purge
      end

      def structure_dump(*arguments)
        configuration = arguments.first
        filename = arguments.delete_at 1
        class_for_adapter(configuration['adapter']).new(*arguments).structure_dump(filename)
      end

      def structure_load(*arguments)
        configuration = arguments.first
        filename = arguments.delete_at 1
        class_for_adapter(configuration['adapter']).new(*arguments).structure_load(filename)
      end

      private

      def database_url_config
        @database_url_config ||=
               ConnectionAdapters::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
      end

      def class_for_adapter(adapter)
        key = @tasks.keys.detect { |pattern| adapter[pattern] }
        unless key
          raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
        end
        @tasks[key]
      end

      def each_current_configuration(environment)
        environments = [environment]
        environments << 'test' if environment.development?

        configurations = ActiveRecord::Base.configurations.values_at(*environments)
        configurations.compact.each do |configuration|
          yield configuration unless configuration['database'].blank?
        end
      end

      def each_local_configuration
        ActiveRecord::Base.configurations.each_value do |configuration|
          next unless configuration['database']

          if local_database?(configuration)
            yield configuration
          else
            $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
          end
        end
      end

      def local_database?(configuration)
        configuration['host'].blank? || LOCAL_HOSTS.include?(configuration['host'])
      end
    end
  end
end
module ActiveRecord
  module Tasks # :nodoc:
    class MySQLDatabaseTasks # :nodoc:
      DEFAULT_CHARSET     = ENV['CHARSET']   || 'utf8'
      DEFAULT_COLLATION   = ENV['COLLATION'] || 'utf8_unicode_ci'
      ACCESS_DENIED_ERROR = 1045

      delegate :connection, :establish_connection, to: ActiveRecord::Base

      def initialize(configuration)
        @configuration = configuration
      end

      def create
        establish_connection configuration_without_database
        connection.create_database configuration['database'], creation_options
        establish_connection configuration
      rescue ActiveRecord::StatementInvalid => error
        if /database exists/ === error.message
          raise DatabaseAlreadyExists
        else
          raise
        end
      rescue error_class => error
        if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
          $stdout.print error.error
          establish_connection root_configuration_without_database
          connection.create_database configuration['database'], creation_options
          connection.execute grant_statement.gsub(/\s+/, ' ').strip
          establish_connection configuration
        else
          $stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
          $stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration['encoding']
        end
      end

      def drop
        establish_connection configuration
        connection.drop_database configuration['database']
      end

      def purge
        establish_connection :test
        connection.recreate_database configuration['database'], creation_options
      end

      def charset
        connection.charset
      end

      def collation
        connection.collation
      end

      def structure_dump(filename)
        args = prepare_command_options('mysqldump')
        args.concat(["--result-file", "#{filename}"])
        args.concat(["--no-data"])
        args.concat(["#{configuration['database']}"])
        Kernel.system(*args)
      end

      def structure_load(filename)
        args = prepare_command_options('mysql')
        args.concat(['--execute', %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
        args.concat(["--database", "#{configuration['database']}"])
        Kernel.system(*args)
      end

      private

      def configuration
        @configuration
      end

      def configuration_without_database
        configuration.merge('database' => nil)
      end

      def creation_options
        Hash.new.tap do |options|
          options[:charset]     = configuration['encoding']   if configuration.include? 'encoding'
          options[:collation]   = configuration['collation']  if configuration.include? 'collation'

          # Set default charset only when collation isn't set.
          options[:charset]   ||= DEFAULT_CHARSET unless options[:collation]

          # Set default collation only when charset is also default.
          options[:collation] ||= DEFAULT_COLLATION if options[:charset] == DEFAULT_CHARSET
        end
      end

      def error_class
        if configuration['adapter'] =~ /jdbc/
          require 'active_record/railties/jdbcmysql_error'
          ArJdbcMySQL::Error
        elsif defined?(Mysql2)
          Mysql2::Error
        elsif defined?(Mysql)
          Mysql::Error
        else
          StandardError
        end
      end

      def grant_statement
        <<-SQL
GRANT ALL PRIVILEGES ON #{configuration['database']}.*
  TO '#{configuration['username']}'@'localhost'
IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
        SQL
      end

      def root_configuration_without_database
        configuration_without_database.merge(
          'username' => 'root',
          'password' => root_password
        )
      end

      def root_password
        $stdout.print "Please provide the root password for your mysql installation\n>"
        $stdin.gets.strip
      end

      def prepare_command_options(command)
        args = [command]
        args.concat(['--user', configuration['username']]) if configuration['username']
        args << "--password=#{configuration['password']}"  if configuration['password']
        args.concat(['--default-character-set', configuration['encoding']]) if configuration['encoding']
        configuration.slice('host', 'port', 'socket').each do |k, v|
          args.concat([ "--#{k}", v ]) if v
        end
        args
      end
    end
  end
end
require 'shellwords'

module ActiveRecord
  module Tasks # :nodoc:
    class PostgreSQLDatabaseTasks # :nodoc:
      DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'

      delegate :connection, :establish_connection, :clear_active_connections!,
        to: ActiveRecord::Base

      def initialize(configuration)
        @configuration = configuration
      end

      def create(master_established = false)
        establish_master_connection unless master_established
        connection.create_database configuration['database'],
          configuration.merge('encoding' => encoding)
        establish_connection configuration
      rescue ActiveRecord::StatementInvalid => error
        if /database .* already exists/ === error.message
          raise DatabaseAlreadyExists
        else
          raise
        end
      end

      def drop
        establish_master_connection
        connection.drop_database configuration['database']
      end

      def charset
        connection.encoding
      end

      def collation
        connection.collation
      end

      def purge
        clear_active_connections!
        drop
        create true
      end

      def structure_dump(filename)
        set_psql_env
        search_path = configuration['schema_search_path']
        unless search_path.blank?
          search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
        end

        command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
        raise 'Error dumping database' unless Kernel.system(command)

        File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
      end

      def structure_load(filename)
        set_psql_env
        Kernel.system("psql -f #{filename} #{configuration['database']}")
      end

      private

      def configuration
        @configuration
      end

      def encoding
        configuration['encoding'] || DEFAULT_ENCODING
      end

      def establish_master_connection
        establish_connection configuration.merge(
          'database'           => 'postgres',
          'schema_search_path' => 'public'
        )
      end

      def set_psql_env
        ENV['PGHOST']     = configuration['host']          if configuration['host']
        ENV['PGPORT']     = configuration['port'].to_s     if configuration['port']
        ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
        ENV['PGUSER']     = configuration['username'].to_s if configuration['username']
      end
    end
  end
end
module ActiveRecord
  module Tasks # :nodoc:
    class SQLiteDatabaseTasks # :nodoc:
      delegate :connection, :establish_connection, to: ActiveRecord::Base

      def initialize(configuration, root = Rails.root)
        @configuration, @root = configuration, root
      end

      def create
        raise DatabaseAlreadyExists if File.exist?(configuration['database'])

        establish_connection configuration
        connection
      end

      def drop
        require 'pathname'
        path = Pathname.new configuration['database']
        file = path.absolute? ? path.to_s : File.join(root, path)

        FileUtils.rm(file) if File.exist?(file)
      end
      alias :purge :drop

      def charset
        connection.encoding
      end

      def structure_dump(filename)
        dbfile = configuration['database']
        `sqlite3 #{dbfile} .schema > #{filename}`
      end

      def structure_load(filename)
        dbfile = configuration['database']
        `sqlite3 #{dbfile} < "#{filename}"`
      end

      private

      def configuration
        @configuration
      end

      def root
        @root
      end
    end
  end
end
require 'active_support/test_case'

ActiveSupport::Deprecation.warn('ActiveRecord::TestCase is deprecated, please use ActiveSupport::TestCase')
module ActiveRecord
  # = Active Record Test Case
  #
  # Defines some test assertions to test against SQL queries.
  class TestCase < ActiveSupport::TestCase #:nodoc:
    def teardown
      SQLCounter.clear_log
    end

    def assert_date_from_db(expected, actual, message = nil)
      # SybaseAdapter doesn't have a separate column type just for dates,
      # so the time is in the string and incorrectly formatted
      if current_adapter?(:SybaseAdapter)
        assert_equal expected.to_s, actual.to_date.to_s, message
      else
        assert_equal expected.to_s, actual.to_s, message
      end
    end

    def assert_sql(*patterns_to_match)
      SQLCounter.clear_log
      yield
      SQLCounter.log_all
    ensure
      failed_patterns = []
      patterns_to_match.each do |pattern|
        failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql }
      end
      assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
    end

    def assert_queries(num = 1, options = {})
      ignore_none = options.fetch(:ignore_none) { num == :any }
      SQLCounter.clear_log
      yield
    ensure
      the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
      if num == :any
        assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
      else
        mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
        assert_equal num, the_log.size, mesg
      end
    end

    def assert_no_queries(&block)
      assert_queries(0, :ignore_none => true, &block)
    end

  end

  class SQLCounter
    class << self
      attr_accessor :ignored_sql, :log, :log_all
      def clear_log; self.log = []; self.log_all = []; end
    end

    self.clear_log

    self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]

    # FIXME: this needs to be refactored so specific database can add their own
    # ignored SQL, or better yet, use a different notification for the queries
    # instead examining the SQL content.
    oracle_ignored     = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im]
    mysql_ignored      = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/]
    postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
    sqlite3_ignored =    [/^\s*SELECT name\b.*\bFROM sqlite_master/im]

    [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
      ignored_sql.concat db_ignored_sql
    end

    attr_reader :ignore

    def initialize(ignore = Regexp.union(self.class.ignored_sql))
      @ignore = ignore
    end

    def call(name, start, finish, message_id, values)
      sql = values[:sql]

      # FIXME: this seems bad. we should probably have a better way to indicate
      # the query was cached
      return if 'CACHE' == values[:name]

      self.class.log_all << sql
      self.class.log << sql unless ignore =~ sql
    end
  end

  ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
end

module ActiveRecord
  # = Active Record Timestamp
  #
  # Active Record automatically timestamps create and update operations if the
  # table has fields named <tt>created_at/created_on</tt> or
  # <tt>updated_at/updated_on</tt>.
  #
  # Timestamping can be turned off by setting:
  #
  #   config.active_record.record_timestamps = false
  #
  # Timestamps are in the local timezone by default but you can use UTC by setting:
  #
  #   config.active_record.default_timezone = :utc
  #
  # == Time Zone aware attributes
  #
  # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code.
  #
  #   config.active_record.time_zone_aware_attributes = true
  #
  # This feature can easily be turned off by assigning value <tt>false</tt> .
  #
  # If your attributes are time zone aware and you desire to skip time zone conversion to the current Time.zone
  # when reading certain attributes then you can do following:
  #
  #   class Topic < ActiveRecord::Base
  #     self.skip_time_zone_conversion_for_attributes = [:written_on]
  #   end
  module Timestamp
    extend ActiveSupport::Concern

    included do
      class_attribute :record_timestamps
      self.record_timestamps = true
    end

    def initialize_dup(other) # :nodoc:
      clear_timestamp_attributes
      super
    end

  private

    def create_record
      if self.record_timestamps
        current_time = current_time_from_proper_timezone

        all_timestamp_attributes.each do |column|
          if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
            write_attribute(column.to_s, current_time)
          end
        end
      end

      super
    end

    def update_record(*args)
      if should_record_timestamps?
        current_time = current_time_from_proper_timezone

        timestamp_attributes_for_update_in_model.each do |column|
          column = column.to_s
          next if attribute_changed?(column)
          write_attribute(column, current_time)
        end
      end
      super
    end

    def should_record_timestamps?
      self.record_timestamps && (!partial_writes? || changed? || (attributes.keys & self.class.serialized_attributes.keys).present?)
    end

    def timestamp_attributes_for_create_in_model
      timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
    end

    def timestamp_attributes_for_update_in_model
      timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
    end

    def all_timestamp_attributes_in_model
      timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
    end

    def timestamp_attributes_for_update
      [:updated_at, :updated_on]
    end

    def timestamp_attributes_for_create
      [:created_at, :created_on]
    end

    def all_timestamp_attributes
      timestamp_attributes_for_create + timestamp_attributes_for_update
    end

    def current_time_from_proper_timezone
      self.class.default_timezone == :utc ? Time.now.utc : Time.now
    end

    # Clear attributes and changed_attributes
    def clear_timestamp_attributes
      all_timestamp_attributes_in_model.each do |attribute_name|
        self[attribute_name] = nil
        changed_attributes.delete(attribute_name)
      end
    end
  end
end
require 'thread'

module ActiveRecord
  # See ActiveRecord::Transactions::ClassMethods for documentation.
  module Transactions
    extend ActiveSupport::Concern
    ACTIONS = [:create, :destroy, :update]

    class TransactionError < ActiveRecordError # :nodoc:
    end

    included do
      define_callbacks :commit, :rollback, :terminator => "result == false", :scope => [:kind, :name]
    end

    # = Active Record Transactions
    #
    # Transactions are protective blocks where SQL statements are only permanent
    # if they can all succeed as one atomic action. The classic example is a
    # transfer between two accounts where you can only have a deposit if the
    # withdrawal succeeded and vice versa. Transactions enforce the integrity of
    # the database and guard the data against program errors or database
    # break-downs. So basically you should use transaction blocks whenever you
    # have a number of statements that must be executed together or not at all.
    #
    # For example:
    #
    #   ActiveRecord::Base.transaction do
    #     david.withdrawal(100)
    #     mary.deposit(100)
    #   end
    #
    # This example will only take money from David and give it to Mary if neither
    # +withdrawal+ nor +deposit+ raise an exception. Exceptions will force a
    # ROLLBACK that returns the database to the state before the transaction
    # began. Be aware, though, that the objects will _not_ have their instance
    # data returned to their pre-transactional state.
    #
    # == Different Active Record classes in a single transaction
    #
    # Though the transaction class method is called on some Active Record class,
    # the objects within the transaction block need not all be instances of
    # that class. This is because transactions are per-database connection, not
    # per-model.
    #
    # In this example a +balance+ record is transactionally saved even
    # though +transaction+ is called on the +Account+ class:
    #
    #   Account.transaction do
    #     balance.save!
    #     account.save!
    #   end
    #
    # The +transaction+ method is also available as a model instance method.
    # For example, you can also do this:
    #
    #   balance.transaction do
    #     balance.save!
    #     account.save!
    #   end
    #
    # == Transactions are not distributed across database connections
    #
    # A transaction acts on a single database connection. If you have
    # multiple class-specific databases, the transaction will not protect
    # interaction among them. One workaround is to begin a transaction
    # on each class whose models you alter:
    #
    #   Student.transaction do
    #     Course.transaction do
    #       course.enroll(student)
    #       student.units += course.units
    #     end
    #   end
    #
    # This is a poor solution, but fully distributed transactions are beyond
    # the scope of Active Record.
    #
    # == +save+ and +destroy+ are automatically wrapped in a transaction
    #
    # Both +save+ and +destroy+ come wrapped in a transaction that ensures
    # that whatever you do in validations or callbacks will happen under its
    # protected cover. So you can use validations to check for values that
    # the transaction depends on or you can raise exceptions in the callbacks
    # to rollback, including <tt>after_*</tt> callbacks.
    #
    # As a consequence changes to the database are not seen outside your connection
    # until the operation is complete. For example, if you try to update the index
    # of a search engine in +after_save+ the indexer won't see the updated record.
    # The +after_commit+ callback is the only one that is triggered once the update
    # is committed. See below.
    #
    # == Exception handling and rolling back
    #
    # Also have in mind that exceptions thrown within a transaction block will
    # be propagated (after triggering the ROLLBACK), so you should be ready to
    # catch those in your application code.
    #
    # One exception is the <tt>ActiveRecord::Rollback</tt> exception, which will trigger
    # a ROLLBACK when raised, but not be re-raised by the transaction block.
    #
    # *Warning*: one should not catch <tt>ActiveRecord::StatementInvalid</tt> exceptions
    # inside a transaction block. <tt>ActiveRecord::StatementInvalid</tt> exceptions indicate that an
    # error occurred at the database level, for example when a unique constraint
    # is violated. On some database systems, such as PostgreSQL, database errors
    # inside a transaction cause the entire transaction to become unusable
    # until it's restarted from the beginning. Here is an example which
    # demonstrates the problem:
    #
    #   # Suppose that we have a Number model with a unique column called 'i'.
    #   Number.transaction do
    #     Number.create(i: 0)
    #     begin
    #       # This will raise a unique constraint error...
    #       Number.create(i: 0)
    #     rescue ActiveRecord::StatementInvalid
    #       # ...which we ignore.
    #     end
    #
    #     # On PostgreSQL, the transaction is now unusable. The following
    #     # statement will cause a PostgreSQL error, even though the unique
    #     # constraint is no longer violated:
    #     Number.create(i: 1)
    #     # => "PGError: ERROR:  current transaction is aborted, commands
    #     #     ignored until end of transaction block"
    #   end
    #
    # One should restart the entire transaction if an
    # <tt>ActiveRecord::StatementInvalid</tt> occurred.
    #
    # == Nested transactions
    #
    # +transaction+ calls can be nested. By default, this makes all database
    # statements in the nested transaction block become part of the parent
    # transaction. For example, the following behavior may be surprising:
    #
    #   User.transaction do
    #     User.create(username: 'Kotori')
    #     User.transaction do
    #       User.create(username: 'Nemu')
    #       raise ActiveRecord::Rollback
    #     end
    #   end
    #
    # creates both "Kotori" and "Nemu". Reason is the <tt>ActiveRecord::Rollback</tt>
    # exception in the nested block does not issue a ROLLBACK. Since these exceptions
    # are captured in transaction blocks, the parent block does not see it and the
    # real transaction is committed.
    #
    # In order to get a ROLLBACK for the nested transaction you may ask for a real
    # sub-transaction by passing <tt>requires_new: true</tt>. If anything goes wrong,
    # the database rolls back to the beginning of the sub-transaction without rolling
    # back the parent transaction. If we add it to the previous example:
    #
    #   User.transaction do
    #     User.create(username: 'Kotori')
    #     User.transaction(requires_new: true) do
    #       User.create(username: 'Nemu')
    #       raise ActiveRecord::Rollback
    #     end
    #   end
    #
    # only "Kotori" is created. (This works on MySQL and PostgreSQL, but not on SQLite3.)
    #
    # Most databases don't support true nested transactions. At the time of
    # writing, the only database that we're aware of that supports true nested
    # transactions, is MS-SQL. Because of this, Active Record emulates nested
    # transactions by using savepoints on MySQL and PostgreSQL. See
    # http://dev.mysql.com/doc/refman/5.6/en/savepoint.html
    # for more information about savepoints.
    #
    # === Callbacks
    #
    # There are two types of callbacks associated with committing and rolling back transactions:
    # +after_commit+ and +after_rollback+.
    #
    # +after_commit+ callbacks are called on every record saved or destroyed within a
    # transaction immediately after the transaction is committed. +after_rollback+ callbacks
    # are called on every record saved or destroyed within a transaction immediately after the
    # transaction or savepoint is rolled back.
    #
    # These callbacks are useful for interacting with other systems since you will be guaranteed
    # that the callback is only executed when the database is in a permanent state. For example,
    # +after_commit+ is a good spot to put in a hook to clearing a cache since clearing it from
    # within a transaction could trigger the cache to be regenerated before the database is updated.
    #
    # === Caveats
    #
    # If you're on MySQL, then do not use DDL operations in nested transactions
    # blocks that are emulated with savepoints. That is, do not execute statements
    # like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
    # releases all savepoints upon executing a DDL operation. When +transaction+
    # is finished and tries to release the savepoint it created earlier, a
    # database error will occur because the savepoint has already been
    # automatically released. The following example demonstrates the problem:
    #
    #   Model.connection.transaction do                           # BEGIN
    #     Model.connection.transaction(requires_new: true) do  # CREATE SAVEPOINT active_record_1
    #       Model.connection.create_table(...)                    # active_record_1 now automatically released
    #     end                                                     # RELEASE savepoint active_record_1
    #                                                             # ^^^^ BOOM! database error!
    #   end
    #
    # Note that "TRUNCATE" is also a MySQL DDL statement!
    module ClassMethods
      # See ActiveRecord::Transactions::ClassMethods for detailed documentation.
      def transaction(options = {}, &block)
        # See the ConnectionAdapters::DatabaseStatements#transaction API docs.
        connection.transaction(options, &block)
      end

      # This callback is called after a record has been created, updated, or destroyed.
      #
      # You can specify that the callback should only be fired by a certain action with
      # the +:on+ option:
      #
      #   after_commit :do_foo, on: :create
      #   after_commit :do_bar, on: :update
      #   after_commit :do_baz, on: :destroy
      #
      # Also, to have the callback fired on create and update, but not on destroy:
      #
      #   after_commit :do_zoo, if: :persisted?
      #
      # Note that transactional fixtures do not play well with this feature. Please
      # use the +test_after_commit+ gem to have these hooks fired in tests.
      def after_commit(*args, &block)
        set_options_for_callbacks!(args)
        set_callback(:commit, :after, *args, &block)
      end

      # This callback is called after a create, update, or destroy are rolled back.
      #
      # Please check the documentation of +after_commit+ for options.
      def after_rollback(*args, &block)
        set_options_for_callbacks!(args)
        set_callback(:rollback, :after, *args, &block)
      end

      private

      def set_options_for_callbacks!(args)
        options = args.last
        if options.is_a?(Hash) && options[:on]
          assert_valid_transaction_action(options[:on])
          options[:if] = Array(options[:if])
          options[:if] << "transaction_include_action?(:#{options[:on]})"
        end
      end

      def assert_valid_transaction_action(action)
        unless ACTIONS.include?(action.to_sym)
          raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS.join(",")}"
        end
      end
    end

    # See ActiveRecord::Transactions::ClassMethods for detailed documentation.
    def transaction(options = {}, &block)
      self.class.transaction(options, &block)
    end

    def destroy #:nodoc:
      with_transaction_returning_status { super }
    end

    def save(*) #:nodoc:
      rollback_active_record_state! do
        with_transaction_returning_status { super }
      end
    end

    def save!(*) #:nodoc:
      with_transaction_returning_status { super }
    end

    # Reset id and @new_record if the transaction rolls back.
    def rollback_active_record_state!
      remember_transaction_record_state
      yield
    rescue Exception
      restore_transaction_record_state
      raise
    ensure
      clear_transaction_record_state
    end

    # Call the after_commit callbacks
    #
    # Ensure that it is not called if the object was never persisted (failed create),
    # but call it after the commit of a destroyed object
    def committed! #:nodoc:
      run_callbacks :commit if destroyed? || persisted?
    ensure
      clear_transaction_record_state
    end

    # Call the after rollback callbacks. The restore_state argument indicates if the record
    # state should be rolled back to the beginning or just to the last savepoint.
    def rolledback!(force_restore_state = false) #:nodoc:
      run_callbacks :rollback
    ensure
      restore_transaction_record_state(force_restore_state)
    end

    # Add the record to the current transaction so that the :after_rollback and :after_commit callbacks
    # can be called.
    def add_to_transaction
      if self.class.connection.add_transaction_record(self)
        remember_transaction_record_state
      end
    end

    # Executes +method+ within a transaction and captures its return value as a
    # status flag. If the status is true the transaction is committed, otherwise
    # a ROLLBACK is issued. In any case the status flag is returned.
    #
    # This method is available within the context of an ActiveRecord::Base
    # instance.
    def with_transaction_returning_status
      status = nil
      self.class.transaction do
        add_to_transaction
        begin
          status = yield
        rescue ActiveRecord::Rollback
          @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
          status = nil
        end

        raise ActiveRecord::Rollback unless status
      end
      status
    end

    protected

    # Save the new record state and id of a record so it can be restored later if a transaction fails.
    def remember_transaction_record_state #:nodoc:
      @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
      @_start_transaction_state[:new_record] = @new_record
      @_start_transaction_state[:destroyed] = @destroyed
      @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
      @_start_transaction_state[:frozen?] = @attributes.frozen?
    end

    # Clear the new record state and id of a record.
    def clear_transaction_record_state #:nodoc:
      @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
      @_start_transaction_state.clear if @_start_transaction_state[:level] < 1
    end

    # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
    def restore_transaction_record_state(force = false) #:nodoc:
      unless @_start_transaction_state.empty?
        @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
        if @_start_transaction_state[:level] < 1 || force
          restore_state = @_start_transaction_state
          was_frozen = restore_state[:frozen?]
          @attributes = @attributes.dup if @attributes.frozen?
          @new_record = restore_state[:new_record]
          @destroyed  = restore_state[:destroyed]
          if restore_state.has_key?(:id)
            self.id = restore_state[:id]
          else
            @attributes.delete(self.class.primary_key)
            @attributes_cache.delete(self.class.primary_key)
          end
          @attributes.freeze if was_frozen
          @_start_transaction_state.clear
        end
      end
    end

    # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
    def transaction_record_state(state) #:nodoc:
      @_start_transaction_state[state]
    end

    # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
    def transaction_include_action?(action) #:nodoc:
      case action
      when :create
        transaction_record_state(:new_record)
      when :destroy
        destroyed?
      when :update
        !(transaction_record_state(:new_record) || destroyed?)
      end
    end
  end
end
module ActiveRecord
  module Translation
    include ActiveModel::Translation

    # Set the lookup ancestors for ActiveModel.
    def lookup_ancestors #:nodoc:
      klass = self
      classes = [klass]
      return classes if klass == ActiveRecord::Base

      while klass != klass.base_class
        classes << klass = klass.superclass
      end
      classes
    end

    # Set the i18n scope to overwrite ActiveModel.
    def i18n_scope #:nodoc:
      :activerecord
    end
  end
end
module ActiveRecord
  module Validations
    class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
      def validate_each(record, attribute, value)
        if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?(record.validation_context) }.any?
          record.errors.add(attribute, :invalid, options.merge(:value => value))
        end
      end
    end

    module ClassMethods
      # Validates whether the associated object or objects are all valid
      # themselves. Works with any kind of association.
      #
      #   class Book < ActiveRecord::Base
      #     has_many :pages
      #     belongs_to :library
      #
      #     validates_associated :pages, :library
      #   end
      #
      # WARNING: This validation must not be used on both ends of an association.
      # Doing so will lead to a circular dependency and cause infinite recursion.
      #
      # NOTE: This validation will not fail if the association hasn't been
      # assigned. If you want to ensure that the association is both present and
      # guaranteed to be valid, you also need to use +validates_presence_of+.
      #
      # Configuration options:
      #
      # * <tt>:message</tt> - A custom error message (default is: "is invalid").
      # * <tt>:on</tt> - Specifies when this validation is active. Runs in all
      #   validation contexts by default (+nil+), other options are <tt>:create</tt>
      #   and <tt>:update</tt>.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
      #   determine if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
      #   method, proc or string should return or evaluate to a +true+ or +false+
      #   value.
      def validates_associated(*attr_names)
        validates_with AssociatedValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveRecord
  module Validations
    class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
      def validate(record)
        super
        attributes.each do |attribute|
          next unless record.class.reflect_on_association(attribute)
          associated_records = Array(record.send(attribute))

          # Superclass validates presence. Ensure present records aren't about to be destroyed.
          if associated_records.present? && associated_records.all? { |r| r.marked_for_destruction? }
            record.errors.add(attribute, :blank, options)
          end
        end
      end
    end

    module ClassMethods
      # Validates that the specified attributes are not blank (as defined by
      # Object#blank?), and, if the attribute is an association, that the
      # associated object is not marked for destruction. Happens by default
      # on save.
      #
      #   class Person < ActiveRecord::Base
      #     has_one :face
      #     validates_presence_of :face
      #   end
      #
      # The face attribute must be in the object and it cannot be blank or marked
      # for destruction.
      #
      # If you want to validate the presence of a boolean field (where the real values
      # are true and false), you will want to use
      # <tt>validates_inclusion_of :field_name, in: [true, false]</tt>.
      #
      # This is due to the way Object#blank? handles boolean values:
      # <tt>false.blank? # => true</tt>.
      #
      # This validator defers to the ActiveModel validation for presence, adding the
      # check to see that an associated object is not marked for destruction. This
      # prevents the parent object from validating successfully and saving, which then
      # deletes the associated object, thus putting the parent object into an invalid
      # state.
      #
      # Configuration options:
      # * <tt>:message</tt> - A custom error message (default is: "can't be blank").
      # * <tt>:on</tt> - Specifies when this validation is active. Runs in all
      #   validation contexts by default (+nil+), other options are <tt>:create</tt>
      #   and <tt>:update</tt>.
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if
      #   the validation should occur (e.g. <tt>if: :allow_validation</tt>, or
      #   <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method, proc
      #   or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:strict</tt> - Specifies whether validation should be strict.
      #   See <tt>ActiveModel::Validation#validates!</tt> for more information.
      def validates_presence_of(*attr_names)
        validates_with PresenceValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveRecord
  module Validations
    class UniquenessValidator < ActiveModel::EachValidator # :nodoc:
      def initialize(options)
        super({ case_sensitive: true }.merge!(options))
      end

      # Unfortunately, we have to tie Uniqueness validators to a class.
      def setup(klass)
        @klass = klass
      end

      def validate_each(record, attribute, value)
        finder_class = find_finder_class_for(record)
        table = finder_class.arel_table
        value = deserialize_attribute(record, attribute, value)

        relation = build_relation(finder_class, table, attribute, value)
        relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.id)) if record.persisted?
        relation = scope_relation(record, table, relation)
        relation = finder_class.unscoped.where(relation)
        relation.merge!(options[:conditions]) if options[:conditions]

        if relation.exists?
          error_options = options.except(:case_sensitive, :scope, :conditions)
          error_options[:value] = value

          record.errors.add(attribute, :taken, error_options)
        end
      end

    protected

      # The check for an existing value should be run from a class that
      # isn't abstract. This means working down from the current class
      # (self), to the first non-abstract class. Since classes don't know
      # their subclasses, we have to build the hierarchy between self and
      # the record's class.
      def find_finder_class_for(record) #:nodoc:
        class_hierarchy = [record.class]

        while class_hierarchy.first != @klass
          class_hierarchy.unshift(class_hierarchy.first.superclass)
        end

        class_hierarchy.detect { |klass| !klass.abstract_class? }
      end

      def build_relation(klass, table, attribute, value) #:nodoc:
        if reflection = klass.reflect_on_association(attribute)
          attribute = reflection.foreign_key
          value = value.attributes[reflection.primary_key_column.name]
        end

        column = klass.columns_hash[attribute.to_s]
        value  = klass.connection.type_cast(value, column)
        value  = value.to_s[0, column.limit] if value && column.limit && column.text?

        if !options[:case_sensitive] && value && column.text?
          # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
          klass.connection.case_insensitive_comparison(table, attribute, column, value)
        else
          value = klass.connection.case_sensitive_modifier(value) unless value.nil?
          table[attribute].eq(value)
        end
      end

      def scope_relation(record, table, relation)
        Array(options[:scope]).each do |scope_item|
          if reflection = record.class.reflect_on_association(scope_item)
            scope_value = record.send(reflection.foreign_key)
            scope_item  = reflection.foreign_key
          else
            scope_value = record.read_attribute(scope_item)
          end
          relation = relation.and(table[scope_item].eq(scope_value))
        end

        relation
      end

      def deserialize_attribute(record, attribute, value)
        coder = record.class.serialized_attributes[attribute.to_s]
        value = coder.dump value if value && coder
        value
      end
    end

    module ClassMethods
      # Validates whether the value of the specified attributes are unique
      # across the system. Useful for making sure that only one user
      # can be named "davidhh".
      #
      #   class Person < ActiveRecord::Base
      #     validates_uniqueness_of :user_name
      #   end
      #
      # It can also validate whether the value of the specified attributes are
      # unique based on a <tt>:scope</tt> parameter:
      #
      #   class Person < ActiveRecord::Base
      #     validates_uniqueness_of :user_name, scope: :account_id
      #   end
      #
      # Or even multiple scope parameters. For example, making sure that a
      # teacher can only be on the schedule once per semester for a particular
      # class.
      #
      #   class TeacherSchedule < ActiveRecord::Base
      #     validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
      #   end
      #
      # It is also possible to limit the uniqueness constraint to a set of
      # records matching certain conditions. In this example archived articles
      # are not being taken into consideration when validating uniqueness
      # of the title attribute:
      #
      #   class Article < ActiveRecord::Base
      #     validates_uniqueness_of :title, conditions: where('status != ?', 'archived')
      #   end
      #
      # When the record is created, a check is performed to make sure that no
      # record exists in the database with the given value for the specified
      # attribute (that maps to a column). When the record is updated,
      # the same check is made but disregarding the record itself.
      #
      # Configuration options:
      #
      # * <tt>:message</tt> - Specifies a custom error message (default is:
      #   "has already been taken").
      # * <tt>:scope</tt> - One or more columns by which to limit the scope of
      #   the uniqueness constraint.
      # * <tt>:conditions</tt> - Specify the conditions to be included as a
      #   <tt>WHERE</tt> SQL fragment to limit the uniqueness constraint lookup
      #   (e.g. <tt>conditions: where('status = ?', 'active')</tt>).
      # * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by
      #   non-text columns (+true+ by default).
      # * <tt>:allow_nil</tt> - If set to +true+, skips this validation if the
      #   attribute is +nil+ (default is +false+).
      # * <tt>:allow_blank</tt> - If set to +true+, skips this validation if the
      #   attribute is blank (default is +false+).
      # * <tt>:if</tt> - Specifies a method, proc or string to call to determine
      #   if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
      #   or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
      #   proc or string should return or evaluate to a +true+ or +false+ value.
      # * <tt>:unless</tt> - Specifies a method, proc or string to call to
      #   determine if the validation should ot occur (e.g. <tt>unless: :skip_validation</tt>,
      #   or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The
      #   method, proc or string should return or evaluate to a +true+ or +false+
      #   value.
      #
      # === Concurrency and integrity
      #
      # Using this validation method in conjunction with ActiveRecord::Base#save
      # does not guarantee the absence of duplicate record insertions, because
      # uniqueness checks on the application level are inherently prone to race
      # conditions. For example, suppose that two users try to post a Comment at
      # the same time, and a Comment's title must be unique. At the database-level,
      # the actions performed by these users could be interleaved in the following manner:
      #
      #               User 1                 |               User 2
      #  ------------------------------------+--------------------------------------
      #  # User 1 checks whether there's     |
      #  # already a comment with the title  |
      #  # 'My Post'. This is not the case.  |
      #  SELECT * FROM comments              |
      #  WHERE title = 'My Post'             |
      #                                      |
      #                                      | # User 2 does the same thing and also
      #                                      | # infers that his title is unique.
      #                                      | SELECT * FROM comments
      #                                      | WHERE title = 'My Post'
      #                                      |
      #  # User 1 inserts his comment.       |
      #  INSERT INTO comments                |
      #  (title, content) VALUES             |
      #  ('My Post', 'hi!')                  |
      #                                      |
      #                                      | # User 2 does the same thing.
      #                                      | INSERT INTO comments
      #                                      | (title, content) VALUES
      #                                      | ('My Post', 'hello!')
      #                                      |
      #                                      | # ^^^^^^
      #                                      | # Boom! We now have a duplicate
      #                                      | # title!
      #
      # This could even happen if you use transactions with the 'serializable'
      # isolation level. The best way to work around this problem is to add a unique
      # index to the database table using
      # ActiveRecord::ConnectionAdapters::SchemaStatements#add_index. In the
      # rare case that a race condition occurs, the database will guarantee
      # the field's uniqueness.
      #
      # When the database catches such a duplicate insertion,
      # ActiveRecord::Base#save will raise an ActiveRecord::StatementInvalid
      # exception. You can either choose to let this error propagate (which
      # will result in the default Rails exception page being shown), or you
      # can catch it and restart the transaction (e.g. by telling the user
      # that the title already exists, and asking him to re-enter the title).
      # This technique is also known as optimistic concurrency control:
      # http://en.wikipedia.org/wiki/Optimistic_concurrency_control.
      #
      # The bundled ActiveRecord::ConnectionAdapters distinguish unique index
      # constraint errors from other types of database errors by throwing an
      # ActiveRecord::RecordNotUnique exception. For other adapters you will
      # have to parse the (database-specific) exception message to detect such
      # a case.
      #
      # The following bundled adapters throw the ActiveRecord::RecordNotUnique exception:
      #
      # * ActiveRecord::ConnectionAdapters::MysqlAdapter.
      # * ActiveRecord::ConnectionAdapters::Mysql2Adapter.
      # * ActiveRecord::ConnectionAdapters::SQLite3Adapter.
      # * ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.
      def validates_uniqueness_of(*attr_names)
        validates_with UniquenessValidator, _merge_attributes(attr_names)
      end
    end
  end
end
module ActiveRecord
  # = Active Record RecordInvalid
  #
  # Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
  # +record+ method to retrieve the record which did not validate.
  #
  #   begin
  #     complex_operation_that_calls_save!_internally
  #   rescue ActiveRecord::RecordInvalid => invalid
  #     puts invalid.record.errors
  #   end
  class RecordInvalid < ActiveRecordError
    attr_reader :record # :nodoc:
    def initialize(record) # :nodoc:
      @record = record
      errors = @record.errors.full_messages.join(", ")
      super(I18n.t(:"#{@record.class.i18n_scope}.errors.messages.record_invalid", :errors => errors, :default => :"errors.messages.record_invalid"))
    end
  end

  # = Active Record Validations
  #
  # Active Record includes the majority of its validations from <tt>ActiveModel::Validations</tt>
  # all of which accept the <tt>:on</tt> argument to define the context where the
  # validations are active. Active Record will always supply either the context of
  # <tt>:create</tt> or <tt>:update</tt> dependent on whether the model is a
  # <tt>new_record?</tt>.
  module Validations
    extend ActiveSupport::Concern
    include ActiveModel::Validations

    module ClassMethods
      # Creates an object just like Base.create but calls <tt>save!</tt> instead of +save+
      # so an exception is raised if the record is invalid.
      def create!(attributes = nil, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| create!(attr, &block) }
        else
          object = new(attributes)
          yield(object) if block_given?
          object.save!
          object
        end
      end
    end

    # The validation process on save can be skipped by passing <tt>validate: false</tt>.
    # The regular Base#save method is replaced with this when the validations
    # module is mixed in, which it is by default.
    def save(options={})
      perform_validations(options) ? super : false
    end

    # Attempts to save the record just like Base#save but will raise a +RecordInvalid+
    # exception instead of returning +false+ if the record is not valid.
    def save!(options={})
      perform_validations(options) ? super : raise(RecordInvalid.new(self))
    end

    # Runs all the validations within the specified context. Returns +true+ if
    # no errors are found, +false+ otherwise.
    #
    # If the argument is +false+ (default is +nil+), the context is set to <tt>:create</tt> if
    # <tt>new_record?</tt> is +true+, and to <tt>:update</tt> if it is not.
    #
    # Validations with no <tt>:on</tt> option will run no matter the context. Validations with
    # some <tt>:on</tt> option will only run in the specified context.
    def valid?(context = nil)
      context ||= (new_record? ? :create : :update)
      output = super(context)
      errors.empty? && output
    end

  protected

    def perform_validations(options={}) # :nodoc:
      perform_validation = options[:validate] != false
      perform_validation ? valid?(options[:context]) : true
    end
  end
end

require "active_record/validations/associated"
require "active_record/validations/uniqueness"
require "active_record/validations/presence"
module ActiveRecord
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
#--
# Copyright (c) 2004-2013 David Heinemeier Hansson
#
# 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.
#++

require 'active_support'
require 'active_support/rails'
require 'active_model'
require 'arel'
require 'active_record/deprecated_finders'

require 'active_record/version'

module ActiveRecord
  extend ActiveSupport::Autoload

  autoload :Base
  autoload :Callbacks
  autoload :Core
  autoload :CounterCache
  autoload :ConnectionHandling
  autoload :DynamicMatchers
  autoload :Explain
  autoload :Inheritance
  autoload :Integration
  autoload :Migration
  autoload :Migrator, 'active_record/migration'
  autoload :ModelSchema
  autoload :NestedAttributes
  autoload :Persistence
  autoload :QueryCache
  autoload :Querying
  autoload :ReadonlyAttributes
  autoload :Reflection
  autoload :Sanitization
  autoload :Schema
  autoload :SchemaDumper
  autoload :SchemaMigration
  autoload :Scoping
  autoload :Serialization
  autoload :Store
  autoload :Timestamp
  autoload :Transactions
  autoload :Translation
  autoload :Validations

  eager_autoload do
    autoload :ActiveRecordError, 'active_record/errors'
    autoload :ConnectionNotEstablished, 'active_record/errors'
    autoload :ConnectionAdapters, 'active_record/connection_adapters/abstract_adapter'

    autoload :Aggregations
    autoload :Associations
    autoload :AttributeMethods
    autoload :AttributeAssignment
    autoload :AutosaveAssociation

    autoload :Relation
    autoload :NullRelation

    autoload_under 'relation' do
      autoload :QueryMethods
      autoload :FinderMethods
      autoload :Calculations
      autoload :PredicateBuilder
      autoload :SpawnMethods
      autoload :Batches
      autoload :Delegation
    end

    autoload :Result
  end

  module Coders
    autoload :YAMLColumn, 'active_record/coders/yaml_column'
  end

  module AttributeMethods
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :BeforeTypeCast
      autoload :Dirty
      autoload :PrimaryKey
      autoload :Query
      autoload :Read
      autoload :TimeZoneConversion
      autoload :Write
      autoload :Serialization
    end
  end

  module Locking
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :Optimistic
      autoload :Pessimistic
    end
  end

  module ConnectionAdapters
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :AbstractAdapter
      autoload :ConnectionManagement, "active_record/connection_adapters/abstract/connection_pool"
    end
  end

  module Scoping
    extend ActiveSupport::Autoload

    eager_autoload do
      autoload :Named
      autoload :Default
    end
  end

  module Tasks
    extend ActiveSupport::Autoload

    autoload :DatabaseTasks
    autoload :SQLiteDatabaseTasks, 'active_record/tasks/sqlite_database_tasks'
    autoload :MySQLDatabaseTasks,  'active_record/tasks/mysql_database_tasks'
    autoload :PostgreSQLDatabaseTasks,
      'active_record/tasks/postgresql_database_tasks'
  end

  autoload :TestCase
  autoload :TestFixtures, 'active_record/fixtures'

  def self.eager_load!
    super
    ActiveRecord::Locking.eager_load!
    ActiveRecord::Scoping.eager_load!
    ActiveRecord::Associations.eager_load!
    ActiveRecord::AttributeMethods.eager_load!
    ActiveRecord::ConnectionAdapters.eager_load!
  end
end

ActiveSupport.on_load(:active_record) do
  Arel::Table.engine = self
end

ActiveSupport.on_load(:i18n) do
  I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
end
require 'rails/generators/active_record'

module ActiveRecord
  module Generators # :nodoc:
    class MigrationGenerator < Base # :nodoc:
      argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"

      def create_migration_file
        set_local_assigns!
        validate_file_name!
        migration_template "migration.rb", "db/migrate/#{file_name}.rb"
      end

      protected
      attr_reader :migration_action, :join_tables

      def set_local_assigns!
        case file_name
        when /^(add|remove)_.*_(?:to|from)_(.*)/
          @migration_action = $1
          @table_name       = $2.pluralize
        when /join_table/
          if attributes.length == 2
            @migration_action = 'join'
            @join_tables      = attributes.map(&:plural_name)

            set_index_names
          end
        end
      end

      def set_index_names
        attributes.each_with_index do |attr, i|
          attr.index_name = [attr, attributes[i - 1]].map{ |a| index_name_for(a) }
        end
      end

      def index_name_for(attribute)
        if attribute.foreign_key?
          attribute.name
        else
          attribute.name.singularize.foreign_key
        end.to_sym
      end

      private

        def validate_file_name!
          unless file_name =~ /^[_a-z0-9]+$/
            raise IllegalMigrationNameError.new(file_name)
          end
        end
    end
  end
end
class <%= migration_class_name %> < ActiveRecord::Migration
<%- if migration_action == 'add' -%>
  def change
<% attributes.each do |attribute| -%>
  <%- if attribute.reference? -%>
    add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
  <%- else -%>
    add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
    <%- if attribute.has_index? -%>
    add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
    <%- end -%>
  <%- end -%>
<%- end -%>
  end
<%- elsif migration_action == 'join' -%>
  def change
    create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
    <%- attributes.each do |attribute| -%>
      <%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
    <%- end -%>
    end
  end
<%- else -%>
  def change
<% attributes.each do |attribute| -%>
<%- if migration_action -%>
  <%- if attribute.reference? -%>
    remove_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
  <%- else -%>
    <%- if attribute.has_index? -%>
    remove_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
    <%- end -%>
    remove_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
  <%- end -%>
<%- end -%>
<%- end -%>
  end
<%- end -%>
end
require 'rails/generators/active_record'

module ActiveRecord
  module Generators # :nodoc:
    class ModelGenerator < Base # :nodoc:
      argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"

      check_class_collision

      class_option :migration,  :type => :boolean
      class_option :timestamps, :type => :boolean
      class_option :parent,     :type => :string, :desc => "The parent class for the generated model"
      class_option :indexes,    :type => :boolean, :default => true, :desc => "Add indexes for references and belongs_to columns"

      def create_migration_file
        return unless options[:migration] && options[:parent].nil?
        attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
        migration_template "migration.rb", "db/migrate/create_#{table_name}.rb"
      end

      def create_model_file
        template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
      end

      def create_module_file
        return if regular_class_path.empty?
        template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
      end

      def attributes_with_index
        attributes.select { |a| !a.reference? && a.has_index? }
      end

      def accessible_attributes
        attributes.reject(&:reference?)
      end

      hook_for :test_framework

      protected

        def parent_class_name
          options[:parent] || "ActiveRecord::Base"
        end

    end
  end
end
class <%= migration_class_name %> < ActiveRecord::Migration
  def change
    create_table :<%= table_name %> do |t|
<% attributes.each do |attribute| -%>
      t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
<% end -%>
<% if options[:timestamps] %>
      t.timestamps
<% end -%>
    end
<% attributes_with_index.each do |attribute| -%>
    add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
<% end -%>
  end
end
<% module_namespacing do -%>
class <%= class_name %> < <%= parent_class_name.classify %>
<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
  belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
<% end -%>
end
<% end -%>
<% module_namespacing do -%>
module <%= class_path.map(&:camelize).join('::') %>
  def self.table_name_prefix
    '<%= namespaced? ? namespaced_class_path.join('_') : class_path.join('_') %>_'
  end
end
<% end -%>
require 'rails/generators/named_base'
require 'rails/generators/migration'
require 'rails/generators/active_model'
require 'active_record'

module ActiveRecord
  module Generators # :nodoc:
    class Base < Rails::Generators::NamedBase # :nodoc:
      include Rails::Generators::Migration

      # Set the current directory as base for the inherited generators.
      def self.base_root
        File.dirname(__FILE__)
      end

      # Implement the required interface for Rails::Generators::Migration.
      def self.next_migration_number(dirname)
        next_migration_number = current_migration_number(dirname) + 1
        ActiveRecord::Migration.next_migration_number(next_migration_number)
      end
    end
  end
end
require 'active_support'
require 'active_support/time'
require 'active_support/core_ext'
module ActiveSupport
  # Backtraces often include many lines that are not relevant for the context
  # under review. This makes it hard to find the signal amongst the backtrace
  # noise, and adds debugging time. With a BacktraceCleaner, filters and
  # silencers are used to remove the noisy lines, so that only the most relevant
  # lines remain.
  #
  # Filters are used to modify lines of data, while silencers are used to remove
  # lines entirely. The typical filter use case is to remove lengthy path
  # information from the start of each line, and view file paths relevant to the
  # app directory instead of the file system root. The typical silencer use case
  # is to exclude the output of a noisy library from the backtrace, so that you
  # can focus on the rest.
  #
  #   bc = BacktraceCleaner.new
  #   bc.add_filter   { |line| line.gsub(Rails.root, '') }
  #   bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
  #   bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
  #
  # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
  # and show as much data as possible, you can always call
  # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
  # backtrace to a pristine state. If you need to reconfigure an existing
  # BacktraceCleaner so that it does not filter or modify the paths of any lines
  # of the backtrace, you can call BacktraceCleaner#remove_filters! These two
  # methods will give you a completely untouched backtrace.
  #
  # Inspired by the Quiet Backtrace gem by Thoughtbot.
  class BacktraceCleaner
    def initialize
      @filters, @silencers = [], []
    end

    # Returns the backtrace after all filters and silencers have been run
    # against it. Filters run first, then silencers.
    def clean(backtrace, kind = :silent)
      filtered = filter_backtrace(backtrace)

      case kind
      when :silent
        silence(filtered)
      when :noise
        noise(filtered)
      else
        filtered
      end
    end
    alias :filter :clean

    # Adds a filter from the block provided. Each line in the backtrace will be
    # mapped against this filter.
    #
    #   # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
    #   backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
    def add_filter(&block)
      @filters << block
    end

    # Adds a silencer from the block provided. If the silencer returns +true+
    # for a given line, it will be excluded from the clean backtrace.
    #
    #   # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
    #   backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
    def add_silencer(&block)
      @silencers << block
    end

    # Will remove all silencers, but leave in the filters. This is useful if
    # your context of debugging suddenly expands as you suspect a bug in one of
    # the libraries you use.
    def remove_silencers!
      @silencers = []
    end

    # Removes all filters, but leaves in silencers. Useful if you suddenly
    # need to see entire filepaths in the backtrace that you had already
    # filtered out.
    def remove_filters!
      @filters = []
    end

    private
      def filter_backtrace(backtrace)
        @filters.each do |f|
          backtrace = backtrace.map { |line| f.call(line) }
        end

        backtrace
      end

      def silence(backtrace)
        @silencers.each do |s|
          backtrace = backtrace.reject { |line| s.call(line) }
        end

        backtrace
      end

      def noise(backtrace)
        @silencers.each do |s|
          backtrace = backtrace.select { |line| s.call(line) }
        end

        backtrace
      end
  end
end
require 'active_support/deprecation'
require 'active_support/proxy_object'

module ActiveSupport
  class BasicObject < ProxyObject # :nodoc:
    def self.inherited(*)
      ::ActiveSupport::Deprecation.warn 'ActiveSupport::BasicObject is deprecated! Use ActiveSupport::ProxyObject instead.'
      super
    end
  end
end
require 'active_support/core_ext/benchmark'
require 'active_support/core_ext/hash/keys'

module ActiveSupport
  module Benchmarkable
    # Allows you to measure the execution time of a block in a template and
    # records the result to the log. Wrap this block around expensive operations
    # or possible bottlenecks to get a time reading for the operation. For
    # example, let's say you thought your file processing method was taking too
    # long; you could wrap it in a benchmark block.
    #
    #  <% benchmark 'Process data files' do %>
    #    <%= expensive_files_operation %>
    #  <% end %>
    #
    # That would add something like "Process data files (345.2ms)" to the log,
    # which you can then use to compare timings when optimizing your code.
    #
    # You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>,
    # <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The
    # default logger level value is <tt>:info</tt>.
    #
    #  <% benchmark 'Low-level files', level: :debug do %>
    #    <%= lowlevel_files_operation %>
    #  <% end %>
    #
    # Finally, you can pass true as the third argument to silence all log
    # activity (other than the timing information) from inside the block. This
    # is great for boiling down a noisy block to just a single statement that
    # produces one log line:
    #
    #  <% benchmark 'Process data files', level: :info, silence: true do %>
    #    <%= expensive_and_chatty_files_operation %>
    #  <% end %>
    def benchmark(message = "Benchmarking", options = {})
      if logger
        options.assert_valid_keys(:level, :silence)
        options[:level] ||= :info

        result = nil
        ms = Benchmark.ms { result = options[:silence] ? silence { yield } : yield }
        logger.send(options[:level], '%s (%.1fms)' % [ message, ms ])
        result
      else
        yield
      end
    end

    # Silence the logger during the execution of the block.
    def silence
      message = "ActiveSupport::Benchmarkable#silence is deprecated. It will be removed from Rails 4.1."
      ActiveSupport::Deprecation.warn message
      old_logger_level, logger.level = logger.level, ::Logger::ERROR if logger
      yield
    ensure
      logger.level = old_logger_level if logger
    end
  end
end
require 'active_support/deprecation'
require 'active_support/logger'

module ActiveSupport
  class BufferedLogger < Logger

    def initialize(*args)
      self.class._deprecation_warning
      super
    end

    def self.inherited(*)
      _deprecation_warning
      super
    end

    def self._deprecation_warning
      ::ActiveSupport::Deprecation.warn 'ActiveSupport::BufferedLogger is deprecated! Use ActiveSupport::Logger instead.'
    end
  end
end
begin
  require 'builder'
rescue LoadError => e
  $stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install"
  raise e
end
require 'active_support/core_ext/marshal'
require 'active_support/core_ext/file/atomic'
require 'active_support/core_ext/string/conversions'
require 'uri/common'

module ActiveSupport
  module Cache
    # A cache store implementation which stores everything on the filesystem.
    #
    # FileStore implements the Strategy::LocalCache strategy which implements
    # an in-memory cache inside of a block.
    class FileStore < Store
      attr_reader :cache_path

      DIR_FORMATTER = "%03X"
      FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
      EXCLUDED_DIRS = ['.', '..'].freeze

      def initialize(cache_path, options = nil)
        super(options)
        @cache_path = cache_path.to_s
        extend Strategy::LocalCache
      end

      def clear(options = nil)
        root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)}
        FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
      end

      def cleanup(options = nil)
        options = merged_options(options)
        each_key(options) do |key|
          entry = read_entry(key, options)
          delete_entry(key, options) if entry && entry.expired?
        end
      end

      def increment(name, amount = 1, options = nil)
        file_name = key_file_path(namespaced_key(name, options))
        lock_file(file_name) do
          options = merged_options(options)
          if num = read(name, options)
            num = num.to_i + amount
            write(name, num, options)
            num
          else
            nil
          end
        end
      end

      def decrement(name, amount = 1, options = nil)
        file_name = key_file_path(namespaced_key(name, options))
        lock_file(file_name) do
          options = merged_options(options)
          if num = read(name, options)
            num = num.to_i - amount
            write(name, num, options)
            num
          else
            nil
          end
        end
      end

      def delete_matched(matcher, options = nil)
        options = merged_options(options)
        instrument(:delete_matched, matcher.inspect) do
          matcher = key_matcher(matcher, options)
          search_dir(cache_path) do |path|
            key = file_path_key(path)
            delete_entry(key, options) if key.match(matcher)
          end
        end
      end

      protected

        def read_entry(key, options)
          file_name = key_file_path(key)
          if File.exist?(file_name)
            File.open(file_name) { |f| Marshal.load(f) }
          end
        rescue => e
          logger.error("FileStoreError (#{e}): #{e.message}") if logger
          nil
        end

        def write_entry(key, entry, options)
          file_name = key_file_path(key)
          ensure_cache_path(File.dirname(file_name))
          File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)}
          true
        end

        def delete_entry(key, options)
          file_name = key_file_path(key)
          if File.exist?(file_name)
            begin
              File.delete(file_name)
              delete_empty_directories(File.dirname(file_name))
              true
            rescue => e
              # Just in case the error was caused by another process deleting the file first.
              raise e if File.exist?(file_name)
              false
            end
          end
        end

      private
        # Lock a file for a block so only one process can modify it at a time.
        def lock_file(file_name, &block) # :nodoc:
          if File.exist?(file_name)
            File.open(file_name, 'r+') do |f|
              begin
                f.flock File::LOCK_EX
                yield
              ensure
                f.flock File::LOCK_UN
              end
            end
          else
            yield
          end
        end

        # Translate a key into a file path.
        def key_file_path(key)
          fname = URI.encode_www_form_component(key)
          hash = Zlib.adler32(fname)
          hash, dir_1 = hash.divmod(0x1000)
          dir_2 = hash.modulo(0x1000)
          fname_paths = []

          # Make sure file name doesn't exceed file system limits.
          begin
            fname_paths << fname[0, FILENAME_MAX_SIZE]
            fname = fname[FILENAME_MAX_SIZE..-1]
          end until fname.blank?

          File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths)
        end

        # Translate a file path into a key.
        def file_path_key(path)
          fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last
          URI.decode_www_form_component(fname, Encoding::UTF_8)
        end

        # Delete empty directories in the cache.
        def delete_empty_directories(dir)
          return if dir == cache_path
          if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty?
            File.delete(dir) rescue nil
            delete_empty_directories(File.dirname(dir))
          end
        end

        # Make sure a file path's directories exist.
        def ensure_cache_path(path)
          FileUtils.makedirs(path) unless File.exist?(path)
        end

        def search_dir(dir, &callback)
          return if !File.exist?(dir)
          Dir.foreach(dir) do |d|
            next if EXCLUDED_DIRS.include?(d)
            name = File.join(dir, d)
            if File.directory?(name)
              search_dir(name, &callback)
            else
              callback.call name
            end
          end
        end
    end
  end
end
begin
  require 'dalli'
rescue LoadError => e
  $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
  raise e
end

require 'digest/md5'
require 'active_support/core_ext/marshal'
require 'active_support/core_ext/array/extract_options'

module ActiveSupport
  module Cache
    # A cache store implementation which stores data in Memcached:
    # http://memcached.org/
    #
    # This is currently the most popular cache store for production websites.
    #
    # Special features:
    # - Clustering and load balancing. One can specify multiple memcached servers,
    #   and MemCacheStore will load balance between all available servers. If a
    #   server goes down, then MemCacheStore will ignore it until it comes back up.
    #
    # MemCacheStore implements the Strategy::LocalCache strategy which implements
    # an in-memory cache inside of a block.
    class MemCacheStore < Store
      ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n

      def self.build_mem_cache(*addresses)
        addresses = addresses.flatten
        options = addresses.extract_options!
        addresses = ["localhost:11211"] if addresses.empty?
        Dalli::Client.new(addresses, options)
      end

      # Creates a new MemCacheStore object, with the given memcached server
      # addresses. Each address is either a host name, or a host-with-port string
      # in the form of "host_name:port". For example:
      #
      #   ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
      #
      # 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)
        addresses = addresses.flatten
        options = addresses.extract_options!
        super(options)

        if addresses.first.respond_to?(:get)
          @data = addresses.first
        else
          mem_cache_options = options.dup
          UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
          @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
        end

        extend Strategy::LocalCache
        extend LocalCacheWithRaw
      end

      # Reads multiple values from the cache using a single call to the
      # servers for all keys. Options can be passed in the last argument.
      def read_multi(*names)
        options = names.extract_options!
        options = merged_options(options)
        keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
        raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
        values = {}
        raw_values.each do |key, value|
          entry = deserialize_entry(value)
          values[keys_to_names[key]] = entry.value unless entry.expired?
        end
        values
      end

      # Increment a cached value. This method uses the memcached incr atomic
      # operator and can only be used on values written with the :raw option.
      # Calling it on a value not stored with :raw will initialize that value
      # to zero.
      def increment(name, amount = 1, options = nil) # :nodoc:
        options = merged_options(options)
        instrument(:increment, name, :amount => amount) do
          @data.incr(escape_key(namespaced_key(name, options)), amount)
        end
      rescue Dalli::DalliError
        logger.error("DalliError (#{e}): #{e.message}") if logger
        nil
      end

      # Decrement a cached value. This method uses the memcached decr atomic
      # operator and can only be used on values written with the :raw option.
      # Calling it on a value not stored with :raw will initialize that value
      # to zero.
      def decrement(name, amount = 1, options = nil) # :nodoc:
        options = merged_options(options)
        instrument(:decrement, name, :amount => amount) do
          @data.decr(escape_key(namespaced_key(name, options)), amount)
        end
      rescue Dalli::DalliError
        logger.error("DalliError (#{e}): #{e.message}") if logger
        nil
      end

      # Clear the entire cache on all memcached servers. This method should
      # be used with care when shared cache is being used.
      def clear(options = nil)
        @data.flush_all
      rescue Dalli::DalliError => e
        logger.error("DalliError (#{e}): #{e.message}") if logger
        nil
      end

      # Get the statistics from the memcached servers.
      def stats
        @data.stats
      end

      protected
        # Read an entry from the cache.
        def read_entry(key, options) # :nodoc:
          deserialize_entry(@data.get(escape_key(key), options))
        rescue Dalli::DalliError => e
          logger.error("DalliError (#{e}): #{e.message}") if logger
          nil
        end

        # Write an entry to the cache.
        def write_entry(key, entry, options) # :nodoc:
          method = options && options[:unless_exist] ? :add : :set
          value = options[:raw] ? entry.value.to_s : entry
          expires_in = options[:expires_in].to_i
          if expires_in > 0 && !options[:raw]
            # Set the memcache expire a few minutes in the future to support race condition ttls on read
            expires_in += 5.minutes
          end
          @data.send(method, escape_key(key), value, expires_in, options)
        rescue Dalli::DalliError => e
          logger.error("DalliError (#{e}): #{e.message}") if logger
          false
        end

        # Delete an entry from the cache.
        def delete_entry(key, options) # :nodoc:
          @data.delete(escape_key(key))
        rescue Dalli::DalliError => e
          logger.error("DalliError (#{e}): #{e.message}") if logger
          false
        end

      private

        # Memcache keys are binaries. So we need to force their encoding to binary
        # before applying the regular expression to ensure we are escaping all
        # characters properly.
        def escape_key(key)
          key = key.to_s.dup
          key = key.force_encoding(Encoding::ASCII_8BIT)
          key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
          key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
          key
        end

        def deserialize_entry(raw_value)
          if raw_value
            entry = Marshal.load(raw_value) rescue raw_value
            entry.is_a?(Entry) ? entry : Entry.new(entry)
          else
            nil
          end
        end

      # Provide support for raw values in the local cache strategy.
      module LocalCacheWithRaw # :nodoc:
        protected
          def read_entry(key, options)
            entry = super
            if options[:raw] && local_cache && entry
               entry = deserialize_entry(entry.value)
            end
            entry
          end

          def write_entry(key, entry, options) # :nodoc:
            retval = super
            if options[:raw] && local_cache && retval
              raw_entry = Entry.new(entry.value.to_s)
              raw_entry.expires_at = entry.expires_at
              local_cache.write_entry(key, raw_entry, options)
            end
            retval
          end
      end
    end
  end
end
require 'monitor'

module ActiveSupport
  module Cache
    # A cache store implementation which stores everything into memory in the
    # same process. If you're running multiple Ruby on Rails server processes
    # (which is the case if you're using mongrel_cluster or Phusion Passenger),
    # then this means that Rails server process instances won't be able
    # to share cache data with each other and this may not be the most
    # appropriate cache in that scenario.
    #
    # This cache has a bounded size specified by the :size options to the
    # initializer (default is 32Mb). When the cache exceeds the allotted size,
    # a cleanup will occur which tries to prune the cache down to three quarters
    # of the maximum size by removing the least recently used entries.
    #
    # MemoryStore is thread-safe.
    class MemoryStore < Store
      def initialize(options = nil)
        options ||= {}
        super(options)
        @data = {}
        @key_access = {}
        @max_size = options[:size] || 32.megabytes
        @max_prune_time = options[:max_prune_time] || 2
        @cache_size = 0
        @monitor = Monitor.new
        @pruning = false
      end

      def clear(options = nil)
        synchronize do
          @data.clear
          @key_access.clear
          @cache_size = 0
        end
      end

      def cleanup(options = nil)
        options = merged_options(options)
        instrument(:cleanup, :size => @data.size) do
          keys = synchronize{ @data.keys }
          keys.each do |key|
            entry = @data[key]
            delete_entry(key, options) if entry && entry.expired?
          end
        end
      end

      # To ensure entries fit within the specified memory prune the cache by removing the least
      # recently accessed entries.
      def prune(target_size, max_time = nil)
        return if pruning?
        @pruning = true
        begin
          start_time = Time.now
          cleanup
          instrument(:prune, target_size, :from => @cache_size) do
            keys = synchronize{ @key_access.keys.sort{|a,b| @key_access[a].to_f <=> @key_access[b].to_f} }
            keys.each do |key|
              delete_entry(key, options)
              return if @cache_size <= target_size || (max_time && Time.now - start_time > max_time)
            end
          end
        ensure
          @pruning = false
        end
      end

      # Returns true if the cache is currently being pruned.
      def pruning?
        @pruning
      end

      # Increment an integer value in the cache.
      def increment(name, amount = 1, options = nil)
        synchronize do
          options = merged_options(options)
          if num = read(name, options)
            num = num.to_i + amount
            write(name, num, options)
            num
          else
            nil
          end
        end
      end

      # Decrement an integer value in the cache.
      def decrement(name, amount = 1, options = nil)
        synchronize do
          options = merged_options(options)
          if num = read(name, options)
            num = num.to_i - amount
            write(name, num, options)
            num
          else
            nil
          end
        end
      end

      def delete_matched(matcher, options = nil)
        options = merged_options(options)
        instrument(:delete_matched, matcher.inspect) do
          matcher = key_matcher(matcher, options)
          keys = synchronize { @data.keys }
          keys.each do |key|
            delete_entry(key, options) if key.match(matcher)
          end
        end
      end

      def inspect # :nodoc:
        "<##{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>"
      end

      # Synchronize calls to the cache. This should be called wherever the underlying cache implementation
      # is not thread safe.
      def synchronize(&block) # :nodoc:
        @monitor.synchronize(&block)
      end

      protected
        def read_entry(key, options) # :nodoc:
          entry = @data[key]
          synchronize do
            if entry
              @key_access[key] = Time.now.to_f
            else
              @key_access.delete(key)
            end
          end
          entry
        end

        def write_entry(key, entry, options) # :nodoc:
          entry.dup_value!
          synchronize do
            old_entry = @data[key]
            return false if @data.key?(key) && options[:unless_exist]
            @cache_size -= old_entry.size if old_entry
            @cache_size += entry.size
            @key_access[key] = Time.now.to_f
            @data[key] = entry
            prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size
            true
          end
        end

        def delete_entry(key, options) # :nodoc:
          synchronize do
            @key_access.delete(key)
            entry = @data.delete(key)
            @cache_size -= entry.size if entry
            !!entry
          end
        end
    end
  end
end
module ActiveSupport
  module Cache
    # A cache store implementation which doesn't actually store anything. Useful in
    # development and test environments where you don't want caching turned on but
    # need to go through the caching interface.
    #
    # This cache does implement the local cache strategy, so values will actually
    # be cached inside blocks that utilize this strategy. See
    # ActiveSupport::Cache::Strategy::LocalCache for more details.
    class NullStore < Store
      def initialize(options = nil)
        super(options)
        extend Strategy::LocalCache
      end

      def clear(options = nil)
      end

      def cleanup(options = nil)
      end

      def increment(name, amount = 1, options = nil)
      end

      def decrement(name, amount = 1, options = nil)
      end

      def delete_matched(matcher, options = nil)
      end

      protected
        def read_entry(key, options) # :nodoc:
        end

        def write_entry(key, entry, options) # :nodoc:
          true
        end

        def delete_entry(key, options) # :nodoc:
          false
        end
    end
  end
end
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/string/inflections'

module ActiveSupport
  module Cache
    module Strategy
      # Caches that implement LocalCache will be backed by an in-memory cache for the
      # duration of a block. Repeated calls to the cache for the same key will hit the
      # in-memory cache for faster access.
      module LocalCache
        # Simple memory backed cache. This cache is not thread safe and is intended only
        # for serving as a temporary memory cache for a single thread.
        class LocalStore < Store
          def initialize
            super
            @data = {}
          end

          # Don't allow synchronizing since it isn't thread safe,
          def synchronize # :nodoc:
            yield
          end

          def clear(options = nil)
            @data.clear
          end

          def read_entry(key, options)
            @data[key]
          end

          def write_entry(key, value, options)
            @data[key] = value
            true
          end

          def delete_entry(key, options)
            !!@data.delete(key)
          end
        end

        # Use a local cache for the duration of block.
        def with_local_cache
          save_val = Thread.current[thread_local_key]
          begin
            Thread.current[thread_local_key] = LocalStore.new
            yield
          ensure
            Thread.current[thread_local_key] = save_val
          end
        end

        #--
        # This class wraps up local storage for middlewares. Only the middleware method should
        # construct them.
        class Middleware # :nodoc:
          attr_reader :name, :thread_local_key

          def initialize(name, thread_local_key)
            @name             = name
            @thread_local_key = thread_local_key
            @app              = nil
          end

          def new(app)
            @app = app
            self
          end

          def call(env)
            Thread.current[thread_local_key] = LocalStore.new
            @app.call(env)
          ensure
            Thread.current[thread_local_key] = nil
          end
        end

        # Middleware class can be inserted as a Rack handler to be local cache for the
        # duration of request.
        def middleware
          @middleware ||= Middleware.new(
            "ActiveSupport::Cache::Strategy::LocalCache",
            thread_local_key)
        end

        def clear(options = nil) # :nodoc:
          local_cache.clear(options) if local_cache
          super
        end

        def cleanup(options = nil) # :nodoc:
          local_cache.clear(options) if local_cache
          super
        end

        def increment(name, amount = 1, options = nil) # :nodoc:
          value = bypass_local_cache{super}
          if local_cache
            local_cache.mute do
              if value
                local_cache.write(name, value, options)
              else
                local_cache.delete(name, options)
              end
            end
          end
          value
        end

        def decrement(name, amount = 1, options = nil) # :nodoc:
          value = bypass_local_cache{super}
          if local_cache
            local_cache.mute do
              if value
                local_cache.write(name, value, options)
              else
                local_cache.delete(name, options)
              end
            end
          end
          value
        end

        protected
          def read_entry(key, options) # :nodoc:
            if local_cache
              entry = local_cache.read_entry(key, options)
              unless entry
                entry = super
                local_cache.write_entry(key, entry, options)
              end
              entry
            else
              super
            end
          end

          def write_entry(key, entry, options) # :nodoc:
            local_cache.write_entry(key, entry, options) if local_cache
            super
          end

          def delete_entry(key, options) # :nodoc:
            local_cache.delete_entry(key, options) if local_cache
            super
          end

        private
          def thread_local_key
            @thread_local_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym
          end

          def local_cache
            Thread.current[thread_local_key]
          end

          def bypass_local_cache
            save_cache = Thread.current[thread_local_key]
            begin
              Thread.current[thread_local_key] = nil
              yield
            ensure
              Thread.current[thread_local_key] = save_cache
            end
          end
      end
    end
  end
end
require 'benchmark'
require 'zlib'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/benchmark'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/numeric/bytes'
require 'active_support/core_ext/numeric/time'
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/string/inflections'

module ActiveSupport
  # See ActiveSupport::Cache::Store for documentation.
  module Cache
    autoload :FileStore, 'active_support/cache/file_store'
    autoload :MemoryStore, 'active_support/cache/memory_store'
    autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
    autoload :NullStore, 'active_support/cache/null_store'

    # These options mean something to all cache implementations. Individual cache
    # implementations may support additional options.
    UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]

    module Strategy
      autoload :LocalCache, 'active_support/cache/strategy/local_cache'
    end

    class << self
      # Creates a new CacheStore object according to the given options.
      #
      # If no arguments are passed to this method, then a new
      # ActiveSupport::Cache::MemoryStore object will be returned.
      #
      # If you pass a Symbol as the first argument, then a corresponding cache
      # store class under the ActiveSupport::Cache namespace will be created.
      # For example:
      #
      #   ActiveSupport::Cache.lookup_store(:memory_store)
      #   # => returns a new ActiveSupport::Cache::MemoryStore object
      #
      #   ActiveSupport::Cache.lookup_store(:mem_cache_store)
      #   # => returns a new ActiveSupport::Cache::MemCacheStore object
      #
      # Any additional arguments will be passed to the corresponding cache store
      # class's constructor:
      #
      #   ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache')
      #   # => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache')
      #
      # If the first argument is not a Symbol, then it will simply be returned:
      #
      #   ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
      #   # => returns MyOwnCacheStore.new
      def lookup_store(*store_option)
        store, *parameters = *Array.wrap(store_option).flatten

        case store
        when Symbol
          store_class_name = store.to_s.camelize
          store_class =
            begin
              require "active_support/cache/#{store}"
            rescue LoadError => e
              raise "Could not find cache store adapter for #{store} (#{e})"
            else
              ActiveSupport::Cache.const_get(store_class_name)
            end
          store_class.new(*parameters)
        when nil
          ActiveSupport::Cache::MemoryStore.new
        else
          store
        end
      end

      def expand_cache_key(key, namespace = nil)
        expanded_cache_key = namespace ? "#{namespace}/" : ""

        if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
          expanded_cache_key << "#{prefix}/"
        end

        expanded_cache_key << retrieve_cache_key(key)
        expanded_cache_key
      end

      private

      def retrieve_cache_key(key)
        case
        when key.respond_to?(:cache_key) then key.cache_key
        when key.is_a?(Array)            then key.map { |element| retrieve_cache_key(element) }.to_param
        when key.respond_to?(:to_a)      then retrieve_cache_key(key.to_a)
        else                                  key.to_param
        end.to_s
      end
    end

    # An abstract cache store class. There are multiple cache store
    # implementations, each having its own additional features. See the classes
    # under the ActiveSupport::Cache module, e.g.
    # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
    # popular cache store for large production websites.
    #
    # Some implementations may not support all methods beyond the basic cache
    # methods of +fetch+, +write+, +read+, +exist?+, and +delete+.
    #
    # ActiveSupport::Cache::Store can store any serializable Ruby object.
    #
    #   cache = ActiveSupport::Cache::MemoryStore.new
    #
    #   cache.read('city')   # => nil
    #   cache.write('city', "Duckburgh")
    #   cache.read('city')   # => "Duckburgh"
    #
    # Keys are always translated into Strings and are case sensitive. When an
    # object is specified as a key and has a +cache_key+ method defined, this
    # method will be called to define the key.  Otherwise, the +to_param+
    # method will be called. Hashes and Arrays can also be used as keys. The
    # elements will be delimited by slashes, and the elements within a Hash
    # will be sorted by key so they are consistent.
    #
    #   cache.read('city') == cache.read(:city)   # => true
    #
    # Nil values can be cached.
    #
    # If your cache is on a shared infrastructure, you can define a namespace
    # for your cache entries. If a namespace is defined, it will be prefixed on
    # to every key. The namespace can be either a static value or a Proc. If it
    # is a Proc, it will be invoked when each key is evaluated so that you can
    # use application logic to invalidate keys.
    #
    #   cache.namespace = -> { @last_mod_time }  # Set the namespace to a variable
    #   @last_mod_time = Time.now  # Invalidate the entire cache by changing namespace
    #
    # Caches can also store values in a compressed format to save space and
    # reduce time spent sending data. Since there is overhead, values must be
    # large enough to warrant compression. To turn on compression either pass
    # <tt>compress: true</tt> in the initializer or as an option to +fetch+
    # or +write+. To specify the threshold at which to compress values, set the
    # <tt>:compress_threshold</tt> option. The default threshold is 16K.
    class Store

      cattr_accessor :logger, :instance_writer => true

      attr_reader :silence, :options
      alias :silence? :silence

      # Create a new cache. The options will be passed to any write method calls
      # except for <tt>:namespace</tt> which can be used to set the global
      # namespace for the cache.
      def initialize(options = nil)
        @options = options ? options.dup : {}
      end

      # Silence the logger.
      def silence!
        @silence = true
        self
      end

      # Silence the logger within a block.
      def mute
        previous_silence, @silence = defined?(@silence) && @silence, true
        yield
      ensure
        @silence = previous_silence
      end

      # Set to +true+ if cache stores should be instrumented.
      # Default is +false+.
      def self.instrument=(boolean)
        Thread.current[:instrument_cache_store] = boolean
      end

      def self.instrument
        Thread.current[:instrument_cache_store] || false
      end

      # Fetches data from the cache, using the given key. If there is data in
      # the cache with the given key, then that data is returned.
      #
      # If there is no such data in the cache (a cache miss), then +nil+ will be
      # returned. However, if a block has been passed, that block will be passed
      # the key and executed in the event of a cache miss. The return value of the
      # block will be written to the cache under the given cache key, and that
      # return value will be returned.
      #
      #   cache.write('today', 'Monday')
      #   cache.fetch('today')  # => "Monday"
      #
      #   cache.fetch('city')   # => nil
      #   cache.fetch('city') do
      #     'Duckburgh'
      #   end
      #   cache.fetch('city')   # => "Duckburgh"
      #
      # You may also specify additional options via the +options+ argument.
      # Setting <tt>force: true</tt> will force a cache miss:
      #
      #   cache.write('today', 'Monday')
      #   cache.fetch('today', force: true)  # => nil
      #
      # Setting <tt>:compress</tt> will store a large cache entry set by the call
      # in a compressed format.
      #
      # Setting <tt>:expires_in</tt> will set an expiration time on the cache.
      # All caches support auto-expiring content after a specified number of
      # seconds. This value can be specified as an option to the constructor
      # (in which case all entries will be affected), or it can be supplied to
      # the +fetch+ or +write+ method to effect just one entry.
      #
      #   cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
      #   cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
      #
      # Setting <tt>:race_condition_ttl</tt> is very useful in situations where
      # a cache entry is used very frequently and is under heavy load. If a
      # cache expires and due to heavy load seven different processes will try
      # to read data natively and then they all will try to write to cache. To
      # avoid that case the first process to find an expired cache entry will
      # bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>.
      # Yes, this process is extending the time for a stale value by another few
      # seconds. Because of extended life of the previous cache, other processes
      # will continue to use slightly stale data for a just a big longer. In the
      # meantime that first process will go ahead and will write into cache the
      # new value. After that all the processes will start getting new value.
      # The key is to keep <tt>:race_condition_ttl</tt> small.
      #
      # If the process regenerating the entry errors out, the entry will be
      # regenerated after the specified number of seconds. Also note that the
      # life of stale cache is extended only if it expired recently. Otherwise
      # a new value is generated and <tt>:race_condition_ttl</tt> does not play
      # any role.
      #
      #   # Set all values to expire after one minute.
      #   cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1.minute)
      #
      #   cache.write('foo', 'original value')
      #   val_1 = nil
      #   val_2 = nil
      #   sleep 60
      #
      #   Thread.new do
      #     val_1 = cache.fetch('foo', race_condition_ttl: 10) do
      #       sleep 1
      #       'new value 1'
      #     end
      #   end
      #
      #   Thread.new do
      #     val_2 = cache.fetch('foo', race_condition_ttl: 10) do
      #       'new value 2'
      #     end
      #   end
      #
      #   # val_1 => "new value 1"
      #   # val_2 => "original value"
      #   # sleep 10 # First thread extend the life of cache by another 10 seconds
      #   # cache.fetch('foo') => "new value 1"
      #
      # Other options will be handled by the specific cache store implementation.
      # Internally, #fetch calls #read_entry, and calls #write_entry on a cache
      # miss. +options+ will be passed to the #read and #write calls.
      #
      # For example, MemCacheStore's #write method supports the +:raw+
      # option, which tells the memcached server to store all values as strings.
      # We can use this option with #fetch too:
      #
      #   cache = ActiveSupport::Cache::MemCacheStore.new
      #   cache.fetch("foo", force: true, raw: true) do
      #     :bar
      #   end
      #   cache.fetch('foo') # => "bar"
      def fetch(name, options = nil)
        if block_given?
          options = merged_options(options)
          key = namespaced_key(name, options)

          cached_entry = find_cached_entry(key, name, options) unless options[:force]
          entry = handle_expired_entry(cached_entry, key, options)

          if entry
            get_entry_value(entry, name, options)
          else
            save_block_result_to_cache(name, options) { |_name| yield _name }
          end
        else
          read(name, options)
        end
      end

      # Fetches data from the cache, using the given key. If there is data in
      # the cache with the given key, then that data is returned. Otherwise,
      # +nil+ is returned.
      #
      # Options are passed to the underlying cache implementation.
      def read(name, options = nil)
        options = merged_options(options)
        key = namespaced_key(name, options)
        instrument(:read, name, options) do |payload|
          entry = read_entry(key, options)
          if entry
            if entry.expired?
              delete_entry(key, options)
              payload[:hit] = false if payload
              nil
            else
              payload[:hit] = true if payload
              entry.value
            end
          else
            payload[:hit] = false if payload
            nil
          end
        end
      end

      # Read multiple values at once from the cache. Options can be passed
      # in the last argument.
      #
      # Some cache implementation may optimize this method.
      #
      # Returns a hash mapping the names provided to the values found.
      def read_multi(*names)
        options = names.extract_options!
        options = merged_options(options)
        results = {}
        names.each do |name|
          key = namespaced_key(name, options)
          entry = read_entry(key, options)
          if entry
            if entry.expired?
              delete_entry(key, options)
            else
              results[name] = entry.value
            end
          end
        end
        results
      end

      # Writes the value to the cache, with the key.
      #
      # Options are passed to the underlying cache implementation.
      def write(name, value, options = nil)
        options = merged_options(options)
        instrument(:write, name, options) do |payload|
          entry = Entry.new(value, options)
          write_entry(namespaced_key(name, options), entry, options)
        end
      end

      # Deletes an entry in the cache. Returns +true+ if an entry is deleted.
      #
      # Options are passed to the underlying cache implementation.
      def delete(name, options = nil)
        options = merged_options(options)
        instrument(:delete, name) do |payload|
          delete_entry(namespaced_key(name, options), options)
        end
      end

      # Return +true+ if the cache contains an entry for the given key.
      #
      # Options are passed to the underlying cache implementation.
      def exist?(name, options = nil)
        options = merged_options(options)
        instrument(:exist?, name) do |payload|
          entry = read_entry(namespaced_key(name, options), options)
          entry && !entry.expired?
        end
      end

      # Delete all entries with keys matching the pattern.
      #
      # Options are passed to the underlying cache implementation.
      #
      # All implementations may not support this method.
      def delete_matched(matcher, options = nil)
        raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
      end

      # Increment an integer value in the cache.
      #
      # Options are passed to the underlying cache implementation.
      #
      # All implementations may not support this method.
      def increment(name, amount = 1, options = nil)
        raise NotImplementedError.new("#{self.class.name} does not support increment")
      end

      # Decrement an integer value in the cache.
      #
      # Options are passed to the underlying cache implementation.
      #
      # All implementations may not support this method.
      def decrement(name, amount = 1, options = nil)
        raise NotImplementedError.new("#{self.class.name} does not support decrement")
      end

      # Cleanup the cache by removing expired entries.
      #
      # Options are passed to the underlying cache implementation.
      #
      # All implementations may not support this method.
      def cleanup(options = nil)
        raise NotImplementedError.new("#{self.class.name} does not support cleanup")
      end

      # Clear the entire cache. Be careful with this method since it could
      # affect other processes if shared cache is being used.
      #
      # Options are passed to the underlying cache implementation.
      #
      # All implementations may not support this method.
      def clear(options = nil)
        raise NotImplementedError.new("#{self.class.name} does not support clear")
      end

      protected
        # Add the namespace defined in the options to a pattern designed to
        # match keys. Implementations that support delete_matched should call
        # this method to translate a pattern that matches names into one that
        # matches namespaced keys.
        def key_matcher(pattern, options)
          prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
          if prefix
            source = pattern.source
            if source.start_with?('^')
              source = source[1, source.length]
            else
              source = ".*#{source[0, source.length]}"
            end
            Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
          else
            pattern
          end
        end

        # Read an entry from the cache implementation. Subclasses must implement
        # this method.
        def read_entry(key, options) # :nodoc:
          raise NotImplementedError.new
        end

        # Write an entry to the cache implementation. Subclasses must implement
        # this method.
        def write_entry(key, entry, options) # :nodoc:
          raise NotImplementedError.new
        end

        # Delete an entry from the cache implementation. Subclasses must
        # implement this method.
        def delete_entry(key, options) # :nodoc:
          raise NotImplementedError.new
        end

      private
        # Merge the default options with ones specific to a method call.
        def merged_options(call_options) # :nodoc:
          if call_options
            options.merge(call_options)
          else
            options.dup
          end
        end

        # Expand key to be a consistent string value. Invoke +cache_key+ if
        # object responds to +cache_key+. Otherwise, +to_param+ method will be
        # called. If the key is a Hash, then keys will be sorted alphabetically.
        def expanded_key(key) # :nodoc:
          return key.cache_key.to_s if key.respond_to?(:cache_key)

          case key
          when Array
            if key.size > 1
              key = key.collect{|element| expanded_key(element)}
            else
              key = key.first
            end
          when Hash
            key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
          end

          key.to_param
        end

        # Prefix a key with the namespace. Namespace and key will be delimited
        # with a colon.
        def namespaced_key(key, options)
          key = expanded_key(key)
          namespace = options[:namespace] if options
          prefix = namespace.is_a?(Proc) ? namespace.call : namespace
          key = "#{prefix}:#{key}" if prefix
          key
        end

        def instrument(operation, key, options = nil)
          log(operation, key, options)

          if self.class.instrument
            payload = { :key => key }
            payload.merge!(options) if options.is_a?(Hash)
            ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
          else
            yield(nil)
          end
        end

        def log(operation, key, options = nil)
          return unless logger && logger.debug? && !silence?
          logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
        end

        def find_cached_entry(key, name, options)
          instrument(:read, name, options) do |payload|
            payload[:super_operation] = :fetch if payload
            read_entry(key, options)
          end
        end

        def handle_expired_entry(entry, key, options)
          if entry && entry.expired?
            race_ttl = options[:race_condition_ttl].to_i
            if race_ttl && (Time.now - entry.expires_at <= race_ttl)
              # When an entry has :race_condition_ttl defined, put the stale entry back into the cache
              # for a brief period while the entry is begin recalculated.
              entry.expires_at = Time.now + race_ttl
              write_entry(key, entry, :expires_in => race_ttl * 2)
            else
              delete_entry(key, options)
            end
            entry = nil
          end
          entry
        end

        def get_entry_value(entry, name, options)
          instrument(:fetch_hit, name, options) { |payload| }
          entry.value
        end

        def save_block_result_to_cache(name, options)
          result = instrument(:generate, name, options) do |payload|
            yield(name)
          end
          write(name, result, options)
          result
        end
    end

    # This class is used to represent cache entries. Cache entries have a value and an optional
    # expiration time. The expiration time is used to support the :race_condition_ttl option
    # on the cache.
    #
    # Since cache entries in most instances will be serialized, the internals of this class are highly optimized
    # using short instance variable names that are lazily defined.
    class Entry # :nodoc:
      DEFAULT_COMPRESS_LIMIT = 16.kilobytes

      # Create a new cache entry for the specified value. Options supported are
      # +:compress+, +:compress_threshold+, and +:expires_in+.
      def initialize(value, options = {})
        if should_compress?(value, options)
          @v = compress(value)
          @c = true
        else
          @v = value
        end
        if expires_in = options[:expires_in]
          @x = (Time.now + expires_in).to_i
        end
      end

      def value
        convert_version_3_entry! if defined?(@value)
        compressed? ? uncompress(@v) : @v
      end

      # Check if the entry is expired. The +expires_in+ parameter can override
      # the value set when the entry was created.
      def expired?
        convert_version_3_entry! if defined?(@value)
        if defined?(@x)
          @x && @x < Time.now.to_i
        else
          false
        end
      end

      def expires_at
        Time.at(@x) if defined?(@x)
      end

      def expires_at=(value)
        @x = value.to_i
      end

      # Returns the size of the cached value. This could be less than
      # <tt>value.size</tt> if the data is compressed.
      def size
        if defined?(@s)
          @s
        else
          case value
          when NilClass
            0
          when String
            @v.bytesize
          else
            @s = Marshal.dump(@v).bytesize
          end
        end
      end

      # Duplicate the value in a class. This is used by cache implementations that don't natively
      # serialize entries to protect against accidental cache modifications.
      def dup_value!
        convert_version_3_entry! if defined?(@value)
        if @v && !compressed? && !(@v.is_a?(Numeric) || @v == true || @v == false)
          if @v.is_a?(String)
            @v = @v.dup
          else
            @v = Marshal.load(Marshal.dump(@v))
          end
        end
      end

      private
        def should_compress?(value, options)
          if value && options[:compress]
            compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT
            serialized_value_size = (value.is_a?(String) ? value : Marshal.dump(value)).bytesize
            return true if serialized_value_size >= compress_threshold
          end
          false
        end

        def compressed?
          defined?(@c) ? @c : false
        end

        def compress(value)
          Zlib::Deflate.deflate(Marshal.dump(value))
        end

        def uncompress(value)
          Marshal.load(Zlib::Inflate.inflate(value))
        end

        # The internals of this method changed between Rails 3.x and 4.0. This method provides the glue
        # to ensure that cache entries created under the old version still work with the new class definition.
        def convert_version_3_entry!
          if defined?(@value)
            @v = @value
            remove_instance_variable(:@value)
          end
          if defined?(@compressed)
            @c = @compressed
            remove_instance_variable(:@compressed)
          end
          if defined?(@expires_in) && defined?(@created_at) && @expires_in && @created_at
            @x = (@created_at + @expires_in).to_i
            remove_instance_variable(:@created_at)
            remove_instance_variable(:@expires_in)
          end
        end
    end
  end
end
require 'thread_safe'
require 'active_support/concern'
require 'active_support/descendants_tracker'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'

module ActiveSupport
  # Callbacks are code hooks that are run at key points in an object's lifecycle.
  # The typical use case is to have a base class define a set of callbacks
  # relevant to the other functionality it supplies, so that subclasses can
  # install callbacks that enhance or modify the base functionality without
  # needing to override or redefine methods of the base class.
  #
  # Mixing in this module allows you to define the events in the object's
  # lifecycle that will support callbacks (via +ClassMethods.define_callbacks+),
  # set the instance methods, procs, or callback objects to be called (via
  # +ClassMethods.set_callback+), and run the installed callbacks at the
  # appropriate times (via +run_callbacks+).
  #
  # Three kinds of callbacks are supported: before callbacks, run before a
  # certain event; after callbacks, run after the event; and around callbacks,
  # blocks that surround the event, triggering it when they yield. Callback code
  # can be contained in instance methods, procs or lambdas, or callback objects
  # that respond to certain predetermined methods. See +ClassMethods.set_callback+
  # for details.
  #
  #   class Record
  #     include ActiveSupport::Callbacks
  #     define_callbacks :save
  #
  #     def save
  #       run_callbacks :save do
  #         puts "- save"
  #       end
  #     end
  #   end
  #
  #   class PersonRecord < Record
  #     set_callback :save, :before, :saving_message
  #     def saving_message
  #       puts "saving..."
  #     end
  #
  #     set_callback :save, :after do |object|
  #       puts "saved"
  #     end
  #   end
  #
  #   person = PersonRecord.new
  #   person.save
  #
  # Output:
  #   saving...
  #   - save
  #   saved
  module Callbacks
    extend Concern

    included do
      extend ActiveSupport::DescendantsTracker
    end

    # Runs the callbacks for the given event.
    #
    # Calls the before and around callbacks in the order they were set, yields
    # the block (if given one), and then runs the after callbacks in reverse
    # order.
    #
    # If the callback chain was halted, returns +false+. Otherwise returns the
    # result of the block, or +true+ if no block is given.
    #
    #   run_callbacks :save do
    #     save
    #   end
    def run_callbacks(kind, &block)
      runner_name = self.class.__define_callbacks(kind, self)
      send(runner_name, &block)
    end

    private

    # A hook invoked everytime a before callback is halted.
    # This can be overridden in AS::Callback implementors in order
    # to provide better debugging/logging.
    def halted_callback_hook(filter)
    end

    class Callback #:nodoc:#
      @@_callback_sequence = 0

      attr_accessor :chain, :filter, :kind, :options, :klass, :raw_filter

      def initialize(chain, filter, kind, options, klass)
        @chain, @kind, @klass = chain, kind, klass
        deprecate_per_key_option(options)
        normalize_options!(options)

        @raw_filter, @options = filter, options
        @filter               = _compile_filter(filter)
        recompile_options!
      end

      def deprecate_per_key_option(options)
        if options[:per_key]
          raise NotImplementedError, ":per_key option is no longer supported. Use generic :if and :unless options instead."
        end
      end

      def clone(chain, klass)
        obj                  = super()
        obj.chain            = chain
        obj.klass            = klass
        obj.options          = @options.dup
        obj.options[:if]     = @options[:if].dup
        obj.options[:unless] = @options[:unless].dup
        obj
      end

      def normalize_options!(options)
        options[:if] = Array(options[:if])
        options[:unless] = Array(options[:unless])
      end

      def name
        chain.name
      end

      def next_id
        @@_callback_sequence += 1
      end

      def matches?(_kind, _filter)
        @kind == _kind && @filter == _filter
      end

      def duplicates?(other)
        matches?(other.kind, other.filter)
      end

      def _update_filter(filter_options, new_options)
        filter_options[:if].concat(Array(new_options[:unless])) if new_options.key?(:unless)
        filter_options[:unless].concat(Array(new_options[:if])) if new_options.key?(:if)
      end

      def recompile!(_options)
        deprecate_per_key_option(_options)
        _update_filter(self.options, _options)

        recompile_options!
      end

      # Wraps code with filter
      def apply(code)
        case @kind
        when :before
          <<-RUBY_EVAL
            if !halted && #{@compiled_options}
              # This double assignment is to prevent warnings in 1.9.3 as
              # the `result` variable is not always used except if the
              # terminator code refers to it.
              result = result = #{@filter}
              halted = (#{chain.config[:terminator]})
              if halted
                halted_callback_hook(#{@raw_filter.inspect.inspect})
              end
            end
            #{code}
          RUBY_EVAL
        when :after
          <<-RUBY_EVAL
          #{code}
          if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}
            #{@filter}
          end
          RUBY_EVAL
        when :around
          name = define_conditional_callback
          <<-RUBY_EVAL
          #{name}(halted) do
            #{code}
            value
          end
          RUBY_EVAL
        end
      end

      private

      # Compile around filters with conditions into proxy methods
      # that contain the conditions.
      #
      # For `set_callback :save, :around, :filter_name, if: :condition':
      #
      #   def _conditional_callback_save_17
      #     if condition
      #       filter_name do
      #         yield self
      #       end
      #     else
      #       yield self
      #     end
      #   end
      def define_conditional_callback
        name = "_conditional_callback_#{@kind}_#{next_id}"
        @klass.class_eval <<-RUBY_EVAL,  __FILE__, __LINE__ + 1
          def #{name}(halted)
           if #{@compiled_options} && !halted
             #{@filter} do
               yield self
             end
           else
             yield self
           end
         end
        RUBY_EVAL
        name
      end

      # Options support the same options as filters themselves (and support
      # symbols, string, procs, and objects), so compile a conditional
      # expression based on the options.
      def recompile_options!
        conditions = ["true"]

        unless options[:if].empty?
          conditions << Array(_compile_filter(options[:if]))
        end

        unless options[:unless].empty?
          conditions << Array(_compile_filter(options[:unless])).map {|f| "!#{f}"}
        end

        @compiled_options = conditions.flatten.join(" && ")
      end

      # Filters support:
      #
      #   Arrays::  Used in conditions. This is used to specify
      #             multiple conditions. Used internally to
      #             merge conditions from skip_* filters.
      #   Symbols:: A method to call.
      #   Strings:: Some content to evaluate.
      #   Procs::   A proc to call with the object.
      #   Objects:: An object with a <tt>before_foo</tt> method on it to call.
      #
      # All of these objects are compiled into methods and handled
      # the same after this point:
      #
      #   Arrays::  Merged together into a single filter.
      #   Symbols:: Already methods.
      #   Strings:: class_eval'ed into methods.
      #   Procs::   define_method'ed into methods.
      #   Objects::
      #     a method is created that calls the before_foo method
      #     on the object.
      def _compile_filter(filter)
        method_name = "_callback_#{@kind}_#{next_id}"
        case filter
        when Array
          filter.map {|f| _compile_filter(f)}
        when Symbol
          filter
        when String
          "(#{filter})"
        when Proc
          @klass.send(:define_method, method_name, &filter)
          return method_name if filter.arity <= 0

          method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ")
        else
          @klass.send(:define_method, "#{method_name}_object") { filter }

          _normalize_legacy_filter(kind, filter)
          scopes = Array(chain.config[:scope])
          method_to_call = scopes.map{ |s| s.is_a?(Symbol) ? send(s) : s }.join("_")

          @klass.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
            def #{method_name}(&blk)
              #{method_name}_object.send(:#{method_to_call}, self, &blk)
            end
          RUBY_EVAL

          method_name
        end
      end

      def _normalize_legacy_filter(kind, filter)
        if !filter.respond_to?(kind) && filter.respond_to?(:filter)
          message = "Filter object with #filter method is deprecated. Define method corresponding " \
                    "to filter type (#before, #after or #around)."
          ActiveSupport::Deprecation.warn message
          filter.singleton_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
            def #{kind}(context, &block) filter(context, &block) end
          RUBY_EVAL
        elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around && !filter.respond_to?(:around)
          message = "Filter object with #before and #after methods is deprecated. Define #around method instead."
          ActiveSupport::Deprecation.warn message
          def filter.around(context)
            should_continue = before(context)
            yield if should_continue
            after(context)
          end
        end
      end
    end

    # An Array with a compile method.
    class CallbackChain < Array #:nodoc:#
      attr_reader :name, :config

      def initialize(name, config)
        @name = name
        @config = {
          :terminator => "false",
          :scope => [ :kind ]
        }.merge(config)
      end

      def compile
        method = []
        method << "value = nil"
        method << "halted = false"

        callbacks = "value = !halted && (!block_given? || yield)"
        reverse_each do |callback|
          callbacks = callback.apply(callbacks)
        end
        method << callbacks

        method << "value"
        method.join("\n")
      end

      def append(*callbacks)
        callbacks.each { |c| append_one(c) }
      end

      def prepend(*callbacks)
        callbacks.each { |c| prepend_one(c) }
      end

      private

      def append_one(callback)
        remove_duplicates(callback)
        push(callback)
      end

      def prepend_one(callback)
        remove_duplicates(callback)
        unshift(callback)
      end

      def remove_duplicates(callback)
        delete_if { |c| callback.duplicates?(c) }
      end

    end

    module ClassMethods

      # This method defines callback chain method for the given kind
      # if it was not yet defined.
      # This generated method plays caching role.
      def __define_callbacks(kind, object) #:nodoc:
        name = __callback_runner_name(kind)
        unless object.respond_to?(name, true)
          str = object.send("_#{kind}_callbacks").compile
          class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
            def #{name}() #{str} end
            protected :#{name}
          RUBY_EVAL
        end
        name
      end

      def __reset_runner(symbol)
        name = __callback_runner_name(symbol)
        undef_method(name) if method_defined?(name)
      end

      def __callback_runner_name_cache
        @__callback_runner_name_cache ||= ThreadSafe::Cache.new {|cache, kind| cache[kind] = __generate_callback_runner_name(kind) }
      end

      def __generate_callback_runner_name(kind)
        "_run__#{self.name.hash.abs}__#{kind}__callbacks"
      end

      def __callback_runner_name(kind)
        __callback_runner_name_cache[kind]
      end

      # This is used internally to append, prepend and skip callbacks to the
      # CallbackChain.
      def __update_callbacks(name, filters = [], block = nil) #:nodoc:
        type = [:before, :after, :around].include?(filters.first) ? filters.shift : :before
        options = filters.last.is_a?(Hash) ? filters.pop : {}
        filters.unshift(block) if block

        ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target|
          chain = target.send("_#{name}_callbacks")
          yield target, chain.dup, type, filters, options
          target.__reset_runner(name)
        end
      end

      # Install a callback for the given event.
      #
      #   set_callback :save, :before, :before_meth
      #   set_callback :save, :after,  :after_meth, if: :condition
      #   set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
      #
      # The second arguments indicates whether the callback is to be run +:before+,
      # +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
      # means the first example above can also be written as:
      #
      #   set_callback :save, :before_meth
      #
      # The callback can specified as a symbol naming an instance method; as a
      # proc, lambda, or block; as a string to be instance evaluated; or as an
      # object that responds to a certain method determined by the <tt>:scope</tt>
      # argument to +define_callback+.
      #
      # If a proc, lambda, or block is given, its body is evaluated in the context
      # of the current object. It can also optionally accept the current object as
      # an argument.
      #
      # Before and around callbacks are called in the order that they are set;
      # after callbacks are called in the reverse order.
      #
      # Around callbacks can access the return value from the event, if it
      # wasn't halted, from the +yield+ call.
      #
      # ===== Options
      #
      # * <tt>:if</tt> - A symbol naming an instance method or a proc; the
      #   callback will be called only when it returns a +true+ value.
      # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the
      #   callback will be called only when it returns a +false+ value.
      # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
      #   existing chain rather than appended.
      def set_callback(name, *filter_list, &block)
        mapped = nil

        __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options|
          mapped ||= filters.map do |filter|
            Callback.new(chain, filter, type, options.dup, self)
          end

          options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped)

          target.send("_#{name}_callbacks=", chain)
        end
      end

      # Skip a previously set callback. Like +set_callback+, <tt>:if</tt> or
      # <tt>:unless</tt> options may be passed in order to control when the
      # callback is skipped.
      #
      #   class Writer < Person
      #      skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 }
      #   end
      def skip_callback(name, *filter_list, &block)
        __update_callbacks(name, filter_list, block) do |target, chain, type, filters, options|
          filters.each do |filter|
            filter = chain.find {|c| c.matches?(type, filter) }

            if filter && options.any?
              new_filter = filter.clone(chain, self)
              chain.insert(chain.index(filter), new_filter)
              new_filter.recompile!(options)
            end

            chain.delete(filter)
          end
          target.send("_#{name}_callbacks=", chain)
        end
      end

      # Remove all set callbacks for the given event.
      def reset_callbacks(symbol)
        callbacks = send("_#{symbol}_callbacks")

        ActiveSupport::DescendantsTracker.descendants(self).each do |target|
          chain = target.send("_#{symbol}_callbacks").dup
          callbacks.each { |c| chain.delete(c) }
          target.send("_#{symbol}_callbacks=", chain)
          target.__reset_runner(symbol)
        end

        self.send("_#{symbol}_callbacks=", callbacks.dup.clear)

        __reset_runner(symbol)
      end

      # Define sets of events in the object lifecycle that support callbacks.
      #
      #   define_callbacks :validate
      #   define_callbacks :initialize, :save, :destroy
      #
      # ===== Options
      #
      # * <tt>:terminator</tt> - Determines when a before filter will halt the
      #   callback chain, preventing following callbacks from being called and
      #   the event from being triggered. This is a string to be eval'ed. The
      #   result of the callback is available in the +result+ variable.
      #
      #     define_callbacks :validate, terminator: 'result == false'
      #
      #   In this example, if any before validate callbacks returns +false+,
      #   other callbacks are not executed. Defaults to +false+, meaning no value
      #   halts the chain.
      #
      # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after
      #   callbacks should be terminated by the <tt>:terminator</tt> option. By
      #   default after callbacks executed no matter if callback chain was
      #   terminated or not. Option makes sense only when <tt>:terminator</tt>
      #   option is specified.
      #
      # * <tt>:scope</tt> - Indicates which methods should be executed when an
      #   object is used as a callback.
      #
      #     class Audit
      #       def before(caller)
      #         puts 'Audit: before is called'
      #       end
      #
      #       def before_save(caller)
      #         puts 'Audit: before_save is called'
      #       end
      #     end
      #
      #     class Account
      #       include ActiveSupport::Callbacks
      #
      #       define_callbacks :save
      #       set_callback :save, :before, Audit.new
      #
      #       def save
      #         run_callbacks :save do
      #           puts 'save in main'
      #         end
      #       end
      #     end
      #
      #   In the above case whenever you save an account the method
      #   <tt>Audit#before</tt> will be called. On the other hand
      #
      #     define_callbacks :save, scope: [:kind, :name]
      #
      #   would trigger <tt>Audit#before_save</tt> instead. That's constructed
      #   by calling <tt>#{kind}_#{name}</tt> on the given instance. In this
      #   case "kind" is "before" and "name" is "save". In this context +:kind+
      #   and +:name+ have special meanings: +:kind+ refers to the kind of
      #   callback (before/after/around) and +:name+ refers to the method on
      #   which callbacks are being defined.
      #
      #   A declaration like
      #
      #     define_callbacks :save, scope: [:name]
      #
      #   would call <tt>Audit#save</tt>.
      def define_callbacks(*callbacks)
        config = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
        callbacks.each do |callback|
          class_attribute "_#{callback}_callbacks"
          send("_#{callback}_callbacks=", CallbackChain.new(callback, config))
        end
      end
    end
  end
end
module ActiveSupport
  # A typical module looks like this:
  #
  #   module M
  #     def self.included(base)
  #       base.extend ClassMethods
  #       base.class_eval do
  #         scope :disabled, -> { where(disabled: true) }
  #       end
  #     end
  #
  #     module ClassMethods
  #       ...
  #     end
  #   end
  #
  # By using <tt>ActiveSupport::Concern</tt> the above module could instead be
  # written as:
  #
  #   require 'active_support/concern'
  #
  #   module M
  #     extend ActiveSupport::Concern
  #
  #     included do
  #       scope :disabled, -> { where(disabled: true) }
  #     end
  #
  #     module ClassMethods
  #       ...
  #     end
  #   end
  #
  # Moreover, it gracefully handles module dependencies. Given a +Foo+ module
  # and a +Bar+ module which depends on the former, we would typically write the
  # following:
  #
  #   module Foo
  #     def self.included(base)
  #       base.class_eval do
  #         def self.method_injected_by_foo
  #           ...
  #         end
  #       end
  #     end
  #   end
  #
  #   module Bar
  #     def self.included(base)
  #       base.method_injected_by_foo
  #     end
  #   end
  #
  #   class Host
  #     include Foo # We need to include this dependency for Bar
  #     include Bar # Bar is the module that Host really needs
  #   end
  #
  # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We
  # could try to hide these from +Host+ directly including +Foo+ in +Bar+:
  #
  #   module Bar
  #     include Foo
  #     def self.included(base)
  #       base.method_injected_by_foo
  #     end
  #   end
  #
  #   class Host
  #     include Bar
  #   end
  #
  # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt>
  # is the +Bar+ module, not the +Host+ class. With <tt>ActiveSupport::Concern</tt>,
  # module dependencies are properly resolved:
  #
  #   require 'active_support/concern'
  #
  #   module Foo
  #     extend ActiveSupport::Concern
  #     included do
  #       def self.method_injected_by_foo
  #         ...
  #       end
  #     end
  #   end
  #
  #   module Bar
  #     extend ActiveSupport::Concern
  #     include Foo
  #
  #     included do
  #       self.method_injected_by_foo
  #     end
  #   end
  #
  #   class Host
  #     include Bar # works, Bar takes care now of its dependencies
  #   end
  module Concern
    def self.extended(base) #:nodoc:
      base.instance_variable_set("@_dependencies", [])
    end

    def append_features(base)
      if base.instance_variable_defined?("@_dependencies")
        base.instance_variable_get("@_dependencies") << self
        return false
      else
        return false if base < self
        @_dependencies.each { |dep| base.send(:include, dep) }
        super
        base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
        base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
      end
    end

    def included(base = nil, &block)
      if base.nil?
        @_included_block = block
      else
        super
      end
    end
  end
end
require 'thread'
require 'monitor'

module ActiveSupport
  module Concurrency
    class Latch
      def initialize(count = 1)
        @count = count
        @lock = Monitor.new
        @cv = @lock.new_cond
      end

      def release
        @lock.synchronize do
          @count -= 1 if @count > 0
          @cv.broadcast if @count.zero?
        end
      end

      def await
        @lock.synchronize do
          @cv.wait_while { @count > 0 }
        end
      end
    end
  end
end
require 'active_support/concern'
require 'active_support/ordered_options'
require 'active_support/core_ext/array/extract_options'

module ActiveSupport
  # Configurable provides a <tt>config</tt> method to store and retrieve
  # configuration options as an <tt>OrderedHash</tt>.
  module Configurable
    extend ActiveSupport::Concern

    class Configuration < ActiveSupport::InheritableOptions
      def compile_methods!
        self.class.compile_methods!(keys)
      end

      # Compiles reader methods so we don't have to go through method_missing.
      def self.compile_methods!(keys)
        keys.reject { |m| method_defined?(m) }.each do |key|
          class_eval <<-RUBY, __FILE__, __LINE__ + 1
            def #{key}; _get(#{key.inspect}); end
          RUBY
        end
      end
    end

    module ClassMethods
      def config
        @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
          superclass.config.inheritable_copy
        else
          # create a new "anonymous" class that will host the compiled reader methods
          Class.new(Configuration).new
        end
      end

      def configure
        yield config
      end

      # Allows you to add shortcut so that you don't have to refer to attribute
      # through config. Also look at the example for config to contrast.
      #
      # Defines both class and instance config accessors.
      #
      #   class User
      #     include ActiveSupport::Configurable
      #     config_accessor :allowed_access
      #   end
      #
      #   User.allowed_access # => nil
      #   User.allowed_access = false
      #   User.allowed_access # => false
      #
      #   user = User.new
      #   user.allowed_access # => false
      #   user.allowed_access = true
      #   user.allowed_access # => true
      #
      #   User.allowed_access # => false
      #
      # The attribute name must be a valid method name in Ruby.
      #
      #   class User
      #     include ActiveSupport::Configurable
      #     config_accessor :"1_Badname"
      #   end
      #   # => NameError: invalid config attribute name
      #
      # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
      # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
      #
      #   class User
      #     include ActiveSupport::Configurable
      #     config_accessor :allowed_access, instance_reader: false, instance_writer: false
      #   end
      #
      #   User.allowed_access = false
      #   User.allowed_access # => false
      #
      #   User.new.allowed_access = true # => NoMethodError
      #   User.new.allowed_access        # => NoMethodError
      #
      # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
      #
      #   class User
      #     include ActiveSupport::Configurable
      #     config_accessor :allowed_access, instance_accessor: false
      #   end
      #
      #   User.allowed_access = false
      #   User.allowed_access # => false
      #
      #   User.new.allowed_access = true # => NoMethodError
      #   User.new.allowed_access        # => NoMethodError
      #
      # Also you can pass a block to set up the attribute with a default value.
      #
      #   class User
      #     include ActiveSupport::Configurable
      #     config_accessor :hair_colors do
      #       [:brown, :black, :blonde, :red]
      #     end
      #   end
      #
      #   User.hair_colors # => [:brown, :black, :blonde, :red]
      def config_accessor(*names)
        options = names.extract_options!

        names.each do |name|
          raise NameError.new('invalid config attribute name') unless name =~ /^[_A-Za-z]\w*$/

          reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
          writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__

          singleton_class.class_eval reader, __FILE__, reader_line
          singleton_class.class_eval writer, __FILE__, writer_line

          unless options[:instance_accessor] == false
            class_eval reader, __FILE__, reader_line unless options[:instance_reader] == false
            class_eval writer, __FILE__, writer_line unless options[:instance_writer] == false
          end
          send("#{name}=", yield) if block_given?
        end
      end
    end

    # Reads and writes attributes from a configuration <tt>OrderedHash</tt>.
    #
    #   require 'active_support/configurable'
    #
    #   class User
    #     include ActiveSupport::Configurable
    #   end
    #
    #   user = User.new
    #
    #   user.config.allowed_access = true
    #   user.config.level = 1
    #
    #   user.config.allowed_access # => true
    #   user.config.level          # => 1
    def config
      @_config ||= self.class.config.inheritable_copy
    end
  end
end

class Array
  # Returns the tail of the array from +position+.
  #
  #   %w( a b c d ).from(0)  # => ["a", "b", "c", "d"]
  #   %w( a b c d ).from(2)  # => ["c", "d"]
  #   %w( a b c d ).from(10) # => []
  #   %w().from(0)           # => []
  def from(position)
    self[position, length] || []
  end

  # Returns the beginning of the array up to +position+.
  #
  #   %w( a b c d ).to(0)  # => ["a"]
  #   %w( a b c d ).to(2)  # => ["a", "b", "c"]
  #   %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
  #   %w().to(0)           # => []
  def to(position)
    first position + 1
  end

  # Equal to <tt>self[1]</tt>.
  #
  #   %w( a b c d e ).second # => "b"
  def second
    self[1]
  end

  # Equal to <tt>self[2]</tt>.
  #
  #   %w( a b c d e ).third # => "c"
  def third
    self[2]
  end

  # Equal to <tt>self[3]</tt>.
  #
  #   %w( a b c d e ).fourth # => "d"
  def fourth
    self[3]
  end

  # Equal to <tt>self[4]</tt>.
  #
  #   %w( a b c d e ).fifth # => "e"
  def fifth
    self[4]
  end

  # Equal to <tt>self[41]</tt>. Also known as accessing "the reddit".
  def forty_two
    self[41]
  end
end
require 'active_support/xml_mini'
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/object/to_query'

class Array
  # Converts the array to a comma-separated sentence where the last element is
  # joined by the connector word.
  #
  # You can pass the following options to change the default behavior. If you
  # pass an option key that doesn't exist in the list below, it will raise an
  # <tt>ArgumentError</tt>.
  #
  # Options:
  #
  # * <tt>:words_connector</tt> - The sign or word used to join the elements
  #   in arrays with two or more elements (default: ", ").
  # * <tt>:two_words_connector</tt> - The sign or word used to join the elements
  #   in arrays with two elements (default: " and ").
  # * <tt>:last_word_connector</tt> - The sign or word used to join the last element
  #   in arrays with three or more elements (default: ", and ").
  # * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
  #   the connector options defined on the 'support.array' namespace in the
  #   corresponding dictionary file.
  #
  #   [].to_sentence                      # => ""
  #   ['one'].to_sentence                 # => "one"
  #   ['one', 'two'].to_sentence          # => "one and two"
  #   ['one', 'two', 'three'].to_sentence # => "one, two, and three"
  #
  #   ['one', 'two'].to_sentence(passing: 'invalid option')
  #   # => ArgumentError: Unknown key :passing
  #
  #   ['one', 'two'].to_sentence(two_words_connector: '-')
  #   # => "one-two"
  #
  #   ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
  #   # => "one or two or at least three"
  #
  # Examples using <tt>:locale</tt> option:
  #
  #   # Given this locale dictionary:
  #   # 
  #   #   es:
  #   #     support:
  #   #       array:
  #   #         words_connector: " o "
  #   #         two_words_connector: " y "
  #   #         last_word_connector: " o al menos "
  #
  #   ['uno', 'dos'].to_sentence(locale: :es)
  #   # => "uno y dos"
  #
  #   ['uno', 'dos', 'tres'].to_sentence(locale: :es)
  #   # => "uno o dos o al menos tres"
  def to_sentence(options = {})
    options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)

    default_connectors = {
      :words_connector     => ', ',
      :two_words_connector => ' and ',
      :last_word_connector => ', and '
    }
    if defined?(I18n)
      i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
      default_connectors.merge!(i18n_connectors)
    end
    options = default_connectors.merge!(options)

    case length
    when 0
      ''
    when 1
      self[0].to_s.dup
    when 2
      "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
    else
      "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
    end
  end

  # Converts a collection of elements into a formatted string by calling
  # <tt>to_s</tt> on all elements and joining them. Having this model:
  #
  #   class Blog < ActiveRecord::Base
  #     def to_s
  #       title
  #     end
  #   end
  #
  #   Blog.all.map(&:title) #=> ["First Post", "Second Post", "Third post"]
  #
  # <tt>to_formatted_s</tt> shows us:
  #
  #   Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
  #
  # Adding in the <tt>:db</tt> argument as the format yields a comma separated
  # id list:
  #
  #   Blog.all.to_formatted_s(:db) # => "1,2,3"
  def to_formatted_s(format = :default)
    case format
    when :db
      if empty?
        'null'
      else
        collect { |element| element.id }.join(',')
      end
    else
      to_default_s
    end
  end
  alias_method :to_default_s, :to_s
  alias_method :to_s, :to_formatted_s

  # Returns a string that represents the array in XML by invoking +to_xml+
  # on each element. Active Record collections delegate their representation
  # in XML to this method.
  #
  # All elements are expected to respond to +to_xml+, if any of them does
  # not then an exception is raised.
  #
  # The root node reflects the class name of the first element in plural
  # if all elements belong to the same type and that's not Hash:
  #
  #   customer.projects.to_xml
  #
  #   <?xml version="1.0" encoding="UTF-8"?>
  #   <projects type="array">
  #     <project>
  #       <amount type="decimal">20000.0</amount>
  #       <customer-id type="integer">1567</customer-id>
  #       <deal-date type="date">2008-04-09</deal-date>
  #       ...
  #     </project>
  #     <project>
  #       <amount type="decimal">57230.0</amount>
  #       <customer-id type="integer">1567</customer-id>
  #       <deal-date type="date">2008-04-15</deal-date>
  #       ...
  #     </project>
  #   </projects>
  #
  # Otherwise the root element is "objects":
  #
  #   [{ foo: 1, bar: 2}, { baz: 3}].to_xml
  #
  #   <?xml version="1.0" encoding="UTF-8"?>
  #   <objects type="array">
  #     <object>
  #       <bar type="integer">2</bar>
  #       <foo type="integer">1</foo>
  #     </object>
  #     <object>
  #       <baz type="integer">3</baz>
  #     </object>
  #   </objects>
  #
  # If the collection is empty the root element is "nil-classes" by default:
  #
  #   [].to_xml
  #
  #   <?xml version="1.0" encoding="UTF-8"?>
  #   <nil-classes type="array"/>
  #
  # To ensure a meaningful root element use the <tt>:root</tt> option:
  #
  #   customer_with_no_projects.projects.to_xml(root: 'projects')
  #
  #   <?xml version="1.0" encoding="UTF-8"?>
  #   <projects type="array"/>
  #
  # By default name of the node for the children of root is <tt>root.singularize</tt>.
  # You can change it with the <tt>:children</tt> option.
  #
  # The +options+ hash is passed downwards:
  #
  #   Message.all.to_xml(skip_types: true)
  #
  #   <?xml version="1.0" encoding="UTF-8"?>
  #   <messages>
  #     <message>
  #       <created-at>2008-03-07T09:58:18+01:00</created-at>
  #       <id>1</id>
  #       <name>1</name>
  #       <updated-at>2008-03-07T09:58:18+01:00</updated-at>
  #       <user-id>1</user-id>
  #     </message>
  #   </messages>
  #
  def to_xml(options = {})
    require 'active_support/builder' unless defined?(Builder)

    options = options.dup
    options[:indent]  ||= 2
    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
    options[:root]    ||= \
      if first.class != Hash && all? { |e| e.is_a?(first.class) }
        underscored = ActiveSupport::Inflector.underscore(first.class.name)
        ActiveSupport::Inflector.pluralize(underscored).tr('/', '_')
      else
        'objects'
      end

    builder = options[:builder]
    builder.instruct! unless options.delete(:skip_instruct)

    root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)
    children = options.delete(:children) || root.singularize
    attributes = options[:skip_types] ? {} : { type: 'array' }

    if empty?
      builder.tag!(root, attributes)
    else
      builder.tag!(root, attributes) do
        each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) }
        yield builder if block_given?
      end
    end
  end
end
class Hash
  # By default, only instances of Hash itself are extractable.
  # Subclasses of Hash may implement this method and return
  # true to declare themselves as extractable. If a Hash
  # is extractable, Array#extract_options! pops it from
  # the Array when it is the last element of the Array.
  def extractable_options?
    instance_of?(Hash)
  end
end

class Array
  # Extracts options from a set of arguments. Removes and returns the last
  # element in the array if it's a hash, otherwise returns a blank hash.
  #
  #   def options(*args)
  #     args.extract_options!
  #   end
  #
  #   options(1, 2)        # => {}
  #   options(1, 2, a: :b) # => {:a=>:b}
  def extract_options!
    if last.is_a?(Hash) && last.extractable_options?
      pop
    else
      {}
    end
  end
end
class Array
  # Splits or iterates over the array in groups of size +number+,
  # padding any remaining slots with +fill_with+ unless it is +false+.
  #
  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
  #   ["1", "2", "3"]
  #   ["4", "5", "6"]
  #   ["7", "8", "9"]
  #   ["10", nil, nil]
  #
  #   %w(1 2 3 4 5).in_groups_of(2, '&nbsp;') {|group| p group}
  #   ["1", "2"]
  #   ["3", "4"]
  #   ["5", "&nbsp;"]
  #
  #   %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
  #   ["1", "2"]
  #   ["3", "4"]
  #   ["5"]
  def in_groups_of(number, fill_with = nil)
    if fill_with == false
      collection = self
    else
      # size % number gives how many extra we have;
      # subtracting from number gives how many to add;
      # modulo number ensures we don't add group of just fill.
      padding = (number - size % number) % number
      collection = dup.concat([fill_with] * padding)
    end

    if block_given?
      collection.each_slice(number) { |slice| yield(slice) }
    else
      groups = []
      collection.each_slice(number) { |group| groups << group }
      groups
    end
  end

  # Splits or iterates over the array in +number+ of groups, padding any
  # remaining slots with +fill_with+ unless it is +false+.
  #
  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
  #   ["1", "2", "3", "4"]
  #   ["5", "6", "7", nil]
  #   ["8", "9", "10", nil]
  #
  #   %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, '&nbsp;') {|group| p group}
  #   ["1", "2", "3", "4"]
  #   ["5", "6", "7", "&nbsp;"]
  #   ["8", "9", "10", "&nbsp;"]
  #
  #   %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
  #   ["1", "2", "3"]
  #   ["4", "5"]
  #   ["6", "7"]
  def in_groups(number, fill_with = nil)
    # size / number gives minor group size;
    # size % number gives how many objects need extra accommodation;
    # each group hold either division or division + 1 items.
    division = size.div number
    modulo = size % number

    # create a new array avoiding dup
    groups = []
    start = 0

    number.times do |index|
      length = division + (modulo > 0 && modulo > index ? 1 : 0)
      groups << last_group = slice(start, length)
      last_group << fill_with if fill_with != false &&
        modulo > 0 && length == division
      start += length
    end

    if block_given?
      groups.each { |g| yield(g) }
    else
      groups
    end
  end

  # Divides the array into one or more subarrays based on a delimiting +value+
  # or the result of an optional block.
  #
  #   [1, 2, 3, 4, 5].split(3)              # => [[1, 2], [4, 5]]
  #   (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
  def split(value = nil, &block)
    inject([[]]) do |results, element|
      if block && block.call(element) || value == element
        results << []
      else
        results.last << element
      end

      results
    end
  end
end
class Array
  # The human way of thinking about adding stuff to the end of a list is with append
  alias_method :append,  :<<

  # The human way of thinking about adding stuff to the beginning of a list is with prepend
  alias_method :prepend, :unshift
endclass Array
  # *DEPRECATED*: Use +Array#uniq+ instead.
  #
  # Returns a unique array based on the criteria in the block.
  #
  #   [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
  def uniq_by(&block)
    ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead'
    uniq(&block)
  end

  # *DEPRECATED*: Use +Array#uniq!+ instead.
  #
  # Same as +uniq_by+, but modifies +self+.
  def uniq_by!(&block)
    ActiveSupport::Deprecation.warn 'uniq_by! is deprecated. Use Array#uniq! instead'
    uniq!(&block)
  end
end
class Array
  # Wraps its argument in an array unless it is already an array (or array-like).
  #
  # Specifically:
  #
  # * If the argument is +nil+ an empty list is returned.
  # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
  # * Otherwise, returns an array with the argument as its single element.
  #
  #     Array.wrap(nil)       # => []
  #     Array.wrap([1, 2, 3]) # => [1, 2, 3]
  #     Array.wrap(0)         # => [0]
  #
  # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
  #
  # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
  #   moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
  #   such a +nil+ right away.
  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
  #   raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
  # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
  #
  # The last point is particularly worth comparing for some enumerables:
  #
  #   Array(foo: :bar)      # => [[:foo, :bar]]
  #   Array.wrap(foo: :bar) # => [{:foo=>:bar}]
  #
  # There's also a related idiom that uses the splat operator:
  #
  #   [*object]
  #
  # which for +nil+ returns <tt>[]</tt>, and calls to <tt>Array(object)</tt> otherwise.
  #
  # Thus, in this case the behavior may be different for +nil+, and the differences with
  # <tt>Kernel#Array</tt> explained above apply to the rest of <tt>object</tt>s.
  def self.wrap(object)
    if object.nil?
      []
    elsif object.respond_to?(:to_ary)
      object.to_ary || [object]
    else
      [object]
    end
  end
end
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/array/access'
require 'active_support/core_ext/array/uniq_by'
require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/array/grouping'
require 'active_support/core_ext/array/prepend_and_append'
require 'benchmark'

class << Benchmark
  def ms
    1000 * realtime { yield }
  end
end
require 'bigdecimal'
require 'yaml'

class BigDecimal
  YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }

  def encode_with(coder)
    string = to_s
    coder.represent_scalar(nil, YAML_MAPPING[string] || string)
  end

  # Backport this method if it doesn't exist
  unless method_defined?(:to_d)
    def to_d
      self
    end
  end

  DEFAULT_STRING_FORMAT = 'F'
  def to_formatted_s(*args)
    if args[0].is_a?(Symbol)
      super
    else
      format = args[0] || DEFAULT_STRING_FORMAT
      _original_to_s(format)
    end
  end
  alias_method :_original_to_s, :to_s
  alias_method :to_s, :to_formatted_s
end
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'
require 'active_support/core_ext/array/extract_options'

class Class
  # Declare a class-level attribute whose value is inheritable by subclasses.
  # Subclasses can change their own value and it will not impact parent class.
  #
  #   class Base
  #     class_attribute :setting
  #   end
  #
  #   class Subclass < Base
  #   end
  #
  #   Base.setting = true
  #   Subclass.setting            # => true
  #   Subclass.setting = false
  #   Subclass.setting            # => false
  #   Base.setting                # => true
  #
  # In the above case as long as Subclass does not assign a value to setting
  # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
  # would read value assigned to parent class. Once Subclass assigns a value then
  # the value assigned by Subclass would be returned.
  #
  # This matches normal Ruby method inheritance: think of writing an attribute
  # on a subclass as overriding the reader method. However, you need to be aware
  # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
  # In such cases, you don't want to do changes in places but use setters:
  #
  #   Base.setting = []
  #   Base.setting                # => []
  #   Subclass.setting            # => []
  #
  #   # Appending in child changes both parent and child because it is the same object:
  #   Subclass.setting << :foo
  #   Base.setting               # => [:foo]
  #   Subclass.setting           # => [:foo]
  #
  #   # Use setters to not propagate changes:
  #   Base.setting = []
  #   Subclass.setting += [:foo]
  #   Base.setting               # => []
  #   Subclass.setting           # => [:foo]
  #
  # For convenience, a query method is defined as well:
  #
  #   Subclass.setting?       # => false
  #
  # Instances may overwrite the class value in the same way:
  #
  #   Base.setting = true
  #   object = Base.new
  #   object.setting          # => true
  #   object.setting = false
  #   object.setting          # => false
  #   Base.setting            # => true
  #
  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
  #
  #   object.setting          # => NoMethodError
  #   object.setting?         # => NoMethodError
  #
  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
  #
  #   object.setting = false  # => NoMethodError
  #
  # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
  def class_attribute(*attrs)
    options = attrs.extract_options!
    # double assignment is used to avoid "assigned but unused variable" warning
    instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
    instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)

    # We use class_eval here rather than define_method because class_attribute
    # may be used in a performance sensitive context therefore the overhead that
    # define_method introduces may become significant.
    attrs.each do |name|
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def self.#{name}() nil end
        def self.#{name}?() !!#{name} end

        def self.#{name}=(val)
          singleton_class.class_eval do
            remove_possible_method(:#{name})
            define_method(:#{name}) { val }
          end

          if singleton_class?
            class_eval do
              remove_possible_method(:#{name})
              def #{name}
                defined?(@#{name}) ? @#{name} : singleton_class.#{name}
              end
            end
          end
          val
        end

        if instance_reader
          remove_possible_method :#{name}
          def #{name}
            defined?(@#{name}) ? @#{name} : self.class.#{name}
          end

          def #{name}?
            !!#{name}
          end
        end
      RUBY

      attr_writer name if instance_writer
    end
  end

  private
    def singleton_class?
      ancestors.first != self
    end
end
require 'active_support/core_ext/array/extract_options'

# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
class Class
  # Defines a class attribute if it's not defined and creates a reader method that
  # returns the attribute value.
  #
  #   class Person
  #     cattr_reader :hair_colors
  #   end
  #
  #   Person.class_variable_set("@@hair_colors", [:brown, :black])
  #   Person.hair_colors     # => [:brown, :black]
  #   Person.new.hair_colors # => [:brown, :black]
  #
  # The attribute name must be a valid method name in Ruby.
  #
  #   class Person
  #     cattr_reader :"1_Badname "
  #   end
  #   # => NameError: invalid attribute name
  #
  # If you want to opt out the instance reader method, you can pass <tt>instance_reader: false</tt>
  # or <tt>instance_accessor: false</tt>.
  #
  #   class Person
  #     cattr_reader :hair_colors, instance_reader: false
  #   end
  #
  #   Person.new.hair_colors # => NoMethodError
  def cattr_reader(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}
          @@#{sym}
        end
      EOS

      unless options[:instance_reader] == false || options[:instance_accessor] == false
        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
          def #{sym}
            @@#{sym}
          end
        EOS
      end
    end
  end

  # Defines a class attribute if it's not defined and creates a writer method to allow
  # assignment to the attribute.
  #
  #   class Person
  #     cattr_writer :hair_colors
  #   end
  #
  #   Person.hair_colors = [:brown, :black]
  #   Person.class_variable_get("@@hair_colors") # => [:brown, :black]
  #   Person.new.hair_colors = [:blonde, :red]
  #   Person.class_variable_get("@@hair_colors") # => [:blonde, :red]
  #
  # The attribute name must be a valid method name in Ruby.
  #
  #   class Person
  #     cattr_writer :"1_Badname "
  #   end
  #   # => NameError: invalid attribute name
  #
  # If you want to opt out the instance writer method, pass <tt>instance_writer: false</tt>
  # or <tt>instance_accessor: false</tt>.
  #
  #   class Person
  #     cattr_writer :hair_colors, instance_writer: false
  #   end
  #
  #   Person.new.hair_colors = [:blonde, :red] # => NoMethodError
  #
  # Also, you can pass a block to set up the attribute with a default value.
  #
  #   class Person
  #     cattr_writer :hair_colors do
  #       [:brown, :black, :blonde, :red]
  #     end
  #   end
  #
  #   Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
  def cattr_writer(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
        unless defined? @@#{sym}
          @@#{sym} = nil
        end

        def self.#{sym}=(obj)
          @@#{sym} = obj
        end
      EOS

      unless options[:instance_writer] == false || options[:instance_accessor] == false
        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
          def #{sym}=(obj)
            @@#{sym} = obj
          end
        EOS
      end
      send("#{sym}=", yield) if block_given?
    end
  end

  # Defines both class and instance accessors for class attributes.
  #
  #   class Person
  #     cattr_accessor :hair_colors
  #   end
  #
  #   Person.hair_colors = [:brown, :black, :blonde, :red]
  #   Person.hair_colors     # => [:brown, :black, :blonde, :red]
  #   Person.new.hair_colors # => [:brown, :black, :blonde, :red]
  #
  # If a subclass changes the value then that would also change the value for
  # parent class. Similarly if parent class changes the value then that would
  # change the value of subclasses too.
  #
  #   class Male < Person
  #   end
  #
  #   Male.hair_colors << :blue
  #   Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
  #
  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
  #
  #   class Person
  #     cattr_accessor :hair_colors, instance_writer: false, instance_reader: false
  #   end
  #
  #   Person.new.hair_colors = [:brown]  # => NoMethodError
  #   Person.new.hair_colors             # => NoMethodError
  #
  # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
  #
  #   class Person
  #     cattr_accessor :hair_colors, instance_accessor: false
  #   end
  #
  #   Person.new.hair_colors = [:brown]  # => NoMethodError
  #   Person.new.hair_colors             # => NoMethodError
  #
  # Also you can pass a block to set up the attribute with a default value.
  #
  #   class Person
  #     cattr_accessor :hair_colors do
  #       [:brown, :black, :blonde, :red]
  #     end
  #   end
  #
  #   Person.class_variable_get("@@hair_colors") #=> [:brown, :black, :blonde, :red]
  def cattr_accessor(*syms, &blk)
    cattr_reader(*syms)
    cattr_writer(*syms, &blk)
  end
end
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/remove_method'

class Class
  def superclass_delegating_accessor(name, options = {})
    # Create private _name and _name= methods that can still be used if the public
    # methods are overridden. This allows
    _superclass_delegating_accessor("_#{name}")

    # Generate the public methods name, name=, and name?
    # These methods dispatch to the private _name, and _name= methods, making them
    # overridable
    singleton_class.send(:define_method, name) { send("_#{name}") }
    singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") }
    singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) }

    # If an instance_reader is needed, generate methods for name and name= on the
    # class itself, so instances will be able to see them
    define_method(name) { send("_#{name}") } if options[:instance_reader] != false
    define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
  end

  private
    # Take the object being set and store it in a method. This gives us automatic
    # inheritance behavior, without having to store the object in an instance
    # variable and look up the superclass chain manually.
    def _stash_object_in_method(object, method, instance_reader = true)
      singleton_class.remove_possible_method(method)
      singleton_class.send(:define_method, method) { object }
      remove_possible_method(method)
      define_method(method) { object } if instance_reader
    end

    def _superclass_delegating_accessor(name, options = {})
      singleton_class.send(:define_method, "#{name}=") do |value|
        _stash_object_in_method(value, name, options[:instance_reader] != false)
      end
      send("#{name}=", nil)
    end
end
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/module/reachable'

class Class
  begin
    ObjectSpace.each_object(Class.new) {}

    def descendants # :nodoc:
      descendants = []
      ObjectSpace.each_object(singleton_class) do |k|
        descendants.unshift k unless k == self
      end
      descendants
    end
  rescue StandardError # JRuby
    def descendants # :nodoc:
      descendants = []
      ObjectSpace.each_object(Class) do |k|
        descendants.unshift k if k < self
      end
      descendants.uniq!
      descendants
    end
  end

  # Returns an array with the direct children of +self+.
  #
  #   Integer.subclasses # => [Fixnum, Bignum]
  #
  #   class Foo; end
  #   class Bar < Foo; end
  #   class Baz < Bar; end
  #
  #   Foo.subclasses # => [Bar]
  def subclasses
    subclasses, chain = [], descendants
    chain.each do |k|
      subclasses << k unless chain.any? { |c| c > k }
    end
    subclasses
  end
end
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/class/delegating_attributes'
require 'active_support/core_ext/class/subclasses'
require 'active_support/core_ext/object/acts_like'

class Date
  # Duck-types as a Date-like class. See Object#acts_like?.
  def acts_like_date?
    true
  end
end
require 'date'
require 'active_support/duration'
require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/date/zones'
require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/date_and_time/calculations'

class Date
  include DateAndTime::Calculations

  class << self
    attr_accessor :beginning_of_week_default

    # Returns the week start (e.g. :monday) for the current request, if this has been set (via Date.beginning_of_week=).
    # If <tt>Date.beginning_of_week</tt> has not been set for the current request, returns the week start specified in <tt>config.beginning_of_week</tt>.
    # If no config.beginning_of_week was specified, returns :monday.
    def beginning_of_week
      Thread.current[:beginning_of_week] || beginning_of_week_default || :monday
    end

    # Sets <tt>Date.beginning_of_week</tt> to a week start (e.g. :monday) for current request/thread.
    #
    # This method accepts any of the following day symbols:
    # :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday
    def beginning_of_week=(week_start)
      Thread.current[:beginning_of_week] = find_beginning_of_week!(week_start)
    end

    # Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.
    def find_beginning_of_week!(week_start)
      raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start)
      week_start
    end

    # Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
    def yesterday
      ::Date.current.yesterday
    end

    # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date).
    def tomorrow
      ::Date.current.tomorrow
    end

    # Returns Time.zone.today when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns Date.today.
    def current
      ::Time.zone ? ::Time.zone.today : ::Date.today
    end
  end

  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
  # and then subtracts the specified number of seconds.
  def ago(seconds)
    in_time_zone.since(-seconds)
  end

  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
  # and then adds the specified number of seconds
  def since(seconds)
    in_time_zone.since(seconds)
  end
  alias :in :since

  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00)
  def beginning_of_day
    in_time_zone
  end
  alias :midnight :beginning_of_day
  alias :at_midnight :beginning_of_day
  alias :at_beginning_of_day :beginning_of_day

  # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59)
  def end_of_day
    in_time_zone.end_of_day
  end
  alias :at_end_of_day :end_of_day

  def plus_with_duration(other) #:nodoc:
    if ActiveSupport::Duration === other
      other.since(self)
    else
      plus_without_duration(other)
    end
  end
  alias_method :plus_without_duration, :+
  alias_method :+, :plus_with_duration

  def minus_with_duration(other) #:nodoc:
    if ActiveSupport::Duration === other
      plus_with_duration(-other)
    else
      minus_without_duration(other)
    end
  end
  alias_method :minus_without_duration, :-
  alias_method :-, :minus_with_duration

  # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
  # any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
  def advance(options)
    options = options.dup
    d = self
    d = d >> options.delete(:years) * 12 if options[:years]
    d = d >> options.delete(:months)     if options[:months]
    d = d +  options.delete(:weeks) * 7  if options[:weeks]
    d = d +  options.delete(:days)       if options[:days]
    d
  end

  # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
  # The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
  #
  #   Date.new(2007, 5, 12).change(day: 1)               # => Date.new(2007, 5, 1)
  #   Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
  def change(options)
    ::Date.new(
      options.fetch(:year, year),
      options.fetch(:month, month),
      options.fetch(:day, day)
    )
  end
end
require 'date'
require 'active_support/inflector/methods'
require 'active_support/core_ext/date/zones'
require 'active_support/core_ext/module/remove_method'

class Date
  DATE_FORMATS = {
    :short        => '%e %b',
    :long         => '%B %e, %Y',
    :db           => '%Y-%m-%d',
    :number       => '%Y%m%d',
    :long_ordinal => lambda { |date|
      day_format = ActiveSupport::Inflector.ordinalize(date.day)
      date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007"
    },
    :rfc822       => '%e %b %Y'
  }

  # Ruby 1.9 has Date#to_time which converts to localtime only.
  remove_method :to_time

  # Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
  remove_method :xmlschema

  # Convert to a formatted string. See DATE_FORMATS for predefined formats.
  #
  # This method is aliased to <tt>to_s</tt>.
  #
  #   date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007
  #
  #   date.to_formatted_s(:db)            # => "2007-11-10"
  #   date.to_s(:db)                      # => "2007-11-10"
  #
  #   date.to_formatted_s(:short)         # => "10 Nov"
  #   date.to_formatted_s(:long)          # => "November 10, 2007"
  #   date.to_formatted_s(:long_ordinal)  # => "November 10th, 2007"
  #   date.to_formatted_s(:rfc822)        # => "10 Nov 2007"
  #
  # == Adding your own time formats to to_formatted_s
  # You can add your own formats to the Date::DATE_FORMATS hash.
  # Use the format name as the hash key and either a strftime string
  # or Proc instance that takes a date argument as the value.
  #
  #   # config/initializers/time_formats.rb
  #   Date::DATE_FORMATS[:month_and_year] = '%B %Y'
  #   Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") }
  def to_formatted_s(format = :default)
    if formatter = DATE_FORMATS[format]
      if formatter.respond_to?(:call)
        formatter.call(self).to_s
      else
        strftime(formatter)
      end
    else
      to_default_s
    end
  end
  alias_method :to_default_s, :to_s
  alias_method :to_s, :to_formatted_s

  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
  def readable_inspect
    strftime('%a, %d %b %Y')
  end
  alias_method :default_inspect, :inspect
  alias_method :inspect, :readable_inspect

  # Converts a Date instance to a Time, where the time is set to the beginning of the day.
  # The timezone can be either :local or :utc (default :local).
  #
  #   date = Date.new(2007, 11, 10)  # => Sat, 10 Nov 2007
  #
  #   date.to_time                   # => Sat Nov 10 00:00:00 0800 2007
  #   date.to_time(:local)           # => Sat Nov 10 00:00:00 0800 2007
  #
  #   date.to_time(:utc)             # => Sat Nov 10 00:00:00 UTC 2007
  def to_time(form = :local)
    ::Time.send(form, year, month, day)
  end

  def xmlschema
    in_time_zone.xmlschema
  end
end
require 'active_support/core_ext/infinite_comparable'

class Date
  include InfiniteComparable
end
require 'date'
require 'active_support/core_ext/time/zones'

class Date
  # *DEPRECATED*: Use +Date#in_time_zone+ instead.
  #
  # Converts Date to a TimeWithZone in the current zone if <tt>Time.zone</tt> or
  # <tt>Time.zone_default</tt> is set, otherwise converts Date to a Time via
  # Date#to_time.
  def to_time_in_current_zone
    ActiveSupport::Deprecation.warn 'Date#to_time_in_current_zone is deprecated. Use Date#in_time_zone instead', caller

    if ::Time.zone
      ::Time.zone.local(year, month, day)
    else
      to_time
    end
  end

  # Converts Date to a TimeWithZone in the current zone if Time.zone or Time.zone_default
  # is set, otherwise converts Date to a Time via Date#to_time
  #
  #   Time.zone = 'Hawaii'         # => 'Hawaii'
  #   Date.new(2000).in_time_zone  # => Sat, 01 Jan 2000 00:00:00 HST -10:00
  #
  # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
  # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
  #
  #   Date.new(2000).in_time_zone('Alaska')  # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
  def in_time_zone(zone = ::Time.zone)
    if zone
      ::Time.find_zone!(zone).local(year, month, day)
    else
      to_time
    end
  end
end
require 'active_support/core_ext/date/acts_like'
require 'active_support/core_ext/date/calculations'
require 'active_support/core_ext/date/conversions'
require 'active_support/core_ext/date/zones'
require 'active_support/core_ext/date/infinite_comparable'

module DateAndTime
  module Calculations
    DAYS_INTO_WEEK = {
      :monday    => 0,
      :tuesday   => 1,
      :wednesday => 2,
      :thursday  => 3,
      :friday    => 4,
      :saturday  => 5,
      :sunday    => 6
    }

    # Returns a new date/time representing yesterday.
    def yesterday
      advance(:days => -1)
    end

    # Returns a new date/time representing tomorrow.
    def tomorrow
      advance(:days => 1)
    end

    # Returns true if the date/time is today.
    def today?
      to_date == ::Date.current
    end

    # Returns true if the date/time is in the past.
    def past?
      self < self.class.current
    end

    # Returns true if the date/time is in the future.
    def future?
      self > self.class.current
    end

    # Returns a new date/time the specified number of days ago.
    def days_ago(days)
      advance(:days => -days)
    end

    # Returns a new date/time the specified number of days in the future.
    def days_since(days)
      advance(:days => days)
    end

    # Returns a new date/time the specified number of weeks ago.
    def weeks_ago(weeks)
      advance(:weeks => -weeks)
    end

    # Returns a new date/time the specified number of weeks in the future.
    def weeks_since(weeks)
      advance(:weeks => weeks)
    end

    # Returns a new date/time the specified number of months ago.
    def months_ago(months)
      advance(:months => -months)
    end

    # Returns a new date/time the specified number of months in the future.
    def months_since(months)
      advance(:months => months)
    end

    # Returns a new date/time the specified number of years ago.
    def years_ago(years)
      advance(:years => -years)
    end

    # Returns a new date/time the specified number of years in the future.
    def years_since(years)
      advance(:years => years)
    end

    # Returns a new date/time at the start of the month.
    # DateTime objects will have a time set to 0:00.
    def beginning_of_month
      first_hour{ change(:day => 1) }
    end
    alias :at_beginning_of_month :beginning_of_month

    # Returns a new date/time at the start of the quarter.
    # Example: 1st January, 1st July, 1st October.
    # DateTime objects will have a time set to 0:00.
    def beginning_of_quarter
      first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
      beginning_of_month.change(:month => first_quarter_month)
    end
    alias :at_beginning_of_quarter :beginning_of_quarter

    # Returns a new date/time at the end of the quarter.
    # Example: 31st March, 30th June, 30th September.
    # DateTIme objects will have a time set to 23:59:59.
    def end_of_quarter
      last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
      beginning_of_month.change(:month => last_quarter_month).end_of_month
    end
    alias :at_end_of_quarter :end_of_quarter

    # Return a new date/time at the beginning of the year.
    # Example: 1st January.
    # DateTime objects will have a time set to 0:00.
    def beginning_of_year
      change(:month => 1).beginning_of_month
    end
    alias :at_beginning_of_year :beginning_of_year

    # Returns a new date/time representing the given day in the next week.
    # Week is assumed to start on +start_day+, default is
    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
    # DateTime objects have their time set to 0:00.
    def next_week(start_day = Date.beginning_of_week)
      first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) }
    end

    # Short-hand for months_since(1).
    def next_month
      months_since(1)
    end

    # Short-hand for months_since(3)
    def next_quarter
      months_since(3)
    end

    # Short-hand for years_since(1).
    def next_year
      years_since(1)
    end

    # Returns a new date/time representing the given day in the previous week.
    # Week is assumed to start on +start_day+, default is
    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
    # DateTime objects have their time set to 0:00.
    def prev_week(start_day = Date.beginning_of_week)
      first_hour{ weeks_ago(1).beginning_of_week.days_since(days_span(start_day)) }
    end
    alias_method :last_week, :prev_week

    # Short-hand for months_ago(1).
    def prev_month
      months_ago(1)
    end
    alias_method :last_month, :prev_month

    # Short-hand for months_ago(3).
    def prev_quarter
      months_ago(3)
    end
    alias_method :last_quarter, :prev_quarter

    # Short-hand for years_ago(1).
    def prev_year
      years_ago(1)
    end
    alias_method :last_year, :prev_year

    # Returns the number of days to the start of the week on the given day.
    # Week is assumed to start on +start_day+, default is
    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
    def days_to_week_start(start_day = Date.beginning_of_week)
      start_day_number = DAYS_INTO_WEEK[start_day]
      current_day_number = wday != 0 ? wday - 1 : 6
      (current_day_number - start_day_number) % 7
    end

    # Returns a new date/time representing the start of this week on the given day.
    # Week is assumed to start on +start_day+, default is
    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
    # +DateTime+ objects have their time set to 0:00.
    def beginning_of_week(start_day = Date.beginning_of_week)
      result = days_ago(days_to_week_start(start_day))
      acts_like?(:time) ? result.midnight : result
    end
    alias :at_beginning_of_week :beginning_of_week

    # Returns Monday of this week assuming that week starts on Monday.
    # +DateTime+ objects have their time set to 0:00.
    def monday
      beginning_of_week(:monday)
    end

    # Returns a new date/time representing the end of this week on the given day.
    # Week is assumed to start on +start_day+, default is
    # +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
    # DateTime objects have their time set to 23:59:59.
    def end_of_week(start_day = Date.beginning_of_week)
      last_hour{ days_since(6 - days_to_week_start(start_day)) }
    end
    alias :at_end_of_week :end_of_week

    # Returns Sunday of this week assuming that week starts on Monday.
    # +DateTime+ objects have their time set to 23:59:59.
    def sunday
      end_of_week(:monday)
    end

    # Returns a new date/time representing the end of the month.
    # DateTime objects will have a time set to 23:59:59.
    def end_of_month
      last_day = ::Time.days_in_month(month, year)
      last_hour{ days_since(last_day - day) }
    end
    alias :at_end_of_month :end_of_month

    # Returns a new date/time representing the end of the year.
    # DateTime objects will have a time set to 23:59:59.
    def end_of_year
      change(:month => 12).end_of_month
    end
    alias :at_end_of_year :end_of_year

    private

    def first_hour
      result = yield
      acts_like?(:time) ? result.change(:hour => 0) : result
    end

    def last_hour
      result = yield
      acts_like?(:time) ? result.end_of_day : result
    end

    def days_span(day)
      (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
    end
  end
end
require 'active_support/core_ext/object/acts_like'

class DateTime
  # Duck-types as a Date-like class. See Object#acts_like?.
  def acts_like_date?
    true
  end

  # Duck-types as a Time-like class. See Object#acts_like?.
  def acts_like_time?
    true
  end
end
require 'active_support/deprecation'

class DateTime
  class << self
    # *DEPRECATED*: Use +DateTime.civil_from_format+ directly.
    def local_offset
      ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.'

      ::Time.local(2012).utc_offset.to_r / 86400
    end

    # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
    # <tt>config.time_zone</tt> are set, otherwise returns
    # <tt>Time.now.to_datetime</tt>.
    def current
      ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
    end
  end

  # Tells whether the DateTime object's datetime lies in the past.
  def past?
    self < ::DateTime.current
  end

  # Tells whether the DateTime object's datetime lies in the future.
  def future?
    self > ::DateTime.current
  end

  # Seconds since midnight: DateTime.now.seconds_since_midnight.
  def seconds_since_midnight
    sec + (min * 60) + (hour * 3600)
  end

  # Returns the number of seconds until 23:59:59.
  #
  #   DateTime.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
  #   DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
  #   DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
  def seconds_until_end_of_day
    end_of_day.to_i - to_i
  end

  # Returns a new DateTime where one or more of the elements have been changed
  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
  # passed, then minute and sec is set to 0. If the hour and minute is passed,
  # then sec is set to 0. The +options+ parameter takes a hash with any of these
  # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
  # <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
  #
  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => DateTime.new(2012, 8, 1, 22, 35, 0)
  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => DateTime.new(1981, 8, 1, 22, 35, 0)
  #   DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
  def change(options)
    ::DateTime.civil(
      options.fetch(:year, year),
      options.fetch(:month, month),
      options.fetch(:day, day),
      options.fetch(:hour, hour),
      options.fetch(:min, options[:hour] ? 0 : min),
      options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec),
      options.fetch(:offset, offset),
      options.fetch(:start, start)
    )
  end

  # Uses Date to provide precise Time calculations for years, months, and days.
  # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
  def advance(options)
    d = to_date.advance(options)
    datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
    seconds_to_advance = \
      options.fetch(:seconds, 0) +
      options.fetch(:minutes, 0) * 60 +
      options.fetch(:hours, 0) * 3600

    if seconds_to_advance.zero?
      datetime_advanced_by_date
    else
      datetime_advanced_by_date.since seconds_to_advance
    end
  end

  # Returns a new DateTime representing the time a number of seconds ago.
  # Do not use this method in combination with x.months, use months_ago instead!
  def ago(seconds)
    since(-seconds)
  end

  # Returns a new DateTime representing the time a number of seconds since the
  # instance time. Do not use this method in combination with x.months, use
  # months_since instead!
  def since(seconds)
    self + Rational(seconds.round, 86400)
  end
  alias :in :since

  # Returns a new DateTime representing the start of the day (0:00).
  def beginning_of_day
    change(:hour => 0)
  end
  alias :midnight :beginning_of_day
  alias :at_midnight :beginning_of_day
  alias :at_beginning_of_day :beginning_of_day

  # Returns a new DateTime representing the end of the day (23:59:59).
  def end_of_day
    change(:hour => 23, :min => 59, :sec => 59)
  end
  alias :at_end_of_day :end_of_day

  # Returns a new DateTime representing the start of the hour (hh:00:00).
  def beginning_of_hour
    change(:min => 0)
  end
  alias :at_beginning_of_hour :beginning_of_hour

  # Returns a new DateTime representing the end of the hour (hh:59:59).
  def end_of_hour
    change(:min => 59, :sec => 59)
  end
  alias :at_end_of_hour :end_of_hour

  # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
  #
  #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))     # => Mon, 21 Feb 2005 10:11:12 -0600
  #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
  def utc
    new_offset(0)
  end
  alias_method :getutc, :utc

  # Returns +true+ if <tt>offset == 0</tt>.
  def utc?
    offset == 0
  end

  # Returns the offset value in seconds.
  def utc_offset
    (offset * 86400).to_i
  end
end
require 'active_support/inflector/methods'
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/date_time/calculations'
require 'active_support/values/time_zone'

class DateTime
  # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
  #
  # This method is aliased to <tt>to_s</tt>.
  #
  # === Examples
  #   datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0)   # => Tue, 04 Dec 2007 00:00:00 +0000
  #
  #   datetime.to_formatted_s(:db)            # => "2007-12-04 00:00:00"
  #   datetime.to_s(:db)                      # => "2007-12-04 00:00:00"
  #   datetime.to_s(:number)                  # => "20071204000000"
  #   datetime.to_formatted_s(:short)         # => "04 Dec 00:00"
  #   datetime.to_formatted_s(:long)          # => "December 04, 2007 00:00"
  #   datetime.to_formatted_s(:long_ordinal)  # => "December 4th, 2007 00:00"
  #   datetime.to_formatted_s(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"
  #
  # == Adding your own datetime formats to to_formatted_s
  # DateTime formats are shared with Time. You can add your own to the
  # Time::DATE_FORMATS hash. Use the format name as the hash key and
  # either a strftime string or Proc instance that takes a time or
  # datetime argument as the value.
  #
  #   # config/initializers/time_formats.rb
  #   Time::DATE_FORMATS[:month_and_year] = '%B %Y'
  #   Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
  def to_formatted_s(format = :default)
    if formatter = ::Time::DATE_FORMATS[format]
      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
    else
      to_default_s
    end
  end
  alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
  alias_method :to_s, :to_formatted_s

  #
  #   datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
  #   datetime.formatted_offset         # => "-06:00"
  #   datetime.formatted_offset(false)  # => "-0600"
  def formatted_offset(colon = true, alternate_utc_string = nil)
    utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
  end

  # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
  def readable_inspect
    to_s(:rfc822)
  end
  alias_method :default_inspect, :inspect
  alias_method :inspect, :readable_inspect

  # Returns DateTime with local offset for given year if format is local else
  # offset is zero.
  #
  #   DateTime.civil_from_format :local, 2012
  #   # => Sun, 01 Jan 2012 00:00:00 +0300
  #   DateTime.civil_from_format :local, 2012, 12, 17
  #   # => Mon, 17 Dec 2012 00:00:00 +0000
  def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
    if utc_or_local.to_sym == :local
      offset = ::Time.local(year, month, day).utc_offset.to_r / 86400
    else
      offset = 0
    end
    civil(year, month, day, hour, min, sec, offset)
  end

  # Converts +self+ to a floating-point number of seconds since the Unix epoch.
  def to_f
    seconds_since_unix_epoch.to_f
  end

  # Converts +self+ to an integer number of seconds since the Unix epoch.
  def to_i
    seconds_since_unix_epoch.to_i
  end

  private

  def offset_in_seconds
    (offset * 86400).to_i
  end

  def seconds_since_unix_epoch
    (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight
  end
end
require 'active_support/core_ext/infinite_comparable'

class DateTime
  include InfiniteComparable
end
require 'active_support/core_ext/time/zones'

class DateTime
  # Returns the simultaneous time in <tt>Time.zone</tt>.
  #
  #   Time.zone = 'Hawaii'             # => 'Hawaii'
  #   DateTime.new(2000).in_time_zone  # => Fri, 31 Dec 1999 14:00:00 HST -10:00
  #
  # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt>
  # as the local zone instead of the operating system's time zone.
  #
  # You can also pass in a TimeZone instance or string that identifies a TimeZone
  # as an argument, and the conversion will be based on that zone instead of
  # <tt>Time.zone</tt>.
  #
  #   DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
  def in_time_zone(zone = ::Time.zone)
    if zone
      ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
    else
      self
    end
  end
end
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/date_time/infinite_comparable'
module Enumerable
  # Calculates a sum from the elements.
  #
  #  payments.sum { |p| p.price * p.tax_rate }
  #  payments.sum(&:price)
  #
  # The latter is a shortcut for:
  #
  #  payments.inject(0) { |sum, p| sum + p.price }
  #
  # It can also calculate the sum without the use of a block.
  #
  #  [5, 15, 10].sum # => 30
  #  ['foo', 'bar'].sum # => "foobar"
  #  [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
  #
  # The default sum of an empty list is zero. You can override this default:
  #
  #  [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
  def sum(identity = 0, &block)
    if block_given?
      map(&block).sum(identity)
    else
      inject { |sum, element| sum + element } || identity
    end
  end

  # Convert an enumerable to a hash.
  #
  #   people.index_by(&:login)
  #     => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
  #   people.index_by { |person| "#{person.first_name} #{person.last_name}" }
  #     => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
  def index_by
    if block_given?
      Hash[map { |elem| [yield(elem), elem] }]
    else
      to_enum :index_by
    end
  end

  # Returns +true+ if the enumerable has more than 1 element. Functionally
  # equivalent to <tt>enum.to_a.size > 1</tt>. Can be called with a block too,
  # much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns +true+
  # if more than one person is over 26.
  def many?
    cnt = 0
    if block_given?
      any? do |element|
        cnt += 1 if yield element
        cnt > 1
      end
    else
      any? { (cnt += 1) > 1 }
    end
  end

  # The negative of the <tt>Enumerable#include?</tt>. Returns +true+ if the
  # collection does not include the object.
  def exclude?(object)
    !include?(object)
  end
end

class Range #:nodoc:
  # Optimize range sum to use arithmetic progression if a block is not given and
  # we have a range of numeric values.
  def sum(identity = 0)
    if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
      super
    else
      actual_last = exclude_end? ? (last - 1) : last
      if actual_last >= first
        (actual_last - first + 1) * (actual_last + first) / 2
      else
        identity
      end
    end
  end
end
require 'fileutils'

class File
  # Write to a file atomically. Useful for situations where you don't
  # want other processes or threads to see half-written files.
  #
  #   File.atomic_write('important.file') do |file|
  #     file.write('hello')
  #   end
  #
  # If your temp directory is not on the same filesystem as the file you're
  # trying to write, you can provide a different temporary directory.
  #
  #   File.atomic_write('/data/something.important', '/data/tmp') do |file|
  #     file.write('hello')
  #   end
  def self.atomic_write(file_name, temp_dir = Dir.tmpdir)
    require 'tempfile' unless defined?(Tempfile)
    require 'fileutils' unless defined?(FileUtils)

    temp_file = Tempfile.new(basename(file_name), temp_dir)
    temp_file.binmode
    yield temp_file
    temp_file.close

    if File.exists?(file_name)
      # Get original file permissions
      old_stat = stat(file_name)
    else
      # If not possible, probe which are the default permissions in the
      # destination directory.
      old_stat = probe_stat_in(dirname(file_name))
    end

    # Overwrite original file with temp file
    FileUtils.mv(temp_file.path, file_name)

    # Set correct permissions on new file
    begin
      chown(old_stat.uid, old_stat.gid, file_name)
      # This operation will affect filesystem ACL's
      chmod(old_stat.mode, file_name)
    rescue Errno::EPERM
      # Changing file ownership failed, moving on.
    end
  end

  # Private utility method.
  def self.probe_stat_in(dir) #:nodoc:
    basename = [
      '.permissions_check',
      Thread.current.object_id,
      Process.pid,
      rand(1000000)
    ].join('.')

    file_name = join(dir, basename)
    FileUtils.touch(file_name)
    stat(file_name)
  ensure
    FileUtils.rm_f(file_name) if file_name
  end
end
require 'active_support/core_ext/file/atomic'
require 'active_support/xml_mini'
require 'active_support/time'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/string/inflections'

class Hash
  # Returns a string containing an XML representation of its receiver:
  #
  #   {'foo' => 1, 'bar' => 2}.to_xml
  #   # =>
  #   # <?xml version="1.0" encoding="UTF-8"?>
  #   # <hash>
  #   #   <foo type="integer">1</foo>
  #   #   <bar type="integer">2</bar>
  #   # </hash>
  #
  # To do so, the method loops over the pairs and builds nodes that depend on
  # the _values_. Given a pair +key+, +value+:
  #
  # * If +value+ is a hash there's a recursive call with +key+ as <tt>:root</tt>.
  #
  # * If +value+ is an array there's a recursive call with +key+ as <tt>:root</tt>,
  #   and +key+ singularized as <tt>:children</tt>.
  #
  # * If +value+ is a callable object it must expect one or two arguments. Depending
  #   on the arity, the callable is invoked with the +options+ hash as first argument
  #   with +key+ as <tt>:root</tt>, and +key+ singularized as second argument. The
  #   callable can add nodes by using <tt>options[:builder]</tt>.
  #
  #     'foo'.to_xml(lambda { |options, key| options[:builder].b(key) })
  #     # => "<b>foo</b>"
  #
  # * If +value+ responds to +to_xml+ the method is invoked with +key+ as <tt>:root</tt>.
  #
  #     class Foo
  #       def to_xml(options)
  #         options[:builder].bar 'fooing!'
  #       end
  #     end
  #
  #     { foo: Foo.new }.to_xml(skip_instruct: true)
  #     # => "<hash><bar>fooing!</bar></hash>"
  #
  # * Otherwise, a node with +key+ as tag is created with a string representation of
  #   +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added.
  #   Unless the option <tt>:skip_types</tt> exists and is true, an attribute "type" is
  #   added as well according to the following mapping:
  #
  #     XML_TYPE_NAMES = {
  #       "Symbol"     => "symbol",
  #       "Fixnum"     => "integer",
  #       "Bignum"     => "integer",
  #       "BigDecimal" => "decimal",
  #       "Float"      => "float",
  #       "TrueClass"  => "boolean",
  #       "FalseClass" => "boolean",
  #       "Date"       => "date",
  #       "DateTime"   => "dateTime",
  #       "Time"       => "dateTime"
  #     }
  #
  # By default the root node is "hash", but that's configurable via the <tt>:root</tt> option.
  #
  # The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can
  # configure your own builder with the <tt>:builder</tt> option. The method also accepts
  # options like <tt>:dasherize</tt> and friends, they are forwarded to the builder.
  def to_xml(options = {})
    require 'active_support/builder' unless defined?(Builder)

    options = options.dup
    options[:indent]  ||= 2
    options[:root]    ||= 'hash'
    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])

    builder = options[:builder]
    builder.instruct! unless options.delete(:skip_instruct)

    root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options)

    builder.tag!(root) do
      each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) }
      yield builder if block_given?
    end
  end

  class << self
    # Returns a Hash containing a collection of pairs when the key is the node name and the value is
    # its content
    #
    #   xml = <<-XML
    #     <?xml version="1.0" encoding="UTF-8"?>
    #       <hash>
    #         <foo type="integer">1</foo>
    #         <bar type="integer">2</bar>
    #       </hash>
    #   XML
    #
    #   hash = Hash.from_xml(xml)
    #   # => {"hash"=>{"foo"=>1, "bar"=>2}}
    #
    # DisallowedType is raise if the XML contains attributes with <tt>type="yaml"</tt> or
    # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
    def from_xml(xml, disallowed_types = nil)
      ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
    end

    # Builds a Hash from XML just like <tt>Hash.from_xml</tt>, but also allows Symbol and YAML.
    def from_trusted_xml(xml)
      from_xml xml, []
    end
  end
end

module ActiveSupport
  class XMLConverter # :nodoc:
    class DisallowedType < StandardError
      def initialize(type)
        super "Disallowed type attribute: #{type.inspect}"
      end
    end

    DISALLOWED_TYPES = %w(symbol yaml)

    def initialize(xml, disallowed_types = nil)
      @xml = normalize_keys(XmlMini.parse(xml))
      @disallowed_types = disallowed_types || DISALLOWED_TYPES
    end

    def to_h
      deep_to_h(@xml)
    end

    private
      def normalize_keys(params)
        case params
          when Hash
            Hash[params.map { |k,v| [k.to_s.tr('-', '_'), normalize_keys(v)] } ]
          when Array
            params.map { |v| normalize_keys(v) }
          else
            params
        end
      end

      def deep_to_h(value)
        case value
          when Hash
            process_hash(value)
          when Array
            process_array(value)
          when String
            value
          else
            raise "can't typecast #{value.class.name} - #{value.inspect}"
        end
      end

      def process_hash(value)
        if value.include?('type') && !value['type'].is_a?(Hash) && @disallowed_types.include?(value['type'])
          raise DisallowedType, value['type']
        end

        if become_array?(value)
          _, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
          if entries.nil? || value['__content__'].try(:empty?)
            []
          else
            case entries
            when Array
              entries.collect { |v| deep_to_h(v) }
            when Hash
              [deep_to_h(entries)]
            else
              raise "can't typecast #{entries.inspect}"
            end
          end
        elsif become_content?(value)
          process_content(value)

        elsif become_empty_string?(value)
          ''
        elsif become_hash?(value)
          xml_value = Hash[value.map { |k,v| [k, deep_to_h(v)] }]

          # Turn { files: { file: #<StringIO> } } into { files: #<StringIO> } so it is compatible with
          # how multipart uploaded files from HTML appear
          xml_value['file'].is_a?(StringIO) ? xml_value['file'] : xml_value
        end
      end

      def become_content?(value)
        value['type'] == 'file' || (value['__content__'] && (value.keys.size == 1 || value['__content__'].present?))
      end

      def become_array?(value)
        value['type'] == 'array'
      end

      def become_empty_string?(value)
        # {"string" => true}
        # No tests fail when the second term is removed.
        value['type'] == 'string' && value['nil'] != 'true'
      end

      def become_hash?(value)
        !nothing?(value) && !garbage?(value)
      end

      def nothing?(value)
        # blank or nil parsed values are represented by nil
        value.blank? || value['nil'] == 'true'
      end

      def garbage?(value)
        # If the type is the only element which makes it then
        # this still makes the value nil, except if type is
        # a XML node(where type['value'] is a Hash)
        value['type'] && !value['type'].is_a?(::Hash) && value.size == 1
      end

      def process_content(value)
        content = value['__content__']
        if parser = ActiveSupport::XmlMini::PARSING[value['type']]
          parser.arity == 1 ? parser.call(content) : parser.call(content, value)
        else
          content
        end
      end

      def process_array(value)
        value.map! { |i| deep_to_h(i) }
        value.length > 1 ? value : value.first
      end

  end
end

class Hash
  # Returns a new hash with +self+ and +other_hash+ merged recursively.
  #
  #   h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
  #   h2 = { x: { y: [7,8,9] }, z: 'xyz' }
  #
  #   h1.deep_merge(h2) #=> {x: {y: [7, 8, 9]}, z: "xyz"}
  #   h2.deep_merge(h1) #=> {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
  #   h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
  #   #=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
  def deep_merge(other_hash, &block)
    dup.deep_merge!(other_hash, &block)
  end

  # Same as +deep_merge+, but modifies +self+.
  def deep_merge!(other_hash, &block)
    other_hash.each_pair do |k,v|
      tv = self[k]
      if tv.is_a?(Hash) && v.is_a?(Hash)
        self[k] = tv.deep_merge(v, &block)
      else
        self[k] = block && tv ? block.call(k, tv, v) : v
      end
    end
    self
  end
end
class Hash
  # Returns a hash that represents the difference between two hashes.
  #
  #   {1 => 2}.diff(1 => 2)         # => {}
  #   {1 => 2}.diff(1 => 3)         # => {1 => 2}
  #   {}.diff(1 => 2)               # => {1 => 2}
  #   {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
  def diff(other)
    ActiveSupport::Deprecation.warn "Hash#diff is no longer used inside of Rails, and is being deprecated with no replacement. If you're using it to compare hashes for the purpose of testing, please use MiniTest's assert_equal instead."
    dup.
      delete_if { |k, v| other[k] == v }.
      merge!(other.dup.delete_if { |k, v| has_key?(k) })
  end
end
class Hash
  # Return a hash that includes everything but the given keys. This is useful for
  # limiting a set of parameters to everything but a few known toggles:
  #
  #   @person.update(params[:person].except(:admin))
  def except(*keys)
    dup.except!(*keys)
  end

  # Replaces the hash without the given keys.
  def except!(*keys)
    keys.each { |key| delete(key) }
    self
  end
end
require 'active_support/hash_with_indifferent_access'

class Hash

  # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
  #
  #   { a: 1 }.with_indifferent_access['a'] # => 1
  def with_indifferent_access
    ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
  end

  # Called when object is nested under an object that receives
  # #with_indifferent_access. This method will be called on the current object
  # by the enclosing object and is aliased to #with_indifferent_access by
  # default. Subclasses of Hash may overwrite this method to return +self+ if
  # converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
  # desirable.
  #
  #   b = { b: 1 }
  #   { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
  alias nested_under_indifferent_access with_indifferent_access
end
class Hash
  # Return a new hash with all keys converted using the block operation.
  #
  #  hash = { name: 'Rob', age: '28' }
  #
  #  hash.transform_keys{ |key| key.to_s.upcase }
  #  # => { "NAME" => "Rob", "AGE" => "28" }
  def transform_keys
    result = {}
    each_key do |key|
      result[yield(key)] = self[key]
    end
    result
  end

  # Destructively convert all keys using the block operations.
  # Same as transform_keys but modifies +self+.
  def transform_keys!
    keys.each do |key|
      self[yield(key)] = delete(key)
    end
    self
  end

  # Return a new hash with all keys converted to strings.
  #
  #   hash = { name: 'Rob', age: '28' }
  #
  #   hash.stringify_keys
  #   #=> { "name" => "Rob", "age" => "28" }
  def stringify_keys
    transform_keys{ |key| key.to_s }
  end

  # Destructively convert all keys to strings. Same as
  # +stringify_keys+, but modifies +self+.
  def stringify_keys!
    transform_keys!{ |key| key.to_s }
  end

  # Return a new hash with all keys converted to symbols, as long as
  # they respond to +to_sym+.
  #
  #   hash = { 'name' => 'Rob', 'age' => '28' }
  #
  #   hash.symbolize_keys
  #   #=> { name: "Rob", age: "28" }
  def symbolize_keys
    transform_keys{ |key| key.to_sym rescue key }
  end
  alias_method :to_options,  :symbolize_keys

  # Destructively convert all keys to symbols, as long as they respond
  # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
  def symbolize_keys!
    transform_keys!{ |key| key.to_sym rescue key }
  end
  alias_method :to_options!, :symbolize_keys!

  # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
  # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
  # use strings for keys but assert symbols as keys, this will fail.
  #
  #   { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
  #   { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
  #   { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age)   # => passes, raises nothing
  def assert_valid_keys(*valid_keys)
    valid_keys.flatten!
    each_key do |k|
      raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
    end
  end

  # Return a new hash with all keys converted by the block operation.
  # This includes the keys from the root hash and from all
  # nested hashes.
  #
  #  hash = { person: { name: 'Rob', age: '28' } }
  #
  #  hash.deep_transform_keys{ |key| key.to_s.upcase }
  #  # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } }
  def deep_transform_keys(&block)
    result = {}
    each do |key, value|
      result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
    end
    result
  end

  # Destructively convert all keys by using the block operation.
  # This includes the keys from the root hash and from all
  # nested hashes.
  def deep_transform_keys!(&block)
    keys.each do |key|
      value = delete(key)
      self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
    end
    self
  end

  # Return a new hash with all keys converted to strings.
  # This includes the keys from the root hash and from all
  # nested hashes.
  #
  #   hash = { person: { name: 'Rob', age: '28' } }
  #
  #   hash.deep_stringify_keys
  #   # => { "person" => { "name" => "Rob", "age" => "28" } }
  def deep_stringify_keys
    deep_transform_keys{ |key| key.to_s }
  end

  # Destructively convert all keys to strings.
  # This includes the keys from the root hash and from all
  # nested hashes.
  def deep_stringify_keys!
    deep_transform_keys!{ |key| key.to_s }
  end

  # Return a new hash with all keys converted to symbols, as long as
  # they respond to +to_sym+. This includes the keys from the root hash
  # and from all nested hashes.
  #
  #   hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
  #
  #   hash.deep_symbolize_keys
  #   # => { person: { name: "Rob", age: "28" } }
  def deep_symbolize_keys
    deep_transform_keys{ |key| key.to_sym rescue key }
  end

  # Destructively convert all keys to symbols, as long as they respond
  # to +to_sym+. This includes the keys from the root hash and from all
  # nested hashes.
  def deep_symbolize_keys!
    deep_transform_keys!{ |key| key.to_sym rescue key }
  end
end
class Hash
  # Merges the caller into +other_hash+. For example,
  #
  #   options = options.reverse_merge(size: 25, velocity: 10)
  #
  # is equivalent to
  #
  #   options = { size: 25, velocity: 10 }.merge(options)
  #
  # This is particularly useful for initializing an options hash
  # with default values.
  def reverse_merge(other_hash)
    other_hash.merge(self)
  end

  # Destructive +reverse_merge+.
  def reverse_merge!(other_hash)
    # right wins if there is no left
    merge!( other_hash ){|key,left,right| left }
  end
  alias_method :reverse_update, :reverse_merge!
end
class Hash
  # Slice a hash to include only the given keys. This is useful for
  # limiting an options hash to valid keys before passing to a method:
  #
  #   def search(criteria = {})
  #     criteria.assert_valid_keys(:mass, :velocity, :time)
  #   end
  #
  #   search(options.slice(:mass, :velocity, :time))
  #
  # If you have an array of keys you want to limit to, you should splat them:
  #
  #   valid_keys = [:mass, :velocity, :time]
  #   search(options.slice(*valid_keys))
  def slice(*keys)
    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
    keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
  end

  # Replaces the hash with only the given keys.
  # Returns a hash containing the removed key/value pairs.
  #
  #   { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
  #   # => {:c=>3, :d=>4}
  def slice!(*keys)
    keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
    omit = slice(*self.keys - keys)
    hash = slice(*keys)
    replace(hash)
    omit
  end

  # Removes and returns the key/value pairs matching the given keys.
  #
  #   { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
  #   { a: 1, b: 2 }.extract!(:a, :x)             # => {:a=>1}
  def extract!(*keys)
    keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
  end
end
require 'active_support/core_ext/hash/conversions'
require 'active_support/core_ext/hash/deep_merge'
require 'active_support/core_ext/hash/diff'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/hash/slice'
require 'active_support/concern'
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/object/try'

module InfiniteComparable
  extend ActiveSupport::Concern

  included do
    alias_method_chain :<=>, :infinity
  end

  define_method :'<=>_with_infinity' do |other|
    if other.class == self.class
      public_send :'<=>_without_infinity', other
    else
      infinite = try(:infinite?)
      other_infinite = other.try(:infinite?)

      # inf <=> inf
      if infinite && other_infinite
        infinite <=> other_infinite
      # not_inf <=> inf
      elsif other_infinite
        -other_infinite
      # inf <=> not_inf
      elsif infinite
        infinite
      else
        conversion = "to_#{self.class.name.downcase}"
        other = other.public_send(conversion) if other.respond_to?(conversion)
        public_send :'<=>_without_infinity', other
      end
    end
  end
end
require 'active_support/inflector'

class Integer
  # Ordinalize turns a number into an ordinal string used to denote the
  # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
  #
  #  1.ordinalize     # => "1st"
  #  2.ordinalize     # => "2nd"
  #  1002.ordinalize  # => "1002nd"
  #  1003.ordinalize  # => "1003rd"
  #  -11.ordinalize   # => "-11th"
  #  -1001.ordinalize # => "-1001st"
  def ordinalize
    ActiveSupport::Inflector.ordinalize(self)
  end

  # Ordinal returns the suffix used to denote the position
  # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
  #
  #  1.ordinal     # => "st"
  #  2.ordinal     # => "nd"
  #  1002.ordinal  # => "nd"
  #  1003.ordinal  # => "rd"
  #  -11.ordinal   # => "th"
  #  -1001.ordinal # => "st"
  def ordinal
    ActiveSupport::Inflector.ordinal(self)
  end
end
class Integer
  # Check whether the integer is evenly divisible by the argument.
  #
  #   0.multiple_of?(0)  #=> true
  #   6.multiple_of?(5)  #=> false
  #   10.multiple_of?(2) #=> true
  def multiple_of?(number)
    number != 0 ? self % number == 0 : zero?
  end
end
require 'active_support/duration'
require 'active_support/core_ext/numeric/time'

class Integer
  # Enables the use of time calculations and declarations, like <tt>45.minutes +
  # 2.hours + 4.years</tt>.
  #
  # These methods use Time#advance for precise date calculations when using
  # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
  # results from a Time object.
  #
  #   # equivalent to Time.now.advance(months: 1)
  #   1.month.from_now
  #
  #   # equivalent to Time.now.advance(years: 2)
  #   2.years.from_now
  #
  #   # equivalent to Time.now.advance(months: 4, years: 5)
  #   (4.months + 5.years).from_now
  #
  # While these methods provide precise calculation when used as in the examples
  # above, care should be taken to note that this is not true if the result of
  # +months+, +years+, etc is converted before use:
  #
  #   # equivalent to 30.days.to_i.from_now
  #   1.month.to_i.from_now
  #
  #   # equivalent to 365.25.days.to_f.from_now
  #   1.year.to_f.from_now
  #
  # In such cases, Ruby's core
  # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
  # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
  # date and time arithmetic.
  def months
    ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
  end
  alias :month :months

  def years
    ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
  end
  alias :year :years
end
require 'active_support/core_ext/integer/multiple'
require 'active_support/core_ext/integer/inflections'
require 'active_support/core_ext/integer/time'
class Object
  # Makes backticks behave (somewhat more) similarly on all platforms.
  # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
  # spawned shell prints a message to stderr and sets $?. We emulate
  # Unix on the former but not the latter.
  def `(command) #:nodoc:
    super
  rescue Errno::ENOENT => e
    STDERR.puts "#$0: #{e}"
  end
end
module Kernel
  unless respond_to?(:debugger)
    # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
    def debugger
      message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
      defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
    end
    alias breakpoint debugger unless respond_to?(:breakpoint)
  end
end
require 'rbconfig'
require 'tempfile'

module Kernel
  # Sets $VERBOSE to nil for the duration of the block and back to its original
  # value afterwards.
  #
  #   silence_warnings do
  #     value = noisy_call # no warning voiced
  #   end
  #
  #   noisy_call # warning voiced
  def silence_warnings
    with_warnings(nil) { yield }
  end

  # Sets $VERBOSE to +true+ for the duration of the block and back to its
  # original value afterwards.
  def enable_warnings
    with_warnings(true) { yield }
  end

  # Sets $VERBOSE for the duration of the block and back to its original
  # value afterwards.
  def with_warnings(flag)
    old_verbose, $VERBOSE = $VERBOSE, flag
    yield
  ensure
    $VERBOSE = old_verbose
  end

  # For compatibility
  def silence_stderr #:nodoc:
    silence_stream(STDERR) { yield }
  end

  # Silences any stream for the duration of the block.
  #
  #   silence_stream(STDOUT) do
  #     puts 'This will never be seen'
  #   end
  #
  #   puts 'But this will'
  def silence_stream(stream)
    old_stream = stream.dup
    stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
    stream.sync = true
    yield
  ensure
    stream.reopen(old_stream)
  end

  # Blocks and ignores any exception passed as argument if raised within the block.
  #
  #   suppress(ZeroDivisionError) do
  #     1/0
  #     puts 'This code is NOT reached'
  #   end
  #
  #   puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
  def suppress(*exception_classes)
    yield
  rescue Exception => e
    raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
  end

  # Captures the given stream and returns it:
  #
  #   stream = capture(:stdout) { puts 'notice' }
  #   stream # => "notice\n"
  #
  #   stream = capture(:stderr) { warn 'error' }
  #   stream # => "error\n"
  #
  # even for subprocesses:
  #
  #   stream = capture(:stdout) { system('echo notice') }
  #   stream # => "notice\n"
  #
  #   stream = capture(:stderr) { system('echo error 1>&2') }
  #   stream # => "error\n"
  def capture(stream)
    stream = stream.to_s
    captured_stream = Tempfile.new(stream)
    stream_io = eval("$#{stream}")
    origin_stream = stream_io.dup
    stream_io.reopen(captured_stream)

    yield

    stream_io.rewind
    return captured_stream.read
  ensure
    captured_stream.unlink
    stream_io.reopen(origin_stream)
  end
  alias :silence :capture

  # Silences both STDOUT and STDERR, even for subprocesses.
  #
  #   quietly { system 'bundle install' }
  def quietly
    silence_stream(STDOUT) do
      silence_stream(STDERR) do
        yield
      end
    end
  end
end
module Kernel
  # class_eval on an object acts like singleton_class.class_eval.
  def class_eval(*args, &block)
    singleton_class.class_eval(*args, &block)
  end
end
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/agnostics'
require 'active_support/core_ext/kernel/debugger'
require 'active_support/core_ext/kernel/singleton_class'
class LoadError
  REGEXPS = [
    /^no such file to load -- (.+)$/i,
    /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
    /^Missing API definition file in (.+)$/i,
    /^cannot load such file -- (.+)$/i,
  ]

  unless method_defined?(:path)
    def path
      @path ||= begin
        REGEXPS.find do |regex|
          message =~ regex
        end
        $1
      end
    end
  end

  def is_missing?(location)
    location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
  end
end

MissingSourceFile = LoadErrorrequire 'active_support/core_ext/class/attribute_accessors'
require 'active_support/deprecation'
require 'active_support/logger_silence'

ActiveSupport::Deprecation.warn 'this file is deprecated and will be removed'

# Adds the 'around_level' method to Logger.
class Logger #:nodoc:
  def self.define_around_helper(level)
    module_eval <<-end_eval, __FILE__, __LINE__ + 1
      def around_#{level}(before_message, after_message)  # def around_debug(before_message, after_message, &block)
        self.#{level}(before_message)                     #   self.debug(before_message)
        return_value = yield(self)                        #   return_value = yield(self)
        self.#{level}(after_message)                      #   self.debug(after_message)
        return_value                                      #   return_value
      end                                                 # end
    end_eval
  end
  [:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
end

require 'logger'

# Extensions to the built-in Ruby logger.
#
# If you want to use the default log formatter as defined in the Ruby core, then you
# will need to set the formatter for the logger as in:
#
#   logger.formatter = Formatter.new
#
# You can then specify the datetime format, for example:
#
#   logger.datetime_format = "%Y-%m-%d"
#
# Note: This logger is deprecated in favor of ActiveSupport::Logger
class Logger
  include LoggerSilence

  alias :old_datetime_format= :datetime_format=
  # Logging date-time format (string passed to +strftime+). Ignored if the formatter
  # does not respond to datetime_format=.
  def datetime_format=(format)
    formatter.datetime_format = format if formatter.respond_to?(:datetime_format=)
  end

  alias :old_datetime_format :datetime_format
  # Get the logging datetime format. Returns nil if the formatter does not support
  # datetime formatting.
  def datetime_format
    formatter.datetime_format if formatter.respond_to?(:datetime_format)
  end

  alias :old_initialize :initialize
  # Overwrite initialize to set a default formatter.
  def initialize(*args)
    old_initialize(*args)
    self.formatter = SimpleFormatter.new
  end

  # Simple formatter which only displays the message.
  class SimpleFormatter < Logger::Formatter
    # This method is invoked when a log event occurs
    def call(severity, timestamp, progname, msg)
      "#{String === msg ? msg : msg.inspect}\n"
    end
  end
end
module Marshal
  class << self
    def load_with_autoloading(source)
      load_without_autoloading(source)
    rescue ArgumentError, NameError => exc
      if exc.message.match(%r|undefined class/module (.+)|)
        # try loading the class/module
        $1.constantize
        # if it is a IO we need to go back to read the object
        source.rewind if source.respond_to?(:rewind)
        retry
      else
        raise exc
      end
    end

    alias_method_chain :load, :autoloading
  end
end
class Module
  # Encapsulates the common pattern of:
  #
  #   alias_method :foo_without_feature, :foo
  #   alias_method :foo, :foo_with_feature
  #
  # With this, you simply do:
  #
  #   alias_method_chain :foo, :feature
  #
  # And both aliases are set up for you.
  #
  # Query and bang methods (foo?, foo!) keep the same punctuation:
  #
  #   alias_method_chain :foo?, :feature
  #
  # is equivalent to
  #
  #   alias_method :foo_without_feature?, :foo?
  #   alias_method :foo?, :foo_with_feature?
  #
  # so you can safely chain foo, foo?, and foo! with the same feature.
  def alias_method_chain(target, feature)
    # Strip out punctuation on predicates or bang methods since
    # e.g. target?_without_feature is not a valid method name.
    aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
    yield(aliased_target, punctuation) if block_given?

    with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
    without_method = "#{aliased_target}_without_#{feature}#{punctuation}"

    alias_method without_method, target
    alias_method target, with_method

    case
    when public_method_defined?(without_method)
      public target
    when protected_method_defined?(without_method)
      protected target
    when private_method_defined?(without_method)
      private target
    end
  end

  # Allows you to make aliases for attributes, which includes
  # getter, setter, and query methods.
  #
  #   class Content < ActiveRecord::Base
  #     # has a title attribute
  #   end
  #
  #   class Email < Content
  #     alias_attribute :subject, :title
  #   end
  #
  #   e = Email.find(1)
  #   e.title    # => "Superstars"
  #   e.subject  # => "Superstars"
  #   e.subject? # => true
  #   e.subject = "Megastars"
  #   e.title    # => "Megastars"
  def alias_attribute(new_name, old_name)
    module_eval <<-STR, __FILE__, __LINE__ + 1
      def #{new_name}; self.#{old_name}; end          # def subject; self.title; end
      def #{new_name}?; self.#{old_name}?; end        # def subject?; self.title?; end
      def #{new_name}=(v); self.#{old_name} = v; end  # def subject=(v); self.title = v; end
    STR
  end
end
class Module
  # A module may or may not have a name.
  #
  #   module M; end
  #   M.name # => "M"
  #
  #   m = Module.new
  #   m.name # => nil
  #
  # A module gets a name when it is first assigned to a constant. Either
  # via the +module+ or +class+ keyword or by an explicit assignment:
  #
  #   m = Module.new # creates an anonymous module
  #   M = m          # => m gets a name here as a side-effect
  #   m.name         # => "M"
  def anonymous?
    name.nil?
  end
end
class Module
  # Declares an attribute reader backed by an internally-named instance variable.
  def attr_internal_reader(*attrs)
    attrs.each {|attr_name| attr_internal_define(attr_name, :reader)}
  end

  # Declares an attribute writer backed by an internally-named instance variable.
  def attr_internal_writer(*attrs)
    attrs.each {|attr_name| attr_internal_define(attr_name, :writer)}
  end

  # Declares an attribute reader and writer backed by an internally-named instance
  # variable.
  def attr_internal_accessor(*attrs)
    attr_internal_reader(*attrs)
    attr_internal_writer(*attrs)
  end
  alias_method :attr_internal, :attr_internal_accessor

  class << self; attr_accessor :attr_internal_naming_format end
  self.attr_internal_naming_format = '@_%s'

  private
    def attr_internal_ivar_name(attr)
      Module.attr_internal_naming_format % attr
    end

    def attr_internal_define(attr_name, type)
      internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
      class_eval do # class_eval is necessary on 1.9 or else the methods a made private
        # use native attr_* methods as they are faster on some Ruby implementations
        send("attr_#{type}", internal_name)
      end
      attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
      alias_method attr_name, internal_name
      remove_method internal_name
    end
end
require 'active_support/core_ext/array/extract_options'

class Module
  def mattr_reader(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
        @@#{sym} = nil unless defined? @@#{sym}

        def self.#{sym}
          @@#{sym}
        end
      EOS

      unless options[:instance_reader] == false || options[:instance_accessor] == false
        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
          def #{sym}
            @@#{sym}
          end
        EOS
      end
    end
  end

  def mattr_writer(*syms)
    options = syms.extract_options!
    syms.each do |sym|
      raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
      class_eval(<<-EOS, __FILE__, __LINE__ + 1)
        def self.#{sym}=(obj)
          @@#{sym} = obj
        end
      EOS

      unless options[:instance_writer] == false || options[:instance_accessor] == false
        class_eval(<<-EOS, __FILE__, __LINE__ + 1)
          def #{sym}=(obj)
            @@#{sym} = obj
          end
        EOS
      end
    end
  end

  # Extends the module object with module and instance accessors for class attributes,
  # just like the native attr* accessors for instance attributes.
  #
  #   module AppConfiguration
  #     mattr_accessor :google_api_key
  #
  #     self.google_api_key = "123456789"
  #   end
  #
  #   AppConfiguration.google_api_key # => "123456789"
  #   AppConfiguration.google_api_key = "overriding the api key!"
  #   AppConfiguration.google_api_key # => "overriding the api key!"
  #
  # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
  # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
  # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
  def mattr_accessor(*syms)
    mattr_reader(*syms)
    mattr_writer(*syms)
  end
end
class Module
  # Provides a delegate class method to easily expose contained objects' public methods
  # as your own. Pass one or more methods (specified as symbols or strings)
  # and the name of the target object via the <tt>:to</tt> option (also a symbol
  # or string). At least one method and the <tt>:to</tt> option are required.
  #
  # Delegation is particularly useful with Active Record associations:
  #
  #   class Greeter < ActiveRecord::Base
  #     def hello
  #       'hello'
  #     end
  #
  #     def goodbye
  #       'goodbye'
  #     end
  #   end
  #
  #   class Foo < ActiveRecord::Base
  #     belongs_to :greeter
  #     delegate :hello, to: :greeter
  #   end
  #
  #   Foo.new.hello   # => "hello"
  #   Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
  #
  # Multiple delegates to the same target are allowed:
  #
  #   class Foo < ActiveRecord::Base
  #     belongs_to :greeter
  #     delegate :hello, :goodbye, to: :greeter
  #   end
  #
  #   Foo.new.goodbye # => "goodbye"
  #
  # Methods can be delegated to instance variables, class variables, or constants
  # by providing them as a symbols:
  #
  #   class Foo
  #     CONSTANT_ARRAY = [0,1,2,3]
  #     @@class_array  = [4,5,6,7]
  #
  #     def initialize
  #       @instance_array = [8,9,10,11]
  #     end
  #     delegate :sum, to: :CONSTANT_ARRAY
  #     delegate :min, to: :@@class_array
  #     delegate :max, to: :@instance_array
  #   end
  #
  #   Foo.new.sum # => 6
  #   Foo.new.min # => 4
  #   Foo.new.max # => 11
  #
  # It's also possible to delegate a method to the class by using +:class+:
  #
  #   class Foo
  #     def self.hello
  #       "world"
  #     end
  #
  #     delegate :hello, to: :class
  #   end
  #
  #   Foo.new.hello # => "world"
  #
  # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
  # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
  # delegated to.
  #
  #   Person = Struct.new(:name, :address)
  #
  #   class Invoice < Struct.new(:client)
  #     delegate :name, :address, to: :client, prefix: true
  #   end
  #
  #   john_doe = Person.new('John Doe', 'Vimmersvej 13')
  #   invoice = Invoice.new(john_doe)
  #   invoice.client_name    # => "John Doe"
  #   invoice.client_address # => "Vimmersvej 13"
  #
  # It is also possible to supply a custom prefix.
  #
  #   class Invoice < Struct.new(:client)
  #     delegate :name, :address, to: :client, prefix: :customer
  #   end
  #
  #   invoice = Invoice.new(john_doe)
  #   invoice.customer_name    # => 'John Doe'
  #   invoice.customer_address # => 'Vimmersvej 13'
  #
  # If the delegate object is +nil+ an exception is raised, and that happens
  # no matter whether +nil+ responds to the delegated method. You can get a
  # +nil+ instead with the +:allow_nil+ option.
  #
  #   class Foo
  #     attr_accessor :bar
  #     def initialize(bar = nil)
  #       @bar = bar
  #     end
  #     delegate :zoo, to: :bar
  #   end
  #
  #   Foo.new.zoo   # raises NoMethodError exception (you called nil.zoo)
  #
  #   class Foo
  #     attr_accessor :bar
  #     def initialize(bar = nil)
  #       @bar = bar
  #     end
  #     delegate :zoo, to: :bar, allow_nil: true
  #   end
  #
  #   Foo.new.zoo   # returns nil
  def delegate(*methods)
    options = methods.pop
    unless options.is_a?(Hash) && to = options[:to]
      raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
    end

    prefix, allow_nil = options.values_at(:prefix, :allow_nil)

    if prefix == true && to =~ /^[^a-z_]/
      raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
    end

    method_prefix = \
      if prefix
        "#{prefix == true ? to : prefix}_"
      else
        ''
      end

    file, line = caller.first.split(':', 2)
    line = line.to_i

    to = to.to_s
    to = 'self.class' if to == 'class'

    methods.each do |method|
      # Attribute writer methods only accept one argument. Makes sure []=
      # methods still accept two arguments.
      definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'

      if allow_nil
        module_eval(<<-EOS, file, line - 2)
          def #{method_prefix}#{method}(#{definition})        # def customer_name(*args, &block)
            if #{to} || #{to}.respond_to?(:#{method})         #   if client || client.respond_to?(:name)
              #{to}.#{method}(#{definition})                  #     client.name(*args, &block)
            end                                               #   end
          end                                                 # end
        EOS
      else
        exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")

        module_eval(<<-EOS, file, line - 1)
          def #{method_prefix}#{method}(#{definition})        # def customer_name(*args, &block)
            #{to}.#{method}(#{definition})                    #   client.name(*args, &block)
          rescue NoMethodError                                # rescue NoMethodError
            if #{to}.nil?                                     #   if client.nil?
              #{exception}                                    #     # add helpful message to the exception
            else                                              #   else
              raise                                           #     raise
            end                                               #   end
          end                                                 # end
        EOS
      end
    end
  end
end
require 'active_support/deprecation/method_wrappers'

class Module
  #   deprecate :foo
  #   deprecate bar: 'message'
  #   deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
  #
  # You can also use custom deprecator instance:
  #
  #   deprecate :foo, deprecator: MyLib::Deprecator.new
  #   deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new
  #
  # \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt>
  # method where you can implement your custom warning behavior.
  #
  #   class MyLib::Deprecator
  #     def deprecation_warning(deprecated_method_name, message, caller_backtrace)
  #        message = "#{method_name} is deprecated and will be removed from MyLibrary | #{message}"
  #        Kernel.warn message
  #     end
  #   end
  def deprecate(*method_names)
    ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
  end
end
require 'active_support/inflector'

class Module
  # Returns the name of the module containing this one.
  #
  #   M::N.parent_name # => "M"
  def parent_name
    if defined? @parent_name
      @parent_name
    else
      @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
    end
  end

  # Returns the module which contains this one according to its name.
  #
  #   module M
  #     module N
  #     end
  #   end
  #   X = M::N
  #
  #   M::N.parent # => M
  #   X.parent    # => M
  #
  # The parent of top-level and anonymous modules is Object.
  #
  #   M.parent          # => Object
  #   Module.new.parent # => Object
  def parent
    parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
  end

  # Returns all the parents of this module according to its name, ordered from
  # nested outwards. The receiver is not contained within the result.
  #
  #   module M
  #     module N
  #     end
  #   end
  #   X = M::N
  #
  #   M.parents    # => [Object]
  #   M::N.parents # => [M, Object]
  #   X.parents    # => [M, Object]
  def parents
    parents = []
    if parent_name
      parts = parent_name.split('::')
      until parts.empty?
        parents << ActiveSupport::Inflector.constantize(parts * '::')
        parts.pop
      end
    end
    parents << Object unless parents.include? Object
    parents
  end

  def local_constants #:nodoc:
    constants(false)
  end

  # *DEPRECATED*: Use +local_constants+ instead.
  #
  # Returns the names of the constants defined locally as strings.
  #
  #   module M
  #     X = 1
  #   end
  #   M.local_constant_names # => ["X"]
  #
  # This method is useful for forward compatibility, since Ruby 1.8 returns
  # constant names as strings, whereas 1.9 returns them as symbols.
  def local_constant_names
    ActiveSupport::Deprecation.warn 'Module#local_constant_names is deprecated, use Module#local_constants instead'
    local_constants.map { |c| c.to_s }
  end
end
require 'active_support/core_ext/string/inflections'

#--
# Allows code reuse in the methods below without polluting Module.
#++
module QualifiedConstUtils
  def self.raise_if_absolute(path)
    raise NameError.new("wrong constant name #$&") if path =~ /\A::[^:]+/
  end

  def self.names(path)
    path.split('::')
  end
end

##
# Extends the API for constants to be able to deal with qualified names. Arguments
# are assumed to be relative to the receiver.
#
#--
# Qualified names are required to be relative because we are extending existing
# methods that expect constant names, ie, relative paths of length 1. For example,
# Object.const_get('::String') raises NameError and so does qualified_const_get.
#++
class Module
  def qualified_const_defined?(path, search_parents=true)
    QualifiedConstUtils.raise_if_absolute(path)

    QualifiedConstUtils.names(path).inject(self) do |mod, name|
      return unless mod.const_defined?(name, search_parents)
      mod.const_get(name)
    end
    return true
  end

  def qualified_const_get(path)
    QualifiedConstUtils.raise_if_absolute(path)

    QualifiedConstUtils.names(path).inject(self) do |mod, name|
      mod.const_get(name)
    end
  end

  def qualified_const_set(path, value)
    QualifiedConstUtils.raise_if_absolute(path)

    const_name = path.demodulize
    mod_name = path.deconstantize
    mod = mod_name.empty? ? self : qualified_const_get(mod_name)
    mod.const_set(const_name, value)
  end
end
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/string/inflections'

class Module
  def reachable? #:nodoc:
    !anonymous? && name.safe_constantize.equal?(self)
  end
end
class Module
  def remove_possible_method(method)
    if method_defined?(method) || private_method_defined?(method)
      undef_method(method)
    end
  end

  def redefine_method(method, &block)
    remove_possible_method(method)
    define_method(method, &block)
  end
end
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/module/introspection'
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/module/reachable'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/deprecation'
require 'active_support/core_ext/module/remove_method'
require 'active_support/core_ext/module/qualified_const'
class NameError
  # Extract the name of the missing constant from the exception message.
  def missing_name
    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?
  def missing_name?(name)
    if name.is_a? Symbol
      last_name = (missing_name || '').split('::').last
      last_name == name.to_s
    else
      missing_name == name.to_s
    end
  end
end
class Numeric
  KILOBYTE = 1024
  MEGABYTE = KILOBYTE * 1024
  GIGABYTE = MEGABYTE * 1024
  TERABYTE = GIGABYTE * 1024
  PETABYTE = TERABYTE * 1024
  EXABYTE  = PETABYTE * 1024

  # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
  def bytes
    self
  end
  alias :byte :bytes

  def kilobytes
    self * KILOBYTE
  end
  alias :kilobyte :kilobytes

  def megabytes
    self * MEGABYTE
  end
  alias :megabyte :megabytes

  def gigabytes
    self * GIGABYTE
  end
  alias :gigabyte :gigabytes

  def terabytes
    self * TERABYTE
  end
  alias :terabyte :terabytes

  def petabytes
    self * PETABYTE
  end
  alias :petabyte :petabytes

  def exabytes
    self * EXABYTE
  end
  alias :exabyte :exabytes
end
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/number_helper'

class Numeric

  # Provides options for converting numbers into formatted strings.
  # Options are provided for phone numbers, currency, percentage,
  # precision, positional notation, file size and pretty printing.
  #
  # ==== Options
  #
  # For details on which formats use which options, see ActiveSupport::NumberHelper
  #
  # ==== Examples
  #
  #  Phone Numbers:
  #  5551234.to_s(:phone)                                     # => 555-1234
  #  1235551234.to_s(:phone)                                  # => 123-555-1234
  #  1235551234.to_s(:phone, area_code: true)                 # => (123) 555-1234
  #  1235551234.to_s(:phone, delimiter: ' ')                  # => 123 555 1234
  #  1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
  #  1235551234.to_s(:phone, country_code: 1)                 # => +1-123-555-1234
  #  1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
  #  # => +1.123.555.1234 x 1343
  #
  #  Currency:
  #  1234567890.50.to_s(:currency)                 # => $1,234,567,890.50
  #  1234567890.506.to_s(:currency)                # => $1,234,567,890.51
  #  1234567890.506.to_s(:currency, precision: 3)  # => $1,234,567,890.506
  #  1234567890.506.to_s(:currency, locale: :fr)   # => 1 234 567 890,51 €
  #  -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
  #  # => ($1,234,567,890.50)
  #  1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
  #  # => &pound;1234567890,50
  #  1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
  #  # => 1234567890,50 &pound;
  #
  #  Percentage:
  #  100.to_s(:percentage)                                  # => 100.000%
  #  100.to_s(:percentage, precision: 0)                    # => 100%
  #  1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
  #  302.24398923423.to_s(:percentage, precision: 5)        # => 302.24399%
  #  1000.to_s(:percentage, locale: :fr)                    # => 1 000,000%
  #  100.to_s(:percentage, format: '%n  %')                 # => 100  %
  #
  #  Delimited:
  #  12345678.to_s(:delimited)                     # => 12,345,678
  #  12345678.05.to_s(:delimited)                  # => 12,345,678.05
  #  12345678.to_s(:delimited, delimiter: '.')     # => 12.345.678
  #  12345678.to_s(:delimited, delimiter: ',')     # => 12,345,678
  #  12345678.05.to_s(:delimited, separator: ' ')  # => 12,345,678 05
  #  12345678.05.to_s(:delimited, locale: :fr)     # => 12 345 678,05
  #  98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
  #  # => 98 765 432,98
  #
  #  Rounded:
  #  111.2345.to_s(:rounded)                                      # => 111.235
  #  111.2345.to_s(:rounded, precision: 2)                        # => 111.23
  #  13.to_s(:rounded, precision: 5)                              # => 13.00000
  #  389.32314.to_s(:rounded, precision: 0)                       # => 389
  #  111.2345.to_s(:rounded, significant: true)                   # => 111
  #  111.2345.to_s(:rounded, precision: 1, significant: true)     # => 100
  #  13.to_s(:rounded, precision: 5, significant: true)           # => 13.000
  #  111.234.to_s(:rounded, locale: :fr)                          # => 111,234
  #  13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
  #  # => 13
  #  389.32314.to_s(:rounded, precision: 4, significant: true)    # => 389.3
  #  1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
  #  # => 1.111,23
  #
  #  Human-friendly size in Bytes:
  #  123.to_s(:human_size)                                   # => 123 Bytes
  #  1234.to_s(:human_size)                                  # => 1.21 KB
  #  12345.to_s(:human_size)                                 # => 12.1 KB
  #  1234567.to_s(:human_size)                               # => 1.18 MB
  #  1234567890.to_s(:human_size)                            # => 1.15 GB
  #  1234567890123.to_s(:human_size)                         # => 1.12 TB
  #  1234567.to_s(:human_size, precision: 2)                 # => 1.2 MB
  #  483989.to_s(:human_size, precision: 2)                  # => 470 KB
  #  1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
  #  1234567890123.to_s(:human_size, precision: 5)           # => "1.1229 TB"
  #  524288000.to_s(:human_size, precision: 5)               # => "500 MB"
  #
  #  Human-friendly format:
  #  123.to_s(:human)                                       # => "123"
  #  1234.to_s(:human)                                      # => "1.23 Thousand"
  #  12345.to_s(:human)                                     # => "12.3 Thousand"
  #  1234567.to_s(:human)                                   # => "1.23 Million"
  #  1234567890.to_s(:human)                                # => "1.23 Billion"
  #  1234567890123.to_s(:human)                             # => "1.23 Trillion"
  #  1234567890123456.to_s(:human)                          # => "1.23 Quadrillion"
  #  1234567890123456789.to_s(:human)                       # => "1230 Quadrillion"
  #  489939.to_s(:human, precision: 2)                      # => "490 Thousand"
  #  489939.to_s(:human, precision: 4)                      # => "489.9 Thousand"
  #  1234567.to_s(:human, precision: 4,
  #                   significant: false)                   # => "1.2346 Million"
  #  1234567.to_s(:human, precision: 1,
  #                   separator: ',',
  #                   significant: false)                   # => "1,2 Million"
  def to_formatted_s(format = :default, options = {})
    case format
    when :phone
      return ActiveSupport::NumberHelper.number_to_phone(self, options)
    when :currency
      return ActiveSupport::NumberHelper.number_to_currency(self, options)
    when :percentage
      return ActiveSupport::NumberHelper.number_to_percentage(self, options)
    when :delimited
      return ActiveSupport::NumberHelper.number_to_delimited(self, options)
    when :rounded
      return ActiveSupport::NumberHelper.number_to_rounded(self, options)
    when :human
      return ActiveSupport::NumberHelper.number_to_human(self, options)
    when :human_size
      return ActiveSupport::NumberHelper.number_to_human_size(self, options)
    else
      self.to_default_s
    end
  end

  [Float, Fixnum, Bignum, BigDecimal].each do |klass|
    klass.send(:alias_method, :to_default_s, :to_s)

    klass.send(:define_method, :to_s) do |*args|
      if args[0].is_a?(Symbol)
        format = args[0]
        options = args[1] || {}

        self.to_formatted_s(format, options)
      else
        to_default_s(*args)
      end
    end
  end
end
require 'active_support/core_ext/infinite_comparable'

class Float
  include InfiniteComparable
end

class BigDecimal
  include InfiniteComparable
end
require 'active_support/duration'
require 'active_support/core_ext/time/calculations'
require 'active_support/core_ext/time/acts_like'

class Numeric
  # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
  #
  # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
  # as well as adding or subtracting their results from a Time object. For example:
  #
  #   # equivalent to Time.current.advance(months: 1)
  #   1.month.from_now
  #
  #   # equivalent to Time.current.advance(years: 2)
  #   2.years.from_now
  #
  #   # equivalent to Time.current.advance(months: 4, years: 5)
  #   (4.months + 5.years).from_now
  #
  # While these methods provide precise calculation when used as in the examples above, care
  # should be taken to note that this is not true if the result of `months', `years', etc is
  # converted before use:
  #
  #   # equivalent to 30.days.to_i.from_now
  #   1.month.to_i.from_now
  #
  #   # equivalent to 365.25.days.to_f.from_now
  #   1.year.to_f.from_now
  #
  # In such cases, Ruby's core
  # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
  # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
  # date and time arithmetic.
  def seconds
    ActiveSupport::Duration.new(self, [[:seconds, self]])
  end
  alias :second :seconds

  def minutes
    ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
  end
  alias :minute :minutes

  def hours
    ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
  end
  alias :hour :hours

  def days
    ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
  end
  alias :day :days

  def weeks
    ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
  end
  alias :week :weeks

  def fortnights
    ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
  end
  alias :fortnight :fortnights

  # Reads best without arguments:  10.minutes.ago
  def ago(time = ::Time.current)
    time - self
  end

  # Reads best with argument:  10.minutes.until(time)
  alias :until :ago

  # Reads best with argument:  10.minutes.since(time)
  def since(time = ::Time.current)
    time + self
  end

  # Reads best without arguments:  10.minutes.from_now
  alias :from_now :since
end
require 'active_support/core_ext/numeric/bytes'
require 'active_support/core_ext/numeric/time'
require 'active_support/core_ext/numeric/conversions'
require 'active_support/core_ext/numeric/infinite_comparable'
class Object
  # A duck-type assistant method. For example, Active Support extends Date
  # to define an <tt>acts_like_date?</tt> method, and extends Time to define
  # <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
  # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
  # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
  def acts_like?(duck)
    respond_to? :"acts_like_#{duck}?"
  end
end
# encoding: utf-8

class Object
  # An object is blank if it's false, empty, or a whitespace string.
  # For example, '', '   ', +nil+, [], and {} are all blank.
  #
  # This simplifies:
  #
  #   if address.nil? || address.empty?
  #
  # ...to:
  #
  #   if address.blank?
  def blank?
    respond_to?(:empty?) ? empty? : !self
  end

  # An object is present if it's not <tt>blank?</tt>.
  def present?
    !blank?
  end

  # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
  # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
  #
  # This is handy for any representation of objects where blank is the same
  # as not present at all. For example, this simplifies a common check for
  # HTTP POST/query parameters:
  #
  #   state   = params[:state]   if params[:state].present?
  #   country = params[:country] if params[:country].present?
  #   region  = state || country || 'US'
  #
  # ...becomes:
  #
  #   region = params[:state].presence || params[:country].presence || 'US'
  def presence
    self if present?
  end
end

class NilClass
  # +nil+ is blank:
  #
  #   nil.blank? # => true
  def blank?
    true
  end
end

class FalseClass
  # +false+ is blank:
  #
  #   false.blank? # => true
  def blank?
    true
  end
end

class TrueClass
  # +true+ is not blank:
  #
  #   true.blank? # => false
  def blank?
    false
  end
end

class Array
  # An array is blank if it's empty:
  #
  #   [].blank?      # => true
  #   [1,2,3].blank? # => false
  alias_method :blank?, :empty?
end

class Hash
  # A hash is blank if it's empty:
  #
  #   {}.blank?                # => true
  #   { key: 'value' }.blank?  # => false
  alias_method :blank?, :empty?
end

class String
  # A string is blank if it's empty or contains whitespaces only:
  #
  #   ''.blank?                 # => true
  #   '   '.blank?              # => true
  #   '　'.blank?               # => true
  #   ' something here '.blank? # => false
  def blank?
    self !~ /[^[:space:]]/
  end
end

class Numeric #:nodoc:
  # No number is blank:
  #
  #   1.blank? # => false
  #   0.blank? # => false
  def blank?
    false
  end
end
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/hash/conversions'
require 'active_support/core_ext/object/duplicable'

class Object
  # Returns a deep copy of object if it's duplicable. If it's
  # not duplicable, returns +self+.
  #
  #   object = Object.new
  #   dup    = object.deep_dup
  #   dup.instance_variable_set(:@a, 1)
  #
  #   object.instance_variable_defined?(:@a) #=> false
  #   dup.instance_variable_defined?(:@a)    #=> true
  def deep_dup
    duplicable? ? dup : self
  end
end

class Array
  # Returns a deep copy of array.
  #
  #   array = [1, [2, 3]]
  #   dup   = array.deep_dup
  #   dup[1][2] = 4
  #
  #   array[1][2] #=> nil
  #   dup[1][2]   #=> 4
  def deep_dup
    map { |it| it.deep_dup }
  end
end

class Hash
  # Returns a deep copy of hash.
  #
  #   hash = { a: { b: 'b' } }
  #   dup  = hash.deep_dup
  #   dup[:a][:c] = 'c'
  #
  #   hash[:a][:c] #=> nil
  #   dup[:a][:c]  #=> "c"
  def deep_dup
    each_with_object(dup) do |(key, value), hash|
      hash[key.deep_dup] = value.deep_dup
    end
  end
end
#--
# Most objects are cloneable, but not all. For example you can't dup +nil+:
#
#   nil.dup # => TypeError: can't dup NilClass
#
# Classes may signal their instances are not duplicable removing +dup+/+clone+
# or raising exceptions from them. So, to dup an arbitrary object you normally
# use an optimistic approach and are ready to catch an exception, say:
#
#   arbitrary_object.dup rescue object
#
# Rails dups objects in a few critical spots where they are not that arbitrary.
# That rescue is very expensive (like 40 times slower than a predicate), and it
# is often triggered.
#
# That's why we hardcode the following cases and check duplicable? instead of
# using that rescue idiom.
#++
class Object
  # Can you safely dup this object?
  #
  # False for +nil+, +false+, +true+, symbol, and number objects;
  # true otherwise.
  def duplicable?
    true
  end
end

class NilClass
  # +nil+ is not duplicable:
  #
  #   nil.duplicable? # => false
  #   nil.dup         # => TypeError: can't dup NilClass
  def duplicable?
    false
  end
end

class FalseClass
  # +false+ is not duplicable:
  #
  #   false.duplicable? # => false
  #   false.dup         # => TypeError: can't dup FalseClass
  def duplicable?
    false
  end
end

class TrueClass
  # +true+ is not duplicable:
  #
  #   true.duplicable? # => false
  #   true.dup         # => TypeError: can't dup TrueClass
  def duplicable?
    false
  end
end

class Symbol
  # Symbols are not duplicable:
  #
  #   :my_symbol.duplicable? # => false
  #   :my_symbol.dup         # => TypeError: can't dup Symbol
  def duplicable?
    false
  end
end

class Numeric
  # Numbers are not duplicable:
  #
  #  3.duplicable? # => false
  #  3.dup         # => TypeError: can't dup Fixnum
  def duplicable?
    false
  end
end

require 'bigdecimal'
class BigDecimal
  begin
    BigDecimal.new('4.56').dup

    def duplicable?
      true
    end
  rescue TypeError
    # can't dup, so use superclass implementation
  end
end
class Object
  # Returns true if this object is included in the argument(s). Argument must be
  # any object which responds to +#include?+ or optionally, multiple arguments can be passed in. Usage:
  #
  #   characters = ['Konata', 'Kagami', 'Tsukasa']
  #   'Konata'.in?(characters) # => true
  #
  #   character = 'Konata'
  #   character.in?('Konata', 'Kagami', 'Tsukasa') # => true
  #
  # This will throw an ArgumentError if a single argument is passed in and it doesn't respond
  # to +#include?+.
  def in?(*args)
    if args.length > 1
      args.include? self
    else
      another_object = args.first
      if another_object.respond_to? :include?
        another_object.include? self
      else
        raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?'
      end
    end
  end
end
class Object
  # Returns a hash with string keys that maps instance variable names without "@" to their
  # corresponding values.
  #
  #   class C
  #     def initialize(x, y)
  #       @x, @y = x, y
  #     end
  #   end
  #
  #   C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
  def instance_values
    Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
  end

  # Returns an array of instance variable names as strings including "@".
  #
  #   class C
  #     def initialize(x, y)
  #       @x, @y = x, y
  #     end
  #   end
  #
  #   C.new(0, 1).instance_variable_names # => ["@y", "@x"]
  def instance_variable_names
    instance_variables.map { |var| var.to_s }
  end
end
# Hack to load json gem first so we can overwrite its to_json.
begin
  require 'json'
rescue LoadError
end

# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
# their default behavior. That said, we need to define the basic to_json method in all of them,
# otherwise they will always use to_json gem implementation, which is backwards incompatible in
# several cases (for instance, the JSON implementation for Hash does not work) with inheritance
# and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
[Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
  klass.class_eval do
    # Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
    def to_json(options = nil)
      ActiveSupport::JSON.encode(self, options)
    end
  end
end

module Process
  class Status
    def as_json(options = nil)
      { :exitstatus => exitstatus, :pid => pid }
    end
  end
end
class Object
  # Alias of <tt>to_s</tt>.
  def to_param
    to_s
  end
end

class NilClass
  # Returns +self+.
  def to_param
    self
  end
end

class TrueClass
  # Returns +self+.
  def to_param
    self
  end
end

class FalseClass
  # Returns +self+.
  def to_param
    self
  end
end

class Array
  # Calls <tt>to_param</tt> on all its elements and joins the result with
  # slashes. This is used by <tt>url_for</tt> in Action Pack.
  def to_param
    collect { |e| e.to_param }.join '/'
  end
end

class Hash
  # Returns a string representation of the receiver suitable for use as a URL
  # query string:
  #
  #   {name: 'David', nationality: 'Danish'}.to_param
  #   # => "name=David&nationality=Danish"
  #
  # An optional namespace can be passed to enclose the param names:
  #
  #   {name: 'David', nationality: 'Danish'}.to_param('user')
  #   # => "user[name]=David&user[nationality]=Danish"
  #
  # The string pairs "key=value" that conform the query string
  # are sorted lexicographically in ascending order.
  #
  # This method is also aliased as +to_query+.
  def to_param(namespace = nil)
    collect do |key, value|
      value.to_query(namespace ? "#{namespace}[#{key}]" : key)
    end.sort * '&'
  end
end
require 'active_support/core_ext/object/to_param'

class Object
  # Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
  # param name.
  #
  # Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
  def to_query(key)
    require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
    "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
  end
end

class Array
  # Converts an array into a string suitable for use as a URL query string,
  # using the given +key+ as the param name.
  #
  #   ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
  def to_query(key)
    prefix = "#{key}[]"
    collect { |value| value.to_query(prefix) }.join '&'
  end
end

class Hash
  alias_method :to_query, :to_param
end
class Object
  # Invokes the public method whose name goes as first argument just like
  # +public_send+ does, except that if the receiver does not respond to it the
  # call returns +nil+ rather than raising an exception.
  #
  # This method is defined to be able to write
  #
  #   @person.try(:name)
  #
  # instead of
  #
  #   @person ? @person.name : nil
  #
  # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
  # to the method:
  #
  #   nil.try(:to_i) # => nil, rather than 0
  #
  # Arguments and blocks are forwarded to the method if invoked:
  #
  #   @posts.try(:each_slice, 2) do |a, b|
  #     ...
  #   end
  #
  # The number of arguments in the signature must match. If the object responds
  # to the method the call is attempted and +ArgumentError+ is still raised
  # otherwise.
  #
  # If +try+ is called without arguments it yields the receiver to a given
  # block unless it is +nil+:
  #
  #   @person.try do |p|
  #     ...
  #   end
  #
  # Please also note that +try+ is defined on +Object+, therefore it won't work
  # with instances of classes that do not have +Object+ among their ancestors,
  # like direct subclasses of +BasicObject+. For example, using +try+ with
  # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
  # delegator itself.
  def try(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      public_send(*a, &b) if respond_to?(a.first)
    end
  end

  # Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
  # does not implemented the tried method.
  def try!(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      public_send(*a, &b)
    end
  end
end

class NilClass
  # Calling +try+ on +nil+ always returns +nil+.
  # It becomes specially helpful when navigating through associations that may return +nil+.
  #
  #   nil.try(:name) # => nil
  #
  # Without +try+
  #   @person && !@person.children.blank? && @person.children.first.name
  #
  # With +try+
  #   @person.try(:children).try(:first).try(:name)
  def try(*args)
    nil
  end

  def try!(*args)
    nil
  end
end
require 'active_support/option_merger'

class Object
  # An elegant way to factor duplication out of options passed to a series of
  # method calls. Each method called in the block, with the block variable as
  # the receiver, will have its options merged with the default +options+ hash
  # provided. Each method called on the block variable must take an options
  # hash as its final argument.
  #
  # Without <tt>with_options></tt>, this code contains duplication:
  #
  #   class Account < ActiveRecord::Base
  #     has_many :customers, dependent: :destroy
  #     has_many :products,  dependent: :destroy
  #     has_many :invoices,  dependent: :destroy
  #     has_many :expenses,  dependent: :destroy
  #   end
  #
  # Using <tt>with_options</tt>, we can remove the duplication:
  #
  #   class Account < ActiveRecord::Base
  #     with_options dependent: :destroy do |assoc|
  #       assoc.has_many :customers
  #       assoc.has_many :products
  #       assoc.has_many :invoices
  #       assoc.has_many :expenses
  #     end
  #   end
  #
  # It can also be used with an explicit receiver:
  #
  #   I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
  #     subject i18n.t :subject
  #     body    i18n.t :body, user_name: user.name
  #   end
  #
  # <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
  # Each nesting level will merge inherited defaults in addition to their own.
  def with_options(options)
    yield ActiveSupport::OptionMerger.new(self, options)
  end
end
require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/duplicable'
require 'active_support/core_ext/object/deep_dup'
require 'active_support/core_ext/object/try'
require 'active_support/core_ext/object/inclusion'

require 'active_support/core_ext/object/conversions'
require 'active_support/core_ext/object/instance_variables'

require 'active_support/core_ext/object/to_json'
require 'active_support/core_ext/object/to_param'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/object/with_options'
require "active_support/core_ext/kernel/singleton_class"
require "active_support/deprecation"

class Proc #:nodoc:
  def bind(object)
    ActiveSupport::Deprecation.warn 'Proc#bind is deprecated and will be removed in future versions'

    block, time = self, Time.now
    object.class_eval do
      method_name = "__bind_#{time.to_i}_#{time.usec}"
      define_method(method_name, &block)
      method = instance_method(method_name)
      remove_method(method_name)
      method
    end.bind(object)
  end
end
class Range
  RANGE_FORMATS = {
    :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
  }

  # Gives a human readable format of the range.
  #
  #   (1..100).to_formatted_s # => "1..100"
  def to_formatted_s(format = :default)
    if formatter = RANGE_FORMATS[format]
      formatter.call(first, last)
    else
      to_default_s
    end
  end

  alias_method :to_default_s, :to_s
  alias_method :to_s, :to_formatted_s
end
class Range
  # Extends the default Range#include? to support range comparisons.
  #  (1..5).include?(1..5) # => true
  #  (1..5).include?(2..3) # => true
  #  (1..5).include?(2..6) # => false
  #
  # The native Range#include? behavior is untouched.
  #  ('a'..'f').include?('c') # => true
  #  (5..9).include?(11) # => false
  def include_with_range?(value)
    if value.is_a?(::Range)
      # 1...10 includes 1..9 but it does not include 1..10.
      operator = exclude_end? && !value.exclude_end? ? :< : :<=
      include_without_range?(value.first) && value.last.send(operator, last)
    else
      include_without_range?(value)
    end
  end

  alias_method_chain :include?, :range
end
class Range
  # Compare two ranges and see if they overlap each other
  #  (1..5).overlaps?(4..6) # => true
  #  (1..5).overlaps?(7..9) # => false
  def overlaps?(other)
    cover?(other.first) || other.cover?(first)
  end
end
require 'active_support/core_ext/range/conversions'
require 'active_support/core_ext/range/include_range'
require 'active_support/core_ext/range/overlaps'
class Regexp #:nodoc:
  def multiline?
    options & MULTILINE == MULTILINE
  end
end
class String
  # If you pass a single Fixnum, returns a substring of one character at that
  # position. The first character of the string is at position 0, the next at
  # position 1, and so on. If a range is supplied, a substring containing
  # characters at offsets given by the range is returned. In both cases, if an
  # offset is negative, it is counted from the end of the string. Returns nil
  # if the initial offset falls outside the string. Returns an empty string if
  # the beginning of the range is greater than the end of the string.
  #
  #   str = "hello"
  #   str.at(0)      #=> "h"
  #   str.at(1..3)   #=> "ell"
  #   str.at(-2)     #=> "l"
  #   str.at(-2..-1) #=> "lo"
  #   str.at(5)      #=> nil
  #   str.at(5..-1)  #=> ""
  #
  # If a Regexp is given, the matching portion of the string is returned.
  # If a String is given, that given string is returned if it occurs in
  # the string. In both cases, nil is returned if there is no match.
  #
  #   str = "hello"
  #   str.at(/lo/) #=> "lo"
  #   str.at(/ol/) #=> nil
  #   str.at("lo") #=> "lo"
  #   str.at("ol") #=> nil
  def at(position)
    self[position]
  end

  # Returns a substring from the given position to the end of the string.
  # If the position is negative, it is counted from the end of the string.
  #
  #   str = "hello"
  #   str.from(0)  #=> "hello"
  #   str.from(3)  #=> "lo"
  #   str.from(-2) #=> "lo"
  #
  # You can mix it with +to+ method and do fun things like:
  #
  #   str = "hello"
  #   str.from(0).to(-1) #=> "hello"
  #   str.from(1).to(-2) #=> "ell"
  def from(position)
    self[position..-1]
  end

  # Returns a substring from the beginning of the string to the given position.
  # If the position is negative, it is counted from the end of the string.
  #
  #   str = "hello"
  #   str.to(0)  #=> "h"
  #   str.to(3)  #=> "hell"
  #   str.to(-2) #=> "hell"
  #
  # You can mix it with +from+ method and do fun things like:
  #
  #   str = "hello"
  #   str.from(0).to(-1) #=> "hello"
  #   str.from(1).to(-2) #=> "ell"
  def to(position)
    self[0..position]
  end

  # Returns the first character. If a limit is supplied, returns a substring
  # from the beginning of the string until it reaches the limit value. If the
  # given limit is greater than or equal to the string length, returns self.
  #
  #   str = "hello"
  #   str.first    #=> "h"
  #   str.first(1) #=> "h"
  #   str.first(2) #=> "he"
  #   str.first(0) #=> ""
  #   str.first(6) #=> "hello"
  def first(limit = 1)
    if limit == 0
      ''
    elsif limit >= size
      self
    else
      to(limit - 1)
    end
  end

  # Returns the last character of the string. If a limit is supplied, returns a substring
  # from the end of the string until it reaches the limit value (counting backwards). If
  # the given limit is greater than or equal to the string length, returns self.
  #
  #   str = "hello"
  #   str.last    #=> "o"
  #   str.last(1) #=> "o"
  #   str.last(2) #=> "lo"
  #   str.last(0) #=> ""
  #   str.last(6) #=> "hello"
  def last(limit = 1)
    if limit == 0
      ''
    elsif limit >= size
      self
    else
      from(-limit)
    end
  end
end
class String
  # Enable more predictable duck-typing on String-like classes. See <tt>Object#acts_like?</tt>.
  def acts_like_string?
    true
  end
end
require 'date'
require 'active_support/core_ext/time/calculations'

class String
  # Converts a string to a Time value.
  # The +form+ can be either :utc or :local (default :local).
  #
  # The time is parsed using Time.parse method.
  # If +form+ is :local, then the time is in the system timezone.
  # If the date part is missing then the current date is used and if
  # the time part is missing then it is assumed to be 00:00:00.
  #
  #   "13-12-2012".to_time               # => 2012-12-13 00:00:00 +0100
  #   "06:12".to_time                    # => 2012-12-13 06:12:00 +0100
  #   "2012-12-13 06:12".to_time         # => 2012-12-13 06:12:00 +0100
  #   "2012-12-13T06:12".to_time         # => 2012-12-13 06:12:00 +0100
  #   "2012-12-13T06:12".to_time(:utc)   # => 2012-12-13 05:12:00 UTC
  def to_time(form = :local)
    parts = Date._parse(self, false)
    return if parts.empty?

    now = Time.now
    offset = parts[:offset]
    utc_offset = form == :utc ? 0 : now.utc_offset
    adjustment = offset ? offset - utc_offset : 0

    Time.send(
      form,
      parts.fetch(:year, now.year),
      parts.fetch(:mon, now.month),
      parts.fetch(:mday, now.day),
      parts.fetch(:hour, 0),
      parts.fetch(:min, 0),
      parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0)
    ) - adjustment
  end

  # Converts a string to a Date value.
  #
  #   "1-1-2012".to_date   #=> Sun, 01 Jan 2012
  #   "01/01/2012".to_date #=> Sun, 01 Jan 2012
  #   "2012-12-13".to_date #=> Thu, 13 Dec 2012
  #   "12/13/2012".to_date #=> ArgumentError: invalid date
  def to_date
    ::Date.parse(self, false) unless blank?
  end

  # Converts a string to a DateTime value.
  #
  #   "1-1-2012".to_datetime            #=> Sun, 01 Jan 2012 00:00:00 +0000
  #   "01/01/2012 23:59:59".to_datetime #=> Sun, 01 Jan 2012 23:59:59 +0000
  #   "2012-12-13 12:50".to_datetime    #=> Thu, 13 Dec 2012 12:50:00 +0000
  #   "12/13/2012".to_datetime          #=> ArgumentError: invalid date
  def to_datetime
    ::DateTime.parse(self, false) unless blank?
  end
end
require 'active_support/deprecation'

class String
  def encoding_aware?
    ActiveSupport::Deprecation.warn 'String#encoding_aware? is deprecated'
    true
  end
end
class String
  # The inverse of <tt>String#include?</tt>. Returns true if the string
  # does not include the other string.
  #
  #   "hello".exclude? "lo" #=> false
  #   "hello".exclude? "ol" #=> true
  #   "hello".exclude? ?h   #=> false
  def exclude?(string)
    !include?(string)
  end
end
class String
  # Returns the string, first removing all whitespace on both ends of
  # the string, and then changing remaining consecutive whitespace
  # groups into one space each.
  #
  # Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
  #
  #   %{ Multi-line
  #      string }.squish                   # => "Multi-line string"
  #   " foo   bar    \n   \t   boo".squish # => "foo bar boo"
  def squish
    dup.squish!
  end

  # Performs a destructive squish. See String#squish.
  def squish!
    gsub!(/\A[[:space:]]+/, '')
    gsub!(/[[:space:]]+\z/, '')
    gsub!(/[[:space:]]+/, ' ')
    self
  end

  # Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
  #
  #   'Once upon a time in a world far far away'.truncate(27)
  #   # => "Once upon a time in a wo..."
  #
  # Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
  #
  #   'Once upon a time in a world far far away'.truncate(27, separator: ' ')
  #   # => "Once upon a time in a..."
  #
  #   'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
  #   # => "Once upon a time in a..."
  #
  # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
  # for a total length not exceeding <tt>length</tt>:
  #
  #   'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
  #   # => "And they f... (continued)"
  def truncate(truncate_at, options = {})
    return dup unless length > truncate_at

    options[:omission] ||= '...'
    length_with_room_for_omission = truncate_at - options[:omission].length
    stop = \
      if options[:separator]
        rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
      else
        length_with_room_for_omission
      end

    self[0...stop] + options[:omission]
  end
end
class String
  # Same as +indent+, except it indents the receiver in-place.
  #
  # Returns the indented string, or +nil+ if there was nothing to indent.
  def indent!(amount, indent_string=nil, indent_empty_lines=false)
    indent_string = indent_string || self[/^[ \t]/] || ' '
    re = indent_empty_lines ? /^/ : /^(?!$)/
    gsub!(re, indent_string * amount)
  end

  # Indents the lines in the receiver:
  #
  #   <<EOS.indent(2)
  #   def some_method
  #     some_code
  #   end
  #   EOS
  #   # =>
  #     def some_method
  #       some_code
  #     end
  #
  # The second argument, +indent_string+, specifies which indent string to
  # use. The default is +nil+, which tells the method to make a guess by
  # peeking at the first indented line, and fallback to a space if there is
  # none.
  #
  #   "  foo".indent(2)        # => "    foo"
  #   "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
  #   "foo".indent(2, "\t")    # => "\t\tfoo"
  #
  # While +indent_string+ is tipically one space or tab, it may be any string.
  #
  # The third argument, +indent_empty_lines+, is a flag that says whether
  # empty lines should be indented. Default is false.
  #
  #   "foo\n\nbar".indent(2)            # => "  foo\n\n  bar"
  #   "foo\n\nbar".indent(2, nil, true) # => "  foo\n  \n  bar"
  #
  def indent(amount, indent_string=nil, indent_empty_lines=false)
    dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
  end
end
require 'active_support/inflector/methods'
require 'active_support/inflector/transliterate'

# String inflections define new methods on the String class to transform names for different purposes.
# For instance, you can figure out the name of a table from the name of a class.
#
#   'ScaleScore'.tableize # => "scale_scores"
#
class String
  # Returns the plural form of the word in the string.
  #
  # If the optional parameter +count+ is specified,
  # the singular form will be returned if <tt>count == 1</tt>.
  # For any other value of +count+ the plural will be returned.
  #
  # If the optional parameter +locale+ is specified,
  # the word will be pluralized as a word of that language.
  # By default, this parameter is set to <tt>:en</tt>.
  # You must define your own inflection rules for languages other than English.
  #
  #   'post'.pluralize             # => "posts"
  #   'octopus'.pluralize          # => "octopi"
  #   'sheep'.pluralize            # => "sheep"
  #   'words'.pluralize            # => "words"
  #   'the blue mailman'.pluralize # => "the blue mailmen"
  #   'CamelOctopus'.pluralize     # => "CamelOctopi"
  #   'apple'.pluralize(1)         # => "apple"
  #   'apple'.pluralize(2)         # => "apples"
  #   'ley'.pluralize(:es)         # => "leyes"
  #   'ley'.pluralize(1, :es)      # => "ley"
  def pluralize(count = nil, locale = :en)
    locale = count if count.is_a?(Symbol)
    if count == 1
      self
    else
      ActiveSupport::Inflector.pluralize(self, locale)
    end
  end

  # The reverse of +pluralize+, returns the singular form of a word in a string.
  #
  # If the optional parameter +locale+ is specified,
  # the word will be singularized as a word of that language.
  # By default, this paramter is set to <tt>:en</tt>.
  # You must define your own inflection rules for languages other than English.
  #
  #   'posts'.singularize            # => "post"
  #   'octopi'.singularize           # => "octopus"
  #   'sheep'.singularize            # => "sheep"
  #   'word'.singularize             # => "word"
  #   'the blue mailmen'.singularize # => "the blue mailman"
  #   'CamelOctopi'.singularize      # => "CamelOctopus"
  #   'leyes'.singularize(:es)       # => "ley"
  def singularize(locale = :en)
    ActiveSupport::Inflector.singularize(self, locale)
  end

  # +constantize+ tries to find a declared constant with the name specified
  # in the string. It raises a NameError when the name is not in CamelCase
  # or is not initialized.  See ActiveSupport::Inflector.constantize
  #
  #   'Module'.constantize  # => Module
  #   'Class'.constantize   # => Class
  #   'blargle'.constantize # => NameError: wrong constant name blargle
  def constantize
    ActiveSupport::Inflector.constantize(self)
  end

  # +safe_constantize+ tries to find a declared constant with the name specified
  # in the string. It returns nil when the name is not in CamelCase
  # or is not initialized.  See ActiveSupport::Inflector.safe_constantize
  #
  #   'Module'.safe_constantize  # => Module
  #   'Class'.safe_constantize   # => Class
  #   'blargle'.safe_constantize # => nil
  def safe_constantize
    ActiveSupport::Inflector.safe_constantize(self)
  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.
  #
  #   'active_record'.camelize                # => "ActiveRecord"
  #   'active_record'.camelize(:lower)        # => "activeRecord"
  #   'active_record/errors'.camelize         # => "ActiveRecord::Errors"
  #   'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
  def camelize(first_letter = :upper)
    case first_letter
    when :upper
      ActiveSupport::Inflector.camelize(self, true)
    when :lower
      ActiveSupport::Inflector.camelize(self, false)
    end
  end
  alias_method :camelcase, :camelize

  # 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 +titlecase+.
  #
  #   'man from the boondocks'.titleize # => "Man From The Boondocks"
  #   'x-men: the last stand'.titleize  # => "X Men: The Last Stand"
  def titleize
    ActiveSupport::Inflector.titleize(self)
  end
  alias_method :titlecase, :titleize

  # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
  #
  # +underscore+ will also change '::' to '/' to convert namespaces to paths.
  #
  #   'ActiveModel'.underscore         # => "active_model"
  #   'ActiveModel::Errors'.underscore # => "active_model/errors"
  def underscore
    ActiveSupport::Inflector.underscore(self)
  end

  # Replaces underscores with dashes in the string.
  #
  #   'puni_puni'.dasherize # => "puni-puni"
  def dasherize
    ActiveSupport::Inflector.dasherize(self)
  end

  # Removes the module part from the constant expression in the string.
  #
  #   'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
  #   'Inflections'.demodulize                                       # => "Inflections"
  #
  # See also +deconstantize+.
  def demodulize
    ActiveSupport::Inflector.demodulize(self)
  end

  # Removes the rightmost segment from the constant expression in the string.
  #
  #   'Net::HTTP'.deconstantize   # => "Net"
  #   '::Net::HTTP'.deconstantize # => "::Net"
  #   'String'.deconstantize      # => ""
  #   '::String'.deconstantize    # => ""
  #   ''.deconstantize            # => ""
  #
  # See also +demodulize+.
  def deconstantize
    ActiveSupport::Inflector.deconstantize(self)
  end

  # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
  #
  #   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) %>
  #   # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
  def parameterize(sep = '-')
    ActiveSupport::Inflector.parameterize(self, sep)
  end

  # Creates 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.
  #
  #   'RawScaledScorer'.tableize # => "raw_scaled_scorers"
  #   'egg_and_ham'.tableize     # => "egg_and_hams"
  #   'fancyCategory'.tableize   # => "fancy_categories"
  def tableize
    ActiveSupport::Inflector.tableize(self)
  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+.)
  #
  #   'egg_and_hams'.classify # => "EggAndHam"
  #   'posts'.classify        # => "Post"
  #
  # Singular names are not handled correctly.
  #
  #   'business'.classify # => "Busines"
  def classify
    ActiveSupport::Inflector.classify(self)
  end

  # Capitalizes the first word, turns underscores into spaces, and strips '_id'.
  # Like +titleize+, this is meant for creating pretty output.
  #
  #   'employee_salary'.humanize # => "Employee salary"
  #   'author_id'.humanize       # => "Author"
  def humanize
    ActiveSupport::Inflector.humanize(self)
  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'.
  #
  #   'Message'.foreign_key        # => "message_id"
  #   'Message'.foreign_key(false) # => "messageid"
  #   'Admin::Post'.foreign_key    # => "post_id"
  def foreign_key(separate_class_name_and_id_with_underscore = true)
    ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
  end
end
require 'active_support/string_inquirer'

class String
  # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
  # which gives you a prettier way to test for equality.
  #
  #   env = 'production'.inquiry
  #   env.production?  # => true
  #   env.development? # => false
  def inquiry
    ActiveSupport::StringInquirer.new(self)
  end
end
# encoding: utf-8
require 'active_support/multibyte'

class String
  # == Multibyte proxy
  #
  # +mb_chars+ is a multibyte safe proxy for string methods.
  #
  # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
  # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
  # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
  #
  #   name = 'Claus Müller'
  #   name.reverse # => "rell??M sualC"
  #   name.length  # => 13
  #
  #   name.mb_chars.reverse.to_s # => "rellüM sualC"
  #   name.mb_chars.length       # => 12
  #
  # == Method chaining
  #
  # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
  # method chaining on the result of any of these methods.
  #
  #   name.mb_chars.reverse.length # => 12
  #
  # == Interoperability and configuration
  #
  # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
  # String and Char work like expected. The bang! methods change the internal string representation in the Chars
  # object. Interoperability problems can be resolved easily with a +to_s+ call.
  #
  # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
  # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
  def mb_chars
    ActiveSupport::Multibyte.proxy_class.new(self)
  end

  def is_utf8?
    case encoding
    when Encoding::UTF_8
      valid_encoding?
    when Encoding::ASCII_8BIT, Encoding::US_ASCII
      dup.force_encoding(Encoding::UTF_8).valid_encoding?
    else
      false
    end
  end
end
require 'erb'
require 'active_support/core_ext/kernel/singleton_class'

class ERB
  module Util
    HTML_ESCAPE = { '&' => '&amp;',  '>' => '&gt;',   '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
    JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
    HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
    JSON_ESCAPE_REGEXP = /[&"><]/

    # A utility method for escaping HTML tag characters.
    # This method is also aliased as <tt>h</tt>.
    #
    # In your ERB templates, use this method to escape any unsafe content. For example:
    #   <%=h @person.name %>
    #
    #   puts html_escape('is a > 0 & a < 10?')
    #   # => is a &gt; 0 &amp; a &lt; 10?
    def html_escape(s)
      s = s.to_s
      if s.html_safe?
        s
      else
        s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
      end
    end

    # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
    remove_method(:h)
    alias h html_escape

    module_function :h

    singleton_class.send(:remove_method, :html_escape)
    module_function :html_escape

    # A utility method for escaping HTML without affecting existing escaped entities.
    #
    #   html_escape_once('1 < 2 &amp; 3')
    #   # => "1 &lt; 2 &amp; 3"
    #
    #   html_escape_once('&lt;&lt; Accept & Checkout')
    #   # => "&lt;&lt; Accept &amp; Checkout"
    def html_escape_once(s)
      result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP) { |special| HTML_ESCAPE[special] }
      s.html_safe? ? result.html_safe : result
    end

    module_function :html_escape_once

    # A utility method for escaping HTML entities in JSON strings
    # using \uXXXX JavaScript escape sequences for string literals:
    #
    #   json_escape('is a > 0 & a < 10?')
    #   # => is a \u003E 0 \u0026 a \u003C 10?
    #
    # Note that after this operation is performed the output is not
    # valid JSON. In particular double quotes are removed:
    #
    #   json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}')
    #   # => {name:john,created_at:2010-04-28T01:39:31Z,id:1}
    def json_escape(s)
      result = s.to_s.gsub(JSON_ESCAPE_REGEXP) { |special| JSON_ESCAPE[special] }
      s.html_safe? ? result.html_safe : result
    end

    module_function :json_escape
  end
end

class Object
  def html_safe?
    false
  end
end

class Numeric
  def html_safe?
    true
  end
end

module ActiveSupport #:nodoc:
  class SafeBuffer < String
    UNSAFE_STRING_METHODS = %w(
      capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
      slice squeeze strip sub succ swapcase tr tr_s upcase prepend
    )

    alias_method :original_concat, :concat
    private :original_concat

    class SafeConcatError < StandardError
      def initialize
        super 'Could not concatenate to the buffer because it is not html safe.'
      end
    end

    def [](*args)
      if args.size < 2
        super
      else
        if html_safe?
          new_safe_buffer = super
          new_safe_buffer.instance_eval { @html_safe = true }
          new_safe_buffer
        else
          to_str[*args]
        end
      end
    end

    def safe_concat(value)
      raise SafeConcatError unless html_safe?
      original_concat(value)
    end

    def initialize(*)
      @html_safe = true
      super
    end

    def initialize_copy(other)
      super
      @html_safe = other.html_safe?
    end

    def clone_empty
      self[0, 0]
    end

    def concat(value)
      if !html_safe? || value.html_safe?
        super(value)
      else
        super(ERB::Util.h(value))
      end
    end
    alias << concat

    def +(other)
      dup.concat(other)
    end

    def %(args)
      args = Array(args).map do |arg|
        if !html_safe? || arg.html_safe?
          arg
        else
          ERB::Util.h(arg)
        end
      end

      self.class.new(super(args))
    end

    def html_safe?
      defined?(@html_safe) && @html_safe
    end

    def to_s
      self
    end

    def to_param
      to_str
    end

    def encode_with(coder)
      coder.represent_scalar nil, to_str
    end

    UNSAFE_STRING_METHODS.each do |unsafe_method|
      if 'String'.respond_to?(unsafe_method)
        class_eval <<-EOT, __FILE__, __LINE__ + 1
          def #{unsafe_method}(*args, &block)       # def capitalize(*args, &block)
            to_str.#{unsafe_method}(*args, &block)  #   to_str.capitalize(*args, &block)
          end                                       # end

          def #{unsafe_method}!(*args)              # def capitalize!(*args)
            @html_safe = false                      #   @html_safe = false
            super                                   #   super
          end                                       # end
        EOT
      end
    end
  end
end

class String
  def html_safe
    ActiveSupport::SafeBuffer.new(self)
  end
end
class String
  alias_method :starts_with?, :start_with?
  alias_method :ends_with?, :end_with?
end
require 'active_support/core_ext/object/try'

class String
  # Strips indentation in heredocs.
  #
  # For example in
  #
  #   if options[:usage]
  #     puts <<-USAGE.strip_heredoc
  #       This command does such and such.
  #
  #       Supported options are:
  #         -h         This message
  #         ...
  #     USAGE
  #   end
  #
  # the user would see the usage message aligned against the left margin.
  #
  # Technically, it looks for the least indented line in the whole string, and removes
  # that amount of leading whitespace.
  def strip_heredoc
    indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
    gsub(/^[ \t]{#{indent}}/, '')
  end
end
begin
  # See http://fast-xs.rubyforge.org/ by Eric Wong.
  # Also included with hpricot.
  require 'fast_xs'
rescue LoadError
  # fast_xs extension unavailable
else
  begin
    require 'builder'
  rescue LoadError
    # builder demands the first shot at defining String#to_xs
  end

  class String
    alias_method :original_xs, :to_xs if method_defined?(:to_xs)
    alias_method :to_xs, :fast_xs
  end
end
require 'active_support/core_ext/time/zones'

class String
  # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
  # is set, otherwise converts String to a Time via String#to_time
  def in_time_zone(zone = ::Time.zone)
    if zone
      ::Time.find_zone!(zone).parse(self)
    else
      to_time
    end
  end
end
require 'active_support/core_ext/string/conversions'
require 'active_support/core_ext/string/filters'
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/xchar'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/string/exclude'
require 'active_support/core_ext/string/strip'
require 'active_support/core_ext/string/inquiry'
require 'active_support/core_ext/string/indent'
require 'active_support/core_ext/string/zones'
#  Backport of Struct#to_h from Ruby 2.0
class Struct # :nodoc:
  def to_h
    Hash[members.zip(values)]
  end
end unless Struct.instance_methods.include?(:to_h)
class Thread
  LOCK = Mutex.new # :nodoc:

  # Returns the value of a thread local variable that has been set. Note that
  # these are different than fiber local values.
  #
  # Thread local values are carried along with threads, and do not respect
  # fibers. For example:
  #
  #   Thread.new {
  #     Thread.current.thread_variable_set("foo", "bar") # set a thread local
  #     Thread.current["foo"] = "bar"                    # set a fiber local
  #
  #     Fiber.new {
  #       Fiber.yield [
  #         Thread.current.thread_variable_get("foo"), # get the thread local
  #         Thread.current["foo"],                     # get the fiber local
  #       ]
  #     }.resume
  #   }.join.value # => ['bar', nil]
  #
  # The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned
  # for the fiber local. The fiber is executed in the same thread, so the
  # thread local values are available.
  def thread_variable_get(key)
    locals[key.to_sym]
  end

  # Sets a thread local with +key+ to +value+. Note that these are local to
  # threads, and not to fibers. Please see Thread#thread_variable_get for
  # more information.
  def thread_variable_set(key, value)
    locals[key.to_sym] = value
  end

  # Returns an an array of the names of the thread-local variables (as Symbols).
  #
  #    thr = Thread.new do
  #      Thread.current.thread_variable_set(:cat, 'meow')
  #      Thread.current.thread_variable_set("dog", 'woof')
  #    end
  #    thr.join               #=> #<Thread:0x401b3f10 dead>
  #    thr.thread_variables   #=> [:dog, :cat]
  #
  # Note that these are not fiber local variables. Please see Thread#thread_variable_get
  # for more details.
  def thread_variables
    locals.keys
  end

  # Returns <tt>true</tt> if the given string (or symbol) exists as a
  # thread-local variable.
  #
  #    me = Thread.current
  #    me.thread_variable_set(:oliver, "a")
  #    me.thread_variable?(:oliver)    #=> true
  #    me.thread_variable?(:stanley)   #=> false
  #
  # Note that these are not fiber local variables. Please see Thread#thread_variable_get
  # for more details.
  def thread_variable?(key)
    locals.has_key?(key.to_sym)
  end

  private

  def locals
    if defined?(@locals)
      @locals
    else
      LOCK.synchronize { @locals ||= {} }
    end
  end
end unless Thread.instance_methods.include?(:thread_variable_set)
require 'active_support/core_ext/object/acts_like'

class Time
  # Duck-types as a Time-like class. See Object#acts_like?.
  def acts_like_time?
    true
  end
end
require 'active_support/duration'
require 'active_support/core_ext/time/conversions'
require 'active_support/time_with_zone'
require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/date_and_time/calculations'
require 'active_support/deprecation'

class Time
  include DateAndTime::Calculations

  COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

  class << self
    # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
    def ===(other)
      super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
    end

    # Return the number of days in the given month.
    # If no year is specified, it will use the current year.
    def days_in_month(month, year = now.year)
      if month == 2 && ::Date.gregorian_leap?(year)
        29
      else
        COMMON_YEAR_DAYS_IN_MONTH[month]
      end
    end

    # *DEPRECATED*: Use +Time#utc+ or +Time#local+ instead.
    #
    # Returns a new Time if requested year can be accommodated by Ruby's Time class
    # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
    # otherwise returns a DateTime.
    def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
      ActiveSupport::Deprecation.warn 'time_with_datetime_fallback is deprecated. Use Time#utc or Time#local instead', caller
      time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)

      # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
      if time.year == year
        time
      else
        ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
      end
    rescue
      ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
    end

    # *DEPRECATED*: Use +Time#utc+ instead.
    #
    # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
    def utc_time(*args)
      ActiveSupport::Deprecation.warn 'utc_time is deprecated. Use Time#utc instead', caller
      time_with_datetime_fallback(:utc, *args)
    end

    # *DEPRECATED*: Use +Time#local+ instead.
    #
    # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
    def local_time(*args)
      ActiveSupport::Deprecation.warn 'local_time is deprecated. Use Time#local instead', caller
      time_with_datetime_fallback(:local, *args)
    end

    # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
    def current
      ::Time.zone ? ::Time.zone.now : ::Time.now
    end
  end

  # Seconds since midnight: Time.now.seconds_since_midnight
  def seconds_since_midnight
    to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
  end

  # Returns the number of seconds until 23:59:59.
  #
  #   Time.new(2012, 8, 29,  0,  0,  0).seconds_until_end_of_day # => 86399
  #   Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
  #   Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0
  def seconds_until_end_of_day
    end_of_day.to_i - to_i
  end

  # Returns a new Time where one or more of the elements have been changed according
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
  # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
  # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
  # sec and usec is set to 0.  The +options+ parameter takes a hash with any of these
  # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
  # <tt>:sec</tt>, <tt>:usec</tt>.
  #
  #   Time.new(2012, 8, 29, 22, 35, 0).change(day: 1)              # => Time.new(2012, 8, 1, 22, 35, 0)
  #   Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1)  # => Time.new(1981, 8, 1, 22, 35, 0)
  #   Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
  def change(options)
    new_year  = options.fetch(:year, year)
    new_month = options.fetch(:month, month)
    new_day   = options.fetch(:day, day)
    new_hour  = options.fetch(:hour, hour)
    new_min   = options.fetch(:min, options[:hour] ? 0 : min)
    new_sec   = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
    new_usec  = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))

    if utc?
      ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
    elsif zone
      ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
    else
      ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
    end
  end

  # Uses Date to provide precise Time calculations for years, months, and days.
  # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
  def advance(options)
    unless options[:weeks].nil?
      options[:weeks], partial_weeks = options[:weeks].divmod(1)
      options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
    end

    unless options[:days].nil?
      options[:days], partial_days = options[:days].divmod(1)
      options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
    end

    d = to_date.advance(options)
    time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
    seconds_to_advance = \
      options.fetch(:seconds, 0) +
      options.fetch(:minutes, 0) * 60 +
      options.fetch(:hours, 0) * 3600

    if seconds_to_advance.zero?
      time_advanced_by_date
    else
      time_advanced_by_date.since(seconds_to_advance)
    end
  end

  # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
  def ago(seconds)
    since(-seconds)
  end

  # Returns a new Time representing the time a number of seconds since the instance time
  def since(seconds)
    self + seconds
  rescue
    to_datetime.since(seconds)
  end
  alias :in :since

  # Returns a new Time representing the start of the day (0:00)
  def beginning_of_day
    #(self - seconds_since_midnight).change(usec: 0)
    change(:hour => 0)
  end
  alias :midnight :beginning_of_day
  alias :at_midnight :beginning_of_day
  alias :at_beginning_of_day :beginning_of_day

  # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
  def end_of_day
    change(
      :hour => 23,
      :min => 59,
      :sec => 59,
      :usec => Rational(999999999, 1000)
    )
  end
  alias :at_end_of_day :end_of_day

  # Returns a new Time representing the start of the hour (x:00)
  def beginning_of_hour
    change(:min => 0)
  end
  alias :at_beginning_of_hour :beginning_of_hour

  # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
  def end_of_hour
    change(
      :min => 59,
      :sec => 59,
      :usec => Rational(999999999, 1000)
    )
  end
  alias :at_end_of_hour :end_of_hour

  # Returns a Range representing the whole day of the current time.
  def all_day
    beginning_of_day..end_of_day
  end

  # Returns a Range representing the whole week of the current time.
  # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
  def all_week(start_day = Date.beginning_of_week)
    beginning_of_week(start_day)..end_of_week(start_day)
  end

  # Returns a Range representing the whole month of the current time.
  def all_month
    beginning_of_month..end_of_month
  end

  # Returns a Range representing the whole quarter of the current time.
  def all_quarter
    beginning_of_quarter..end_of_quarter
  end

  # Returns a Range representing the whole year of the current time.
  def all_year
    beginning_of_year..end_of_year
  end

  def plus_with_duration(other) #:nodoc:
    if ActiveSupport::Duration === other
      other.since(self)
    else
      plus_without_duration(other)
    end
  end
  alias_method :plus_without_duration, :+
  alias_method :+, :plus_with_duration

  def minus_with_duration(other) #:nodoc:
    if ActiveSupport::Duration === other
      other.until(self)
    else
      minus_without_duration(other)
    end
  end
  alias_method :minus_without_duration, :-
  alias_method :-, :minus_with_duration

  # Time#- can also be used to determine the number of seconds between two Time instances.
  # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
  # are coerced into values that Time#- will recognize
  def minus_with_coercion(other)
    other = other.comparable_time if other.respond_to?(:comparable_time)
    other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
  end
  alias_method :minus_without_coercion, :-
  alias_method :-, :minus_with_coercion

  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
  # can be chronologically compared with a Time
  def compare_with_coercion(other)
    # we're avoiding Time#to_datetime cause it's expensive
    if other.is_a?(Time)
      compare_without_coercion(other.to_time)
    else
      to_datetime <=> other
    end
  end
  alias_method :compare_without_coercion, :<=>
  alias_method :<=>, :compare_with_coercion

  # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
  # can be eql? to an equivalent Time
  def eql_with_coercion(other)
    # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
    other = other.comparable_time if other.respond_to?(:comparable_time)
    eql_without_coercion(other)
  end
  alias_method :eql_without_coercion, :eql?
  alias_method :eql?, :eql_with_coercion

end
require 'active_support/inflector/methods'
require 'active_support/values/time_zone'

class Time
  DATE_FORMATS = {
    :db           => '%Y-%m-%d %H:%M:%S',
    :number       => '%Y%m%d%H%M%S',
    :nsec         => '%Y%m%d%H%M%S%9N',
    :time         => '%H:%M',
    :short        => '%d %b %H:%M',
    :long         => '%B %d, %Y %H:%M',
    :long_ordinal => lambda { |time|
      day_format = ActiveSupport::Inflector.ordinalize(time.day)
      time.strftime("%B #{day_format}, %Y %H:%M")
    },
    :rfc822       => lambda { |time|
      offset_format = time.formatted_offset(false)
      time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
    }
  }

  # Converts to a formatted string. See DATE_FORMATS for builtin formats.
  #
  # This method is aliased to <tt>to_s</tt>.
  #
  #   time = Time.now                    # => Thu Jan 18 06:10:17 CST 2007
  #
  #   time.to_formatted_s(:time)         # => "06:10"
  #   time.to_s(:time)                   # => "06:10"
  #
  #   time.to_formatted_s(:db)           # => "2007-01-18 06:10:17"
  #   time.to_formatted_s(:number)       # => "20070118061017"
  #   time.to_formatted_s(:short)        # => "18 Jan 06:10"
  #   time.to_formatted_s(:long)         # => "January 18, 2007 06:10"
  #   time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
  #   time.to_formatted_s(:rfc822)       # => "Thu, 18 Jan 2007 06:10:17 -0600"
  #
  # == Adding your own time formats to +to_formatted_s+
  # You can add your own formats to the Time::DATE_FORMATS hash.
  # Use the format name as the hash key and either a strftime string
  # or Proc instance that takes a time argument as the value.
  #
  #   # config/initializers/time_formats.rb
  #   Time::DATE_FORMATS[:month_and_year] = '%B %Y'
  #   Time::DATE_FORMATS[:short_ordinal]  = ->(time) { time.strftime("%B #{time.day.ordinalize}") }
  def to_formatted_s(format = :default)
    if formatter = DATE_FORMATS[format]
      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
    else
      to_default_s
    end
  end
  alias_method :to_default_s, :to_s
  alias_method :to_s, :to_formatted_s

  # Returns the UTC offset as an +HH:MM formatted string.
  #
  #   Time.local(2000).formatted_offset        # => "-06:00"
  #   Time.local(2000).formatted_offset(false) # => "-0600"
  def formatted_offset(colon = true, alternate_utc_string = nil)
    utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
  end
end
require 'active_support/core_ext/infinite_comparable'

class Time
  include InfiniteComparable
end
# Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
# preserves utc_offset. Preserve zone also, even though it may not
# work in some edge cases.
if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
  class Time
    class << self
      alias_method :_load_without_zone, :_load
      def _load(marshaled_time)
        time = _load_without_zone(marshaled_time)
        time.instance_eval do
          if zone = defined?(@_zone) && remove_instance_variable('@_zone')
            ary = to_a
            ary[0] += subsec if ary[0] == sec
            ary[-1] = zone
            utc? ? Time.utc(*ary) : Time.local(*ary)
          else
            self
          end
        end
      end
    end

    alias_method :_dump_without_zone, :_dump
    def _dump(*args)
      obj = dup
      obj.instance_variable_set('@_zone', zone)
      obj.send :_dump_without_zone, *args
    end
  end
end
require 'active_support/time_with_zone'

class Time
  class << self
    attr_accessor :zone_default

    # Returns the TimeZone for the current request, if this has been set (via Time.zone=).
    # If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
    def zone
      Thread.current[:time_zone] || zone_default
    end

    # Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
    #
    # This method accepts any of the following:
    #
    # * A Rails TimeZone object.
    # * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
    # * A TZInfo::Timezone object.
    # * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
    #
    # Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
    # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
    #
    #   class ApplicationController < ActionController::Base
    #     around_filter :set_time_zone
    #
    #     def set_time_zone
    #       if logged_in?
    #         Time.use_zone(current_user.time_zone) { yield }
    #       else
    #         yield
    #       end
    #     end
    #   end
    def zone=(time_zone)
      Thread.current[:time_zone] = find_zone!(time_zone)
    end

    # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
    def use_zone(time_zone)
      new_zone = find_zone!(time_zone)
      begin
        old_zone, ::Time.zone = ::Time.zone, new_zone
        yield
      ensure
        ::Time.zone = old_zone
      end
    end

    # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
    def find_zone!(time_zone)
      if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
        time_zone
      else
        # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
        unless time_zone.respond_to?(:period_for_local)
          time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
        end

        # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
        if time_zone.is_a?(ActiveSupport::TimeZone)
          time_zone
        else
          ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
        end
      end
    rescue TZInfo::InvalidTimezoneIdentifier
      raise ArgumentError, "Invalid Timezone: #{time_zone}"
    end

    def find_zone(time_zone)
      find_zone!(time_zone) rescue nil
    end
  end

  # Returns the simultaneous time in <tt>Time.zone</tt>.
  #
  #   Time.zone = 'Hawaii'        # => 'Hawaii'
  #   Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
  #
  # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
  # instead of the operating system's time zone.
  #
  # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
  # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
  #
  #   Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
  def in_time_zone(zone = ::Time.zone)
    if zone
      ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
    else
      self
    end
  end
end
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/marshal'
require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/time/infinite_comparable'
# encoding: utf-8

require 'uri'
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
parser = URI::Parser.new

unless str == parser.unescape(parser.escape(str))
  URI::Parser.class_eval do
    remove_method :unescape
    def unescape(str, escaped = /%[a-fA-F\d]{2}/)
      # TODO: Are we actually sure that ASCII == UTF-8?
      # YK: My initial experiments say yes, but let's be sure please
      enc = str.encoding
      enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
      str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
    end
  end
end

module URI
  class << self
    def parser
      @parser ||= URI::Parser.new
    end
  end
end
Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].sort.each do |path|
  next if File.basename(path, '.rb') == 'logger'
  require "active_support/core_ext/#{File.basename(path, '.rb')}"
end
require "active_support/inflector/methods"

module ActiveSupport
  # Autoload and eager load conveniences for your library.
  #
  # This module allows you to define autoloads based on
  # Rails conventions (i.e. no need to define the path
  # it is automatically guessed based on the filename)
  # and also define a set of constants that needs to be
  # eager loaded:
  #
  #   module MyLib
  #     extend ActiveSupport::Autoload
  #
  #     autoload :Model
  #
  #     eager_autoload do
  #       autoload :Cache
  #     end
  #   end
  #
  # Then your library can be eager loaded by simply calling:
  #
  #   MyLib.eager_load!
  module Autoload
    def self.extended(base) # :nodoc:
      base.class_eval do
        @_autoloads = {}
        @_under_path = nil
        @_at_path = nil
        @_eager_autoload = false
      end
    end

    def autoload(const_name, path = @_at_path)
      unless path
        full = [name, @_under_path, const_name.to_s].compact.join("::")
        path = Inflector.underscore(full)
      end

      if @_eager_autoload
        @_autoloads[const_name] = path
      end

      super const_name, path
    end

    def autoload_under(path)
      @_under_path, old_path = path, @_under_path
      yield
    ensure
      @_under_path = old_path
    end

    def autoload_at(path)
      @_at_path, old_path = path, @_at_path
      yield
    ensure
      @_at_path = old_path
    end

    def eager_autoload
      old_eager, @_eager_autoload = @_eager_autoload, true
      yield
    ensure
      @_eager_autoload = old_eager
    end

    def eager_load!
      @_autoloads.values.each { |file| require file }
    end

    def autoloads
      @_autoloads
    end
  end
end
require 'set'
require 'thread'
require 'thread_safe'
require 'pathname'
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/introspection'
require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/module/qualified_const'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/load_error'
require 'active_support/core_ext/name_error'
require 'active_support/core_ext/string/starts_ends_with'
require 'active_support/inflector'

module ActiveSupport #:nodoc:
  module Dependencies #:nodoc:
    extend self

    # Should we turn on Ruby warnings on the first load of dependent files?
    mattr_accessor :warnings_on_first_load
    self.warnings_on_first_load = false

    # All files ever loaded.
    mattr_accessor :history
    self.history = Set.new

    # All files currently loaded.
    mattr_accessor :loaded
    self.loaded = Set.new

    # Should we load files or require them?
    mattr_accessor :mechanism
    self.mechanism = ENV['NO_RELOAD'] ? :require : :load

    # The set of directories from which we may automatically load files. Files
    # under these directories will be reloaded on each request in development mode,
    # unless the directory also appears in autoload_once_paths.
    mattr_accessor :autoload_paths
    self.autoload_paths = []

    # The set of directories from which automatically loaded constants are loaded
    # only once. All directories in this set must also be present in +autoload_paths+.
    mattr_accessor :autoload_once_paths
    self.autoload_once_paths = []

    # An array of qualified constant names that have been loaded. Adding a name
    # to this array will cause it to be unloaded the next time Dependencies are
    # cleared.
    mattr_accessor :autoloaded_constants
    self.autoloaded_constants = []

    # An array of constant names that need to be unloaded on every request. Used
    # to allow arbitrary constants to be marked for unloading.
    mattr_accessor :explicitly_unloadable_constants
    self.explicitly_unloadable_constants = []

    # The logger is used for generating information on the action run-time
    # (including benchmarking) if available. Can be set to nil for no logging.
    # Compatible with both Ruby's own Logger and Log4r loggers.
    mattr_accessor :logger

    # Set to +true+ to enable logging of const_missing and file loads.
    mattr_accessor :log_activity
    self.log_activity = false

    # The WatchStack keeps a stack of the modules being watched as files are
    # loaded. If a file in the process of being loaded (parent.rb) triggers the
    # load of another file (child.rb) the stack will ensure that child.rb
    # handles the new constants.
    #
    # If child.rb is being autoloaded, its constants will be added to
    # autoloaded_constants. If it was being `require`d, they will be discarded.
    #
    # This is handled by walking back up the watch stack and adding the constants
    # found by child.rb to the list of original constants in parent.rb.
    class WatchStack
      include Enumerable

      # @watching is a stack of lists of constants being watched. For instance,
      # if parent.rb is autoloaded, the stack will look like [[Object]]. If
      # parent.rb then requires namespace/child.rb, the stack will look like
      # [[Object], [Namespace]].

      def initialize
        @watching = []
        @stack = Hash.new { |h,k| h[k] = [] }
      end

      def each(&block)
        @stack.each(&block)
      end

      def watching?
        !@watching.empty?
      end

      # Returns a list of new constants found since the last call to
      # <tt>watch_namespaces</tt>.
      def new_constants
        constants = []

        # Grab the list of namespaces that we're looking for new constants under
        @watching.last.each do |namespace|
          # Retrieve the constants that were present under the namespace when watch_namespaces
          # was originally called
          original_constants = @stack[namespace].last

          mod = Inflector.constantize(namespace) if Dependencies.qualified_const_defined?(namespace)
          next unless mod.is_a?(Module)

          # Get a list of the constants that were added
          new_constants = mod.local_constants - original_constants

          # self[namespace] returns an Array of the constants that are being evaluated
          # for that namespace. For instance, if parent.rb requires child.rb, the first
          # element of self[Object] will be an Array of the constants that were present
          # before parent.rb was required. The second element will be an Array of the
          # constants that were present before child.rb was required.
          @stack[namespace].each do |namespace_constants|
            namespace_constants.concat(new_constants)
          end

          # Normalize the list of new constants, and add them to the list we will return
          new_constants.each do |suffix|
            constants << ([namespace, suffix] - ["Object"]).join("::")
          end
        end
        constants
      ensure
        # A call to new_constants is always called after a call to watch_namespaces
        pop_modules(@watching.pop)
      end

      # Add a set of modules to the watch stack, remembering the initial
      # constants.
      def watch_namespaces(namespaces)
        @watching << namespaces.map do |namespace|
          module_name = Dependencies.to_constant_name(namespace)
          original_constants = Dependencies.qualified_const_defined?(module_name) ?
            Inflector.constantize(module_name).local_constants : []

          @stack[module_name] << original_constants
          module_name
        end
      end

      private
      def pop_modules(modules)
        modules.each { |mod| @stack[mod].pop }
      end
    end

    # An internal stack used to record which constants are loaded by any block.
    mattr_accessor :constant_watch_stack
    self.constant_watch_stack = WatchStack.new

    # Module includes this module.
    module ModuleConstMissing #:nodoc:
      def self.append_features(base)
        base.class_eval do
          # Emulate #exclude via an ivar
          return if defined?(@_const_missing) && @_const_missing
          @_const_missing = instance_method(:const_missing)
          remove_method(:const_missing)
        end
        super
      end

      def self.exclude_from(base)
        base.class_eval do
          define_method :const_missing, @_const_missing
          @_const_missing = nil
        end
      end

      def const_missing(const_name)
        # The interpreter does not pass nesting information, and in the
        # case of anonymous modules we cannot even make the trade-off of
        # assuming their name reflects the nesting. Resort to Object as
        # the only meaningful guess we can make.
        from_mod = anonymous? ? ::Object : self
        Dependencies.load_missing_constant(from_mod, const_name)
      end

      def unloadable(const_desc = self)
        super(const_desc)
      end
    end

    # Object includes this module.
    module Loadable #:nodoc:
      def self.exclude_from(base)
        base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
      end

      def require_or_load(file_name)
        Dependencies.require_or_load(file_name)
      end

      def require_dependency(file_name, message = "No such file to load -- %s")
        unless file_name.is_a?(String)
          raise ArgumentError, "the file name must be a String -- you passed #{file_name.inspect}"
        end

        Dependencies.depend_on(file_name, message)
      end

      def load_dependency(file)
        if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
          Dependencies.new_constants_in(Object) { yield }
        else
          yield
        end
      rescue Exception => exception  # errors from loading file
        exception.blame_file! file
        raise
      end

      def load(file, wrap = false)
        result = false
        load_dependency(file) { result = super }
        result
      end

      def require(file)
        result = false
        load_dependency(file) { result = super }
        result
      end

      # Mark the given constant as unloadable. Unloadable constants are removed
      # each time dependencies are cleared.
      #
      # Note that marking a constant for unloading need only be done once. Setup
      # or init scripts may list each unloadable constant that may need unloading;
      # each constant will be removed for every subsequent clear, as opposed to
      # for the first clear.
      #
      # The provided constant descriptor may be a (non-anonymous) module or class,
      # or a qualified constant name as a string or symbol.
      #
      # Returns +true+ if the constant was not previously marked for unloading,
      # +false+ otherwise.
      def unloadable(const_desc)
        Dependencies.mark_for_unload const_desc
      end
    end

    # Exception file-blaming.
    module Blamable #:nodoc:
      def blame_file!(file)
        (@blamed_files ||= []).unshift file
      end

      def blamed_files
        @blamed_files ||= []
      end

      def describe_blame
        return nil if blamed_files.empty?
        "This error occurred while loading the following files:\n   #{blamed_files.join "\n   "}"
      end

      def copy_blame!(exc)
        @blamed_files = exc.blamed_files.clone
        self
      end
    end

    def hook!
      Object.class_eval { include Loadable }
      Module.class_eval { include ModuleConstMissing }
      Exception.class_eval { include Blamable }
    end

    def unhook!
      ModuleConstMissing.exclude_from(Module)
      Loadable.exclude_from(Object)
    end

    def load?
      mechanism == :load
    end

    def depend_on(file_name, message = "No such file to load -- %s.rb")
      path = search_for_file(file_name)
      require_or_load(path || file_name)
    rescue LoadError => load_error
      if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
        load_error.message.replace(message % file_name)
        load_error.copy_blame!(load_error)
      end
      raise
    end

    def clear
      log_call
      loaded.clear
      remove_unloadable_constants!
    end

    def require_or_load(file_name, const_path = nil)
      log_call file_name, const_path
      file_name = $` if file_name =~ /\.rb\z/
      expanded = File.expand_path(file_name)
      return if loaded.include?(expanded)

      # Record that we've seen this file *before* loading it to avoid an
      # infinite loop with mutual dependencies.
      loaded << expanded

      begin
        if load?
          log "loading #{file_name}"

          # Enable warnings if this file has not been loaded before and
          # warnings_on_first_load is set.
          load_args = ["#{file_name}.rb"]
          load_args << const_path unless const_path.nil?

          if !warnings_on_first_load or history.include?(expanded)
            result = load_file(*load_args)
          else
            enable_warnings { result = load_file(*load_args) }
          end
        else
          log "requiring #{file_name}"
          result = require file_name
        end
      rescue Exception
        loaded.delete expanded
        raise
      end

      # Record history *after* loading so first load gets warnings.
      history << expanded
      result
    end

    # Is the provided constant path defined?
    def qualified_const_defined?(path)
      Object.qualified_const_defined?(path.sub(/^::/, ''), false)
    end

    # Given +path+, a filesystem path to a ruby file, return an array of
    # constant paths which would cause Dependencies to attempt to load this
    # file.
    def loadable_constants_for_path(path, bases = autoload_paths)
      path = $` if path =~ /\.rb\z/
      expanded_path = File.expand_path(path)
      paths = []

      bases.each do |root|
        expanded_root = File.expand_path(root)
        next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path

        nesting = expanded_path[(expanded_root.size)..-1]
        nesting = nesting[1..-1] if nesting && nesting[0] == ?/
        next if nesting.blank?

        paths << nesting.camelize
      end

      paths.uniq!
      paths
    end

    # Search for a file in autoload_paths matching the provided suffix.
    def search_for_file(path_suffix)
      path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")

      autoload_paths.each do |root|
        path = File.join(root, path_suffix)
        return path if File.file? path
      end
      nil # Gee, I sure wish we had first_match ;-)
    end

    # Does the provided path_suffix correspond to an autoloadable module?
    # Instead of returning a boolean, the autoload base for this module is
    # returned.
    def autoloadable_module?(path_suffix)
      autoload_paths.each do |load_path|
        return load_path if File.directory? File.join(load_path, path_suffix)
      end
      nil
    end

    def load_once_path?(path)
      # to_s works around a ruby1.9 issue where #starts_with?(Pathname) will always return false
      autoload_once_paths.any? { |base| path.starts_with? base.to_s }
    end

    # Attempt to autoload the provided module name by searching for a directory
    # matching the expected path suffix. If found, the module is created and
    # assigned to +into+'s constants with the name +const_name+. Provided that
    # the directory was loaded from a reloadable base path, it is added to the
    # set of constants that are to be unloaded.
    def autoload_module!(into, const_name, qualified_name, path_suffix)
      return nil unless base_path = autoloadable_module?(path_suffix)
      mod = Module.new
      into.const_set const_name, mod
      autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
      mod
    end

    # Load the file at the provided path. +const_paths+ is a set of qualified
    # constant names. When loading the file, Dependencies will watch for the
    # addition of these constants. Each that is defined will be marked as
    # autoloaded, and will be removed when Dependencies.clear is next called.
    #
    # If the second parameter is left off, then Dependencies will construct a
    # set of names that the file at +path+ may define. See
    # +loadable_constants_for_path+ for more details.
    def load_file(path, const_paths = loadable_constants_for_path(path))
      log_call path, const_paths
      const_paths = [const_paths].compact unless const_paths.is_a? Array
      parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || :Object }

      result = nil
      newly_defined_paths = new_constants_in(*parent_paths) do
        result = Kernel.load path
      end

      autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
      autoloaded_constants.uniq!
      log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
      result
    end

    # Returns the constant path for the provided parent and constant name.
    def qualified_name_for(mod, name)
      mod_name = to_constant_name mod
      mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
    end

    # Load the constant named +const_name+ which is missing from +from_mod+. If
    # it is not possible to load the constant into from_mod, try its parent
    # module using +const_missing+.
    def load_missing_constant(from_mod, const_name)
      log_call from_mod, const_name

      unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
        raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
      end

      raise NameError, "#{from_mod} is not missing constant #{const_name}!" if from_mod.const_defined?(const_name, false)

      qualified_name = qualified_name_for from_mod, const_name
      path_suffix = qualified_name.underscore

      file_path = search_for_file(path_suffix)

      if file_path
        expanded = File.expand_path(file_path)
        expanded.sub!(/\.rb\z/, '')

        if loaded.include?(expanded)
          raise "Circular dependency detected while autoloading constant #{qualified_name}"
        else
          require_or_load(expanded)
          raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
          return from_mod.const_get(const_name)
        end
      elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
        return mod
      elsif (parent = from_mod.parent) && parent != from_mod &&
            ! from_mod.parents.any? { |p| p.const_defined?(const_name, false) }
        # If our parents do not have a constant named +const_name+ then we are free
        # to attempt to load upwards. If they do have such a constant, then this
        # const_missing must be due to from_mod::const_name, which should not
        # return constants from from_mod's parents.
        begin
          # Since Ruby does not pass the nesting at the point the unknown
          # constant triggered the callback we cannot fully emulate constant
          # name lookup and need to make a trade-off: we are going to assume
          # that the nesting in the body of Foo::Bar is [Foo::Bar, Foo] even
          # though it might not be. Counterexamples are
          #
          #   class Foo::Bar
          #     Module.nesting # => [Foo::Bar]
          #   end
          #
          # or
          #
          #   module M::N
          #     module S::T
          #       Module.nesting # => [S::T, M::N]
          #     end
          #   end
          #
          # for example.
          return parent.const_missing(const_name)
        rescue NameError => e
          raise unless e.missing_name? qualified_name_for(parent, const_name)
        end
      end

      raise NameError,
            "uninitialized constant #{qualified_name}",
            caller.reject { |l| l.starts_with? __FILE__ }
    end

    # Remove the constants that have been autoloaded, and those that have been
    # marked for unloading. Before each constant is removed a callback is sent
    # to its class/module if it implements +before_remove_const+.
    #
    # The callback implementation should be restricted to cleaning up caches, etc.
    # as the environment will be in an inconsistent state, e.g. other constants
    # may have already been unloaded and not accessible.
    def remove_unloadable_constants!
      autoloaded_constants.each { |const| remove_constant const }
      autoloaded_constants.clear
      Reference.clear!
      explicitly_unloadable_constants.each { |const| remove_constant const }
    end

    class ClassCache
      def initialize
        @store = ThreadSafe::Cache.new
      end

      def empty?
        @store.empty?
      end

      def key?(key)
        @store.key?(key)
      end

      def get(key)
        key = key.name if key.respond_to?(:name)
        @store[key] ||= Inflector.constantize(key)
      end
      alias :[] :get

      def safe_get(key)
        key = key.name if key.respond_to?(:name)
        @store[key] ||= Inflector.safe_constantize(key)
      end

      def store(klass)
        return self unless klass.respond_to?(:name)
        raise(ArgumentError, 'anonymous classes cannot be cached') if klass.name.empty?
        @store[klass.name] = klass
        self
      end

      def clear!
        @store.clear
      end
    end

    Reference = ClassCache.new

    # Store a reference to a class +klass+.
    def reference(klass)
      Reference.store klass
    end

    # Get the reference for class named +name+.
    # Raises an exception if referenced class does not exist.
    def constantize(name)
      Reference.get(name)
    end

    # Get the reference for class named +name+ if one exists.
    # Otherwise returns +nil+.
    def safe_constantize(name)
      Reference.safe_get(name)
    end

    # Determine if the given constant has been automatically loaded.
    def autoloaded?(desc)
      return false if desc.is_a?(Module) && desc.anonymous?
      name = to_constant_name desc
      return false unless qualified_const_defined? name
      return autoloaded_constants.include?(name)
    end

    # Will the provided constant descriptor be unloaded?
    def will_unload?(const_desc)
      autoloaded?(const_desc) ||
        explicitly_unloadable_constants.include?(to_constant_name(const_desc))
    end

    # Mark the provided constant name for unloading. This constant will be
    # unloaded on each request, not just the next one.
    def mark_for_unload(const_desc)
      name = to_constant_name const_desc
      if explicitly_unloadable_constants.include? name
        false
      else
        explicitly_unloadable_constants << name
        true
      end
    end

    # Run the provided block and detect the new constants that were loaded during
    # its execution. Constants may only be regarded as 'new' once -- so if the
    # block calls +new_constants_in+ again, then the constants defined within the
    # inner call will not be reported in this one.
    #
    # If the provided block does not run to completion, and instead raises an
    # exception, any new constants are regarded as being only partially defined
    # and will be removed immediately.
    def new_constants_in(*descs)
      log_call(*descs)

      constant_watch_stack.watch_namespaces(descs)
      aborting = true

      begin
        yield # Now yield to the code that is to define new constants.
        aborting = false
      ensure
        new_constants = constant_watch_stack.new_constants

        log "New constants: #{new_constants * ', '}"
        return new_constants unless aborting

        log "Error during loading, removing partially loaded constants "
        new_constants.each { |c| remove_constant(c) }.clear
      end

      []
    end

    # Convert the provided const desc to a qualified constant name (as a string).
    # A module, class, symbol, or string may be provided.
    def to_constant_name(desc) #:nodoc:
      case desc
        when String then desc.sub(/^::/, '')
        when Symbol then desc.to_s
        when Module
          desc.name.presence ||
            raise(ArgumentError, "Anonymous modules have no name to be referenced by")
        else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
      end
    end

    def remove_constant(const) #:nodoc:
      # Normalize ::Foo, ::Object::Foo, Object::Foo, Object::Object::Foo, etc. as Foo.
      normalized = const.to_s.sub(/\A::/, '')
      normalized.sub!(/\A(Object::)+/, '')

      constants = normalized.split('::')
      to_remove = constants.pop

      if constants.empty?
        parent = Object
      else
        # This method is robust to non-reachable constants.
        #
        # Non-reachable constants may be passed if some of the parents were
        # autoloaded and already removed. It is easier to do a sanity check
        # here than require the caller to be clever. We check the parent
        # rather than the very const argument because we do not want to
        # trigger Kernel#autoloads, see the comment below.
        parent_name = constants.join('::')
        return unless qualified_const_defined?(parent_name)
        parent = constantize(parent_name)
      end

      log "removing constant #{const}"

      # In an autoloaded user.rb like this
      #
      #   autoload :Foo, 'foo'
      #
      #   class User < ActiveRecord::Base
      #   end
      #
      # we correctly register "Foo" as being autoloaded. But if the app does
      # not use the "Foo" constant we need to be careful not to trigger
      # loading "foo.rb" ourselves. While #const_defined? and #const_get? do
      # require the file, #autoload? and #remove_const don't.
      #
      # We are going to remove the constant nonetheless ---which exists as
      # far as Ruby is concerned--- because if the user removes the macro
      # call from a class or module that were not autoloaded, as in the
      # example above with Object, accessing to that constant must err.
      unless parent.autoload?(to_remove)
        begin
          constantized = parent.const_get(to_remove, false)
        rescue NameError
          log "the constant #{const} is not reachable anymore, skipping"
          return
        else
          constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
        end
      end

      begin
        parent.instance_eval { remove_const to_remove }
      rescue NameError
        log "the constant #{const} is not reachable anymore, skipping"
      end
    end

    protected
      def log_call(*args)
        if log_activity?
          arg_str = args.collect { |arg| arg.inspect } * ', '
          /in `([a-z_\?\!]+)'/ =~ caller(1).first
          selector = $1 || '<unknown>'
          log "called #{selector}(#{arg_str})"
        end
      end

      def log(msg)
        logger.debug "Dependencies: #{msg}" if log_activity?
      end

      def log_activity?
        logger && log_activity
      end
  end
end

ActiveSupport::Dependencies.hook!
require "active_support/notifications"

module ActiveSupport
  class Deprecation
    # Default warning behaviors per Rails.env.
    DEFAULT_BEHAVIORS = {
      :stderr => Proc.new { |message, callstack|
        $stderr.puts(message)
        $stderr.puts callstack.join("\n  ") if debug
      },
      :log => Proc.new { |message, callstack|
        logger =
            if defined?(Rails) && Rails.logger
              Rails.logger
            else
              require 'active_support/logger'
              ActiveSupport::Logger.new($stderr)
            end
        logger.warn message
        logger.debug callstack.join("\n  ") if debug
      },
      :notify => Proc.new { |message, callstack|
        ActiveSupport::Notifications.instrument("deprecation.rails",
                                                :message => message, :callstack => callstack)
      },
      :silence => Proc.new { |message, callstack| }
    }

    module Behavior
      # Whether to print a backtrace along with the warning.
      attr_accessor :debug

      # Returns the current behavior or if one isn't set, defaults to +:stderr+.
      def behavior
        @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
      end

      # Sets the behavior to the specified value. Can be a single value, array,
      # or an object that responds to +call+.
      #
      # Available behaviors:
      #
      # [+stderr+]  Log all deprecation warnings to +$stderr+.
      # [+log+]     Log all deprecation warnings to +Rails.logger+.
      # [+notify+]  Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
      # [+silence+] Do nothing.
      #
      # Setting behaviors only affects deprecations that happen after boot time.
      # Deprecation warnings raised by gems are not affected by this setting
      # because they happen before Rails boots up.
      #
      #   ActiveSupport::Deprecation.behavior = :stderr
      #   ActiveSupport::Deprecation.behavior = [:stderr, :log]
      #   ActiveSupport::Deprecation.behavior = MyCustomHandler
      #   ActiveSupport::Deprecation.behavior = proc { |message, callstack|
      #     # custom stuff
      #   }
      def behavior=(behavior)
        @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
      end
    end
  end
end
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/module/delegation'

module ActiveSupport
  class Deprecation
    module InstanceDelegator # :nodoc:
      def self.included(base)
        base.extend(ClassMethods)
        base.public_class_method :new
      end

      module ClassMethods # :nodoc:
        def include(included_module)
          included_module.instance_methods.each { |m| method_added(m) }
          super
        end

        def method_added(method_name)
          singleton_class.delegate(method_name, to: :instance)
        end
      end
    end
  end
end
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/array/extract_options'

module ActiveSupport
  class Deprecation
    module MethodWrapper
      # Declare that a method has been deprecated.
      #
      #   module Fred
      #     extend self
      #
      #     def foo; end
      #     def bar; end
      #     def baz; end
      #   end
      #
      #   ActiveSupport::Deprecation.deprecate_methods(Fred, :foo, bar: :qux, baz: 'use Bar#baz instead')
      #   # => [:foo, :bar, :baz]
      #
      #   Fred.foo
      #   # => "DEPRECATION WARNING: foo is deprecated and will be removed from Rails 4.1."
      #
      #   Fred.bar
      #   # => "DEPRECATION WARNING: bar is deprecated and will be removed from Rails 4.1 (use qux instead)."
      #
      #   Fred.baz
      #   # => "DEPRECATION WARNING: baz is deprecated and will be removed from Rails 4.1 (use Bar#baz instead)."
      def deprecate_methods(target_module, *method_names)
        options = method_names.extract_options!
        deprecator = options.delete(:deprecator) || ActiveSupport::Deprecation.instance
        method_names += options.keys

        method_names.each do |method_name|
          target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
            target_module.send(:define_method, "#{target}_with_deprecation#{punctuation}") do |*args, &block|
              deprecator.deprecation_warning(method_name, options[method_name])
              send(:"#{target}_without_deprecation#{punctuation}", *args, &block)
            end
          end
        end
      end
    end
  end
end
require 'active_support/inflector/methods'

module ActiveSupport
  class Deprecation
    class DeprecationProxy #:nodoc:
      def self.new(*args, &block)
        object = args.first

        return object unless object
        super
      end

      instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ }

      # Don't give a deprecation warning on inspect since test/unit and error
      # logs rely on it for diagnostics.
      def inspect
        target.inspect
      end

      private
        def method_missing(called, *args, &block)
          warn caller, called, args
          target.__send__(called, *args, &block)
        end
    end

    # This DeprecatedObjectProxy transforms object to depracated object.
    #
    #   @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!")
    #   @old_object = DeprecatedObjectProxy.new(Object.new, "Don't use this object anymore!", deprecator_instance)
    #
    # When someone executes any method except +inspect+ on proxy object this will
    # trigger +warn+ method on +deprecator_instance+.
    #
    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>
    class DeprecatedObjectProxy < DeprecationProxy
      def initialize(object, message, deprecator = ActiveSupport::Deprecation.instance)
        @object = object
        @message = message
        @deprecator = deprecator
      end

      private
        def target
          @object
        end

        def warn(callstack, called, args)
          @deprecator.warn(@message, callstack)
        end
    end

    # This DeprecatedInstanceVariableProxy transforms instance variable to
    # depracated instance variable.
    #
    #   class Example
    #     def initialize(deprecator)
    #       @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator)
    #       @_request = :a_request
    #     end
    #
    #     def request
    #       @_request
    #     end
    #
    #     def old_request
    #       @request
    #     end
    #   end
    #
    # When someone execute any method on @request variable this will trigger
    # +warn+ method on +deprecator_instance+ and will fetch <tt>@_request</tt>
    # variable via +request+ method and execute the same method on non-proxy
    # instance variable.
    #
    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
    class DeprecatedInstanceVariableProxy < DeprecationProxy
      def initialize(instance, method, var = "@#{method}", deprecator = ActiveSupport::Deprecation.instance)
        @instance = instance
        @method = method
        @var = var
        @deprecator = deprecator
      end

      private
        def target
          @instance.__send__(@method)
        end

        def warn(callstack, called, args)
          @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
        end
    end

    # This DeprecatedConstantProxy transforms constant to depracated constant.
    #
    #   OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST')
    #   OLD_CONST = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OLD_CONST', 'NEW_CONST', deprecator_instance)
    #
    # When someone use old constant this will trigger +warn+ method on
    # +deprecator_instance+.
    #
    # Default deprecator is <tt>ActiveSupport::Deprecation</tt>.
    class DeprecatedConstantProxy < DeprecationProxy
      def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance)
        @old_const = old_const
        @new_const = new_const
        @deprecator = deprecator
      end

      def class
        target.class
      end

      private
        def target
          ActiveSupport::Inflector.constantize(@new_const.to_s)
        end

        def warn(callstack, called, args)
          @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
        end
    end
  end
end
module ActiveSupport
  class Deprecation
    module Reporting
      # Whether to print a message (silent mode)
      attr_accessor :silenced
      # Name of gem where method is deprecated
      attr_accessor :gem_name

      # Outputs a deprecation warning to the output configured by
      # <tt>ActiveSupport::Deprecation.behavior</tt>.
      #
      #   ActiveSupport::Deprecation.warn('something broke!')
      #   # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
      def warn(message = nil, callstack = nil)
        return if silenced

        callstack ||= caller(2)
        deprecation_message(callstack, message).tap do |m|
          behavior.each { |b| b.call(m, callstack) }
        end
      end

      # Silence deprecation warnings within the block.
      #
      #   ActiveSupport::Deprecation.warn('something broke!')
      #   # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
      #
      #   ActiveSupport::Deprecation.silence do
      #     ActiveSupport::Deprecation.warn('something broke!')
      #   end
      #   # => nil
      def silence
        old_silenced, @silenced = @silenced, true
        yield
      ensure
        @silenced = old_silenced
      end

      def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
        caller_backtrace ||= caller(2)
        deprecated_method_warning(deprecated_method_name, message).tap do |msg|
          warn(msg, caller_backtrace)
        end
      end

      private
        # Outputs a deprecation warning message
        #
        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name)
        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}"
        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name, :another_method)
        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)"
        #   ActiveSupport::Deprecation.deprecated_method_warning(:method_name, "Optional message")
        #   # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)"
        def deprecated_method_warning(method_name, message = nil)
          warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}"
          case message
            when Symbol then "#{warning} (use #{message} instead)"
            when String then "#{warning} (#{message})"
            else warning
          end
        end

        def deprecation_message(callstack, message = nil)
          message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
          message += '.' unless message =~ /\.$/
          "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
        end

        def deprecation_caller_message(callstack)
          file, line, method = extract_callstack(callstack)
          if file
            if line && method
              "(called from #{method} at #{file}:#{line})"
            else
              "(called from #{file}:#{line})"
            end
          end
        end

        def extract_callstack(callstack)
          rails_gem_root = File.expand_path("../../../../..", __FILE__) + "/"
          offending_line = callstack.find { |line| !line.start_with?(rails_gem_root) } || callstack.first
          if offending_line
            if md = offending_line.match(/^(.+?):(\d+)(?::in `(.*?)')?/)
              md.captures
            else
              offending_line
            end
          end
        end
    end
  end
end
require 'singleton'

module ActiveSupport
  # \Deprecation specifies the API used by Rails to deprecate methods, instance
  # variables, objects and constants.
  class Deprecation
    # active_support.rb sets an autoload for ActiveSupport::Deprecation.
    #
    # If these requires were at the top of the file the constant would not be
    # defined by the time their files were loaded. Since some of them reopen
    # ActiveSupport::Deprecation its autoload would be triggered, resulting in
    # a circular require warning for active_support/deprecation.rb.
    #
    # So, we define the constant first, and load dependencies later.
    require 'active_support/deprecation/instance_delegator'
    require 'active_support/deprecation/behaviors'
    require 'active_support/deprecation/reporting'
    require 'active_support/deprecation/method_wrappers'
    require 'active_support/deprecation/proxy_wrappers'
    require 'active_support/core_ext/module/deprecation'

    include Singleton
    include InstanceDelegator
    include Behavior
    include Reporting
    include MethodWrapper

    # The version the deprecated behavior will be removed, by default.
    attr_accessor :deprecation_horizon

    # It accepts two parameters on initialization. The first is an version of library
    # and the second is an library name
    #
    #   ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
    def initialize(deprecation_horizon = '4.1', gem_name = 'Rails')
      self.gem_name = gem_name
      self.deprecation_horizon = deprecation_horizon
      # By default, warnings are not silenced and debugging is off.
      self.silenced = false
      self.debug = false
    end
  end
end
module ActiveSupport
  # This module provides an internal implementation to track descendants
  # which is faster than iterating through ObjectSpace.
  module DescendantsTracker
    @@direct_descendants = {}

    class << self
      def direct_descendants(klass)
        @@direct_descendants[klass] || []
      end

      def descendants(klass)
        arr = []
        accumulate_descendants(klass, arr)
        arr
      end

      def clear
        if defined? ActiveSupport::Dependencies
          @@direct_descendants.each do |klass, descendants|
            if ActiveSupport::Dependencies.autoloaded?(klass)
              @@direct_descendants.delete(klass)
            else
              descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
            end
          end
        else
          @@direct_descendants.clear
        end
      end

      # This is the only method that is not thread safe, but is only ever called
      # during the eager loading phase.
      def store_inherited(klass, descendant)
        (@@direct_descendants[klass] ||= []) << descendant
      end

      private
      def accumulate_descendants(klass, acc)
        if direct_descendants = @@direct_descendants[klass]
          acc.concat(direct_descendants)
          direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) }
        end
      end
    end

    def inherited(base)
      DescendantsTracker.store_inherited(self, base)
      super
    end

    def direct_descendants
      DescendantsTracker.direct_descendants(self)
    end

    def descendants
      DescendantsTracker.descendants(self)
    end
  end
end
require 'active_support/proxy_object'
require 'active_support/core_ext/array/conversions'
require 'active_support/core_ext/object/acts_like'

module ActiveSupport
  # Provides accurate date and time measurements using Date#advance and
  # Time#advance, respectively. It mainly supports the methods on Numeric.
  #
  #   1.month.ago       # equivalent to Time.now.advance(months: -1)
  class Duration < ProxyObject
    attr_accessor :value, :parts

    def initialize(value, parts) #:nodoc:
      @value, @parts = value, parts
    end

    # Adds another Duration or a Numeric to this Duration. Numeric values
    # are treated as seconds.
    def +(other)
      if Duration === other
        Duration.new(value + other.value, @parts + other.parts)
      else
        Duration.new(value + other, @parts + [[:seconds, other]])
      end
    end

    # Subtracts another Duration or a Numeric from this Duration. Numeric
    # values are treated as seconds.
    def -(other)
      self + (-other)
    end

    def -@ #:nodoc:
      Duration.new(-value, parts.map { |type,number| [type, -number] })
    end

    def is_a?(klass) #:nodoc:
      Duration == klass || value.is_a?(klass)
    end
    alias :kind_of? :is_a?

    # Returns +true+ if +other+ is also a Duration instance with the
    # same +value+, or if <tt>other == value</tt>.
    def ==(other)
      if Duration === other
        other.value == value
      else
        other == value
      end
    end

    def self.===(other) #:nodoc:
      other.is_a?(Duration)
    rescue ::NoMethodError
      false
    end

    # Calculates a new Time or Date that is as far in the future
    # as this Duration represents.
    def since(time = ::Time.current)
      sum(1, time)
    end
    alias :from_now :since

    # Calculates a new Time or Date that is as far in the past
    # as this Duration represents.
    def ago(time = ::Time.current)
      sum(-1, time)
    end
    alias :until :ago

    def inspect #:nodoc:
      consolidated = parts.inject(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }
      parts = [:years, :months, :days, :minutes, :seconds].map do |length|
        n = consolidated[length]
        "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
      end.compact
      parts = ["0 seconds"] if parts.empty?
      parts.to_sentence(:locale => :en)
    end

    def as_json(options = nil) #:nodoc:
      to_i
    end

    protected

      def sum(sign, time = ::Time.current) #:nodoc:
        parts.inject(time) do |t,(type,number)|
          if t.acts_like?(:time) || t.acts_like?(:date)
            if type == :seconds
              t.since(sign * number)
            else
              t.advance(type => sign * number)
            end
          else
            raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
          end
        end
      end

    private

      def method_missing(method, *args, &block) #:nodoc:
        value.send(method, *args, &block)
      end
  end
end
module ActiveSupport
  # FileUpdateChecker specifies the API used by Rails to watch files
  # and control reloading. The API depends on four methods:
  #
  # * +initialize+ which expects two parameters and one block as
  #   described below.
  #
  # * +updated?+ which returns a boolean if there were updates in
  #   the filesystem or not.
  #
  # * +execute+ which executes the given block on initialization
  #   and updates the latest watched files and timestamp.
  #
  # * +execute_if_updated+ which just executes the block if it was updated.
  #
  # After initialization, a call to +execute_if_updated+ must execute
  # the block only if there was really a change in the filesystem.
  #
  # This class is used by Rails to reload the I18n framework whenever
  # they are changed upon a new request.
  #
  #   i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
  #     I18n.reload!
  #   end
  #
  #   ActionDispatch::Reloader.to_prepare do
  #     i18n_reloader.execute_if_updated
  #   end
  class FileUpdateChecker
    # It accepts two parameters on initialization. The first is an array
    # of files and the second is an optional hash of directories. The hash must
    # have directories as keys and the value is an array of extensions to be
    # watched under that directory.
    #
    # This method must also receive a block that will be called once a path
    # changes. The array of files and list of directories cannot be changed
    # after FileUpdateChecker has been initialized.
    def initialize(files, dirs={}, &block)
      @files = files.freeze
      @glob  = compile_glob(dirs)
      @block = block

      @watched    = nil
      @updated_at = nil

      @last_watched   = watched
      @last_update_at = updated_at(@last_watched)
    end

    # Check if any of the entries were updated. If so, the watched and/or
    # updated_at values are cached until the block is executed via +execute+
    # or +execute_if_updated+.
    def updated?
      current_watched = watched
      if @last_watched.size != current_watched.size
        @watched = current_watched
        true
      else
        current_updated_at = updated_at(current_watched)
        if @last_update_at < current_updated_at
          @watched    = current_watched
          @updated_at = current_updated_at
          true
        else
          false
        end
      end
    end

    # Executes the given block and updates the latest watched files and
    # timestamp.
    def execute
      @last_watched   = watched
      @last_update_at = updated_at(@last_watched)
      @block.call
    ensure
      @watched = nil
      @updated_at = nil
    end

    # Execute the block given if updated.
    def execute_if_updated
      if updated?
        execute
        true
      else
        false
      end
    end

    private

    def watched
      @watched || begin
        all = @files.select { |f| File.exists?(f) }
        all.concat(Dir[@glob]) if @glob
        all
      end
    end

    def updated_at(paths)
      @updated_at || max_mtime(paths) || Time.at(0)
    end

    # This method returns the maximum mtime of the files in +paths+, or +nil+
    # if the array is empty.
    #
    # Files with a mtime in the future are ignored. Such abnormal situation
    # can happen for example if the user changes the clock by hand. It is
    # healthy to consider this edge case because with mtimes in the future
    # reloading is not triggered.
    def max_mtime(paths)
      time_now = Time.now
      paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max
    end

    def compile_glob(hash)
      hash.freeze # Freeze so changes aren't accidently pushed
      return if hash.empty?

      globs = hash.map do |key, value|
        "#{escape(key)}/**/*#{compile_ext(value)}"
      end
      "{#{globs.join(",")}}"
    end

    def escape(key)
      key.gsub(',','\,')
    end

    def compile_ext(array)
      array = Array(array)
      return if array.empty?
      ".{#{array.join(",")}}"
    end
  end
end
module ActiveSupport
  class FileWatcher
    class Backend
      def initialize(path, watcher)
        @watcher = watcher
        @path    = path
      end

      def trigger(files)
        @watcher.trigger(files)
      end
    end

    def initialize
      @regex_matchers = {}
    end

    def watch(pattern, &block)
      @regex_matchers[pattern] = block
    end

    def trigger(files)
      trigger_files = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }

      files.each do |file, state|
        @regex_matchers.each do |pattern, block|
          trigger_files[block][state] << file if pattern === file
        end
      end

      trigger_files.each do |block, payload|
        block.call payload
      end
    end
  end
end
require 'zlib'
require 'stringio'

module ActiveSupport
  # A convenient wrapper for the zlib standard library that allows
  # compression/decompression of strings with gzip.
  #
  #   gzip = ActiveSupport::Gzip.compress('compress me!')
  #   # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
  #
  #   ActiveSupport::Gzip.decompress(gzip)
  #   # => "compress me!" 
  module Gzip
    class Stream < StringIO
      def initialize(*)
        super
        set_encoding "BINARY"
      end
      def close; rewind; end
    end

    # Decompresses a gzipped string.
    def self.decompress(source)
      Zlib::GzipReader.new(StringIO.new(source)).read
    end

    # Compresses a string using gzip.
    def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
      output = Stream.new
      gz = Zlib::GzipWriter.new(output, level, strategy)
      gz.write(source)
      gz.close
      output.string
    end
  end
end
require 'active_support/core_ext/hash/keys'

module ActiveSupport
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
  # to be the same.
  #
  #   rgb = ActiveSupport::HashWithIndifferentAccess.new
  #
  #   rgb[:black] = '#000000'
  #   rgb[:black]  # => '#000000'
  #   rgb['black'] # => '#000000'
  #
  #   rgb['white'] = '#FFFFFF'
  #   rgb[:white]  # => '#FFFFFF'
  #   rgb['white'] # => '#FFFFFF'
  #
  # Internally symbols are mapped to strings when used as keys in the entire
  # writing interface (calling <tt>[]=</tt>, <tt>merge</tt>, etc). This
  # mapping belongs to the public interface. For example, given:
  #
  #   hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
  #
  # You are guaranteed that the key is returned as a string:
  #
  #   hash.keys # => ["a"]
  #
  # Technically other types of keys are accepted:
  #
  #   hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
  #   hash[0] = 0
  #   hash # => {"a"=>1, 0=>0}
  #
  # but this class is intended for use cases where strings or symbols are the
  # expected keys and it is convenient to understand both as the same. For
  # example the +params+ hash in Ruby on Rails.
  #
  # Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
  #
  #   rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
  #
  # which may be handy.
  class HashWithIndifferentAccess < Hash
    # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
    # this class.
    def extractable_options?
      true
    end

    def with_indifferent_access
      dup
    end

    def nested_under_indifferent_access
      self
    end

    def initialize(constructor = {})
      if constructor.is_a?(Hash)
        super()
        update(constructor)
      else
        super(constructor)
      end
    end

    def default(key = nil)
      if key.is_a?(Symbol) && include?(key = key.to_s)
        self[key]
      else
        super
      end
    end

    def self.new_from_hash_copying_default(hash)
      new(hash).tap do |new_hash|
        new_hash.default = hash.default
      end
    end

    def self.[](*args)
      new.merge(Hash[*args])
    end

    alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
    alias_method :regular_update, :update unless method_defined?(:regular_update)

    # Assigns a new value to the hash:
    #
    #   hash = ActiveSupport::HashWithIndifferentAccess.new
    #   hash[:key] = 'value'
    #
    # This value can be later fetched using either +:key+ or +'key'+.
    def []=(key, value)
      regular_writer(convert_key(key), convert_value(value))
    end

    alias_method :store, :[]=

    # Updates the receiver in-place, merging in the hash passed as argument:
    #
    #   hash_1 = ActiveSupport::HashWithIndifferentAccess.new
    #   hash_1[:key] = 'value'
    #
    #   hash_2 = ActiveSupport::HashWithIndifferentAccess.new
    #   hash_2[:key] = 'New Value!'
    #
    #   hash_1.update(hash_2) # => {"key"=>"New Value!"}
    #
    # The argument can be either an
    # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
    # In either case the merge respects the semantics of indifferent access.
    #
    # If the argument is a regular hash with keys +:key+ and +"key"+ only one
    # of the values end up in the receiver, but which one is unspecified.
    #
    # When given a block, the value for duplicated keys will be determined
    # by the result of invoking the block with the duplicated key, the value
    # in the receiver, and the value in +other_hash+. The rules for duplicated
    # keys follow the semantics of indifferent access:
    #
    #   hash_1[:key] = 10
    #   hash_2['key'] = 12
    #   hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
    def update(other_hash)
      if other_hash.is_a? HashWithIndifferentAccess
        super(other_hash)
      else
        other_hash.each_pair do |key, value|
          if block_given? && key?(key)
            value = yield(convert_key(key), self[key], value)
          end
          regular_writer(convert_key(key), convert_value(value))
        end
        self
      end
    end

    alias_method :merge!, :update

    # Checks the hash for a key matching the argument passed in:
    #
    #   hash = ActiveSupport::HashWithIndifferentAccess.new
    #   hash['key'] = 'value'
    #   hash.key?(:key)  # => true
    #   hash.key?('key') # => true
    def key?(key)
      super(convert_key(key))
    end

    alias_method :include?, :key?
    alias_method :has_key?, :key?
    alias_method :member?, :key?

    # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
    # either a string or a symbol:
    #
    #   counters = ActiveSupport::HashWithIndifferentAccess.new
    #   counters[:foo] = 1
    #
    #   counters.fetch('foo')          # => 1
    #   counters.fetch(:bar, 0)        # => 0
    #   counters.fetch(:bar) {|key| 0} # => 0
    #   counters.fetch(:zoo)           # => KeyError: key not found: "zoo"
    def fetch(key, *extras)
      super(convert_key(key), *extras)
    end

    # Returns an array of the values at the specified indices:
    #
    #   hash = ActiveSupport::HashWithIndifferentAccess.new
    #   hash[:a] = 'x'
    #   hash[:b] = 'y'
    #   hash.values_at('a', 'b') # => ["x", "y"]
    def values_at(*indices)
      indices.collect {|key| self[convert_key(key)]}
    end

    # Returns an exact copy of the hash.
    def dup
      self.class.new(self).tap do |new_hash|
        new_hash.default = default
      end
    end

    # This method has the same semantics of +update+, except it does not
    # modify the receiver but rather returns a new hash with indifferent
    # access with the result of the merge.
    def merge(hash, &block)
      self.dup.update(hash, &block)
    end

    # Like +merge+ but the other way around: Merges the receiver into the
    # argument and returns a new hash with indifferent access as result:
    #
    #   hash = ActiveSupport::HashWithIndifferentAccess.new
    #   hash['a'] = nil
    #   hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
    def reverse_merge(other_hash)
      super(self.class.new_from_hash_copying_default(other_hash))
    end

    # Same semantics as +reverse_merge+ but modifies the receiver in-place.
    def reverse_merge!(other_hash)
      replace(reverse_merge( other_hash ))
    end

    # Replaces the contents of this hash with other_hash.
    #
    #   h = { "a" => 100, "b" => 200 }
    #   h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
    def replace(other_hash)
      super(self.class.new_from_hash_copying_default(other_hash))
    end

    # Removes the specified key from the hash.
    def delete(key)
      super(convert_key(key))
    end

    def stringify_keys!; self end
    def deep_stringify_keys!; self end
    def stringify_keys; dup end
    def deep_stringify_keys; dup end
    undef :symbolize_keys!
    undef :deep_symbolize_keys!
    def symbolize_keys; to_hash.symbolize_keys end
    def deep_symbolize_keys; to_hash.deep_symbolize_keys end
    def to_options!; self end

    # Convert to a regular hash with string keys.
    def to_hash
      Hash.new(default).merge!(self)
    end

    protected
      def convert_key(key)
        key.kind_of?(Symbol) ? key.to_s : key
      end

      def convert_value(value)
        if value.is_a? Hash
          value.nested_under_indifferent_access
        elsif value.is_a?(Array)
          value = value.dup if value.frozen?
          value.map! { |e| convert_value(e) }
        else
          value
        end
      end
  end
end

HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
begin
  require 'active_support/core_ext/hash/deep_merge'
  require 'active_support/core_ext/hash/except'
  require 'active_support/core_ext/hash/slice'
  require 'i18n'
  require 'active_support/lazy_load_hooks'
rescue LoadError => e
  $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
  raise e
end

ActiveSupport.run_load_hooks(:i18n)
I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
require "active_support"
require "active_support/file_update_checker"
require "active_support/core_ext/array/wrap"

module I18n
  class Railtie < Rails::Railtie
    config.i18n = ActiveSupport::OrderedOptions.new
    config.i18n.railties_load_path = []
    config.i18n.load_path = []
    config.i18n.fallbacks = ActiveSupport::OrderedOptions.new

    # Set the i18n configuration after initialization since a lot of
    # configuration is still usually done in application initializers.
    config.after_initialize do |app|
      I18n::Railtie.initialize_i18n(app)
    end

    # Trigger i18n config before any eager loading has happened
    # so it's ready if any classes require it when eager loaded.
    config.before_eager_load do |app|
      I18n::Railtie.initialize_i18n(app)
    end

  protected

    @i18n_inited = false

    # Setup i18n configuration.
    def self.initialize_i18n(app)
      return if @i18n_inited

      fallbacks = app.config.i18n.delete(:fallbacks)

      app.config.i18n.each do |setting, value|
        case setting
        when :railties_load_path
          app.config.i18n.load_path.unshift(*value)
        when :load_path
          I18n.load_path += value
        else
          I18n.send("#{setting}=", value)
        end
      end

      init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)

      reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
      app.reloaders << reloader
      ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
      reloader.execute

      @i18n_inited = true
    end

    def self.include_fallbacks_module
      I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
    end

    def self.init_fallbacks(fallbacks)
      include_fallbacks_module

      args = case fallbacks
      when ActiveSupport::OrderedOptions
        [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
      when Hash, Array
        Array.wrap(fallbacks)
      else # TrueClass
        []
      end

      I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
    end

    def self.validate_fallbacks(fallbacks)
      case fallbacks
      when ActiveSupport::OrderedOptions
        !fallbacks.empty?
      when TrueClass, Array, Hash
        true
      else
        raise "Unexpected fallback type #{fallbacks.inspect}"
      end
    end
  end
end
require 'active_support/inflector/inflections'

module ActiveSupport
  Inflector.inflections(:en) do |inflect|
    inflect.plural(/$/, 's')
    inflect.plural(/s$/i, 's')
    inflect.plural(/^(ax|test)is$/i, '\1es')
    inflect.plural(/(octop|vir)us$/i, '\1i')
    inflect.plural(/(octop|vir)i$/i, '\1i')
    inflect.plural(/(alias|status)$/i, '\1es')
    inflect.plural(/(bu)s$/i, '\1ses')
    inflect.plural(/(buffal|tomat)o$/i, '\1oes')
    inflect.plural(/([ti])um$/i, '\1a')
    inflect.plural(/([ti])a$/i, '\1a')
    inflect.plural(/sis$/i, 'ses')
    inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
    inflect.plural(/(hive)$/i, '\1s')
    inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
    inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
    inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
    inflect.plural(/^(m|l)ouse$/i, '\1ice')
    inflect.plural(/^(m|l)ice$/i, '\1ice')
    inflect.plural(/^(ox)$/i, '\1en')
    inflect.plural(/^(oxen)$/i, '\1')
    inflect.plural(/(quiz)$/i, '\1zes')

    inflect.singular(/s$/i, '')
    inflect.singular(/(ss)$/i, '\1')
    inflect.singular(/(n)ews$/i, '\1ews')
    inflect.singular(/([ti])a$/i, '\1um')
    inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis')
    inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
    inflect.singular(/([^f])ves$/i, '\1fe')
    inflect.singular(/(hive)s$/i, '\1')
    inflect.singular(/(tive)s$/i, '\1')
    inflect.singular(/([lr])ves$/i, '\1f')
    inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
    inflect.singular(/(s)eries$/i, '\1eries')
    inflect.singular(/(m)ovies$/i, '\1ovie')
    inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
    inflect.singular(/^(m|l)ice$/i, '\1ouse')
    inflect.singular(/(bus)(es)?$/i, '\1')
    inflect.singular(/(o)es$/i, '\1')
    inflect.singular(/(shoe)s$/i, '\1')
    inflect.singular(/(cris|test)(is|es)$/i, '\1is')
    inflect.singular(/^(a)x[ie]s$/i, '\1xis')
    inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
    inflect.singular(/(alias|status)(es)?$/i, '\1')
    inflect.singular(/^(ox)en/i, '\1')
    inflect.singular(/(vert|ind)ices$/i, '\1ex')
    inflect.singular(/(matr)ices$/i, '\1ix')
    inflect.singular(/(quiz)zes$/i, '\1')
    inflect.singular(/(database)s$/i, '\1')

    inflect.irregular('person', 'people')
    inflect.irregular('man', 'men')
    inflect.irregular('child', 'children')
    inflect.irregular('sex', 'sexes')
    inflect.irregular('move', 'moves')
    inflect.irregular('cow', 'kine')
    inflect.irregular('zombie', 'zombies')

    inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
  end
end
require 'thread_safe'
require 'active_support/core_ext/array/prepend_and_append'
require 'active_support/i18n'

module ActiveSupport
  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. If passed
    # an optional locale, rules for other languages can be specified. The
    # default locale is <tt>:en</tt>. Only rules for English are provided.
    #
    #   ActiveSupport::Inflector.inflections(:en) 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
      @__instance__ = ThreadSafe::Cache.new

      def self.instance(locale = :en)
        @__instance__[locale] ||= new
      end

      attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex

      def initialize
        @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
      end

      # Private, for the test suite.
      def initialize_dup(orig) # :nodoc:
        %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
          instance_variable_set("@#{scope}", orig.send(scope).dup)
        end
      end

      # Specifies a new acronym. An acronym must be specified as it will appear
      # in a camelized string. An underscore string that contains the acronym
      # will retain the acronym when passed to +camelize+, +humanize+, or
      # +titleize+. A camelized string that contains the acronym will maintain
      # the acronym when titleized or humanized, and will convert the acronym
      # into a non-delimited single lowercase word when passed to +underscore+.
      #
      #   acronym 'HTML'
      #   titleize 'html'     #=> 'HTML'
      #   camelize 'html'     #=> 'HTML'
      #   underscore 'MyHTML' #=> 'my_html'
      #
      # The acronym, however, must occur as a delimited unit and not be part of
      # another word for conversions to recognize it:
      #
      #   acronym 'HTTP'
      #   camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
      #   camelize 'https'             #=> 'Https', not 'HTTPs'
      #   underscore 'HTTPS'           #=> 'http_s', not 'https'
      #
      #   acronym 'HTTPS'
      #   camelize 'https'   #=> 'HTTPS'
      #   underscore 'HTTPS' #=> 'https'
      #
      # Note: Acronyms that are passed to +pluralize+ will no longer be
      # recognized, since the acronym will not occur as a delimited unit in the
      # pluralized result. To work around this, you must specify the pluralized
      # form as an acronym as well:
      #
      #    acronym 'API'
      #    camelize(pluralize('api')) #=> 'Apis'
      #
      #    acronym 'APIs'
      #    camelize(pluralize('api')) #=> 'APIs'
      #
      # +acronym+ may be used to specify any word that contains an acronym or
      # otherwise needs to maintain a non-standard capitalization. The only
      # restriction is that the word must begin with a capital letter.
      #
      #   acronym 'RESTful'
      #   underscore 'RESTful'           #=> 'restful'
      #   underscore 'RESTfulController' #=> 'restful_controller'
      #   titleize 'RESTfulController'   #=> 'RESTful Controller'
      #   camelize 'restful'             #=> 'RESTful'
      #   camelize 'restful_controller'  #=> 'RESTfulController'
      #
      #   acronym 'McDonald'
      #   underscore 'McDonald' #=> 'mcdonald'
      #   camelize 'mcdonald'   #=> 'McDonald'
      def acronym(word)
        @acronyms[word.downcase] = word
        @acronym_regex = /#{@acronyms.values.join("|")}/
      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.prepend([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.prepend([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.
      #
      #   irregular 'octopus', 'octopi'
      #   irregular 'person', 'people'
      def irregular(singular, plural)
        @uncountables.delete(singular)
        @uncountables.delete(plural)

        s0 = singular[0]
        srest = singular[1..-1]

        p0 = plural[0]
        prest = plural[1..-1]

        if s0.upcase == p0.upcase
          plural(/(#{s0})#{srest}$/i, '\1' + prest)
          plural(/(#{p0})#{prest}$/i, '\1' + prest)

          singular(/(#{s0})#{srest}$/i, '\1' + srest)
          singular(/(#{p0})#{prest}$/i, '\1' + srest)
        else
          plural(/#{s0.upcase}(?i)#{srest}$/,   p0.upcase   + prest)
          plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
          plural(/#{p0.upcase}(?i)#{prest}$/,   p0.upcase   + prest)
          plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)

          singular(/#{s0.upcase}(?i)#{srest}$/,   s0.upcase   + srest)
          singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
          singular(/#{p0.upcase}(?i)#{prest}$/,   s0.upcase   + srest)
          singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
        end
      end

      # Add uncountable words that shouldn't be attempted inflected.
      #
      #   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').
      #
      #   human /_cnt$/i, '\1_count'
      #   human 'legacy_col_person_name', 'Name'
      def human(rule, replacement)
        @humans.prepend([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>.
      #
      #   clear :all
      #   clear :plurals
      def clear(scope = :all)
        case scope
          when :all
            @plurals, @singulars, @uncountables, @humans = [], [], [], []
          else
            instance_variable_set "@#{scope}", []
        end
      end
    end

    # Yields a singleton instance of Inflector::Inflections so you can specify
    # additional inflector rules. If passed an optional locale, rules for other
    # languages can be specified. If not specified, defaults to <tt>:en</tt>.
    # Only rules for English are provided.
    #
    #   ActiveSupport::Inflector.inflections(:en) do |inflect|
    #     inflect.uncountable 'rails'
    #   end
    def inflections(locale = :en)
      if block_given?
        yield Inflections.instance(locale)
      else
        Inflections.instance(locale)
      end
    end
  end
end
# encoding: utf-8

require 'active_support/inflector/inflections'
require 'active_support/inflections'

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 or wish to define rules for languages other
  # than English, please correct or add them yourself (explained below).
  module Inflector
    extend self

    # Returns the plural form of the word in the string.
    #
    # If passed an optional +locale+ parameter, the word will be
    # pluralized using rules defined for that language. By default,
    # this parameter is set to <tt>:en</tt>.
    #
    #   'post'.pluralize             # => "posts"
    #   'octopus'.pluralize          # => "octopi"
    #   'sheep'.pluralize            # => "sheep"
    #   'words'.pluralize            # => "words"
    #   'CamelOctopus'.pluralize     # => "CamelOctopi"
    #   'ley'.pluralize(:es)         # => "leyes"
    def pluralize(word, locale = :en)
      apply_inflections(word, inflections(locale).plurals)
    end

    # The reverse of +pluralize+, returns the singular form of a word in a
    # string.
    #
    # If passed an optional +locale+ parameter, the word will be
    # pluralized using rules defined for that language. By default,
    # this parameter is set to <tt>:en</tt>.
    #
    #   'posts'.singularize            # => "post"
    #   'octopi'.singularize           # => "octopus"
    #   'sheep'.singularize            # => "sheep"
    #   'word'.singularize             # => "word"
    #   'CamelOctopi'.singularize      # => "CamelOctopus"
    #   'leyes'.singularize(:es)       # => "ley"
    def singularize(word, locale = :en)
      apply_inflections(word, inflections(locale).singulars)
    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.
    #
    #   'active_model'.camelize                # => "ActiveModel"
    #   'active_model'.camelize(:lower)        # => "activeModel"
    #   'active_model/errors'.camelize         # => "ActiveModel::Errors"
    #   'active_model/errors'.camelize(:lower) # => "activeModel::Errors"
    #
    # As a rule of thumb you can think of +camelize+ as the inverse of
    # +underscore+, though there are cases where that does not hold:
    #
    #   'SSLError'.underscore.camelize # => "SslError"
    def camelize(term, uppercase_first_letter = true)
      string = term.to_s
      if uppercase_first_letter
        string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
      else
        string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
      end
      string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
    end

    # Makes an underscored, lowercase form from the expression in the string.
    #
    # Changes '::' to '/' to convert namespaces to paths.
    #
    #   'ActiveModel'.underscore         # => "active_model"
    #   'ActiveModel::Errors'.underscore # => "active_model/errors"
    #
    # As a rule of thumb you can think of +underscore+ as the inverse of
    # +camelize+, though there are cases where that does not hold:
    #
    #   'SSLError'.underscore.camelize # => "SslError"
    def underscore(camel_cased_word)
      word = camel_cased_word.to_s.dup
      word.gsub!('::', '/')
      word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
      word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
      word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
      word.tr!("-", "_")
      word.downcase!
      word
    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.
    #
    #   'employee_salary'.humanize # => "Employee salary"
    #   'author_id'.humanize       # => "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.sub!(rule, replacement) }
      result.gsub!(/_id$/, "")
      result.tr!('_', ' ')
      result.gsub(/([a-z\d]*)/i) { |match|
        "#{inflections.acronyms[match] || match.downcase}"
      }.gsub(/^\w/) { $&.upcase }
    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 +titlecase+.
    #
    #   'man from the boondocks'.titleize   # => "Man From The Boondocks"
    #   'x-men: the last stand'.titleize    # => "X Men: The Last Stand"
    #   'TheManWithoutAPast'.titleize       # => "The Man Without A Past"
    #   'raiders_of_the_lost_ark'.titleize  # => "Raiders Of The Lost Ark"
    def titleize(word)
      humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.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.
    #
    #   '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+).
    #
    #   '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

    # Replaces underscores with dashes in the string.
    #
    #   'puni_puni'.dasherize # => "puni-puni"
    def dasherize(underscored_word)
      underscored_word.tr('_', '-')
    end

    # Removes the module part from the expression in the string.
    #
    #   'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
    #   'Inflections'.demodulize                                       # => "Inflections"
    #
    # See also +deconstantize+.
    def demodulize(path)
      path = path.to_s
      if i = path.rindex('::')
        path[(i+2)..-1]
      else
        path
      end
    end

    # Removes the rightmost segment from the constant expression in the string.
    #
    #   'Net::HTTP'.deconstantize   # => "Net"
    #   '::Net::HTTP'.deconstantize # => "::Net"
    #   'String'.deconstantize      # => ""
    #   '::String'.deconstantize    # => ""
    #   ''.deconstantize            # => ""
    #
    # See also +demodulize+.
    def deconstantize(path)
      path.to_s[0...(path.rindex('::') || 0)] # implementation based on the one in facets' Module#spacename
    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'.
    #
    #   '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

    # 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?

      names.inject(Object) do |constant, name|
        if constant == Object
          constant.const_get(name)
        else
          candidate = constant.const_get(name)
          next candidate if constant.const_defined?(name, false)
          next candidate unless Object.const_defined?(name)

          # Go down the ancestors to check it it's owned
          # directly before we reach Object or the end of ancestors.
          constant = constant.ancestors.inject do |const, ancestor|
            break const    if ancestor == Object
            break ancestor if ancestor.const_defined?(name, false)
            const
          end

          # owner is in Object, so raise
          constant.const_get(name, false)
        end
      end
    end

    # Tries to find a constant with the name specified in the argument string.
    #
    #   'Module'.safe_constantize     # => Module
    #   'Test::Unit'.safe_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'.safe_constantize # => 'outside', same as ::C
    #   end
    #
    # +nil+ is returned when the name is not in CamelCase or the constant (or
    # part of it) is unknown.
    #
    #   'blargle'.safe_constantize  # => nil
    #   'UnknownModule'.safe_constantize  # => nil
    #   'UnknownModule::Foo::Bar'.safe_constantize  # => nil
    def safe_constantize(camel_cased_word)
      constantize(camel_cased_word)
    rescue NameError => e
      raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
        e.name.to_s == camel_cased_word.to_s
    rescue ArgumentError => e
      raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
    end

    # Returns the suffix that should be added to a number to denote the position
    # in an ordered sequence such as 1st, 2nd, 3rd, 4th.
    #
    #   ordinal(1)     # => "st"
    #   ordinal(2)     # => "nd"
    #   ordinal(1002)  # => "nd"
    #   ordinal(1003)  # => "rd"
    #   ordinal(-11)   # => "th"
    #   ordinal(-1021) # => "st"
    def ordinal(number)
      abs_number = number.to_i.abs

      if (11..13).include?(abs_number % 100)
        "th"
      else
        case abs_number % 10
          when 1; "st"
          when 2; "nd"
          when 3; "rd"
          else    "th"
        end
      end
    end

    # Turns a number into an ordinal string used to denote the position in an
    # ordered sequence such as 1st, 2nd, 3rd, 4th.
    #
    #   ordinalize(1)     # => "1st"
    #   ordinalize(2)     # => "2nd"
    #   ordinalize(1002)  # => "1002nd"
    #   ordinalize(1003)  # => "1003rd"
    #   ordinalize(-11)   # => "-11th"
    #   ordinalize(-1021) # => "-1021st"
    def ordinalize(number)
      "#{number}#{ordinal(number)}"
    end

    private

    # Mount a regular expression that will match part by part of the constant.
    # For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)?
    def const_regexp(camel_cased_word) #:nodoc:
      parts = camel_cased_word.split("::")
      last  = parts.pop

      parts.reverse.inject(last) do |acc, part|
        part.empty? ? acc : "#{part}(::#{acc})?"
      end
    end

    # Applies inflection rules for +singularize+ and +pluralize+.
    #
    #  apply_inflections('post', inflections.plurals)    # => "posts"
    #  apply_inflections('posts', inflections.singulars) # => "post"
    def apply_inflections(word, rules)
      result = word.to_s.dup

      if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
        result
      else
        rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
        result
      end
    end
  end
end
# encoding: utf-8
require 'active_support/core_ext/string/multibyte'
require 'active_support/i18n'

module ActiveSupport
  module Inflector

    # Replaces non-ASCII characters with an ASCII approximation, or if none
    # exists, a replacement character which defaults to "?".
    #
    #    transliterate('Ærøskøbing')
    #    # => "AEroskobing"
    #
    # Default approximations are provided for Western/Latin characters,
    # e.g, "ø", "ñ", "é", "ß", etc.
    #
    # This method is I18n aware, so you can set up custom approximations for a
    # locale. This can be useful, for example, to transliterate German's "ü"
    # and "ö" to "ue" and "oe", or to add support for transliterating Russian
    # to ASCII.
    #
    # In order to make your custom transliterations available, you must set
    # them as the <tt>i18n.transliterate.rule</tt> i18n key:
    #
    #   # Store the transliterations in locales/de.yml
    #   i18n:
    #     transliterate:
    #       rule:
    #         ü: "ue"
    #         ö: "oe"
    #
    #   # Or set them using Ruby
    #   I18n.backend.store_translations(:de, i18n: {
    #     transliterate: {
    #       rule: {
    #         'ü' => 'ue',
    #         'ö' => 'oe'
    #       }
    #     }
    #   })
    #
    # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
    # maps characters to ASCII approximations as shown above, or, for more
    # complex requirements, a Proc:
    #
    #   I18n.backend.store_translations(:de, i18n: {
    #     transliterate: {
    #       rule: ->(string) { MyTransliterator.transliterate(string) }
    #     }
    #   })
    #
    # Now you can have different transliterations for each locale:
    #
    #   I18n.locale = :en
    #   transliterate('Jürgen')
    #   # => "Jurgen"
    #
    #   I18n.locale = :de
    #   transliterate('Jürgen')
    #   # => "Juergen"
    def transliterate(string, replacement = "?")
      I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
        ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
          :replacement => replacement)
    end

    # Replaces special characters in a string so that it may be used as part of
    # a 'pretty' URL.
    #
    #   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
# 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'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/delegation'
require 'multi_json'

module ActiveSupport
  # Look for and parse json strings that look like ISO 8601 times.
  mattr_accessor :parse_json_times

  module JSON
    class << self
      # Parses a JSON string (JavaScript Object Notation) into a hash.
      # See www.json.org for more info.
      #
      #   ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
      #   => {"team" => "rails", "players" => "36"}
      def decode(json, options ={})
        data = MultiJson.load(json, options)
        if ActiveSupport.parse_json_times
          convert_dates_from(data)
        else
          data
        end
      end

      def engine
        MultiJson.adapter
      end
      alias :backend :engine

      def engine=(name)
        MultiJson.use(name)
      end
      alias :backend= :engine=

      def with_backend(name)
        old_backend, self.backend = backend, name
        yield
      ensure
        self.backend = old_backend
      end

      # Returns the class of the error that will be raised when there is an
      # error in decoding JSON. Using this method means you won't directly
      # depend on the ActiveSupport's JSON implementation, in case it changes
      # in the future.
      #
      #   begin
      #     obj = ActiveSupport::JSON.decode(some_string)
      #   rescue ActiveSupport::JSON.parse_error
      #     Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
      #   end
      def parse_error
        MultiJson::DecodeError
      end

      private

      def convert_dates_from(data)
        case data
        when nil
          nil
        when DATE_REGEX
          begin
            DateTime.parse(data)
          rescue ArgumentError
            data
          end
        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
  end
end
require 'active_support/core_ext/object/to_json'
require 'active_support/core_ext/module/delegation'
require 'active_support/json/variable'

require 'bigdecimal'
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/instance_variables'
require 'time'
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/date_time/conversions'
require 'active_support/core_ext/date/conversions'
require 'set'

module ActiveSupport
  class << self
    delegate :use_standard_json_time_format, :use_standard_json_time_format=,
      :escape_html_entities_in_json, :escape_html_entities_in_json=,
      :encode_big_decimal_as_string, :encode_big_decimal_as_string=,
      :to => :'ActiveSupport::JSON::Encoding'
  end

  module JSON
    # matches YAML-formatted dates
    DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/

    # Dumps objects in JSON (JavaScript Object Notation).
    # See www.json.org for more info.
    #
    #   ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
    #   # => "{\"team\":\"rails\",\"players\":\"36\"}"
    def self.encode(value, options = nil)
      Encoding::Encoder.new(options).encode(value)
    end

    module Encoding #:nodoc:
      class CircularReferenceError < StandardError; end

      class Encoder
        attr_reader :options

        def initialize(options = nil)
          @options = options || {}
          @seen = Set.new
        end

        def encode(value, use_options = true)
          check_for_circular_references(value) do
            jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
            jsonified.encode_json(self)
          end
        end

        # like encode, but only calls as_json, without encoding to string.
        def as_json(value, use_options = true)
          check_for_circular_references(value) do
            use_options ? value.as_json(options_for(value)) : value.as_json
          end
        end

        def options_for(value)
          if value.is_a?(Array) || value.is_a?(Hash)
            # hashes and arrays need to get encoder in the options, so that
            # they can detect circular references.
            options.merge(:encoder => self)
          else
            options.dup
          end
        end

        def escape(string)
          Encoding.escape(string)
        end

        private
          def check_for_circular_references(value)
            unless @seen.add?(value.__id__)
              raise CircularReferenceError, 'object references itself'
            end
            yield
          ensure
            @seen.delete(value.__id__)
          end
      end


      ESCAPED_CHARS = {
        "\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002',
        "\x03" => '\u0003', "\x04" => '\u0004', "\x05" => '\u0005',
        "\x06" => '\u0006', "\x07" => '\u0007', "\x0B" => '\u000B',
        "\x0E" => '\u000E', "\x0F" => '\u000F', "\x10" => '\u0010',
        "\x11" => '\u0011', "\x12" => '\u0012', "\x13" => '\u0013',
        "\x14" => '\u0014', "\x15" => '\u0015', "\x16" => '\u0016',
        "\x17" => '\u0017', "\x18" => '\u0018', "\x19" => '\u0019',
        "\x1A" => '\u001A', "\x1B" => '\u001B', "\x1C" => '\u001C',
        "\x1D" => '\u001D', "\x1E" => '\u001E', "\x1F" => '\u001F',
        "\010" =>  '\b',
        "\f"   =>  '\f',
        "\n"   =>  '\n',
        "\r"   =>  '\r',
        "\t"   =>  '\t',
        '"'    =>  '\"',
        '\\'   =>  '\\\\',
        '>'    =>  '\u003E',
        '<'    =>  '\u003C',
        '&'    =>  '\u0026' }

      class << self
        # If true, use ISO 8601 format for dates and times. Otherwise, fall back
        # to the Active Support legacy format.
        attr_accessor :use_standard_json_time_format

        # If false, serializes BigDecimal objects as numeric instead of wrapping
        # them in a string.
        attr_accessor :encode_big_decimal_as_string

        attr_accessor :escape_regex
        attr_reader :escape_html_entities_in_json

        def escape_html_entities_in_json=(value)
          self.escape_regex = \
            if @escape_html_entities_in_json = value
              /[\x00-\x1F"\\><&]/
            else
              /[\x00-\x1F"\\]/
            end
        end

        def escape(string)
          string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
          json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
          json = %("#{json}")
          json.force_encoding(::Encoding::UTF_8)
          json
        end
      end

      self.use_standard_json_time_format = true
      self.escape_html_entities_in_json  = true
      self.encode_big_decimal_as_string  = true
    end
  end
end

class Object
  def as_json(options = nil) #:nodoc:
    if respond_to?(:to_hash)
      to_hash
    else
      instance_values
    end
  end
end

class Struct #:nodoc:
  def as_json(options = nil)
    Hash[members.zip(values)]
  end
end

class TrueClass
  def as_json(options = nil) #:nodoc:
    self
  end

  def encode_json(encoder) #:nodoc:
    to_s
  end
end

class FalseClass
  def as_json(options = nil) #:nodoc:
    self
  end

  def encode_json(encoder) #:nodoc:
    to_s
  end
end

class NilClass
  def as_json(options = nil) #:nodoc:
    self
  end

  def encode_json(encoder) #:nodoc:
    'null'
  end
end

class String
  def as_json(options = nil) #:nodoc:
    self
  end

  def encode_json(encoder) #:nodoc:
    encoder.escape(self)
  end
end

class Symbol
  def as_json(options = nil) #:nodoc:
    to_s
  end
end

class Numeric
  def as_json(options = nil) #:nodoc:
    self
  end

  def encode_json(encoder) #:nodoc:
    to_s
  end
end

class Float
  # Encoding Infinity or NaN to JSON should return "null". The default returns
  # "Infinity" or "NaN" which breaks parsing the JSON. E.g. JSON.parse('[NaN]').
  def as_json(options = nil) #:nodoc:
    finite? ? self : nil
  end
end

class BigDecimal
  # A BigDecimal would be naturally represented as a JSON number. Most libraries,
  # however, parse non-integer JSON numbers directly as floats. Clients using
  # those libraries would get in general a wrong number and no way to recover
  # other than manually inspecting the string with the JSON code itself.
  #
  # That's why a JSON string is returned. The JSON literal is not numeric, but
  # if the other end knows by contract that the data is supposed to be a
  # BigDecimal, it still has the chance to post-process the string and get the
  # real value.
  #
  # Use <tt>ActiveSupport.use_standard_json_big_decimal_format = true</tt> to
  # override this behavior.
  def as_json(options = nil) #:nodoc:
    if finite?
      ActiveSupport.encode_big_decimal_as_string ? to_s : self
    else
      nil
    end
  end
end

class Regexp
  def as_json(options = nil) #:nodoc:
    to_s
  end
end

module Enumerable
  def as_json(options = nil) #:nodoc:
    to_a.as_json(options)
  end
end

class Range
  def as_json(options = nil) #:nodoc:
    to_s
  end
end

class Array
  def as_json(options = nil) #:nodoc:
    # use encoder as a proxy to call as_json on all elements, to protect from circular references
    encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
    map { |v| encoder.as_json(v, options) }
  end

  def encode_json(encoder) #:nodoc:
    # we assume here that the encoder has already run as_json on self and the elements, so we run encode_json directly
    "[#{map { |v| v.encode_json(encoder) } * ','}]"
  end
end

class Hash
  def as_json(options = nil) #:nodoc:
    # create a subset of the hash by applying :only or :except
    subset = if options
      if attrs = options[:only]
        slice(*Array(attrs))
      elsif attrs = options[:except]
        except(*Array(attrs))
      else
        self
      end
    else
      self
    end

    # use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
    encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
    Hash[subset.map { |k, v| [k.to_s, encoder.as_json(v, options)] }]
  end

  def encode_json(encoder) #:nodoc:
    # values are encoded with use_options = false, because we don't want hash representations from ActiveModel to be
    # processed once again with as_json with options, as this could cause unexpected results (i.e. missing fields);

    # on the other hand, we need to run as_json on the elements, because the model representation may contain fields
    # like Time/Date in their original (not jsonified) form, etc.

    "{#{map { |k,v| "#{encoder.encode(k.to_s)}:#{encoder.encode(v, false)}" } * ','}}"
  end
end

class Time
  def as_json(options = nil) #:nodoc:
    if ActiveSupport.use_standard_json_time_format
      xmlschema
    else
      %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
    end
  end
end

class Date
  def as_json(options = nil) #:nodoc:
    if ActiveSupport.use_standard_json_time_format
      strftime("%Y-%m-%d")
    else
      strftime("%Y/%m/%d")
    end
  end
end

class DateTime
  def as_json(options = nil) #:nodoc:
    if ActiveSupport.use_standard_json_time_format
      xmlschema
    else
      strftime('%Y/%m/%d %H:%M:%S %z')
    end
  end
end
require 'active_support/deprecation'

module ActiveSupport
  module JSON
    # Deprecated: A string that returns itself as its JSON-encoded form.
    class Variable < String
      def initialize(*args)
        message = 'ActiveSupport::JSON::Variable is deprecated and will be removed in Rails 4.1. ' \
                  'For your own custom JSON literals, define #as_json and #encode_json yourself.'
        ActiveSupport::Deprecation.warn message
        super
      end

      def as_json(options = nil) self end #:nodoc:
      def encode_json(encoder) self end #:nodoc:
    end
  end
end
require 'active_support/json/decoding'
require 'active_support/json/encoding'
require 'thread_safe'
require 'openssl'

module ActiveSupport
  # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
  # It can be used to derive a number of keys for various purposes from a given secret.
  # This lets rails applications have a single secure secret, but avoid reusing that
  # key in multiple incompatible contexts.
  class KeyGenerator
    def initialize(secret, options = {})
      @secret = secret
      # The default iterations are higher than required for our key derivation uses
      # on the off chance someone uses this for password storage
      @iterations = options[:iterations] || 2**16
    end

    # Returns a derived key suitable for use.  The default key_size is chosen
    # to be compatible with the default settings of ActiveSupport::MessageVerifier.
    # i.e. OpenSSL::Digest::SHA1#block_length
    def generate_key(salt, key_size=64)
      OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
    end
  end

  # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
  # re-executing the key generation process when it's called using the same salt and
  # key_size
  class CachingKeyGenerator
    def initialize(key_generator)
      @key_generator = key_generator
      @cache_keys = ThreadSafe::Cache.new
    end

    # Returns a derived key suitable for use.  The default key_size is chosen
    # to be compatible with the default settings of ActiveSupport::MessageVerifier.
    # i.e. OpenSSL::Digest::SHA1#block_length
    def generate_key(salt, key_size=64)
      @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
    end
  end

  class DummyKeyGenerator # :nodoc:
    SECRET_MIN_LENGTH = 30 # Characters

    def initialize(secret)
      ensure_secret_secure(secret)
      @secret = secret
    end

    def generate_key(salt)
      @secret
    end

    private

    # To prevent users from using something insecure like "Password" we make sure that the
    # secret they've provided is at least 30 characters in length.
    def ensure_secret_secure(secret)
      if secret.blank?
        raise ArgumentError, "A secret is required to generate an " +
          "integrity hash for cookie session data. Use " +
          "config.secret_key_base = \"some secret phrase of at " +
          "least #{SECRET_MIN_LENGTH} characters\"" +
          "in config/initializers/secret_token.rb"
      end

      if secret.length < SECRET_MIN_LENGTH
        raise ArgumentError, "Secret should be something secure, " +
          "like \"#{SecureRandom.hex(16)}\". The value you " +
          "provided, \"#{secret}\", is shorter than the minimum length " +
          "of #{SECRET_MIN_LENGTH} characters"
      end
    end
  end
end
module ActiveSupport
  # lazy_load_hooks allows rails to lazily load a lot of components and thus
  # making the app boot faster. Because of this feature now there is no need to
  # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
  # configuration. Instead a hook is registered that applies configuration once
  # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
  # used as example but this feature can be applied elsewhere too.
  #
  # Here is an example where +on_load+ method is called to register a hook.
  #
  #   initializer 'active_record.initialize_timezone' do
  #     ActiveSupport.on_load(:active_record) do
  #       self.time_zone_aware_attributes = true
  #       self.default_timezone = :utc
  #     end
  #   end
  #
  # When the entirety of +activerecord/lib/active_record/base.rb+ has been
  # evaluated then +run_load_hooks+ is invoked. The very last line of
  # +activerecord/lib/active_record/base.rb+ is:
  #
  #   ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
  @load_hooks = Hash.new { |h,k| h[k] = [] }
  @loaded = Hash.new { |h,k| h[k] = [] }

  def self.on_load(name, options = {}, &block)
    @loaded[name].each do |base|
      execute_hook(base, options, block)
    end

    @load_hooks[name] << [block, options]
  end

  def self.execute_hook(base, options, block)
    if options[:yield]
      block.call(base)
    else
      base.instance_eval(&block)
    end
  end

  def self.run_load_hooks(name, base = Object)
    @loaded[name] << base
    @load_hooks[name].each do |hook, options|
      execute_hook(base, options, hook)
    end
  end
end
require 'active_support/log_subscriber'
require 'active_support/buffered_logger'
require 'active_support/notifications'

module ActiveSupport
  class LogSubscriber
    # Provides some helpers to deal with testing log subscribers by setting up
    # notifications. Take for instance Active Record subscriber tests:
    #
    #   class SyncLogSubscriberTest < ActiveSupport::TestCase
    #     include ActiveSupport::LogSubscriber::TestHelper
    #
    #     def setup
    #       ActiveRecord::LogSubscriber.attach_to(:active_record)
    #     end
    #
    #     def test_basic_query_logging
    #       Developer.all.to_a
    #       wait
    #       assert_equal 1, @logger.logged(:debug).size
    #       assert_match(/Developer Load/, @logger.logged(:debug).last)
    #       assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last)
    #     end
    #   end
    #
    # All you need to do is to ensure that your log subscriber is added to
    # Rails::Subscriber, as in the second line of the code above. The test
    # helpers are responsible for setting up the queue, subscriptions and
    # turning colors in logs off.
    #
    # The messages are available in the @logger instance, which is a logger with
    # limited powers (it actually does not send anything to your output), and
    # you can collect them doing @logger.logged(level), where level is the level
    # used in logging, like info, debug, warn and so on.
    module TestHelper
      def setup
        @logger   = MockLogger.new
        @notifier = ActiveSupport::Notifications::Fanout.new

        ActiveSupport::LogSubscriber.colorize_logging = false

        @old_notifier = ActiveSupport::Notifications.notifier
        set_logger(@logger)
        ActiveSupport::Notifications.notifier = @notifier
      end

      def teardown
        set_logger(nil)
        ActiveSupport::Notifications.notifier = @old_notifier
      end

      class MockLogger
        include ActiveSupport::Logger::Severity

        attr_reader :flush_count
        attr_accessor :level

        def initialize(level = DEBUG)
          @flush_count = 0
          @level = level
          @logged = Hash.new { |h,k| h[k] = [] }
        end

        def method_missing(level, message = nil)
           if block_given?
             @logged[level] << yield
           else
             @logged[level] << message
           end
        end

        def logged(level)
          @logged[level].compact.map { |l| l.to_s.strip }
        end

        def flush
          @flush_count += 1
        end

        ActiveSupport::Logger::Severity.constants.each do |severity|
          class_eval <<-EOT, __FILE__, __LINE__ + 1
            def #{severity.downcase}?
              #{severity} >= @level
            end
          EOT
        end
      end

      # Wait notifications to be published.
      def wait
        @notifier.wait
      end

      # Overwrite if you use another logger in your log subscriber.
      #
      #   def logger
      #     ActiveRecord::Base.logger = @logger
      #   end
      def set_logger(logger)
        ActiveSupport::LogSubscriber.logger = logger
      end
    end
  end
end
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/class/attribute'

module ActiveSupport
  # ActiveSupport::LogSubscriber is an object set to consume
  # ActiveSupport::Notifications with the sole purpose of logging them.
  # The log subscriber dispatches notifications to a registered object based
  # on its given namespace.
  #
  # An example would be Active Record log subscriber responsible for logging
  # queries:
  #
  #   module ActiveRecord
  #     class LogSubscriber < ActiveSupport::LogSubscriber
  #       def sql(event)
  #         "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
  #       end
  #     end
  #   end
  #
  # And it's finally registered as:
  #
  #   ActiveRecord::LogSubscriber.attach_to :active_record
  #
  # Since we need to know all instance methods before attaching the log
  # subscriber, the line above should be called after your
  # <tt>ActiveRecord::LogSubscriber</tt> definition.
  #
  # After configured, whenever a "sql.active_record" notification is published,
  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
  # the sql method.
  #
  # Log subscriber also has some helpers to deal with logging and automatically
  # flushes all logs when the request finishes (via action_dispatch.callback
  # notification) in a Rails environment.
  class LogSubscriber
    # Embed in a String to clear all previous ANSI sequences.
    CLEAR   = "\e[0m"
    BOLD    = "\e[1m"

    # Colors
    BLACK   = "\e[30m"
    RED     = "\e[31m"
    GREEN   = "\e[32m"
    YELLOW  = "\e[33m"
    BLUE    = "\e[34m"
    MAGENTA = "\e[35m"
    CYAN    = "\e[36m"
    WHITE   = "\e[37m"

    mattr_accessor :colorize_logging
    self.colorize_logging = true

    class << self
      def logger
        if defined?(Rails) && Rails.respond_to?(:logger)
          @logger ||= Rails.logger
        end
        @logger
      end

      attr_writer :logger

      def attach_to(namespace, log_subscriber=new, notifier=ActiveSupport::Notifications)
        log_subscribers << log_subscriber

        log_subscriber.public_methods(false).each do |event|
          next if %w{ start finish }.include?(event.to_s)

          notifier.subscribe("#{event}.#{namespace}", log_subscriber)
        end
      end

      def log_subscribers
        @@log_subscribers ||= []
      end

      # Flush all log_subscribers' logger.
      def flush_all!
        logger.flush if logger.respond_to?(:flush)
      end
    end

    def initialize
      @queue_key = [self.class.name, object_id].join  "-"
      super
    end

    def logger
      LogSubscriber.logger
    end

    def start(name, id, payload)
      return unless logger

      e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
      parent = event_stack.last
      parent << e if parent

      event_stack.push e
    end

    def finish(name, id, payload)
      return unless logger

      finished  = Time.now
      event     = event_stack.pop
      event.end = finished
      event.payload.merge!(payload)

      method = name.split('.').first
      begin
        send(method, event)
      rescue Exception => e
        logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
      end
    end

  protected

    %w(info debug warn error fatal unknown).each do |level|
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{level}(progname = nil, &block)
          logger.#{level}(progname, &block) if logger
        end
      METHOD
    end

    # Set color by using a string or one of the defined constants. If a third
    # option is set to +true+, it also adds bold to the string. This is based
    # on the Highline implementation and will automatically append CLEAR to the
    # end of the returned String.
    def color(text, color, bold=false)
      return text unless colorize_logging
      color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
      bold  = bold ? BOLD : ""
      "#{bold}#{color}#{text}#{CLEAR}"
    end

    private

    def event_stack
      Thread.current[@queue_key] ||= []
    end
  end
end
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/logger_silence'
require 'logger'

module ActiveSupport
  class Logger < ::Logger
    include LoggerSilence

    # Broadcasts logs to multiple loggers.
    def self.broadcast(logger) # :nodoc:
      Module.new do
        define_method(:add) do |*args, &block|
          logger.add(*args, &block)
          super(*args, &block)
        end

        define_method(:<<) do |x|
          logger << x
          super(x)
        end

        define_method(:close) do
          logger.close
          super()
        end

        define_method(:progname=) do |name|
          logger.progname = name
          super(name)
        end

        define_method(:formatter=) do |formatter|
          logger.formatter = formatter
          super(formatter)
        end

        define_method(:level=) do |level|
          logger.level = level
          super(level)
        end
      end
    end

    def initialize(*args)
      super
      @formatter = SimpleFormatter.new
    end

    # Simple formatter which only displays the message.
    class SimpleFormatter < ::Logger::Formatter
      # This method is invoked when a log event occurs
      def call(severity, timestamp, progname, msg)
        "#{String === msg ? msg : msg.inspect}\n"
      end
    end
  end
end
require 'active_support/concern'

module LoggerSilence
  extend ActiveSupport::Concern
  
  included do
    cattr_accessor :silencer
    self.silencer = true
  end

  # Silences the logger for the duration of the block.
  def silence(temporary_level = Logger::ERROR)
    if silencer
      begin
        old_logger_level, self.level = level, temporary_level
        yield self
      ensure
        self.level = old_logger_level
      end
    else
      yield self
    end
  end
endrequire 'openssl'
require 'base64'
require 'active_support/core_ext/array/extract_options'

module ActiveSupport
  # MessageEncryptor is a simple way to encrypt values which get stored
  # somewhere you don't trust.
  #
  # The cipher text and initialization vector are base64 encoded and returned
  # to you.
  #
  # This can be used in situations similar to the <tt>MessageVerifier</tt>, but
  # where you don't want users to be able to determine the value of the payload.
  #
  #   key = OpenSSL::Digest::SHA256.new('password').digest        # => "\x89\xE0\x156\xAC..."
  #   crypt = ActiveSupport::MessageEncryptor.new(key)            # => #<ActiveSupport::MessageEncryptor ...>
  #   encrypted_data = crypt.encrypt_and_sign('my secret data')   # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
  #   crypt.decrypt_and_verify(encrypted_data)                    # => "my secret data"
  class MessageEncryptor
    module NullSerializer #:nodoc:
      def self.load(value)
        value
      end

      def self.dump(value)
        value
      end
    end

    class InvalidMessage < StandardError; end
    OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError

    # Initialize a new MessageEncryptor. +secret+ must be at least as long as
    # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256
    # bits. If you are using a user-entered secret, you can generate a suitable
    # key with <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or
    # similar.
    #
    # Options:
    # * <tt>:cipher</tt>     - Cipher to use. Can be any cipher returned by
    #   <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
    # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
    def initialize(secret, *signature_key_or_options)
      options = signature_key_or_options.extract_options!
      sign_secret = signature_key_or_options.first
      @secret = secret
      @sign_secret = sign_secret
      @cipher = options[:cipher] || 'aes-256-cbc'
      @verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer)
      @serializer = options[:serializer] || Marshal
    end

    # Encrypt and sign a message. We need to sign the message in order to avoid
    # padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
    def encrypt_and_sign(value)
      verifier.generate(_encrypt(value))
    end

    # Decrypt and verify a message. We need to verify the message in order to
    # avoid padding attacks. Reference: http://www.limited-entropy.com/padding-oracle-attacks.
    def decrypt_and_verify(value)
      _decrypt(verifier.verify(value))
    end

    private

    def _encrypt(value)
      cipher = new_cipher
      # Rely on OpenSSL for the initialization vector
      iv = cipher.random_iv

      cipher.encrypt
      cipher.key = @secret
      cipher.iv  = iv

      encrypted_data = cipher.update(@serializer.dump(value))
      encrypted_data << cipher.final

      [encrypted_data, iv].map {|v| ::Base64.strict_encode64(v)}.join("--")
    end

    def _decrypt(encrypted_message)
      cipher = new_cipher
      encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.decode64(v)}

      cipher.decrypt
      cipher.key = @secret
      cipher.iv  = iv

      decrypted_data = cipher.update(encrypted_data)
      decrypted_data << cipher.final

      @serializer.load(decrypted_data)
    rescue OpenSSLCipherError, TypeError
      raise InvalidMessage
    end

    def new_cipher
      OpenSSL::Cipher::Cipher.new(@cipher)
    end

    def verifier
      @verifier
    end
  end
end
require 'base64'
require 'active_support/core_ext/object/blank'

module ActiveSupport
  # +MessageVerifier+ makes it easy to generate and verify messages which are
  # signed to prevent tampering.
  #
  # This is useful for cases like remember-me tokens and auto-unsubscribe links
  # where the session store isn't suitable or available.
  #
  # Remember Me:
  #   cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
  #
  # In the authentication filter:
  #
  #   id, time = @verifier.verify(cookies[:remember_me])
  #   if time < Time.now
  #     self.current_user = User.find(id)
  #   end
  #
  # By default it uses Marshal to serialize the message. If you want to use
  # another serialization method, you can set the serializer attribute to
  # something that responds to dump and load, e.g.:
  #
  #   @verifier.serializer = YAML
  class MessageVerifier
    class InvalidSignature < StandardError; end

    def initialize(secret, options = {})
      @secret = secret
      @digest = options[:digest] || 'SHA1'
      @serializer = options[:serializer] || Marshal
    end

    def verify(signed_message)
      raise InvalidSignature if signed_message.blank?

      data, digest = signed_message.split("--")
      if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
        @serializer.load(::Base64.decode64(data))
      else
        raise InvalidSignature
      end
    end

    def generate(value)
      data = ::Base64.strict_encode64(@serializer.dump(value))
      "#{data}--#{generate_digest(data)}"
    end

    private
      # constant-time comparison algorithm to prevent timing attacks
      def secure_compare(a, b)
        return false unless a.bytesize == b.bytesize

        l = a.unpack "C#{a.bytesize}"

        res = 0
        b.each_byte { |byte| res |= byte ^ l.shift }
        res == 0
      end

      def generate_digest(data)
        require 'openssl' unless defined?(OpenSSL)
        OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
      end
  end
end
# encoding: utf-8
require 'active_support/json'
require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/module/delegation'

module ActiveSupport #:nodoc:
  module Multibyte #:nodoc:
    # Chars enables you to work transparently with UTF-8 encoding in the Ruby
    # String class without having extensive knowledge about the encoding. A
    # Chars object accepts a string upon initialization and proxies String
    # methods in an encoding safe manner. All the normal String methods are also
    # implemented on the proxy.
    #
    # String methods are proxied through the Chars object, and can be accessed
    # through the +mb_chars+ method. Methods which would normally return a
    # String object now return a Chars object so methods can be chained.
    #
    #   'The Perfect String  '.mb_chars.downcase.strip.normalize # => "the perfect string"
    #
    # Chars objects are perfectly interchangeable with String objects as long as
    # no explicit class checks are made. If certain methods do explicitly check
    # the class, call +to_s+ before you pass chars objects to them.
    #
    #   bad.explicit_checking_method 'T'.mb_chars.downcase.to_s
    #
    # The default Chars implementation assumes that the encoding of the string
    # is UTF-8, if you want to handle different encodings you can write your own
    # multibyte string handler and configure it through
    # ActiveSupport::Multibyte.proxy_class.
    #
    #   class CharsForUTF32
    #     def size
    #       @wrapped_string.size / 4
    #     end
    #
    #     def self.accepts?(string)
    #       string.length % 4 == 0
    #     end
    #   end
    #
    #   ActiveSupport::Multibyte.proxy_class = CharsForUTF32
    class Chars
      include Comparable
      attr_reader :wrapped_string
      alias to_s wrapped_string
      alias to_str wrapped_string

      delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string

      # Creates a new Chars instance by wrapping _string_.
      def initialize(string)
        @wrapped_string = string
        @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
      end

      # Forward all undefined methods to the wrapped string.
      def method_missing(method, *args, &block)
        if method.to_s =~ /!$/
          result = @wrapped_string.__send__(method, *args, &block)
          self if result
        else
          result = @wrapped_string.__send__(method, *args, &block)
          result.kind_of?(String) ? chars(result) : result
        end
      end

      # Returns +true+ if _obj_ responds to the given method. Private methods
      # are included in the search only if the optional second parameter
      # evaluates to +true+.
      def respond_to_missing?(method, include_private)
        @wrapped_string.respond_to?(method, include_private)
      end

      # Returns +true+ when the proxy class can handle the string. Returns
      # +false+ otherwise.
      def self.consumes?(string)
        string.encoding == Encoding::UTF_8
      end

      # Works just like <tt>String#split</tt>, with the exception that the items
      # in the resulting list are Chars instances instead of String. This makes
      # chaining methods easier.
      #
      #   'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"]
      def split(*args)
        @wrapped_string.split(*args).map { |i| self.class.new(i) }
      end

      # Works like like <tt>String#slice!</tt>, but returns an instance of
      # Chars, or nil if the string was not modified.
      def slice!(*args)
        chars(@wrapped_string.slice!(*args))
      end

      # Reverses all characters in the string.
      #
      #   'Café'.mb_chars.reverse.to_s # => 'éfaC'
      def reverse
        chars(Unicode.unpack_graphemes(@wrapped_string).reverse.flatten.pack('U*'))
      end

      # Limits the byte size of the string to a number of bytes without breaking
      # characters. Usable when the storage for a string is limited for some
      # reason.
      #
      #   'こんにちは'.mb_chars.limit(7).to_s # => "こん"
      def limit(limit)
        slice(0...translate_offset(limit))
      end

      # Converts characters in the string to uppercase.
      #
      #   'Laurent, où sont les tests ?'.mb_chars.upcase.to_s # => "LAURENT, OÙ SONT LES TESTS ?"
      def upcase
        chars Unicode.upcase(@wrapped_string)
      end

      # Converts characters in the string to lowercase.
      #
      #   'VĚDA A VÝZKUM'.mb_chars.downcase.to_s # => "věda a výzkum"
      def downcase
        chars Unicode.downcase(@wrapped_string)
      end

      # Converts characters in the string to the opposite case.
      #
      #    'El Cañón".mb_chars.swapcase.to_s # => "eL cAÑÓN"
      def swapcase
        chars Unicode.swapcase(@wrapped_string)
      end

      # Converts the first character to uppercase and the remainder to lowercase.
      #
      #  'über'.mb_chars.capitalize.to_s # => "Über"
      def capitalize
        (slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase
      end

      # Capitalizes the first letter of every word, when possible.
      #
      #   "ÉL QUE SE ENTERÓ".mb_chars.titleize    # => "Él Que Se Enteró"
      #   "日本語".mb_chars.titleize                 # => "日本語"
      def titleize
        chars(downcase.to_s.gsub(/\b('?\S)/u) { Unicode.upcase($1)})
      end
      alias_method :titlecase, :titleize

      # Returns the KC normalization of the string by default. NFKC is
      # considered the best normalization form for passing strings to databases
      # and validations.
      #
      # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
      #   <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
      #   ActiveSupport::Multibyte::Unicode.default_normalization_form
      def normalize(form = nil)
        chars(Unicode.normalize(@wrapped_string, form))
      end

      # Performs canonical decomposition on all the characters.
      #
      #   'é'.length                         # => 2
      #   'é'.mb_chars.decompose.to_s.length # => 3
      def decompose
        chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack('U*'))
      end

      # Performs composition on all the characters.
      #
      #   'é'.length                       # => 3
      #   'é'.mb_chars.compose.to_s.length # => 2
      def compose
        chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack('U*'))
      end

      # Returns the number of grapheme clusters in the string.
      #
      #   'क्षि'.mb_chars.length   # => 4
      #   'क्षि'.mb_chars.grapheme_length # => 3
      def grapheme_length
        Unicode.unpack_graphemes(@wrapped_string).length
      end

      # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
      # resulting in a valid UTF-8 string.
      #
      # Passing +true+ will forcibly tidy all bytes, assuming that the string's
      # encoding is entirely CP1252 or ISO-8859-1.
      def tidy_bytes(force = false)
        chars(Unicode.tidy_bytes(@wrapped_string, force))
      end

      def as_json(options = nil) #:nodoc:
        to_s.as_json(options)
      end

      %w(capitalize downcase reverse tidy_bytes upcase).each do |method|
        define_method("#{method}!") do |*args|
          @wrapped_string = send(method, *args).to_s
          self
        end
      end

      protected

        def translate_offset(byte_offset) #:nodoc:
          return nil if byte_offset.nil?
          return 0   if @wrapped_string == ''

          begin
            @wrapped_string.byteslice(0...byte_offset).unpack('U*').length
          rescue ArgumentError
            byte_offset -= 1
            retry
          end
        end

        def chars(string) #:nodoc:
          self.class.new(string)
        end
    end
  end
end
# encoding: utf-8
module ActiveSupport
  module Multibyte
    module Unicode

      extend self

      # A list of all available normalization forms.
      # See http://www.unicode.org/reports/tr15/tr15-29.html for more
      # information about normalization.
      NORMALIZATION_FORMS = [:c, :kc, :d, :kd]

      # The Unicode version that is supported by the implementation
      UNICODE_VERSION = '6.2.0'

      # The default normalization used for operations that require
      # normalization. It can be set to any of the normalizations
      # in NORMALIZATION_FORMS.
      #
      #   ActiveSupport::Multibyte::Unicode.default_normalization_form = :c
      attr_accessor :default_normalization_form
      @default_normalization_form = :kc

      # Hangul character boundaries and properties
      HANGUL_SBASE = 0xAC00
      HANGUL_LBASE = 0x1100
      HANGUL_VBASE = 0x1161
      HANGUL_TBASE = 0x11A7
      HANGUL_LCOUNT = 19
      HANGUL_VCOUNT = 21
      HANGUL_TCOUNT = 28
      HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
      HANGUL_SCOUNT = 11172
      HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
      HANGUL_JAMO_FIRST = 0x1100
      HANGUL_JAMO_LAST = 0x11FF

      # All the unicode whitespace
      WHITESPACE = [
        (0x0009..0x000D).to_a, # White_Space # Cc   [5] <control-0009>..<control-000D>
        0x0020,                # White_Space # Zs       SPACE
        0x0085,                # White_Space # Cc       <control-0085>
        0x00A0,                # White_Space # Zs       NO-BREAK SPACE
        0x1680,                # White_Space # Zs       OGHAM SPACE MARK
        0x180E,                # White_Space # Zs       MONGOLIAN VOWEL SEPARATOR
        (0x2000..0x200A).to_a, # White_Space # Zs  [11] EN QUAD..HAIR SPACE
        0x2028,                # White_Space # Zl       LINE SEPARATOR
        0x2029,                # White_Space # Zp       PARAGRAPH SEPARATOR
        0x202F,                # White_Space # Zs       NARROW NO-BREAK SPACE
        0x205F,                # White_Space # Zs       MEDIUM MATHEMATICAL SPACE
        0x3000,                # White_Space # Zs       IDEOGRAPHIC SPACE
      ].flatten.freeze

      # BOM (byte order mark) can also be seen as whitespace, it's a
      # non-rendering character used to distinguish between little and big
      # endian. This is not an issue in utf-8, so it must be ignored.
      LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM

      # Returns a regular expression pattern that matches the passed Unicode
      # codepoints.
      def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
        array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
      end
      TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
      LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u

      # Detect whether the codepoint is in a certain character class. Returns
      # +true+ when it's in the specified character class and +false+ otherwise.
      # Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
      # <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
      #
      # Primarily used by the grapheme cluster support.
      def in_char_class?(codepoint, classes)
        classes.detect { |c| database.boundary[c] === codepoint } ? true : false
      end

      # Unpack the string at grapheme boundaries. Returns a list of character
      # lists.
      #
      #   Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
      #   Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
      def unpack_graphemes(string)
        codepoints = string.codepoints.to_a
        unpacked = []
        pos = 0
        marker = 0
        eoc = codepoints.length
        while(pos < eoc)
          pos += 1
          previous = codepoints[pos-1]
          current = codepoints[pos]
          if (
              # CR X LF
              ( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
              # L X (L|V|LV|LVT)
              ( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
              # (LV|V) X (V|T)
              ( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
              # (LVT|T) X (T)
              ( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
              # X Extend
              (database.boundary[:extend] === current)
            )
          else
            unpacked << codepoints[marker..pos-1]
            marker = pos
          end
        end
        unpacked
      end

      # Reverse operation of unpack_graphemes.
      #
      #   Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
      def pack_graphemes(unpacked)
        unpacked.flatten.pack('U*')
      end

      # Re-order codepoints so the string becomes canonical.
      def reorder_characters(codepoints)
        length = codepoints.length- 1
        pos = 0
        while pos < length do
          cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
          if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
            codepoints[pos..pos+1] = cp2.code, cp1.code
            pos += (pos > 0 ? -1 : 1)
          else
            pos += 1
          end
        end
        codepoints
      end

      # Decompose composed characters to the decomposed form.
      def decompose(type, codepoints)
        codepoints.inject([]) do |decomposed, cp|
          # if it's a hangul syllable starter character
          if HANGUL_SBASE <= cp and cp < HANGUL_SLAST
            sindex = cp - HANGUL_SBASE
            ncp = [] # new codepoints
            ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
            ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
            tindex = sindex % HANGUL_TCOUNT
            ncp << (HANGUL_TBASE + tindex) unless tindex == 0
            decomposed.concat ncp
          # if the codepoint is decomposable in with the current decomposition type
          elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatability)
            decomposed.concat decompose(type, ncp.dup)
          else
            decomposed << cp
          end
        end
      end

      # Compose decomposed characters to the composed form.
      def compose(codepoints)
        pos = 0
        eoa = codepoints.length - 1
        starter_pos = 0
        starter_char = codepoints[0]
        previous_combining_class = -1
        while pos < eoa
          pos += 1
          lindex = starter_char - HANGUL_LBASE
          # -- Hangul
          if 0 <= lindex and lindex < HANGUL_LCOUNT
            vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
            if 0 <= vindex and vindex < HANGUL_VCOUNT
              tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
              if 0 <= tindex and tindex < HANGUL_TCOUNT
                j = starter_pos + 2
                eoa -= 2
              else
                tindex = 0
                j = starter_pos + 1
                eoa -= 1
              end
              codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
            end
            starter_pos += 1
            starter_char = codepoints[starter_pos]
          # -- Other characters
          else
            current_char = codepoints[pos]
            current = database.codepoints[current_char]
            if current.combining_class > previous_combining_class
              if ref = database.composition_map[starter_char]
                composition = ref[current_char]
              else
                composition = nil
              end
              unless composition.nil?
                codepoints[starter_pos] = composition
                starter_char = composition
                codepoints.delete_at pos
                eoa -= 1
                pos -= 1
                previous_combining_class = -1
              else
                previous_combining_class = current.combining_class
              end
            else
              previous_combining_class = current.combining_class
            end
            if current.combining_class == 0
              starter_pos = pos
              starter_char = codepoints[pos]
            end
          end
        end
        codepoints
      end

      # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
      # resulting in a valid UTF-8 string.
      #
      # Passing +true+ will forcibly tidy all bytes, assuming that the string's
      # encoding is entirely CP1252 or ISO-8859-1.
      def tidy_bytes(string, force = false)
        if force
          return string.unpack("C*").map do |b|
            tidy_byte(b)
          end.flatten.compact.pack("C*").unpack("U*").pack("U*")
        end

        bytes = string.unpack("C*")
        conts_expected = 0
        last_lead = 0

        bytes.each_index do |i|

          byte          = bytes[i]
          is_cont       = byte > 127 && byte < 192
          is_lead       = byte > 191 && byte < 245
          is_unused     = byte > 240
          is_restricted = byte > 244

          # Impossible or highly unlikely byte? Clean it.
          if is_unused || is_restricted
            bytes[i] = tidy_byte(byte)
          elsif is_cont
            # Not expecting continuation byte? Clean up. Otherwise, now expect one less.
            conts_expected == 0 ? bytes[i] = tidy_byte(byte) : conts_expected -= 1
          else
            if conts_expected > 0
              # Expected continuation, but got ASCII or leading? Clean backwards up to
              # the leading byte.
              (1..(i - last_lead)).each {|j| bytes[i - j] = tidy_byte(bytes[i - j])}
              conts_expected = 0
            end
            if is_lead
              # Final byte is leading? Clean it.
              if i == bytes.length - 1
                bytes[i] = tidy_byte(bytes.last)
              else
                # Valid leading byte? Expect continuations determined by position of
                # first zero bit, with max of 3.
                conts_expected = byte < 224 ? 1 : byte < 240 ? 2 : 3
                last_lead = i
              end
            end
          end
        end
        bytes.empty? ? "" : bytes.flatten.compact.pack("C*").unpack("U*").pack("U*")
      end

      # Returns the KC normalization of the string by default. NFKC is
      # considered the best normalization form for passing strings to databases
      # and validations.
      #
      # * <tt>string</tt> - The string to perform normalization on.
      # * <tt>form</tt> - The form you want to normalize in. Should be one of
      #   the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
      #   Default is ActiveSupport::Multibyte.default_normalization_form.
      def normalize(string, form=nil)
        form ||= @default_normalization_form
        # See http://www.unicode.org/reports/tr15, Table 1
        codepoints = string.codepoints.to_a
        case form
          when :d
            reorder_characters(decompose(:canonical, codepoints))
          when :c
            compose(reorder_characters(decompose(:canonical, codepoints)))
          when :kd
            reorder_characters(decompose(:compatability, codepoints))
          when :kc
            compose(reorder_characters(decompose(:compatability, codepoints)))
          else
            raise ArgumentError, "#{form} is not a valid normalization variant", caller
        end.pack('U*')
      end

      def downcase(string)
        apply_mapping string, :lowercase_mapping
      end

      def upcase(string)
        apply_mapping string, :uppercase_mapping
      end

      def swapcase(string)
        apply_mapping string, :swapcase_mapping
      end

      # Holds data about a codepoint in the Unicode database.
      class Codepoint
        attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping

        def swapcase_mapping
          uppercase_mapping > 0 ? uppercase_mapping : lowercase_mapping
        end
      end

      # Holds static data from the Unicode database.
      class UnicodeDatabase
        ATTRIBUTES = :codepoints, :composition_exclusion, :composition_map, :boundary, :cp1252

        attr_writer(*ATTRIBUTES)

        def initialize
          @codepoints = Hash.new(Codepoint.new)
          @composition_exclusion = []
          @composition_map = {}
          @boundary = {}
          @cp1252 = {}
        end

        # Lazy load the Unicode database so it's only loaded when it's actually used
        ATTRIBUTES.each do |attr_name|
          class_eval(<<-EOS, __FILE__, __LINE__ + 1)
            def #{attr_name}     # def codepoints
              load               #   load
              @#{attr_name}      #   @codepoints
            end                  # end
          EOS
        end

        # Loads the Unicode database and returns all the internal objects of
        # UnicodeDatabase.
        def load
          begin
            @codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
          rescue => e
              raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
          end

          # Redefine the === method so we can write shorter rules for grapheme cluster breaks
          @boundary.each do |k,_|
            @boundary[k].instance_eval do
              def ===(other)
                detect { |i| i === other } ? true : false
              end
            end if @boundary[k].kind_of?(Array)
          end

          # define attr_reader methods for the instance variables
          class << self
            attr_reader(*ATTRIBUTES)
          end
        end

        # Returns the directory in which the data files are stored.
        def self.dirname
          File.dirname(__FILE__) + '/../values/'
        end

        # Returns the filename for the data file for this version.
        def self.filename
          File.expand_path File.join(dirname, "unicode_tables.dat")
        end
      end

      private

      def apply_mapping(string, mapping) #:nodoc:
        string.each_codepoint.map do |codepoint|
          cp = database.codepoints[codepoint]
          if cp and (ncp = cp.send(mapping)) and ncp > 0
            ncp
          else
            codepoint
          end
        end.pack('U*')
      end

      def tidy_byte(byte)
        if byte < 160
          [database.cp1252[byte] || byte].pack("U").unpack("C*")
        elsif byte < 192
          [194, byte]
        else
          [195, byte - 64]
        end
      end

      def database
        @database ||= UnicodeDatabase.new
      end

    end
  end
end
module ActiveSupport #:nodoc:
  module Multibyte
    autoload :Chars, 'active_support/multibyte/chars'
    autoload :Unicode, 'active_support/multibyte/unicode'

    # The proxy class returned when calling mb_chars. You can use this accessor
    # to configure your own proxy class so you can support other encodings. See
    # the ActiveSupport::Multibyte::Chars implementation for an example how to
    # do this.
    #
    #   ActiveSupport::Multibyte.proxy_class = CharsForUTF32
    def self.proxy_class=(klass)
      @proxy_class = klass
    end

    # Returns the current proxy class.
    def self.proxy_class
      @proxy_class ||= ActiveSupport::Multibyte::Chars
    end
  end
end
require 'mutex_m'
require 'thread_safe'

module ActiveSupport
  module Notifications
    # This is a default queue implementation that ships with Notifications.
    # It just pushes events to all registered log subscribers.
    #
    # This class is thread safe. All methods are reentrant.
    class Fanout
      include Mutex_m

      def initialize
        @subscribers = []
        @listeners_for = ThreadSafe::Cache.new
        super
      end

      def subscribe(pattern = nil, block = Proc.new)
        subscriber = Subscribers.new pattern, block
        synchronize do
          @subscribers << subscriber
          @listeners_for.clear
        end
        subscriber
      end

      def unsubscribe(subscriber)
        synchronize do
          @subscribers.reject! { |s| s.matches?(subscriber) }
          @listeners_for.clear
        end
      end

      def start(name, id, payload)
        listeners_for(name).each { |s| s.start(name, id, payload) }
      end

      def finish(name, id, payload)
        listeners_for(name).each { |s| s.finish(name, id, payload) }
      end

      def publish(name, *args)
        listeners_for(name).each { |s| s.publish(name, *args) }
      end

      def listeners_for(name)
        # this is correctly done double-checked locking (ThreadSafe::Cache's lookups have volatile semantics)
        @listeners_for[name] || synchronize do
          # use synchronisation when accessing @subscribers
          @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
        end
      end

      def listening?(name)
        listeners_for(name).any?
      end

      # This is a sync queue, so there is no waiting.
      def wait
      end

      module Subscribers # :nodoc:
        def self.new(pattern, listener)
          if listener.respond_to?(:start) and listener.respond_to?(:finish)
            subscriber = Evented.new pattern, listener
          else
            subscriber = Timed.new pattern, listener
          end

          unless pattern
            AllMessages.new(subscriber)
          else
            subscriber
          end
        end

        class Evented #:nodoc:
          def initialize(pattern, delegate)
            @pattern = pattern
            @delegate = delegate
          end

          def start(name, id, payload)
            @delegate.start name, id, payload
          end

          def finish(name, id, payload)
            @delegate.finish name, id, payload
          end

          def subscribed_to?(name)
            @pattern === name.to_s
          end

          def matches?(subscriber_or_name)
            self === subscriber_or_name ||
              @pattern && @pattern === subscriber_or_name
          end
        end

        class Timed < Evented
          def initialize(pattern, delegate)
            @timestack = []
            super
          end

          def publish(name, *args)
            @delegate.call name, *args
          end

          def start(name, id, payload)
            @timestack.push Time.now
          end

          def finish(name, id, payload)
            started = @timestack.pop
            @delegate.call(name, started, Time.now, id, payload)
          end
        end

        class AllMessages # :nodoc:
          def initialize(delegate)
            @delegate = delegate
          end

          def start(name, id, payload)
            @delegate.start name, id, payload
          end

          def finish(name, id, payload)
            @delegate.finish name, id, payload
          end

          def publish(name, *args)
            @delegate.publish name, *args
          end

          def subscribed_to?(name)
            true
          end

          alias :matches? :===
        end
      end
    end
  end
end
require 'securerandom'

module ActiveSupport
  module Notifications
    # Instrumentors are stored in a thread local.
    class Instrumenter
      attr_reader :id

      def initialize(notifier)
        @id       = unique_id
        @notifier = notifier
      end

      # Instrument the given block by measuring the time taken to execute it
      # and publish it. Notice that events get sent even if an error occurs
      # in the passed-in block.
      def instrument(name, payload={})
        start name, payload
        begin
          yield
        rescue Exception => e
          payload[:exception] = [e.class.name, e.message]
          raise e
        ensure
          finish name, payload
        end
      end

      # Send a start notification with +name+ and +payload+.
      def start(name, payload)
        @notifier.start name, @id, payload
      end

      # Send a finish notification with +name+ and +payload+.
      def finish(name, payload)
        @notifier.finish name, @id, payload
      end

      private

      def unique_id
        SecureRandom.hex(10)
      end
    end

    class Event
      attr_reader :name, :time, :transaction_id, :payload, :children
      attr_accessor :end

      def initialize(name, start, ending, transaction_id, payload)
        @name           = name
        @payload        = payload.dup
        @time           = start
        @transaction_id = transaction_id
        @end            = ending
        @children       = []
      end

      def duration
        1000.0 * (self.end - time)
      end

      def <<(event)
        @children << event
      end

      def parent_of?(event)
        @children.include? event
      end
    end
  end
end
require 'active_support/notifications/instrumenter'
require 'active_support/notifications/fanout'

module ActiveSupport
  # = Notifications
  #
  # <tt>ActiveSupport::Notifications</tt> provides an instrumentation API for
  # Ruby.
  #
  # == Instrumenters
  #
  # To instrument an event you just need to do:
  #
  #   ActiveSupport::Notifications.instrument('render', extra: :information) do
  #     render text: 'Foo'
  #   end
  #
  # That executes the block first and notifies all subscribers once done.
  #
  # In the example above +render+ is the name of the event, and the rest is called
  # the _payload_. The payload is a mechanism that allows instrumenters to pass
  # extra information to subscribers. Payloads consist of a hash whose contents
  # are arbitrary and generally depend on the event.
  #
  # == Subscribers
  #
  # You can consume those events and the information they provide by registering
  # a subscriber.
  #
  #   ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload|
  #     name    # => String, name of the event (such as 'render' from above)
  #     start   # => Time, when the instrumented block started execution
  #     finish  # => Time, when the instrumented block ended execution
  #     id      # => String, unique ID for this notification
  #     payload # => Hash, the payload
  #   end
  #
  # For instance, let's store all "render" events in an array:
  #
  #   events = []
  #
  #   ActiveSupport::Notifications.subscribe('render') do |*args|
  #     events << ActiveSupport::Notifications::Event.new(*args)
  #   end
  #
  # That code returns right away, you are just subscribing to "render" events.
  # The block is saved and will be called whenever someone instruments "render":
  #
  #   ActiveSupport::Notifications.instrument('render', extra: :information) do
  #     render text: 'Foo'
  #   end
  #
  #   event = events.first
  #   event.name      # => "render"
  #   event.duration  # => 10 (in milliseconds)
  #   event.payload   # => { extra: :information }
  #
  # The block in the <tt>subscribe</tt> call gets the name of the event, start
  # timestamp, end timestamp, a string with a unique identifier for that event
  # (something like "535801666f04d0298cd6"), and a hash with the payload, in
  # that order.
  #
  # If an exception happens during that particular instrumentation the payload will
  # have a key <tt>:exception</tt> with an array of two elements as value: a string with
  # the name of the exception class, and the exception message.
  #
  # As the previous example depicts, the class <tt>ActiveSupport::Notifications::Event</tt>
  # is able to take the arguments as they come and provide an object-oriented
  # interface to that data.
  #
  # It is also possible to pass an object as the second parameter passed to the
  # <tt>subscribe</tt> method instead of a block:
  #
  #   module ActionController
  #     class PageRequest
  #       def call(name, started, finished, unique_id, payload)
  #         Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
  #       end
  #     end
  #   end
  #
  #   ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new)
  #
  # resulting in the following output within the logs including a hash with the payload:
  #
  #   notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 {
  #      controller: "Devise::SessionsController",
  #      action: "new",
  #      params: {"action"=>"new", "controller"=>"devise/sessions"},
  #      format: :html,
  #      method: "GET",
  #      path: "/login/sign_in",
  #      status: 200,
  #      view_runtime: 279.3080806732178,
  #      db_runtime: 40.053
  #    }
  #
  # You can also subscribe to all events whose name matches a certain regexp:
  #
  #   ActiveSupport::Notifications.subscribe(/render/) do |*args|
  #     ...
  #   end
  #
  # and even pass no argument to <tt>subscribe</tt>, in which case you are subscribing
  # to all events.
  #
  # == Temporary Subscriptions
  #
  # Sometimes you do not want to subscribe to an event for the entire life of
  # the application. There are two ways to unsubscribe.
  #
  # WARNING: The instrumentation framework is designed for long-running subscribers,
  # use this feature sparingly because it wipes some internal caches and that has
  # a negative impact on performance.
  #
  # === Subscribe While a Block Runs
  #
  # You can subscribe to some event temporarily while some block runs. For
  # example, in
  #
  #   callback = lambda {|*args| ... }
  #   ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do
  #     ...
  #   end
  #
  # the callback will be called for all "sql.active_record" events instrumented
  # during the execution of the block. The callback is unsubscribed automatically
  # after that.
  #
  # === Manual Unsubscription
  #
  # The +subscribe+ method returns a subscriber object:
  #
  #   subscriber = ActiveSupport::Notifications.subscribe("render") do |*args|
  #     ...
  #   end
  #
  # To prevent that block from being called anymore, just unsubscribe passing
  # that reference:
  #
  #   ActiveSupport::Notifications.unsubscribe(subscriber)
  #
  # == Default Queue
  #
  # Notifications ships with a queue implementation that consumes and publish events
  # to log subscribers in a thread. You can use any queue implementation you want.
  #
  module Notifications
    class << self
      attr_accessor :notifier

      def publish(name, *args)
        notifier.publish(name, *args)
      end

      def instrument(name, payload = {})
        if notifier.listening?(name)
          instrumenter.instrument(name, payload) { yield payload if block_given? }
        else
          yield payload if block_given?
        end
      end

      def subscribe(*args, &block)
        notifier.subscribe(*args, &block)
      end

      def subscribed(callback, *args, &block)
        subscriber = subscribe(*args, &callback)
        yield
      ensure
        unsubscribe(subscriber)
      end

      def unsubscribe(args)
        notifier.unsubscribe(args)
      end

      def instrumenter
        Thread.current[:"instrumentation_#{notifier.object_id}"] ||= Instrumenter.new(notifier)
      end
    end

    self.notifier = Fanout.new
  end
end
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/hash/keys'
require 'active_support/i18n'

module ActiveSupport
  module NumberHelper
    extend self

    DEFAULTS = {
      # Used in number_to_delimited
      # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
      format: {
        # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
        separator: ".",
        # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three)
        delimiter: ",",
        # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
        precision: 3,
        # If set to true, precision will mean the number of significant digits instead
        # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
        significant: false,
        # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
        strip_insignificant_zeros: false
      },

      # Used in number_to_currency
      currency: {
        format: {
          format: "%u%n",
          negative_format: "-%u%n",
          unit: "$",
          # These five are to override number.format and are optional
          separator: ".",
          delimiter: ",",
          precision: 2,
          significant: false,
          strip_insignificant_zeros: false
        }
      },

      # Used in number_to_percentage
      percentage: {
        format: {
          delimiter: "",
          format: "%n%"
        }
      },

      # Used in number_to_rounded
      precision: {
        format: {
          delimiter: ""
        }
      },

      # Used in number_to_human_size and number_to_human
      human: {
        format: {
          # These five are to override number.format and are optional
          delimiter: "",
          precision: 3,
          significant: true,
          strip_insignificant_zeros: true
        },
        # Used in number_to_human_size
        storage_units: {
          # Storage units output formatting.
          # %u is the storage unit, %n is the number (default: 2 MB)
          format: "%n %u",
          units: {
            byte: "Bytes",
            kb: "KB",
            mb: "MB",
            gb: "GB",
            tb: "TB"
          }
        },
        # Used in number_to_human
        decimal_units: {
          format: "%n %u",
          # Decimal units output formatting
          # By default we will only quantify some of the exponents
          # but the commented ones might be defined or overridden
          # by the user.
          units: {
            # femto: Quadrillionth
            # pico: Trillionth
            # nano: Billionth
            # micro: Millionth
            # mili: Thousandth
            # centi: Hundredth
            # deci: Tenth
            unit: "",
            # ten:
            #   one: Ten
            #   other: Tens
            # hundred: Hundred
            thousand: "Thousand",
            million: "Million",
            billion: "Billion",
            trillion: "Trillion",
            quadrillion: "Quadrillion"
          }
        }
      }
    }

    DECIMAL_UNITS = { 0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
      -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto }

    STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]

    # Formats a +number+ into a US phone number (e.g., (555)
    # 123-9876). You can customize the format in the +options+ hash.
    #
    # ==== Options
    #
    # * <tt>:area_code</tt> - Adds parentheses around the area code.
    # * <tt>:delimiter</tt> - Specifies the delimiter to use
    #   (defaults to "-").
    # * <tt>:extension</tt> - Specifies an extension to add to the
    #   end of the generated number.
    # * <tt>:country_code</tt> - Sets the country code for the phone
    #   number.
    # ==== Examples
    #
    #   number_to_phone(5551234)                                     # => 555-1234
    #   number_to_phone('5551234')                                   # => 555-1234
    #   number_to_phone(1235551234)                                  # => 123-555-1234
    #   number_to_phone(1235551234, area_code: true)                 # => (123) 555-1234
    #   number_to_phone(1235551234, delimiter: ' ')                  # => 123 555 1234
    #   number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
    #   number_to_phone(1235551234, country_code: 1)                 # => +1-123-555-1234
    #   number_to_phone('123a456')                                   # => 123a456
    #
    #   number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
    #   # => +1.123.555.1234 x 1343
    def number_to_phone(number, options = {})
      return unless number
      options = options.symbolize_keys

      number       = number.to_s.strip
      area_code    = options[:area_code]
      delimiter    = options[:delimiter] || "-"
      extension    = options[:extension]
      country_code = options[:country_code]

      if area_code
        number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
      else
        number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
        number.slice!(0, 1) if number.start_with?(delimiter) && !delimiter.blank?
      end

      str = ''
      str << "+#{country_code}#{delimiter}" unless country_code.blank?
      str << number
      str << " x #{extension}" unless extension.blank?
      str
    end

    # Formats a +number+ into a currency string (e.g., $13.65). You
    # can customize the format in the +options+ hash.
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:precision</tt> - Sets the level of precision (defaults
    #   to 2).
    # * <tt>:unit</tt> - Sets the denomination of the currency
    #   (defaults to "$").
    # * <tt>:separator</tt> - Sets the separator between the units
    #   (defaults to ".").
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to ",").
    # * <tt>:format</tt> - Sets the format for non-negative numbers
    #   (defaults to "%u%n").  Fields are <tt>%u</tt> for the
    #   currency, and <tt>%n</tt> for the number.
    # * <tt>:negative_format</tt> - Sets the format for negative
    #   numbers (defaults to prepending an hyphen to the formatted
    #   number given by <tt>:format</tt>).  Accepts the same fields
    #   than <tt>:format</tt>, except <tt>%n</tt> is here the
    #   absolute value of the number.
    #
    # ==== Examples
    #
    #   number_to_currency(1234567890.50)                # => $1,234,567,890.50
    #   number_to_currency(1234567890.506)               # => $1,234,567,890.51
    #   number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
    #   number_to_currency(1234567890.506, locale: :fr)  # => 1 234 567 890,51 €
    #   number_to_currency('123a456')                    # => $123a456
    #
    #   number_to_currency(-1234567890.50, negative_format: '(%u%n)')
    #   # => ($1,234,567,890.50)
    #   number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
    #   # => &pound;1234567890,50
    #   number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
    #   # => 1234567890,50 &pound;
    def number_to_currency(number, options = {})
      return unless number
      options = options.symbolize_keys

      currency = i18n_format_options(options[:locale], :currency)
      currency[:negative_format] ||= "-" + currency[:format] if currency[:format]

      defaults  = default_format_options(:currency).merge!(currency)
      defaults[:negative_format] = "-" + options[:format] if options[:format]
      options   = defaults.merge!(options)

      unit      = options.delete(:unit)
      format    = options.delete(:format)

      if number.to_f.phase != 0
        format = options.delete(:negative_format)
        number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
      end

      format.gsub('%n', self.number_to_rounded(number, options)).gsub('%u', unit)
    end

    # Formats a +number+ as a percentage string (e.g., 65%). You can
    # customize the format in the +options+ hash.
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:precision</tt> - Sets the precision of the number
    #   (defaults to 3).
    # * <tt>:significant</tt> - If +true+, precision will be the #
    #   of significant_digits. If +false+, the # of fractional
    #   digits (defaults to +false+).
    # * <tt>:separator</tt> - Sets the separator between the
    #   fractional and integer digits (defaults to ".").
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to "").
    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
    #   insignificant zeros after the decimal separator (defaults to
    #   +false+).
    # * <tt>:format</tt> - Specifies the format of the percentage
    #   string The number field is <tt>%n</tt> (defaults to "%n%").
    #
    # ==== Examples
    #
    #   number_to_percentage(100)                                 # => 100.000%
    #   number_to_percentage('98')                                # => 98.000%
    #   number_to_percentage(100, precision: 0)                   # => 100%
    #   number_to_percentage(1000, delimiter: '.', separator: ,') # => 1.000,000%
    #   number_to_percentage(302.24398923423, precision: 5)       # => 302.24399%
    #   number_to_percentage(1000, locale: :fr)                   # => 1 000,000%
    #   number_to_percentage('98a')                               # => 98a%
    #   number_to_percentage(100, format: '%n  %')                # => 100  %
    def number_to_percentage(number, options = {})
      return unless number
      options = options.symbolize_keys

      defaults = format_options(options[:locale], :percentage)
      options  = defaults.merge!(options)

      format = options[:format] || "%n%"
      format.gsub('%n', self.number_to_rounded(number, options))
    end

    # Formats a +number+ with grouped thousands using +delimiter+
    # (e.g., 12,324). You can customize the format in the +options+
    # hash.
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to ",").
    # * <tt>:separator</tt> - Sets the separator between the
    #   fractional and integer digits (defaults to ".").
    #
    # ==== Examples
    #
    #   number_to_delimited(12345678)                    # => 12,345,678
    #   number_to_delimited('123456')                    # => 123,456
    #   number_to_delimited(12345678.05)                 # => 12,345,678.05
    #   number_to_delimited(12345678, delimiter: '.')    # => 12.345.678
    #   number_to_delimited(12345678, delimiter: ',')    # => 12,345,678
    #   number_to_delimited(12345678.05, separator: ' ') # => 12,345,678 05
    #   number_to_delimited(12345678.05, locale: :fr)    # => 12 345 678,05
    #   number_to_delimited('112a')                      # => 112a
    #   number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
    #   # => 98 765 432,98
    def number_to_delimited(number, options = {})
      options = options.symbolize_keys

      return number unless valid_float?(number)

      options = format_options(options[:locale]).merge!(options)

      parts = number.to_s.to_str.split('.')
      parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
      parts.join(options[:separator])
    end

    # Formats a +number+ with the specified level of
    # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
    # +:significant+ is +false+, and 5 if +:significant+ is +true+).
    # You can customize the format in the +options+ hash.
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:precision</tt> - Sets the precision of the number
    #   (defaults to 3).
    # * <tt>:significant</tt> - If +true+, precision will be the #
    #   of significant_digits. If +false+, the # of fractional
    #   digits (defaults to +false+).
    # * <tt>:separator</tt> - Sets the separator between the
    #   fractional and integer digits (defaults to ".").
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to "").
    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
    #   insignificant zeros after the decimal separator (defaults to
    #   +false+).
    #
    # ==== Examples
    #
    #   number_to_rounded(111.2345)                                  # => 111.235
    #   number_to_rounded(111.2345, precision: 2)                    # => 111.23
    #   number_to_rounded(13, precision: 5)                          # => 13.00000
    #   number_to_rounded(389.32314, precision: 0)                   # => 389
    #   number_to_rounded(111.2345, significant: true)               # => 111
    #   number_to_rounded(111.2345, precision: 1, significant: true) # => 100
    #   number_to_rounded(13, precision: 5, significant: true)       # => 13.000
    #   number_to_rounded(111.234, locale: :fr)                      # => 111,234
    #
    #   number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
    #   # => 13
    #
    #   number_to_rounded(389.32314, precision: 4, significant: true) # => 389.3
    #   number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
    #   # => 1.111,23
    def number_to_rounded(number, options = {})
      return number unless valid_float?(number)
      number  = Float(number)
      options = options.symbolize_keys

      defaults = format_options(options[:locale], :precision)
      options  = defaults.merge!(options)

      precision = options.delete :precision
      significant = options.delete :significant
      strip_insignificant_zeros = options.delete :strip_insignificant_zeros

      if significant && precision > 0
        if number == 0
          digits, rounded_number = 1, 0
        else
          digits = (Math.log10(number.abs) + 1).floor
          rounded_number = (BigDecimal.new(number.to_s) / BigDecimal.new((10 ** (digits - precision)).to_f.to_s)).round.to_f * 10 ** (digits - precision)
          digits = (Math.log10(rounded_number.abs) + 1).floor # After rounding, the number of digits may have changed
        end
        precision -= digits
        precision = 0 if precision < 0 # don't let it be negative
      else
        rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
        rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
      end
      formatted_number = self.number_to_delimited("%01.#{precision}f" % rounded_number, options)
      if strip_insignificant_zeros
        escaped_separator = Regexp.escape(options[:separator])
        formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
      else
        formatted_number
      end
    end

    # Formats the bytes in +number+ into a more understandable
    # representation (e.g., giving it 1500 yields 1.5 KB). This
    # method is useful for reporting file sizes to users. You can
    # customize the format in the +options+ hash.
    #
    # See <tt>number_to_human</tt> if you want to pretty-print a
    # generic number.
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:precision</tt> - Sets the precision of the number
    #   (defaults to 3).
    # * <tt>:significant</tt> - If +true+, precision will be the #
    #   of significant_digits. If +false+, the # of fractional
    #   digits (defaults to +true+)
    # * <tt>:separator</tt> - Sets the separator between the
    #   fractional and integer digits (defaults to ".").
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to "").
    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
    #   insignificant zeros after the decimal separator (defaults to
    #   +true+)
    # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
    #   prefix (defaults to :binary)
    #
    # ==== Examples
    #
    #   number_to_human_size(123)                                    # => 123 Bytes
    #   number_to_human_size(1234)                                   # => 1.21 KB
    #   number_to_human_size(12345)                                  # => 12.1 KB
    #   number_to_human_size(1234567)                                # => 1.18 MB
    #   number_to_human_size(1234567890)                             # => 1.15 GB
    #   number_to_human_size(1234567890123)                          # => 1.12 TB
    #   number_to_human_size(1234567, precision: 2)                  # => 1.2 MB
    #   number_to_human_size(483989, precision: 2)                   # => 470 KB
    #   number_to_human_size(1234567, precision: 2, separator: ',')  # => 1,2 MB
    #
    # Non-significant zeros after the fractional separator are stripped out by
    # default (set <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
    #
    #   number_to_human_size(1234567890123, precision: 5) # => "1.1229 TB"
    #   number_to_human_size(524288000, precision: 5)     # => "500 MB"
    def number_to_human_size(number, options = {})
      options = options.symbolize_keys

      return number unless valid_float?(number)
      number = Float(number)

      defaults = format_options(options[:locale], :human)
      options  = defaults.merge!(options)

      #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
      options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)

      storage_units_format = translate_number_value_with_default('human.storage_units.format', :locale => options[:locale], :raise => true)

      base = options[:prefix] == :si ? 1000 : 1024

      if number.to_i < base
        unit = translate_number_value_with_default('human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
        storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit)
      else
        max_exp  = STORAGE_UNITS.size - 1
        exponent = (Math.log(number) / Math.log(base)).to_i # Convert to base
        exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
        number  /= base ** exponent

        unit_key = STORAGE_UNITS[exponent]
        unit = translate_number_value_with_default("human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)

        formatted_number = self.number_to_rounded(number, options)
        storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
      end
    end

    # Pretty prints (formats and approximates) a number in a way it
    # is more readable by humans (eg.: 1200000000 becomes "1.2
    # Billion"). This is useful for numbers that can get very large
    # (and too hard to read).
    #
    # See <tt>number_to_human_size</tt> if you want to print a file
    # size.
    #
    # You can also define you own unit-quantifier names if you want
    # to use other decimal units (eg.: 1500 becomes "1.5
    # kilometers", 0.150 becomes "150 milliliters", etc). You may
    # define a wide range of unit quantifiers, even fractional ones
    # (centi, deci, mili, etc).
    #
    # ==== Options
    #
    # * <tt>:locale</tt> - Sets the locale to be used for formatting
    #   (defaults to current locale).
    # * <tt>:precision</tt> - Sets the precision of the number
    #   (defaults to 3).
    # * <tt>:significant</tt> - If +true+, precision will be the #
    #   of significant_digits. If +false+, the # of fractional
    #   digits (defaults to +true+)
    # * <tt>:separator</tt> - Sets the separator between the
    #   fractional and integer digits (defaults to ".").
    # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
    #   to "").
    # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
    #   insignificant zeros after the decimal separator (defaults to
    #   +true+)
    # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
    #   string containing an i18n scope where to find this hash. It
    #   might have the following keys:
    #   * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
    #     *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
    #     *<tt>:billion</tt>, <tt>:trillion</tt>,
    #     *<tt>:quadrillion</tt>
    #   * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
    #     *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
    #     *<tt>:pico</tt>, <tt>:femto</tt>
    # * <tt>:format</tt> - Sets the format of the output string
    #   (defaults to "%n %u"). The field types are:
    #   * %u - The quantifier (ex.: 'thousand')
    #   * %n - The number
    #
    # ==== Examples
    #
    #   number_to_human(123)                         # => "123"
    #   number_to_human(1234)                        # => "1.23 Thousand"
    #   number_to_human(12345)                       # => "12.3 Thousand"
    #   number_to_human(1234567)                     # => "1.23 Million"
    #   number_to_human(1234567890)                  # => "1.23 Billion"
    #   number_to_human(1234567890123)               # => "1.23 Trillion"
    #   number_to_human(1234567890123456)            # => "1.23 Quadrillion"
    #   number_to_human(1234567890123456789)         # => "1230 Quadrillion"
    #   number_to_human(489939, precision: 2)        # => "490 Thousand"
    #   number_to_human(489939, precision: 4)        # => "489.9 Thousand"
    #   number_to_human(1234567, precision: 4,
    #                            significant: false) # => "1.2346 Million"
    #   number_to_human(1234567, precision: 1,
    #                            separator: ',',
    #                            significant: false) # => "1,2 Million"
    #
    # Non-significant zeros after the decimal separator are stripped
    # out by default (set <tt>:strip_insignificant_zeros</tt> to
    # +false+ to change that):
    #
    #   number_to_human(12345012345, significant_digits: 6) # => "12.345 Billion"
    #   number_to_human(500000000, precision: 5)            # => "500 Million"
    #
    # ==== Custom Unit Quantifiers
    #
    # You can also use your own custom unit quantifiers:
    #  number_to_human(500000, units: { unit: 'ml', thousand: 'lt' })  # => "500 lt"
    #
    # If in your I18n locale you have:
    #
    #   distance:
    #     centi:
    #       one: "centimeter"
    #       other: "centimeters"
    #     unit:
    #       one: "meter"
    #       other: "meters"
    #     thousand:
    #       one: "kilometer"
    #       other: "kilometers"
    #     billion: "gazillion-distance"
    #
    # Then you could do:
    #
    #   number_to_human(543934, units: :distance)            # => "544 kilometers"
    #   number_to_human(54393498, units: :distance)          # => "54400 kilometers"
    #   number_to_human(54393498000, units: :distance)       # => "54.4 gazillion-distance"
    #   number_to_human(343, units: :distance, precision: 1) # => "300 meters"
    #   number_to_human(1, units: :distance)                 # => "1 meter"
    #   number_to_human(0.34, units: :distance)              # => "34 centimeters"
    def number_to_human(number, options = {})
      options = options.symbolize_keys

      return number unless valid_float?(number)
      number = Float(number)

      defaults = format_options(options[:locale], :human)
      options  = defaults.merge!(options)

      #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
      options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)

      inverted_du = DECIMAL_UNITS.invert

      units = options.delete :units
      unit_exponents = case units
      when Hash
        units
      when String, Symbol
        I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
      when nil
        translate_number_value_with_default("human.decimal_units.units", :locale => options[:locale], :raise => true)
      else
        raise ArgumentError, ":units must be a Hash or String translation scope."
      end.keys.map{|e_name| inverted_du[e_name] }.sort_by{|e| -e}

      number_exponent = number != 0 ? Math.log10(number.abs).floor : 0
      display_exponent = unit_exponents.find{ |e| number_exponent >= e } || 0
      number  /= 10 ** display_exponent

      unit = case units
      when Hash
        units[DECIMAL_UNITS[display_exponent]]
      when String, Symbol
        I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
      else
        translate_number_value_with_default("human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
      end

      decimal_format = options[:format] || translate_number_value_with_default('human.decimal_units.format', :locale => options[:locale])
      formatted_number = self.number_to_rounded(number, options)
      decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip
    end

    def self.private_module_and_instance_method(method_name) #:nodoc:
      private method_name
      private_class_method method_name
    end
    private_class_method :private_module_and_instance_method

    def format_options(locale, namespace = nil) #:nodoc:
      default_format_options(namespace).merge!(i18n_format_options(locale, namespace))
    end
    private_module_and_instance_method :format_options

    def default_format_options(namespace = nil) #:nodoc:
      options = DEFAULTS[:format].dup
      options.merge!(DEFAULTS[namespace][:format]) if namespace
      options
    end
    private_module_and_instance_method :default_format_options

    def i18n_format_options(locale, namespace = nil) #:nodoc:
      options = I18n.translate(:'number.format', locale: locale, default: {}).dup
      if namespace
        options.merge!(I18n.translate(:"number.#{namespace}.format", locale: locale, default: {}))
      end
      options
    end
    private_module_and_instance_method :i18n_format_options

    def translate_number_value_with_default(key, i18n_options = {}) #:nodoc:
      default = key.split('.').reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }

      I18n.translate(key, { default: default, scope: :number }.merge!(i18n_options))
    end
    private_module_and_instance_method :translate_number_value_with_default

    def valid_float?(number) #:nodoc:
      Float(number)
    rescue ArgumentError, TypeError
      false
    end
    private_module_and_instance_method :valid_float?
  end
end
require 'active_support/core_ext/hash/deep_merge'

module ActiveSupport
  class OptionMerger #:nodoc:
    instance_methods.each do |method|
      undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/
    end

    def initialize(context, options)
      @context, @options = context, options
    end

    private
      def method_missing(method, *arguments, &block)
        if arguments.last.is_a?(Proc)
          proc = arguments.pop
          arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
        else
          arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
        end

        @context.__send__(method, *arguments, &block)
      end
  end
end
require 'yaml'

YAML.add_builtin_type("omap") do |type, val|
  ActiveSupport::OrderedHash[val.map{ |v| v.to_a.first }]
end

module ActiveSupport
  # <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
  # insertion order.
  #
  #   oh = ActiveSupport::OrderedHash.new
  #   oh[:a] = 1
  #   oh[:b] = 2
  #   oh.keys # => [:a, :b], this order is guaranteed
  #
  # Also, maps the +omap+ feature for YAML files
  # (See http://yaml.org/type/omap.html) to support ordered items
  # when loading from yaml.
  #
  # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
  # with other implementations.
  class OrderedHash < ::Hash
    def to_yaml_type
      "!tag:yaml.org,2002:omap"
    end

    def encode_with(coder)
      coder.represent_seq '!omap', map { |k,v| { k => v } }
    end

    def nested_under_indifferent_access
      self
    end

    # Returns true to make sure that this hash is extractable via <tt>Array#extract_options!</tt>
    def extractable_options?
      true
    end
  end
end
module ActiveSupport
  # Usually key value pairs are handled something like this:
  #
  #   h = {}
  #   h[:boy] = 'John'
  #   h[:girl] = 'Mary'
  #   h[:boy]  # => 'John'
  #   h[:girl] # => 'Mary'
  #
  # Using +OrderedOptions+, the above code could be reduced to:
  #
  #   h = ActiveSupport::OrderedOptions.new
  #   h.boy = 'John'
  #   h.girl = 'Mary'
  #   h.boy  # => 'John'
  #   h.girl # => 'Mary'
  class OrderedOptions < Hash
    alias_method :_get, :[] # preserve the original #[] method
    protected :_get # make it protected

    def []=(key, value)
      super(key.to_sym, value)
    end

    def [](key)
      super(key.to_sym)
    end

    def method_missing(name, *args)
      name_string = name.to_s
      if name_string.chomp!('=')
        self[name_string] = args.first
      else
        self[name]
      end
    end

    def respond_to_missing?(name, include_private)
      true
    end
  end

  class InheritableOptions < OrderedOptions
    def initialize(parent = nil)
      if parent.kind_of?(OrderedOptions)
        # use the faster _get when dealing with OrderedOptions
        super() { |h,k| parent._get(k) }
      elsif parent
        super() { |h,k| parent[k] }
      else
        super()
      end
    end

    def inheritable_copy
      self.class.new(self)
    end
  end
end
module ActiveSupport
  # A class with no predefined methods that behaves similarly to Builder's
  # BlankSlate. Used for proxy classes.
  class ProxyObject < ::BasicObject
    undef_method :==
    undef_method :equal?

    # Let ActiveSupport::ProxyObject at least raise exceptions.
    def raise(*args)
      ::Object.send(:raise, *args)
    end
  end
end
# This is private interface.
#
# Rails components cherry pick from Active Support as needed, but there are a
# few features that are used for sure some way or another and it is not worth
# to put individual requires absolutely everywhere. Think blank? for example.
#
# This file is loaded by every Rails component except Active Support itself,
# but it does not belong to the Rails public interface. It is internal to
# Rails and can change anytime.

# Defines Object#blank? and Object#present?.
require 'active_support/core_ext/object/blank'

# Rails own autoload, eager_load, etc.
require 'active_support/dependencies/autoload'

# Support for ClassMethods and the included macro.
require 'active_support/concern'

# Defines Class#class_attribute.
require 'active_support/core_ext/class/attribute'

# Defines Module#delegate.
require 'active_support/core_ext/module/delegation'

# Defines ActiveSupport::Deprecation.
require 'active_support/deprecation'
require "active_support"
require "active_support/i18n_railtie"

module ActiveSupport
  class Railtie < Rails::Railtie # :nodoc:
    config.active_support = ActiveSupport::OrderedOptions.new

    config.eager_load_namespaces << ActiveSupport

    initializer "active_support.deprecation_behavior" do |app|
      if deprecation = app.config.active_support.deprecation
        ActiveSupport::Deprecation.behavior = deprecation
      end
    end

    # Sets the default value for Time.zone
    # If assigned value cannot be matched to a TimeZone, an exception will be raised.
    initializer "active_support.initialize_time_zone" do |app|
      require 'active_support/core_ext/time/zones'
      zone_default = Time.find_zone!(app.config.time_zone)

      unless zone_default
        raise 'Value assigned to config.time_zone not recognized. ' \
          'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
      end

      Time.zone_default = zone_default
    end

    # Sets the default week start
    # If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
    initializer "active_support.initialize_beginning_of_week" do |app|
      require 'active_support/core_ext/date/calculations'
      beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)

      Date.beginning_of_week_default = beginning_of_week_default
    end

    initializer "active_support.set_configs" do |app|
      app.config.active_support.each do |k, v|
        k = "#{k}="
        ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
      end
    end
  end
end
require 'active_support/concern'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/proc'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/array/extract_options'

module ActiveSupport
  # Rescuable module adds support for easier exception handling.
  module Rescuable
    extend Concern

    included do
      class_attribute :rescue_handlers
      self.rescue_handlers = []
    end

    module ClassMethods
      # Rescue exceptions raised in controller actions.
      #
      # <tt>rescue_from</tt> receives a series of exception classes or class
      # names, and a trailing <tt>:with</tt> option with the name of a method
      # or a Proc object to be called to handle them. Alternatively a block can
      # be given.
      #
      # Handlers that take one argument will be called with the exception, so
      # that the exception can be inspected when dealing with it.
      #
      # Handlers are inherited. They are searched from right to left, from
      # bottom to top, and up the hierarchy. The handler of the first class for
      # which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if
      # any.
      #
      #   class ApplicationController < ActionController::Base
      #     rescue_from User::NotAuthorized, with: :deny_access # self defined exception
      #     rescue_from ActiveRecord::RecordInvalid, with: :show_errors
      #
      #     rescue_from 'MyAppError::Base' do |exception|
      #       render xml: exception, status: 500
      #     end
      #
      #     protected
      #       def deny_access
      #         ...
      #       end
      #
      #       def show_errors(exception)
      #         exception.record.new_record? ? ...
      #       end
      #   end
      #
      # Exceptions raised inside exception handlers are not propagated up.
      def rescue_from(*klasses, &block)
        options = klasses.extract_options!

        unless options.has_key?(:with)
          if block_given?
            options[:with] = block
          else
            raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument."
          end
        end

        klasses.each do |klass|
          key = if klass.is_a?(Class) && klass <= Exception
            klass.name
          elsif klass.is_a?(String)
            klass
          else
            raise ArgumentError, "#{klass} is neither an Exception nor a String"
          end

          # put the new handler at the end because the list is read in reverse
          self.rescue_handlers += [[key, options[:with]]]
        end
      end
    end

    # Tries to rescue the exception by looking up and calling a registered handler.
    def rescue_with_handler(exception)
      if handler = handler_for_rescue(exception)
        handler.arity != 0 ? handler.call(exception) : handler.call
        true # don't rely on the return value of the handler
      end
    end

    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 = self.class.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.
        #
        # Since this loop needs the constants it would be inconsistent to
        # assume they should exist at this point. An early raised exception
        # could trigger some other handler and the array could include
        # precisely a string whose corresponding constant has not yet been
        # seen. This is why we are tolerant to unknown constants.
        #
        # Note that this tolerance only matters if the exception was given as
        # a string, otherwise a NameError will be raised by the interpreter
        # itself when rescue_from CONSTANT is executed.
        klass = self.class.const_get(klass_name) rescue nil
        klass ||= klass_name.constantize rescue nil
        exception.is_a?(klass) if klass
      end

      case rescuer
      when Symbol
        method(rescuer)
      when Proc
        if rescuer.arity == 0
          Proc.new { instance_exec(&rescuer) }
        else
          Proc.new { |_exception| instance_exec(_exception, &rescuer) }
        end
      end
    end
  end
end
module ActiveSupport
  # Wrapping a string in this class gives you a prettier way to test
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
  # in a StringInquirer object so instead of calling this:
  #
  #   Rails.env == 'production'
  #
  # you can call this:
  #
  #   Rails.env.production?
  class StringInquirer < String
    private

      def respond_to_missing?(method_name, include_private = false)
        method_name[-1] == '?'
      end

      def method_missing(method_name, *arguments)
        if method_name[-1] == '?'
          self == method_name[0..-2]
        else
          super
        end
      end
  end
end
require 'active_support/core_ext/object/blank'
require 'logger'
require 'active_support/logger'

module ActiveSupport
  # Wraps any standard Logger object to provide tagging capabilities.
  #
  #   logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
  #   logger.tagged('BCX') { logger.info 'Stuff' }                            # Logs "[BCX] Stuff"
  #   logger.tagged('BCX', "Jason") { logger.info 'Stuff' }                   # Logs "[BCX] [Jason] Stuff"
  #   logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
  #
  # This is used by the default Rails.logger as configured by Railties to make
  # it easy to stamp log lines with subdomains, request ids, and anything else
  # to aid debugging of multi-user production applications.
  module TaggedLogging
    module Formatter # :nodoc:
      # This method is invoked when a log event occurs.
      def call(severity, timestamp, progname, msg)
        super(severity, timestamp, progname, "#{tags_text}#{msg}")
      end

      def tagged(*tags)
        new_tags = push_tags(*tags)
        yield self
      ensure
        pop_tags(new_tags.size)
      end

      def push_tags(*tags)
        tags.flatten.reject(&:blank?).tap do |new_tags|
          current_tags.concat new_tags
        end
      end

      def pop_tags(size = 1)
        current_tags.pop size
      end

      def clear_tags!
        current_tags.clear
      end

      def current_tags
        Thread.current[:activesupport_tagged_logging_tags] ||= []
      end

      private
        def tags_text
          tags = current_tags
          if tags.any?
            tags.collect { |tag| "[#{tag}] " }.join
          end
        end
    end

    def self.new(logger)
      # Ensure we set a default formatter so we aren't extending nil!
      logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
      logger.formatter.extend Formatter
      logger.extend(self)
    end

    delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter

    def tagged(*tags)
      formatter.tagged(*tags) { yield self }
    end

    def flush
      clear_tags!
      super if defined?(super)
    end
  end
end
gem 'minitest' # make sure we get the gem, not stdlib
require 'minitest/unit'
require 'active_support/testing/tagged_logging'
require 'active_support/testing/setup_and_teardown'
require 'active_support/testing/assertions'
require 'active_support/testing/deprecation'
require 'active_support/testing/pending'
require 'active_support/testing/declarative'
require 'active_support/testing/isolation'
require 'active_support/testing/constant_lookup'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/deprecation'

begin
  silence_warnings { require 'mocha/setup' }
rescue LoadError
end

module ActiveSupport
  class TestCase < ::MiniTest::Unit::TestCase
    Assertion = MiniTest::Assertion
    alias_method :method_name, :__name__

    $tags = {}
    def self.for_tag(tag)
      yield if $tags[tag]
    end

    # FIXME: we have tests that depend on run order, we should fix that and
    # remove this method.
    def self.test_order # :nodoc:
      :sorted
    end

    include ActiveSupport::Testing::TaggedLogging
    include ActiveSupport::Testing::SetupAndTeardown
    include ActiveSupport::Testing::Assertions
    include ActiveSupport::Testing::Deprecation
    include ActiveSupport::Testing::Pending
    extend ActiveSupport::Testing::Declarative

    # test/unit backwards compatibility methods
    alias :assert_raise :assert_raises
    alias :assert_not_empty :refute_empty
    alias :assert_not_equal :refute_equal
    alias :assert_not_in_delta :refute_in_delta
    alias :assert_not_in_epsilon :refute_in_epsilon
    alias :assert_not_includes :refute_includes
    alias :assert_not_instance_of :refute_instance_of
    alias :assert_not_kind_of :refute_kind_of
    alias :assert_no_match :refute_match
    alias :assert_not_nil :refute_nil
    alias :assert_not_operator :refute_operator
    alias :assert_not_predicate :refute_predicate
    alias :assert_not_respond_to :refute_respond_to
    alias :assert_not_same :refute_same

    # Fails if the block raises an exception.
    #
    #   assert_nothing_raised do
    #     ...
    #   end
    def assert_nothing_raised(*args)
      yield
    end
  end
end
require 'active_support/core_ext/object/blank'

module ActiveSupport
  module Testing
    module Assertions
      # Assert that an expression is not truthy. Passes if <tt>object</tt> is
      # +nil+ or +false+. "Truthy" means "considered true in a conditional"
      # like <tt>if foo</tt>.
      #
      #   assert_not nil    # => true
      #   assert_not false  # => true
      #   assert_not 'foo'  # => 'foo' is not nil or false
      #
      # An error message can be specified.
      #
      #   assert_not foo, 'foo should be false'
      def assert_not(object, message = nil)
        message ||= "Expected #{mu_pp(object)} to be nil or false"
        assert !object, message
      end

      # Test numeric difference between the return value of an expression as a
      # result of what is evaluated in the yielded block.
      #
      #   assert_difference 'Article.count' do
      #     post :create, article: {...}
      #   end
      #
      # An arbitrary expression is passed in and evaluated.
      #
      #   assert_difference 'assigns(:article).comments(:reload).size' do
      #     post :create, comment: {...}
      #   end
      #
      # An arbitrary positive or negative difference can be specified.
      # The default is <tt>1</tt>.
      #
      #   assert_difference 'Article.count', -1 do
      #     post :delete, id: ...
      #   end
      #
      # An array of expressions can also be passed in and evaluated.
      #
      #   assert_difference [ 'Article.count', 'Post.count' ], 2 do
      #     post :create, article: {...}
      #   end
      #
      # A lambda or a list of lambdas can be passed in and evaluated:
      #
      #   assert_difference ->{ Article.count }, 2 do
      #     post :create, article: {...}
      #   end
      #
      #   assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
      #     post :create, article: {...}
      #   end
      #
      # An error message can be specified.
      #
      #   assert_difference 'Article.count', -1, 'An Article should be destroyed' do
      #     post :delete, id: ...
      #   end
      def assert_difference(expression, difference = 1, message = nil, &block)
        expressions = Array(expression)

        exps = expressions.map { |e|
          e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
        }
        before = exps.map { |e| e.call }

        yield

        expressions.zip(exps).each_with_index do |(code, e), i|
          error  = "#{code.inspect} didn't change by #{difference}"
          error  = "#{message}.\n#{error}" if message
          assert_equal(before[i] + difference, e.call, error)
        end
      end

      # Assertion that the numeric result of evaluating an expression is not
      # changed before and after invoking the passed in block.
      #
      #   assert_no_difference 'Article.count' do
      #     post :create, article: invalid_attributes
      #   end
      #
      # An error message can be specified.
      #
      #   assert_no_difference 'Article.count', 'An Article should not be created' do
      #     post :create, article: invalid_attributes
      #   end
      def assert_no_difference(expression, message = nil, &block)
        assert_difference expression, 0, message, &block
      end

      # Test if an expression is blank. Passes if <tt>object.blank?</tt>
      # is +true+.
      #
      #   assert_blank []   # => true
      #   assert_blank [[]] # => [[]] is not blank
      #
      # An error message can be specified.
      #
      #   assert_blank [], 'this should be blank'
      def assert_blank(object, message=nil)
        ActiveSupport::Deprecation.warn('"assert_blank" is deprecated. Please use "assert object.blank?" instead')
        message ||= "#{object.inspect} is not blank"
        assert object.blank?, message
      end

      # Test if an expression is not blank. Passes if <tt>object.present?</tt>
      # is +true+.
      #
      #   assert_present({ data: 'x' }) # => true
      #   assert_present({})            # => {} is blank
      #
      # An error message can be specified.
      #
      #   assert_present({ data: 'x' }, 'this should not be blank')
      def assert_present(object, message=nil)
        ActiveSupport::Deprecation.warn('"assert_present" is deprecated. Please use "assert object.present?" instead')
        message ||= "#{object.inspect} is blank"
        assert object.present?, message
      end
    end
  end
end
gem 'minitest'

require 'minitest/unit'

MiniTest::Unit.autorun
require "active_support/concern"
require "active_support/inflector"

module ActiveSupport
  module Testing
    # Resolves a constant from a minitest spec name.
    #
    # Given the following spec-style test:
    #
    #   describe WidgetsController, :index do
    #     describe "authenticated user" do
    #       describe "returns widgets" do
    #         it "has a controller that exists" do
    #           assert_kind_of WidgetsController, @controller
    #         end
    #       end
    #     end
    #   end
    #
    # The test will have the following name:
    #
    #   "WidgetsController::index::authenticated user::returns widgets"
    #
    # The constant WidgetsController can be resolved from the name.
    # The following code will resolve the constant:
    #
    #   controller = determine_constant_from_test_name(name) do |constant|
    #     Class === constant && constant < ::ActionController::Metal
    #   end
    module ConstantLookup
      extend ::ActiveSupport::Concern

      module ClassMethods  # :nodoc:
        def determine_constant_from_test_name(test_name)
          names = test_name.split "::"
          while names.size > 0 do
            names.last.sub!(/Test$/, "")
            begin
              constant = names.join("::").constantize
              break(constant) if yield(constant)
            rescue NameError
              # Constant wasn't found, move on
            ensure
              names.pop
            end
          end
        end
      end

    end
  end
end
module ActiveSupport
  module Testing
    module Declarative

      def self.extended(klass) #:nodoc:
        klass.class_eval do

          unless method_defined?(:describe)
            def self.describe(text)
              class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
                def self.name
                  "#{text}"
                end
              RUBY_EVAL
            end
          end

        end
      end

      unless defined?(Spec)
        # test "verify something" do
        #   ...
        # end
        def test(name, &block)
          test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
          defined = instance_method(test_name) rescue false
          raise "#{test_name} is already defined in #{self}" if defined
          if block_given?
            define_method(test_name, &block)
          else
            define_method(test_name) do
              flunk "No implementation provided for #{name}"
            end
          end
        end
      end
    end
  end
end
require 'active_support/deprecation'

module ActiveSupport
  module Testing
    module Deprecation #:nodoc:
      def assert_deprecated(match = nil, &block)
        result, warnings = collect_deprecations(&block)
        assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
        if match
          match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
          assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
        end
        result
      end

      def assert_not_deprecated(&block)
        result, deprecations = collect_deprecations(&block)
        assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n  #{deprecations * "\n  "}"
        result
      end

      private
        def collect_deprecations
          old_behavior = ActiveSupport::Deprecation.behavior
          deprecations = []
          ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
            deprecations << message
          end
          result = yield
          [result, deprecations]
        ensure
          ActiveSupport::Deprecation.behavior = old_behavior
        end
    end
  end
end
require 'rbconfig'
begin
  require 'minitest/parallel_each'
rescue LoadError
end

module ActiveSupport
  module Testing
    class RemoteError < StandardError

      attr_reader :message, :backtrace

      def initialize(exception)
        @message = "caught #{exception.class.name}: #{exception.message}"
        @backtrace = exception.backtrace
      end
    end

    class ProxyTestResult
      def initialize(calls = [])
        @calls = calls
      end

      def add_error(e)
        e = Test::Unit::Error.new(e.test_name, RemoteError.new(e.exception))
        @calls << [:add_error, e]
      end

      def __replay__(result)
        @calls.each do |name, args|
          result.send(name, *args)
        end
      end

      def marshal_dump
        @calls
      end

      def marshal_load(calls)
        initialize(calls)
      end

      def method_missing(name, *args)
        @calls << [name, args]
      end
    end

    module Isolation
      require 'thread'

      # Recent versions of MiniTest (such as the one shipped with Ruby 2.0) already define
      # a ParallelEach class.
      unless defined? ParallelEach
        class ParallelEach
          include Enumerable

          # default to 2 cores
          CORES = (ENV['TEST_CORES'] || 2).to_i

          def initialize list
            @list  = list
            @queue = SizedQueue.new CORES
          end

          def grep pattern
            self.class.new super
          end

          def each
            threads = CORES.times.map {
              Thread.new {
                while job = @queue.pop
                  yield job
                end
              }
            }
            @list.each { |i| @queue << i }
            CORES.times { @queue << nil }
            threads.each(&:join)
          end
        end
      end

      def self.included(klass) #:nodoc:
        klass.extend(Module.new {
          def test_methods
            ParallelEach.new super
          end
        })
      end

      def self.forking_env?
        !ENV["NO_FORK"] && ((RbConfig::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/))
      end

      @@class_setup_mutex = Mutex.new

      def _run_class_setup      # class setup method should only happen in parent
        @@class_setup_mutex.synchronize do
          unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
            self.class.setup if self.class.respond_to?(:setup)
            @@ran_class_setup = true
          end
        end
      end

      def run(runner)
        _run_class_setup

        serialized = run_in_isolation do |isolated_runner|
          super(isolated_runner)
        end

        retval, proxy = Marshal.load(serialized)
        proxy.__replay__(runner)
        retval
      end

      module Forking
        def run_in_isolation(&blk)
          read, write = IO.pipe

          pid = fork do
            read.close
            proxy = ProxyTestResult.new
            retval = yield proxy
            write.puts [Marshal.dump([retval, proxy])].pack("m")
            exit!
          end

          write.close
          result = read.read
          Process.wait2(pid)
          return result.unpack("m")[0]
        end
      end

      module Subprocess
        ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)

        # Crazy H4X to get this working in windows / jruby with
        # no forking.
        def run_in_isolation(&blk)
          require "tempfile"

          if ENV["ISOLATION_TEST"]
            proxy = ProxyTestResult.new
            retval = yield proxy
            File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
              file.puts [Marshal.dump([retval, proxy])].pack("m")
            end
            exit!
          else
            Tempfile.open("isolation") do |tmpfile|
              ENV["ISOLATION_TEST"]   = @method_name
              ENV["ISOLATION_OUTPUT"] = tmpfile.path

              load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
              `#{Gem.ruby} #{load_paths} #{$0} #{ORIG_ARGV.join(" ")} -t\"#{self.class}\"`

              ENV.delete("ISOLATION_TEST")
              ENV.delete("ISOLATION_OUTPUT")

              return tmpfile.read.unpack("m")[0]
            end
          end
        end
      end

      include forking_env? ? Forking : Subprocess
    end
  end
end
require 'active_support/deprecation'

module ActiveSupport
  module Testing
    module Pending # :nodoc:
      unless defined?(Spec) 
        def pending(description = "", &block)
          ActiveSupport::Deprecation.warn("#pending is deprecated and will be removed in Rails 4.1, please use #skip instead.")
          skip(description.blank? ? nil : description)
        end
      end
    end
  end
end
require 'active_support/concern'
require 'active_support/callbacks'

module ActiveSupport
  module Testing
    module SetupAndTeardown
      extend ActiveSupport::Concern

      included do
        include ActiveSupport::Callbacks
        define_callbacks :setup, :teardown
      end

      module ClassMethods
        def setup(*args, &block)
          set_callback(:setup, :before, *args, &block)
        end

        def teardown(*args, &block)
          set_callback(:teardown, :after, *args, &block)
        end
      end

      def before_setup
        super
        run_callbacks :setup
      end

      def after_teardown
        run_callbacks :teardown
        super
      end
    end
  end
end
module ActiveSupport
  module Testing
    # Logs a "PostsControllerTest: test name" heading before each test to
    # make test.log easier to search and follow along with.
    module TaggedLogging #:nodoc:
      attr_writer :tagged_logger

      def before_setup
        if tagged_logger
          heading = "#{self.class}: #{__name__}"
          divider = '-' * heading.size
          tagged_logger.info divider
          tagged_logger.info heading
          tagged_logger.info divider
        end
        super
      end

      private
        def tagged_logger
          @tagged_logger ||= (defined?(Rails.logger) && Rails.logger)
        end
    end
  end
end
require 'active_support'

module ActiveSupport
  autoload :Duration, 'active_support/duration'
  autoload :TimeWithZone, 'active_support/time_with_zone'
  autoload :TimeZone, 'active_support/values/time_zone'
end

require 'date'
require 'time'

require 'active_support/core_ext/time'
require 'active_support/core_ext/date'
require 'active_support/core_ext/date_time'

require 'active_support/core_ext/integer/time'
require 'active_support/core_ext/numeric/time'

require 'active_support/core_ext/string/conversions'
require 'active_support/core_ext/string/zones'
require 'active_support/values/time_zone'
require 'active_support/core_ext/object/acts_like'

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.
  #
  # You shouldn't ever need to create a TimeWithZone instance directly via +new+.
  # Instead use methods +local+, +parse+, +at+ and +now+ on TimeZone instances,
  # and +in_time_zone+ on Time and DateTime instances.
  #
  #   Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  #   Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #   Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  #   Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  #
  # See Time and TimeZone for further documentation of these methods.
  #
  # TimeWithZone instances implement the same API as Ruby Time instances, so
  # that Time and TimeWithZone instances are interchangeable.
  #
  #   t = Time.zone.now                     # => Sun, 18 May 2008 13:27:25 EDT -04:00
  #   t.hour                                # => 13
  #   t.dst?                                # => true
  #   t.utc_offset                          # => -14400
  #   t.zone                                # => "EDT"
  #   t.to_s(:rfc822)                       # => "Sun, 18 May 2008 13:27:25 -0400"
  #   t + 1.day                             # => Mon, 19 May 2008 13:27:25 EDT -04:00
  #   t.beginning_of_year                   # => Tue, 01 Jan 2008 00:00:00 EST -05:00
  #   t > Time.utc(1999)                    # => true
  #   t.is_a?(Time)                         # => true
  #   t.is_a?(ActiveSupport::TimeWithZone)  # => true
  class TimeWithZone

    # Report class name as 'Time' to thwart type checking.
    def self.name
      'Time'
    end

    include Comparable
    attr_reader :time_zone

    def initialize(utc_time, time_zone, local_time = nil, period = nil)
      @utc, @time_zone, @time = utc_time, time_zone, local_time
      @period = @utc ? period : get_period_and_ensure_valid_local_time
    end

    # Returns a Time or DateTime instance that represents the time in +time_zone+.
    def time
      @time ||= period.to_local(@utc)
    end

    # Returns a Time or DateTime instance that represents the time in UTC.
    def utc
      @utc ||= period.to_utc(@time)
    end
    alias_method :comparable_time, :utc
    alias_method :getgm, :utc
    alias_method :getutc, :utc
    alias_method :gmtime, :utc

    # Returns the underlying TZInfo::TimezonePeriod.
    def period
      @period ||= time_zone.period_for_utc(@utc)
    end

    # Returns the simultaneous time in <tt>Time.zone</tt>, or the specified zone.
    def in_time_zone(new_zone = ::Time.zone)
      return self if time_zone == new_zone
      utc.in_time_zone(new_zone)
    end

    # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
    # system's <tt>ENV['TZ']</tt> zone.
    def localtime
      utc.respond_to?(:getlocal) ? utc.getlocal : utc.to_time.getlocal
    end
    alias_method :getlocal, :localtime

    # Returns true if the current time is within Daylight Savings Time for the
    # specified time zone.
    #
    #   Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
    #   Time.zone.parse("2012-5-30").dst?           # => true
    #   Time.zone.parse("2012-11-30").dst?          # => false
    def dst?
      period.dst?
    end
    alias_method :isdst, :dst?

    # Returns true if the current time zone is set to UTC.
    #
    #   Time.zone = 'UTC'                           # => 'UTC'
    #   Time.zone.now.utc?                          # => true
    #   Time.zone = 'Eastern Time (US & Canada)'    # => 'Eastern Time (US & Canada)'
    #   Time.zone.now.utc?                          # => false
    def utc?
      time_zone.name == 'UTC'
    end
    alias_method :gmt?, :utc?

    # Returns the offset from current time to UTC time in seconds.
    def utc_offset
      period.utc_total_offset
    end
    alias_method :gmt_offset, :utc_offset
    alias_method :gmtoff, :utc_offset

    # Returns a formatted string of the offset from UTC, or an alternative
    # string if the time zone is already UTC.
    #
    #   Time.zone = 'Eastern Time (US & Canada)'   # => "Eastern Time (US & Canada)"
    #   Time.zone.now.formatted_offset(true)       # => "-05:00"
    #   Time.zone.now.formatted_offset(false)      # => "-0500"
    #   Time.zone = 'UTC'                          # => "UTC"
    #   Time.zone.now.formatted_offset(true, "0")  # => "0"
    def formatted_offset(colon = true, alternate_utc_string = nil)
      utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
    end

    # Time uses +zone+ to display the time zone abbreviation, so we're
    # duck-typing it.
    def zone
      period.zone_identifier.to_s
    end

    def inspect
      "#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
    end

    def xmlschema(fraction_digits = 0)
      fraction = if fraction_digits > 0
        (".%06i" % time.usec)[0, fraction_digits + 1]
      end

      "#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
    end
    alias_method :iso8601, :xmlschema

    # Coerces time to a string for JSON encoding. The default format is ISO 8601.
    # You can get %Y/%m/%d %H:%M:%S +offset style by setting
    # <tt>ActiveSupport::JSON::Encoding.use_standard_json_time_format</tt>
    # to +false+.
    #
    #   # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
    #   Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
    #   # => "2005-02-01T15:15:10Z"
    #
    #   # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
    #   Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
    #   # => "2005/02/01 15:15:10 +0000"
    def as_json(options = nil)
      if ActiveSupport::JSON::Encoding.use_standard_json_time_format
        xmlschema(3)
      else
        %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
      end
    end

    def encode_with(coder)
      if coder.respond_to?(:represent_object)
        coder.represent_object(nil, utc)
      else
        coder.represent_scalar(nil, utc.strftime("%Y-%m-%d %H:%M:%S.%9NZ"))
      end
    end

    # Returns a string of the object's date and time in the format used by
    # HTTP requests.
    #
    #   Time.zone.now.httpdate  # => "Tue, 01 Jan 2013 04:39:43 GMT"
    def httpdate
      utc.httpdate
    end

    # Returns a string of the object's date and time in the RFC 2822 standard
    # format.
    #
    #   Time.zone.now.rfc2822  # => "Tue, 01 Jan 2013 04:51:39 +0000"
    def rfc2822
      to_s(:rfc822)
    end
    alias_method :rfc822, :rfc2822

    # <tt>:db</tt> format outputs time in UTC; all others output time in local.
    # Uses TimeWithZone's +strftime+, so <tt>%Z</tt> and <tt>%z</tt> work correctly.
    def to_s(format = :default)
      if format == :db
        utc.to_s(format)
      elsif formatter = ::Time::DATE_FORMATS[format]
        formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
      else
        "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
      end
    end
    alias_method :to_formatted_s, :to_s

    # Replaces <tt>%Z</tt> and <tt>%z</tt> directives with +zone+ and
    # +formatted_offset+, respectively, before passing to Time#strftime, so
    # that zone information is correct
    def strftime(format)
      format = format.gsub('%Z', zone)
                     .gsub('%z',   formatted_offset(false))
                     .gsub('%:z',  formatted_offset(true))
                     .gsub('%::z', formatted_offset(true) + ":00")
      time.strftime(format)
    end

    # Use the time in UTC for comparisons.
    def <=>(other)
      utc <=> other
    end

    # Returns true if the current object's time is within the specified
    # +min+ and +max+ time.
    def between?(min, max)
      utc.between?(min, max)
    end

    # Returns true if the current object's time is in the past.
    def past?
      utc.past?
    end

    # Returns true if the current object's time falls within
    # the current day.
    def today?
      time.today?
    end

    # Returns true if the current object's time is in the future.
    def future?
      utc.future?
    end

    def eql?(other)
      utc.eql?(other)
    end

    def hash
      utc.hash
    end

    def +(other)
      # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
      # otherwise move forward from #utc, for accuracy when moving across DST boundaries
      if duration_of_variable_length?(other)
        method_missing(:+, other)
      else
        result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
        result.in_time_zone(time_zone)
      end
    end

    def -(other)
      # If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
      # otherwise move backwards #utc, for accuracy when moving across DST boundaries
      if other.acts_like?(:time)
        utc.to_f - other.to_f
      elsif duration_of_variable_length?(other)
        method_missing(:-, other)
      else
        result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
        result.in_time_zone(time_zone)
      end
    end

    def since(other)
      # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
      # otherwise move forward from #utc, for accuracy when moving across DST boundaries
      if duration_of_variable_length?(other)
        method_missing(:since, other)
      else
        utc.since(other).in_time_zone(time_zone)
      end
    end

    def ago(other)
      since(-other)
    end

    def advance(options)
      # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
      # otherwise advance from #utc, for accuracy when moving across DST boundaries
      if options.values_at(:years, :weeks, :months, :days).any?
        method_missing(:advance, options)
      else
        utc.advance(options).in_time_zone(time_zone)
      end
    end

    %w(year mon month day mday wday yday hour min sec to_date).each do |method_name|
      class_eval <<-EOV, __FILE__, __LINE__ + 1
        def #{method_name}    # def month
          time.#{method_name} #   time.month
        end                   # end
      EOV
    end

    def usec
      time.respond_to?(:usec) ? time.usec : 0
    end

    def to_a
      [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
    end

    def to_f
      utc.to_f
    end

    def to_i
      utc.to_i
    end
    alias_method :tv_sec, :to_i

    # Return an instance of Time in the system timezone.
    def to_time
      utc.to_time
    end

    def to_datetime
      utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
    end

    # So that +self+ <tt>acts_like?(:time)</tt>.
    def acts_like_time?
      true
    end

    # Say we're a Time to thwart type checking.
    def is_a?(klass)
      klass == ::Time || super
    end
    alias_method :kind_of?, :is_a?

    def freeze
      period; utc; time # preload instance variables before freezing
      super
    end

    def marshal_dump
      [utc, time_zone.name, time]
    end

    def marshal_load(variables)
      initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc)
    end

    # Ensure proxy class responds to all methods that underlying time instance
    # responds to.
    def respond_to_missing?(sym, include_priv)
      # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
      return false if sym.to_sym == :acts_like_date?
      time.respond_to?(sym, include_priv)
    end

    # Send the missing method to +time+ instance, and wrap result in a new
    # TimeWithZone with the existing +time_zone+.
    def method_missing(sym, *args, &block)
      wrap_with_time_zone time.__send__(sym, *args, &block)
    end

    private
      def get_period_and_ensure_valid_local_time
        # we don't want a Time.local instance enforcing its own DST rules as well,
        # so transfer time values to a utc constructor if necessary
        @time = transfer_time_values_to_utc_constructor(@time) unless @time.utc?
        begin
          @time_zone.period_for_local(@time)
        rescue ::TZInfo::PeriodNotFound
          # time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again
          @time += 1.hour
          retry
        end
      end

      def transfer_time_values_to_utc_constructor(time)
        ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000))
      end

      def duration_of_variable_length?(obj)
        ActiveSupport::Duration === obj && obj.parts.any? {|p| [:years, :months, :days].include?(p[0]) }
      end

      def wrap_with_time_zone(time)
        if time.acts_like?(:time)
          self.class.new(nil, time_zone, time)
        elsif time.is_a?(Range)
          wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end)
        else
          time
        end
      end
  end
end
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/try'

module ActiveSupport
  # The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
  # It allows us to do the following:
  #
  # * Limit the set of zones provided by TZInfo to a meaningful subset of 142
  #   zones.
  # * Retrieve and display zones with a friendlier name
  #   (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
  # * Lazily load TZInfo::Timezone instances only when they're needed.
  # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
  #   +parse+, +at+ and +now+ methods.
  #
  # If you set <tt>config.time_zone</tt> in the Rails Application, you can
  # access this TimeZone object via <tt>Time.zone</tt>:
  #
  #   # application.rb:
  #   class Application < Rails::Application
  #     config.time_zone = 'Eastern Time (US & Canada)'
  #   end
  #
  #   Time.zone      # => #<TimeZone:0x514834...>
  #   Time.zone.name # => "Eastern Time (US & Canada)"
  #   Time.zone.now  # => Sun, 18 May 2008 14:30:44 EDT -04:00
  #
  # The version of TZInfo bundled with Active Support only includes the
  # definitions necessary to support the zones defined by the TimeZone class.
  # If you need to use zones that aren't defined by TimeZone, you'll need to
  # install the TZInfo gem (if a recent version of the gem is installed locally,
  # this will be used instead of the bundled version.)
  class TimeZone
    # Keys are Rails TimeZone names, values are TZInfo identifiers.
    MAPPING = {
      "International Date Line West" => "Pacific/Midway",
      "Midway Island"                => "Pacific/Midway",
      "American Samoa"               => "Pacific/Pago_Pago",
      "Hawaii"                       => "Pacific/Honolulu",
      "Alaska"                       => "America/Juneau",
      "Pacific Time (US & Canada)"   => "America/Los_Angeles",
      "Tijuana"                      => "America/Tijuana",
      "Mountain Time (US & Canada)"  => "America/Denver",
      "Arizona"                      => "America/Phoenix",
      "Chihuahua"                    => "America/Chihuahua",
      "Mazatlan"                     => "America/Mazatlan",
      "Central Time (US & Canada)"   => "America/Chicago",
      "Saskatchewan"                 => "America/Regina",
      "Guadalajara"                  => "America/Mexico_City",
      "Mexico City"                  => "America/Mexico_City",
      "Monterrey"                    => "America/Monterrey",
      "Central America"              => "America/Guatemala",
      "Eastern Time (US & Canada)"   => "America/New_York",
      "Indiana (East)"               => "America/Indiana/Indianapolis",
      "Bogota"                       => "America/Bogota",
      "Lima"                         => "America/Lima",
      "Quito"                        => "America/Lima",
      "Atlantic Time (Canada)"       => "America/Halifax",
      "Caracas"                      => "America/Caracas",
      "La Paz"                       => "America/La_Paz",
      "Santiago"                     => "America/Santiago",
      "Newfoundland"                 => "America/St_Johns",
      "Brasilia"                     => "America/Sao_Paulo",
      "Buenos Aires"                 => "America/Argentina/Buenos_Aires",
      "Georgetown"                   => "America/Guyana",
      "Greenland"                    => "America/Godthab",
      "Mid-Atlantic"                 => "Atlantic/South_Georgia",
      "Azores"                       => "Atlantic/Azores",
      "Cape Verde Is."               => "Atlantic/Cape_Verde",
      "Dublin"                       => "Europe/Dublin",
      "Edinburgh"                    => "Europe/London",
      "Lisbon"                       => "Europe/Lisbon",
      "London"                       => "Europe/London",
      "Casablanca"                   => "Africa/Casablanca",
      "Monrovia"                     => "Africa/Monrovia",
      "UTC"                          => "Etc/UTC",
      "Belgrade"                     => "Europe/Belgrade",
      "Bratislava"                   => "Europe/Bratislava",
      "Budapest"                     => "Europe/Budapest",
      "Ljubljana"                    => "Europe/Ljubljana",
      "Prague"                       => "Europe/Prague",
      "Sarajevo"                     => "Europe/Sarajevo",
      "Skopje"                       => "Europe/Skopje",
      "Warsaw"                       => "Europe/Warsaw",
      "Zagreb"                       => "Europe/Zagreb",
      "Brussels"                     => "Europe/Brussels",
      "Copenhagen"                   => "Europe/Copenhagen",
      "Madrid"                       => "Europe/Madrid",
      "Paris"                        => "Europe/Paris",
      "Amsterdam"                    => "Europe/Amsterdam",
      "Berlin"                       => "Europe/Berlin",
      "Bern"                         => "Europe/Berlin",
      "Rome"                         => "Europe/Rome",
      "Stockholm"                    => "Europe/Stockholm",
      "Vienna"                       => "Europe/Vienna",
      "West Central Africa"          => "Africa/Algiers",
      "Bucharest"                    => "Europe/Bucharest",
      "Cairo"                        => "Africa/Cairo",
      "Helsinki"                     => "Europe/Helsinki",
      "Kyiv"                         => "Europe/Kiev",
      "Riga"                         => "Europe/Riga",
      "Sofia"                        => "Europe/Sofia",
      "Tallinn"                      => "Europe/Tallinn",
      "Vilnius"                      => "Europe/Vilnius",
      "Athens"                       => "Europe/Athens",
      "Istanbul"                     => "Europe/Istanbul",
      "Minsk"                        => "Europe/Minsk",
      "Jerusalem"                    => "Asia/Jerusalem",
      "Harare"                       => "Africa/Harare",
      "Pretoria"                     => "Africa/Johannesburg",
      "Moscow"                       => "Europe/Moscow",
      "St. Petersburg"               => "Europe/Moscow",
      "Volgograd"                    => "Europe/Moscow",
      "Kuwait"                       => "Asia/Kuwait",
      "Riyadh"                       => "Asia/Riyadh",
      "Nairobi"                      => "Africa/Nairobi",
      "Baghdad"                      => "Asia/Baghdad",
      "Tehran"                       => "Asia/Tehran",
      "Abu Dhabi"                    => "Asia/Muscat",
      "Muscat"                       => "Asia/Muscat",
      "Baku"                         => "Asia/Baku",
      "Tbilisi"                      => "Asia/Tbilisi",
      "Yerevan"                      => "Asia/Yerevan",
      "Kabul"                        => "Asia/Kabul",
      "Ekaterinburg"                 => "Asia/Yekaterinburg",
      "Islamabad"                    => "Asia/Karachi",
      "Karachi"                      => "Asia/Karachi",
      "Tashkent"                     => "Asia/Tashkent",
      "Chennai"                      => "Asia/Kolkata",
      "Kolkata"                      => "Asia/Kolkata",
      "Mumbai"                       => "Asia/Kolkata",
      "New Delhi"                    => "Asia/Kolkata",
      "Kathmandu"                    => "Asia/Kathmandu",
      "Astana"                       => "Asia/Dhaka",
      "Dhaka"                        => "Asia/Dhaka",
      "Sri Jayawardenepura"          => "Asia/Colombo",
      "Almaty"                       => "Asia/Almaty",
      "Novosibirsk"                  => "Asia/Novosibirsk",
      "Rangoon"                      => "Asia/Rangoon",
      "Bangkok"                      => "Asia/Bangkok",
      "Hanoi"                        => "Asia/Bangkok",
      "Jakarta"                      => "Asia/Jakarta",
      "Krasnoyarsk"                  => "Asia/Krasnoyarsk",
      "Beijing"                      => "Asia/Shanghai",
      "Chongqing"                    => "Asia/Chongqing",
      "Hong Kong"                    => "Asia/Hong_Kong",
      "Urumqi"                       => "Asia/Urumqi",
      "Kuala Lumpur"                 => "Asia/Kuala_Lumpur",
      "Singapore"                    => "Asia/Singapore",
      "Taipei"                       => "Asia/Taipei",
      "Perth"                        => "Australia/Perth",
      "Irkutsk"                      => "Asia/Irkutsk",
      "Ulaan Bataar"                 => "Asia/Ulaanbaatar",
      "Seoul"                        => "Asia/Seoul",
      "Osaka"                        => "Asia/Tokyo",
      "Sapporo"                      => "Asia/Tokyo",
      "Tokyo"                        => "Asia/Tokyo",
      "Yakutsk"                      => "Asia/Yakutsk",
      "Darwin"                       => "Australia/Darwin",
      "Adelaide"                     => "Australia/Adelaide",
      "Canberra"                     => "Australia/Melbourne",
      "Melbourne"                    => "Australia/Melbourne",
      "Sydney"                       => "Australia/Sydney",
      "Brisbane"                     => "Australia/Brisbane",
      "Hobart"                       => "Australia/Hobart",
      "Vladivostok"                  => "Asia/Vladivostok",
      "Guam"                         => "Pacific/Guam",
      "Port Moresby"                 => "Pacific/Port_Moresby",
      "Magadan"                      => "Asia/Magadan",
      "Solomon Is."                  => "Pacific/Guadalcanal",
      "New Caledonia"                => "Pacific/Noumea",
      "Fiji"                         => "Pacific/Fiji",
      "Kamchatka"                    => "Asia/Kamchatka",
      "Marshall Is."                 => "Pacific/Majuro",
      "Auckland"                     => "Pacific/Auckland",
      "Wellington"                   => "Pacific/Auckland",
      "Nuku'alofa"                   => "Pacific/Tongatapu",
      "Tokelau Is."                  => "Pacific/Fakaofo",
      "Samoa"                        => "Pacific/Apia"
    }

    UTC_OFFSET_WITH_COLON = '%s%02d:%02d'
    UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.sub(':', '')

    # Assumes self represents an offset from UTC in seconds (as returned from
    # Time#utc_offset) and turns this into an +HH:MM formatted string.
    #
    #   TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00"
    def self.seconds_to_utc_offset(seconds, colon = true)
      format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON
      sign = (seconds < 0 ? '-' : '+')
      hours = seconds.abs / 3600
      minutes = (seconds.abs % 3600) / 60
      format % [sign, hours, minutes]
    end

    include Comparable
    attr_reader :name
    attr_reader :tzinfo

    # Create a new TimeZone object with the given name and offset. The
    # offset is the number of seconds that this time zone is offset from UTC
    # (GMT). Seconds were chosen as the offset unit because that is the unit
    # that Ruby uses to represent time zone offsets (see Time#utc_offset).
    def initialize(name, utc_offset = nil, tzinfo = nil)
      self.class.send(:require_tzinfo)

      @name = name
      @utc_offset = utc_offset
      @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
      @current_period = nil
    end

    # Returns the offset of this time zone from UTC in seconds.
    def utc_offset
      if @utc_offset
        @utc_offset
      else
        @current_period ||= tzinfo.try(:current_period)
        @current_period.try(:utc_offset)
      end
    end

    # Returns the offset of this time zone as a formatted string, of the
    # format "+HH:MM".
    def formatted_offset(colon=true, alternate_utc_string = nil)
      utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon)
    end

    # Compare this time zone to the parameter. The two are compared first on
    # their offsets, and then by name.
    def <=>(zone)
      result = (utc_offset <=> zone.utc_offset)
      result = (name <=> zone.name) if result == 0
      result
    end

    # Compare #name and TZInfo identifier to a supplied regexp, returning +true+
    # if a match is found.
    def =~(re)
      return true if name =~ re || MAPPING[name] =~ re
    end

    # Returns a textual representation of this time zone.
    def to_s
      "(GMT#{formatted_offset}) #{name}"
    end

    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
    # of +self+ from given values.
    #
    #   Time.zone = 'Hawaii'                    # => "Hawaii"
    #   Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00
    def local(*args)
      time = Time.utc(*args)
      ActiveSupport::TimeWithZone.new(nil, self, time)
    end

    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
    # of +self+ from number of seconds since the Unix epoch.
    #
    #   Time.zone = 'Hawaii'        # => "Hawaii"
    #   Time.utc(2000).to_f         # => 946684800.0
    #   Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00
    def at(secs)
      Time.at(secs).utc.in_time_zone(self)
    end

    # Method for creating new ActiveSupport::TimeWithZone instance in time zone
    # of +self+ from parsed string.
    #
    #   Time.zone = 'Hawaii'                   # => "Hawaii"
    #   Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
    #
    # If upper components are missing from the string, they are supplied from
    # TimeZone#now:
    #
    #   Time.zone.now               # => Fri, 31 Dec 1999 14:00:00 HST -10:00
    #   Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00
    def parse(str, now=now)
      parts = Date._parse(str, false)
      return if parts.empty?

      time = Time.new(
        parts.fetch(:year, now.year),
        parts.fetch(:mon, now.month),
        parts.fetch(:mday, now.day),
        parts.fetch(:hour, 0),
        parts.fetch(:min, 0),
        parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
        parts.fetch(:offset, 0)
      )

      if parts[:offset]
        TimeWithZone.new(time.utc, self)
      else
        TimeWithZone.new(nil, self, time)
      end
    end

    # Returns an ActiveSupport::TimeWithZone instance representing the current
    # time in the time zone represented by +self+.
    #
    #   Time.zone = 'Hawaii'  # => "Hawaii"
    #   Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00
    def now
      time_now.utc.in_time_zone(self)
    end

    # Return the current date in this time zone.
    def today
      tzinfo.now.to_date
    end

    # Adjust the given time to the simultaneous time in the time zone
    # represented by +self+. Returns a Time.utc() instance -- if you want an
    # ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.
    def utc_to_local(time)
      tzinfo.utc_to_local(time)
    end

    # Adjust the given time to the simultaneous time in UTC. Returns a
    # Time.utc() instance.
    def local_to_utc(time, dst=true)
      tzinfo.local_to_utc(time, dst)
    end

    # Available so that TimeZone instances respond like TZInfo::Timezone
    # instances.
    def period_for_utc(time)
      tzinfo.period_for_utc(time)
    end

    # Available so that TimeZone instances respond like TZInfo::Timezone
    # instances.
    def period_for_local(time, dst=true)
      tzinfo.period_for_local(time, dst)
    end

    def self.find_tzinfo(name)
      TZInfo::TimezoneProxy.new(MAPPING[name] || name)
    end

    class << self
      alias_method :create, :new

      # Return a TimeZone instance with the given name, or +nil+ if no
      # such TimeZone instance exists. (This exists to support the use of
      # this class with the +composed_of+ macro.)
      def new(name)
        self[name]
      end

      # Return an array of all TimeZone objects. There are multiple
      # TimeZone objects per time zone, in many cases, to make it easier
      # for users to find their own time zone.
      def all
        @zones ||= zones_map.values.sort
      end

      def zones_map
        @zones_map ||= begin
          new_zones_names = MAPPING.keys - lazy_zones_map.keys
          new_zones       = Hash[new_zones_names.map { |place| [place, create(place)] }]

          lazy_zones_map.merge(new_zones)
        end
      end

      # Locate a specific time zone object. If the argument is a string, it
      # is interpreted to mean the name of the timezone to locate. If it is a
      # numeric value it is either the hour offset, or the second offset, of the
      # timezone to find. (The first one with that offset will be returned.)
      # Returns +nil+ if no such time zone is known to the system.
      def [](arg)
        case arg
          when String
          begin
            lazy_zones_map[arg] ||= lookup(arg).tap { |tz| tz.utc_offset }
          rescue TZInfo::InvalidTimezoneIdentifier
            nil
          end
          when Numeric, ActiveSupport::Duration
            arg *= 3600 if arg.abs <= 13
            all.find { |z| z.utc_offset == arg.to_i }
          else
            raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}"
        end
      end

      # A convenience method for returning a collection of TimeZone objects
      # for time zones in the USA.
      def us_zones
        @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
      end

      protected

        def require_tzinfo
          require 'tzinfo' unless defined?(::TZInfo)
        rescue LoadError
          $stderr.puts "You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"
          raise
        end

      private

        def lookup(name)
          (tzinfo = find_tzinfo(name)) && create(tzinfo.name.freeze)
        end

        def lazy_zones_map
          require_tzinfo

          @lazy_zones_map ||= Hash.new do |hash, place|
            hash[place] = create(place) if MAPPING.has_key?(place)
          end
        end
    end

    private

    def time_now
      Time.now
    end
  end
end
module ActiveSupport
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/

require 'jruby'
include Java

require 'active_support/core_ext/object/blank'

java_import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder
java_import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory
java_import java.io.StringReader unless defined? StringReader
java_import org.xml.sax.InputSource unless defined? InputSource
java_import org.xml.sax.Attributes unless defined? Attributes
java_import org.w3c.dom.Node unless defined? Node

module ActiveSupport
  module XmlMini_JDOM #:nodoc:
    extend self

    CONTENT_KEY = '__content__'.freeze

    NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
    DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
    PROCESSING_INSTRUCTION_NODE TEXT_NODE}

    node_type_map = {}
    NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }

    # Parse an XML Document string or IO into a simple hash using Java's jdom.
    # data::
    #   XML Document string or IO to parse
    def parse(data)
      if data.respond_to?(:read)
        data = data.read
      end

      if data.blank?
        {}
      else
        @dbf = DocumentBuilderFactory.new_instance
        xml_string_reader = StringReader.new(data)
        xml_input_source = InputSource.new(xml_string_reader)
        doc = @dbf.new_document_builder.parse(xml_input_source)
        merge_element!({CONTENT_KEY => ''}, doc.document_element)
      end
    end

    private

    # Convert an XML element and merge into the hash
    #
    # hash::
    #   Hash to merge the converted element into.
    # element::
    #   XML element to merge into hash
    def merge_element!(hash, element)
      delete_empty(hash)
      merge!(hash, element.tag_name, collapse(element))
    end

    def delete_empty(hash)
      hash.delete(CONTENT_KEY) if hash[CONTENT_KEY] == ''
    end

    # Actually converts an XML document element into a data structure.
    #
    # element::
    #   The document element to be collapsed.
    def collapse(element)
      hash = get_attributes(element)

      child_nodes = element.child_nodes
      if child_nodes.length > 0
        (0...child_nodes.length).each do |i|
          child = child_nodes.item(i)
          merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE
        end
        merge_texts!(hash, element) unless empty_content?(element)
        hash
      else
        merge_texts!(hash, element)
      end
    end

    # Merge all the texts of an element into the hash
    #
    # hash::
    #   Hash to add the converted element to.
    # element::
    #   XML element whose texts are to me merged into the hash
    def merge_texts!(hash, element)
      delete_empty(hash)
      text_children = texts(element)
      if text_children.join.empty?
        hash
      else
        # must use value to prevent double-escaping
        merge!(hash, CONTENT_KEY, text_children.join)
      end
    end

    # Adds a new key/value pair to an existing Hash. If the key to be added
    # already exists and the existing value associated with key is not
    # an Array, it will be wrapped in an Array. Then the new value is
    # appended to that Array.
    #
    # hash::
    #   Hash to add key/value pair to.
    # key::
    #   Key to be added.
    # value::
    #   Value to be associated with key.
    def merge!(hash, key, value)
      if hash.has_key?(key)
        if hash[key].instance_of?(Array)
          hash[key] << value
        else
          hash[key] = [hash[key], value]
        end
      elsif value.instance_of?(Array)
        hash[key] = [value]
      else
        hash[key] = value
      end
      hash
    end

    # Converts the attributes array of an XML element into a hash.
    # Returns an empty Hash if node has no attributes.
    #
    # element::
    #   XML element to extract attributes from.
    def get_attributes(element)
      attribute_hash = {}
      attributes = element.attributes
      (0...attributes.length).each do |i|
         attribute_hash[CONTENT_KEY] ||= ''
         attribute_hash[attributes.item(i).name] =  attributes.item(i).value
       end
      attribute_hash
    end

    # Determines if a document element has text content
    #
    # element::
    #   XML element to be checked.
    def texts(element)
      texts = []
      child_nodes = element.child_nodes
      (0...child_nodes.length).each do |i|
        item = child_nodes.item(i)
        if item.node_type == Node.TEXT_NODE
          texts << item.get_data
        end
      end
      texts
    end

    # Determines if a document element has text content
    #
    # element::
    #   XML element to be checked.
    def empty_content?(element)
      text = ''
      child_nodes = element.child_nodes
      (0...child_nodes.length).each do |i|
        item = child_nodes.item(i)
        if item.node_type == Node.TEXT_NODE
          text << item.get_data.strip
        end
      end
      text.strip.length == 0
    end
  end
end
require 'libxml'
require 'active_support/core_ext/object/blank'
require 'stringio'

module ActiveSupport
  module XmlMini_LibXML #:nodoc:
    extend self

    # Parse an XML Document string or IO into a simple hash using libxml.
    # data::
    #   XML Document string or IO to parse
    def parse(data)
      if !data.respond_to?(:read)
        data = StringIO.new(data || '')
      end

      char = data.getc
      if char.nil?
        {}
      else
        data.ungetc(char)
        LibXML::XML::Parser.io(data).parse.to_hash
      end
    end

  end
end

module LibXML #:nodoc:
  module Conversions #:nodoc:
    module Document #:nodoc:
      def to_hash
        root.to_hash
      end
    end

    module Node #:nodoc:
      CONTENT_ROOT = '__content__'.freeze

      # Convert XML document to hash.
      #
      # hash::
      #   Hash to merge the converted element into.
      def to_hash(hash={})
        node_hash = {}

        # Insert node hash into parent hash correctly.
        case hash[name]
          when Array then hash[name] << node_hash
          when Hash  then hash[name] = [hash[name], node_hash]
          when nil   then hash[name] = node_hash
        end

        # Handle child elements
        each_child do |c|
          if c.element?
            c.to_hash(node_hash)
          elsif c.text? || c.cdata?
            node_hash[CONTENT_ROOT] ||= ''
            node_hash[CONTENT_ROOT] << c.content
          end
        end

        # Remove content node if it is blank
        if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank?
          node_hash.delete(CONTENT_ROOT)
        end

        # Handle attributes
        each_attr { |a| node_hash[a.name] = a.value }

        hash
      end
    end
  end
end

LibXML::XML::Document.send(:include, LibXML::Conversions::Document)
LibXML::XML::Node.send(:include, LibXML::Conversions::Node)
require 'libxml'
require 'active_support/core_ext/object/blank'
require 'stringio'

module ActiveSupport
  module XmlMini_LibXMLSAX #:nodoc:
    extend self

    # Class that will build the hash while the XML document
    # is being parsed using SAX events.
    class HashBuilder

      include LibXML::XML::SaxParser::Callbacks

      CONTENT_KEY   = '__content__'.freeze
      HASH_SIZE_KEY = '__hash_size__'.freeze

      attr_reader :hash

      def current_hash
        @hash_stack.last
      end

      def on_start_document
        @hash = { CONTENT_KEY => '' }
        @hash_stack = [@hash]
      end

      def on_end_document
        @hash = @hash_stack.pop
        @hash.delete(CONTENT_KEY)
      end

      def on_start_element(name, attrs = {})
        new_hash = { CONTENT_KEY => '' }.merge(attrs)
        new_hash[HASH_SIZE_KEY] = new_hash.size + 1

        case current_hash[name]
          when Array then current_hash[name] << new_hash
          when Hash  then current_hash[name] = [current_hash[name], new_hash]
          when nil   then current_hash[name] = new_hash
        end

        @hash_stack.push(new_hash)
      end

      def on_end_element(name)
        if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ''
          current_hash.delete(CONTENT_KEY)
        end
        @hash_stack.pop
      end

      def on_characters(string)
        current_hash[CONTENT_KEY] << string
      end

      alias_method :on_cdata_block, :on_characters
    end

    attr_accessor :document_class
    self.document_class = HashBuilder

    def parse(data)
      if !data.respond_to?(:read)
        data = StringIO.new(data || '')
      end

      char = data.getc
      if char.nil?
        {}
      else
        data.ungetc(char)

        LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
        parser = LibXML::XML::SaxParser.io(data)
        document = self.document_class.new

        parser.callbacks = document
        parser.parse
        document.hash
      end
    end
  end
end
begin
  require 'nokogiri'
rescue LoadError => e
  $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
  raise e
end
require 'active_support/core_ext/object/blank'
require 'stringio'

module ActiveSupport
  module XmlMini_Nokogiri #:nodoc:
    extend self

    # Parse an XML Document string or IO into a simple hash using libxml / nokogiri.
    # data::
    #   XML Document string or IO to parse
    def parse(data)
      if !data.respond_to?(:read)
        data = StringIO.new(data || '')
      end

      char = data.getc
      if char.nil?
        {}
      else
        data.ungetc(char)
        doc = Nokogiri::XML(data)
        raise doc.errors.first if doc.errors.length > 0
        doc.to_hash
      end
    end

    module Conversions #:nodoc:
      module Document #:nodoc:
        def to_hash
          root.to_hash
        end
      end

      module Node #:nodoc:
        CONTENT_ROOT = '__content__'.freeze

        # Convert XML document to hash.
        #
        # hash::
        #   Hash to merge the converted element into.
        def to_hash(hash={})
          node_hash = {}

          # Insert node hash into parent hash correctly.
          case hash[name]
            when Array then hash[name] << node_hash
            when Hash  then hash[name] = [hash[name], node_hash]
            when nil   then hash[name] = node_hash
          end

          # Handle child elements
          children.each do |c|
            if c.element?
              c.to_hash(node_hash)
            elsif c.text? || c.cdata?
              node_hash[CONTENT_ROOT] ||= ''
              node_hash[CONTENT_ROOT] << c.content
            end
          end

          # Remove content node if it is blank and there are child tags
          if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank?
            node_hash.delete(CONTENT_ROOT)
          end

          # Handle attributes
          attribute_nodes.each { |a| node_hash[a.node_name] = a.value }

          hash
        end
      end
    end

    Nokogiri::XML::Document.send(:include, Conversions::Document)
    Nokogiri::XML::Node.send(:include, Conversions::Node)
  end
end
begin
  require 'nokogiri'
rescue LoadError => e
  $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
  raise e
end
require 'active_support/core_ext/object/blank'
require 'stringio'

module ActiveSupport
  module XmlMini_NokogiriSAX #:nodoc:
    extend self

    # Class that will build the hash while the XML document
    # is being parsed using SAX events.
    class HashBuilder < Nokogiri::XML::SAX::Document

      CONTENT_KEY   = '__content__'.freeze
      HASH_SIZE_KEY = '__hash_size__'.freeze

      attr_reader :hash

      def current_hash
        @hash_stack.last
      end

      def start_document
        @hash = {}
        @hash_stack = [@hash]
      end

      def end_document
        raise "Parse stack not empty!" if @hash_stack.size > 1
      end

      def error(error_message)
        raise error_message
      end

      def start_element(name, attrs = [])
        new_hash = { CONTENT_KEY => '' }.merge(Hash[attrs])
        new_hash[HASH_SIZE_KEY] = new_hash.size + 1

        case current_hash[name]
          when Array then current_hash[name] << new_hash
          when Hash  then current_hash[name] = [current_hash[name], new_hash]
          when nil   then current_hash[name] = new_hash
        end

        @hash_stack.push(new_hash)
      end

      def end_element(name)
        if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == ''
          current_hash.delete(CONTENT_KEY)
        end
        @hash_stack.pop
      end

      def characters(string)
        current_hash[CONTENT_KEY] << string
      end

      alias_method :cdata_block, :characters
    end

    attr_accessor :document_class
    self.document_class = HashBuilder

    def parse(data)
      if !data.respond_to?(:read)
        data = StringIO.new(data || '')
      end

      char = data.getc
      if char.nil?
        {}
      else
        data.ungetc(char)
        document = self.document_class.new
        parser = Nokogiri::XML::SAX::Parser.new(document)
        parser.parse(data)
        document.hash
      end
    end
  end
end
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/object/blank'
require 'stringio'

module ActiveSupport
  module XmlMini_REXML #:nodoc:
    extend self

    CONTENT_KEY = '__content__'.freeze

    # Parse an XML Document string or IO into a simple hash.
    #
    # Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
    # and uses the defaults from Active Support.
    #
    # data::
    #   XML Document string or IO to parse
    def parse(data)
      if !data.respond_to?(:read)
        data = StringIO.new(data || '')
      end

      char = data.getc
      if char.nil?
        {}
      else
        data.ungetc(char)
        silence_warnings { require 'rexml/document' } unless defined?(REXML::Document)
        doc = REXML::Document.new(data)

        if doc.root
          merge_element!({}, doc.root)
        else
          raise REXML::ParseException,
            "The document #{doc.to_s.inspect} does not have a valid root"
        end
      end
    end

    private
      # Convert an XML element and merge into the hash
      #
      # hash::
      #   Hash to merge the converted element into.
      # element::
      #   XML element to merge into hash
      def merge_element!(hash, element)
        merge!(hash, element.name, collapse(element))
      end

      # Actually converts an XML document element into a data structure.
      #
      # element::
      #   The document element to be collapsed.
      def collapse(element)
        hash = get_attributes(element)

        if element.has_elements?
          element.each_element {|child| merge_element!(hash, child) }
          merge_texts!(hash, element) unless empty_content?(element)
          hash
        else
          merge_texts!(hash, element)
        end
      end

      # Merge all the texts of an element into the hash
      #
      # hash::
      #   Hash to add the converted element to.
      # element::
      #   XML element whose texts are to me merged into the hash
      def merge_texts!(hash, element)
        unless element.has_text?
          hash
        else
          # must use value to prevent double-escaping
          texts = ''
          element.texts.each { |t| texts << t.value }
          merge!(hash, CONTENT_KEY, texts)
        end
      end

      # Adds a new key/value pair to an existing Hash. If the key to be added
      # already exists and the existing value associated with key is not
      # an Array, it will be wrapped in an Array. Then the new value is
      # appended to that Array.
      #
      # hash::
      #   Hash to add key/value pair to.
      # key::
      #   Key to be added.
      # value::
      #   Value to be associated with key.
      def merge!(hash, key, value)
        if hash.has_key?(key)
          if hash[key].instance_of?(Array)
            hash[key] << value
          else
            hash[key] = [hash[key], value]
          end
        elsif value.instance_of?(Array)
          hash[key] = [value]
        else
          hash[key] = value
        end
        hash
      end

      # Converts the attributes array of an XML element into a hash.
      # Returns an empty Hash if node has no attributes.
      #
      # element::
      #   XML element to extract attributes from.
      def get_attributes(element)
        attributes = {}
        element.attributes.each { |n,v| attributes[n] = v }
        attributes
      end

      # Determines if a document element has text content
      #
      # element::
      #   XML element to be checked.
      def empty_content?(element)
        element.texts.join.blank?
      end
  end
end
require 'time'
require 'base64'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/string/inflections'

module ActiveSupport
  # = XmlMini
  #
  # To use the much faster libxml parser:
  #   gem 'libxml-ruby', '=0.9.7'
  #   XmlMini.backend = 'LibXML'
  module XmlMini
    extend self

    # This module decorates files deserialized using Hash.from_xml with
    # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
    module FileLike #:nodoc:
      attr_writer :original_filename, :content_type

      def original_filename
        @original_filename || 'untitled'
      end

      def content_type
        @content_type || 'application/octet-stream'
      end
    end

    DEFAULT_ENCODINGS = {
      "binary" => "base64"
    } unless defined?(DEFAULT_ENCODINGS)

    TYPE_NAMES = {
      "Symbol"     => "symbol",
      "Fixnum"     => "integer",
      "Bignum"     => "integer",
      "BigDecimal" => "decimal",
      "Float"      => "float",
      "TrueClass"  => "boolean",
      "FalseClass" => "boolean",
      "Date"       => "date",
      "DateTime"   => "dateTime",
      "Time"       => "dateTime",
      "Array"      => "array",
      "Hash"       => "hash"
    } unless defined?(TYPE_NAMES)

    FORMATTING = {
      "symbol"   => Proc.new { |symbol| symbol.to_s },
      "date"     => Proc.new { |date| date.to_s(:db) },
      "dateTime" => Proc.new { |time| time.xmlschema },
      "binary"   => Proc.new { |binary| ::Base64.encode64(binary) },
      "yaml"     => Proc.new { |yaml| yaml.to_yaml }
    } unless defined?(FORMATTING)

    # TODO use regexp instead of Date.parse
    unless defined?(PARSING)
      PARSING = {
        "symbol"       => Proc.new { |symbol|  symbol.to_sym },
        "date"         => Proc.new { |date|    ::Date.parse(date) },
        "datetime"     => Proc.new { |time|    Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
        "integer"      => Proc.new { |integer| integer.to_i },
        "float"        => Proc.new { |float|   float.to_f },
        "decimal"      => Proc.new { |number|  BigDecimal(number) },
        "boolean"      => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
        "string"       => Proc.new { |string|  string.to_s },
        "yaml"         => Proc.new { |yaml|    YAML::load(yaml) rescue yaml },
        "base64Binary" => Proc.new { |bin|     ::Base64.decode64(bin) },
        "binary"       => Proc.new { |bin, entity| _parse_binary(bin, entity) },
        "file"         => Proc.new { |file, entity| _parse_file(file, entity) }
      }

      PARSING.update(
        "double"   => PARSING["float"],
        "dateTime" => PARSING["datetime"]
      )
    end

    delegate :parse, :to => :backend

    def backend
      current_thread_backend || @backend
    end

    def backend=(name)
      backend = name && cast_backend_name_to_module(name)
      self.current_thread_backend = backend if current_thread_backend
      @backend = backend
    end

    def with_backend(name)
      old_backend = current_thread_backend
      self.current_thread_backend = name && cast_backend_name_to_module(name)
      yield
    ensure
      self.current_thread_backend = old_backend
    end

    def to_tag(key, value, options)
      type_name = options.delete(:type)
      merged_options = options.merge(:root => key, :skip_instruct => true)

      if value.is_a?(::Method) || value.is_a?(::Proc)
        if value.arity == 1
          value.call(merged_options)
        else
          value.call(merged_options, key.to_s.singularize)
        end
      elsif value.respond_to?(:to_xml)
        value.to_xml(merged_options)
      else
        type_name ||= TYPE_NAMES[value.class.name]
        type_name ||= value.class.name if value && !value.respond_to?(:to_str)
        type_name   = type_name.to_s   if type_name
        type_name   = "dateTime" if type_name == "datetime"

        key = rename_key(key.to_s, options)

        attributes = options[:skip_types] || type_name.nil? ? { } : { :type => type_name }
        attributes[:nil] = true if value.nil?

        encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name]
        attributes[:encoding] = encoding if encoding

        formatted_value = FORMATTING[type_name] && !value.nil? ?
          FORMATTING[type_name].call(value) : value

        options[:builder].tag!(key, formatted_value, attributes)
      end
    end

    def rename_key(key, options = {})
      camelize  = options[:camelize]
      dasherize = !options.has_key?(:dasherize) || options[:dasherize]
      if camelize
        key = true == camelize ? key.camelize : key.camelize(camelize)
      end
      key = _dasherize(key) if dasherize
      key
    end

    protected

    def _dasherize(key)
      # $2 must be a non-greedy regex for this to work
      left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1,3]
      "#{left}#{middle.tr('_ ', '--')}#{right}"
    end

    # TODO: Add support for other encodings
    def _parse_binary(bin, entity) #:nodoc:
      case entity['encoding']
      when 'base64'
        ::Base64.decode64(bin)
      else
        bin
      end
    end

    def _parse_file(file, entity)
      f = StringIO.new(::Base64.decode64(file))
      f.extend(FileLike)
      f.original_filename = entity['name']
      f.content_type = entity['content_type']
      f
    end

    private

      def current_thread_backend
        Thread.current[:xml_mini_backend]
      end

      def current_thread_backend=(name)
        Thread.current[:xml_mini_backend] = name && cast_backend_name_to_module(name)
      end

      def cast_backend_name_to_module(name)
        if name.is_a?(Module)
          name
        else
          require "active_support/xml_mini/#{name.downcase}"
          ActiveSupport.const_get("XmlMini_#{name}")
        end
      end
  end

  XmlMini.backend = 'REXML'
end
#--
# Copyright (c) 2005-2013 David Heinemeier Hansson
#
# 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.
#++

require 'securerandom'
require "active_support/dependencies/autoload"
require "active_support/version"
require "active_support/logger"
require "active_support/lazy_load_hooks"

module ActiveSupport
  extend ActiveSupport::Autoload

  autoload :Concern
  autoload :Dependencies
  autoload :DescendantsTracker
  autoload :FileUpdateChecker
  autoload :LogSubscriber
  autoload :Notifications

  eager_autoload do
    autoload :BacktraceCleaner
    autoload :BasicObject
    autoload :ProxyObject
    autoload :Benchmarkable
    autoload :Cache
    autoload :Callbacks
    autoload :Configurable
    autoload :Deprecation
    autoload :Gzip
    autoload :Inflector
    autoload :JSON
    autoload :KeyGenerator
    autoload :MessageEncryptor
    autoload :MessageVerifier
    autoload :Multibyte
    autoload :OptionMerger
    autoload :OrderedHash
    autoload :OrderedOptions
    autoload :StringInquirer
    autoload :TaggedLogging
    autoload :XmlMini
  end

  autoload :Rescuable
  autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
  autoload :TestCase
end

autoload :I18n, "active_support/i18n"
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :reset_session instead.
  protect_from_forgery :with => :exception
endmodule ApplicationHelper
end
require File.expand_path('../boot', __FILE__)

require 'rails/all'

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line.
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line.
  # Bundler.require(:default, :assets, Rails.env)
end

module Blog
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)

    # Activate observers that should always be running.
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Enable escaping HTML in JSON. The default is false.
    # config.active_support.escape_html_entities_in_json = true

    # Use SQL instead of Active Record's schema dumper when creating the database.
    # This is necessary if your schema can't be completely dumped by the schema dumper,
    # like if you have constraints or database-specific column types.
    # config.active_record.schema_format = :sql

    # Enforce whitelist mode for mass assignment.
    # This will create an empty whitelist of attributes available for mass-assignment for all models
    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
    # parameters by using an attr_accessible or attr_protected declaration.
    config.active_record.whitelist_attributes = true

    # Specifies whether or not has_many or has_one association option :dependent => :restrict raises
    # an exception. If set to true, then an ActiveRecord::DeleteRestrictionError exception would be
    # raised. If set to false, then an error will be added on the model instead.
    config.active_record.dependent_restrict_raises = false

    # Enable the asset pipeline.
    config.assets.enabled = true

    # Version of your assets, change this if you want to expire all your assets.
    config.assets.version = '1.0'
  end
end
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
# Load the rails application
require File.expand_path('../application', __FILE__)

# Initialize the rails application
Blog::Application.initialize!
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Only use best-standards-support built into browsers.
  config.action_dispatch.best_standards_support = :builtin

  # Raise exception on mass assignment protection for Active Record models.
  config.active_record.mass_assignment_sanitizer = :strict

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Do not compress assets.
  config.assets.compress = false

  # Expands the lines which load the assets.
  config.assets.debug = true

  # In development, use an in-memory queue for queueing
  config.queue = Rails::Queueing::Queue
end
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Disable Rails's static asset server (Apache or nginx will already do this).
  config.serve_static_assets = false

  # Compress JavaScripts and CSS.
  config.assets.compress = true

  # Don't fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Generate digests for assets URLs.
  config.assets.digest = true

  # Defaults to nil and saved in location specified by config.assets.prefix
  # config.assets.manifest = YOUR_PATH

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  # config.force_ssl = true

  # Set to :debug to see everything in the log.
  config.log_level = :info

  # Prepend all log lines with the following tags.
  # config.log_tags = [ :subdomain, :uuid ]

  # Use a different logger for distributed setups.
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = "http://assets.example.com"

  # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added).
  # config.assets.precompile += %w( search.js )

  # Disable delivery errors, bad email addresses will be ignored.
  # config.action_mailer.raise_delivery_errors = false

  # Enable threaded mode.
  # config.threadsafe!

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  # config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Disable automatic flushing of the log to improve performance.
  # config.autoflush_log = false

  # Use default logging formatter so that PID and timestamp are not suppressed
  config.log_formatter = ::Logger::Formatter.new

  # Default the production mode queue to an in-memory queue. You will probably
  # want to replace this with an out-of-process queueing solution
  config.queue = Rails::Queueing::Queue
end
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # The test environment is used exclusively to run your application's
  # test suite. You never need to work with it otherwise. Remember that
  # your test database is "scratch space" for the test suite and is wiped
  # and recreated between test runs. Don't rely on the data there!
  config.cache_classes = true

  # Configure static asset server for tests with Cache-Control for performance.
  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=3600"

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Raise exceptions instead of rendering exception templates.
  config.action_dispatch.show_exceptions = false

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Raise exception on mass assignment protection for Active Record models.
  config.active_record.mass_assignment_sanitizer = :strict

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr

  # Use the testing queue
  config.queue = Rails::Queueing::TestQueue
end
# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end
#
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect|
#   inflect.acronym 'RESTful'
# end
# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
# Be sure to restart your server when you modify this file.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# Make sure your secret_token is kept private
# if you're sharing your code publicly.
Blog::Application.config.secret_token = 'c3506f27fb9dccbc56aaa14aef6bbbd2f2c115ba3198830bc97dca5bcc0d55db9fd12caa8aabeaa6fd31a12316575d2ef09c1b340b3fb168596ad3ad5196eb6a'
# Be sure to restart your server when you modify this file.

Blog::Application.config.session_store :cookie_store, key: '_blog_session'

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Blog::Application.config.session_store :active_record_store
# Be sure to restart your server when you modify this file.
#
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
  self.include_root_in_json = false
end
Blog::Application.routes.draw do
  # The priority is based upon order of creation:
  # first created -> highest priority.

  # Sample of regular route:
  #   get 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  #   get 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)

  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', :on => :collection
  #     end
  #   end

  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => 'welcome#index'

  # See how all your routes lay out with "rake routes"
end# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
#   Mayor.create(name: 'Emanuel', city: cities.first)
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils

commands = [
  'mysql -e "create database activerecord_unittest;"',
  'mysql -e "create database activerecord_unittest2;"',
  'psql  -c "create database activerecord_unittest;" -U postgres',
  'psql  -c "create database activerecord_unittest2;" -U postgres'
]

commands.each do |command|
  system("#{command} > /dev/null 2>&1")
end

class Build
  MAP = {
    'railties' => 'railties',
    'ap'   => 'actionpack',
    'am'   => 'actionmailer',
    'amo'  => 'activemodel',
    'as'   => 'activesupport',
    'ar'   => 'activerecord'
  }

  attr_reader :component, :options

  def initialize(component, options = {})
    @component = component
    @options = options
  end

  def run!(options = {})
    self.options.update(options)
    Dir.chdir(dir) do
      announce(heading)
      rake(*tasks)
    end
  end

  def announce(heading)
    puts "\n\e[1;33m[Travis CI] #{heading}\e[m\n"
  end

  def heading
    heading = [gem]
    heading << "with #{adapter}" if activerecord?
    heading << "in isolation" if isolated?
    heading.join(' ')
  end

  def tasks
    if activerecord?
      ['mysql:rebuild_databases', "#{adapter}:#{'isolated_' if isolated?}test"]
    else
      ["test#{':isolated' if isolated?}"]
    end
  end

  def key
    key = [gem]
    key << adapter if activerecord?
    key << 'isolated' if isolated?
    key.join(':')
  end

  def activerecord?
    gem == 'activerecord'
  end

  def isolated?
    options[:isolated]
  end

  def gem
    MAP[component.split(':').first]
  end
  alias :dir :gem

  def adapter
    component.split(':').last
  end

  def rake(*tasks)
    tasks.each do |task|
      cmd = "bundle exec rake #{task}"
      puts "Running command: #{cmd}"
      return false unless system(cmd)
    end
    true
  end
end

results = {}

ENV['GEM'].split(',').each do |gem|
  [false, true].each do |isolated|
    next if gem == 'railties' && isolated

    build = Build.new(gem, :isolated => isolated)
    results[build.key] = build.run!

  end
end

# puts
# puts "Build environment:"
# puts "  #{`cat /etc/issue`}"
# puts "  #{`uname -a`}"
# puts "  #{`ruby -v`}"
# puts "  #{`mysql --version`}"
# # puts "  #{`pg_config --version`}"
# puts "  SQLite3: #{`sqlite3 -version`}"
# `gem env`.each_line {|line| print "   #{line}"}
# puts "   Bundled gems:"
# `bundle show`.each_line {|line| print "     #{line}"}
# puts "   Local gems:"
# `gem list`.each_line {|line| print "     #{line}"}

failures = results.select { |key, value| value == false }

if failures.empty?
  puts
  puts "Rails build finished successfully"
  exit(true)
else
  puts
  puts "Rails build FAILED"
  puts "Failed components: #{failures.map { |component| component.first }.join(', ')}"
  exit(false)
end
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end
class CommentsController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy
  
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(params[:comment].permit(:commenter, :body))
    redirect_to post_path(@post)
  end

  def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])
    @comment.destroy
    redirect_to post_path(@post)
  end
end
class PostsController < ApplicationController

  http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
  
  def index
    @posts = Post.all
  end

  def show
    @post = Post.find(params[:id])
  end

  def edit
    @post = Post.find(params[:id])
  end

  def update
    @post = Post.find(params[:id])

    if @post.update(params[:post].permit(:title, :text))
      redirect_to action: :show, id: @post.id
    else
      render 'edit'
    end
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new(params[:post].permit(:title, :text))

    if @post.save
      redirect_to action: :show, id: @post.id
    else
      render 'new'
    end
  end

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    redirect_to action: :index
  end
end
class WelcomeController < ApplicationController
  def index
  end
end
module ApplicationHelper
end
module CommentsHelper
end
module PostsHelper
end
module WelcomeHelper
end
class Comment < ActiveRecord::Base
  belongs_to :post
end
class Post < ActiveRecord::Base
  has_many :comments, dependent: :destroy
  
  validates :title,
    presence: true,
    length: { minimum: 5 }
end
require File.expand_path('../boot', __FILE__)

require 'rails/all'

# Assets should be precompiled for production (so we don't need the gems loaded then)
Bundler.require(*Rails.groups(assets: %w(development test)))

module Blog
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)
  end
end
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
# Load the rails application.
require File.expand_path('../application', __FILE__)

# Initialize the rails application.
Blog::Application.initialize!
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Do not eager load code on boot.
  config.eager_load = false

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Only use best-standards-support built into browsers.
  config.action_dispatch.best_standards_support = :builtin

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Raise an error on page load if there are pending migrations
  config.active_record.migration_error = :page_load

  # Debug mode disables concatenation and preprocessing of assets.
  config.assets.debug = true
end
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Eager load code on boot. This eager loads most of Rails and
  # your application in memory, allowing both thread web servers
  # and those relying on copy on write to perform better.
  # Rake tasks automatically ignore this option for performance.
  config.eager_load = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Enable Rack::Cache to put a simple HTTP cache in front of your application
  # Add `rack-cache` to your Gemfile before enabling this.
  # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
  # config.action_dispatch.rack_cache = true

  # Disable Rails's static asset server (Apache or nginx will already do this).
  config.serve_static_assets = false

  # Compress JavaScripts and CSS.
  config.assets.js_compressor  = :uglifier
  # config.assets.css_compressor = :sass

  # Whether to fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Generate digests for assets URLs.
  config.assets.digest = true

  # Version of your assets, change this if you want to expire all your assets.
  config.assets.version = '1.0'

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  # config.force_ssl = true

  # Set to :debug to see everything in the log.
  config.log_level = :info

  # Prepend all log lines with the following tags.
  # config.log_tags = [ :subdomain, :uuid ]

  # Use a different logger for distributed setups.
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = "http://assets.example.com"

  # Precompile additional assets.
  # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
  # config.assets.precompile += %w( search.js )

  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  # config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Disable automatic flushing of the log to improve performance.
  # config.autoflush_log = false

  # Use default logging formatter so that PID and timestamp are not suppressed.
  config.log_formatter = ::Logger::Formatter.new
end
Blog::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # The test environment is used exclusively to run your application's
  # test suite. You never need to work with it otherwise. Remember that
  # your test database is "scratch space" for the test suite and is wiped
  # and recreated between test runs. Don't rely on the data there!
  config.cache_classes = true

  # Do not eager load code on boot. This avoids loading your whole application
  # just for the purpose of running a single test. If you are using a tool that
  # preloads Rails for running tests, you may have to set it to true.
  config.eager_load = false

  # Configure static asset server for tests with Cache-Control for performance.
  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=3600"

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Raise exceptions instead of rendering exception templates.
  config.action_dispatch.show_exceptions = false

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr
end
# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# Be sure to restart your server when you modify this file.

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end

# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.acronym 'RESTful'
# end
# Be sure to restart your server when you modify this file.

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# Rails.application.config.time_zone = 'Central Time (US & Canada)'

# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# Rails.application.config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# Rails.application.config.i18n.default_locale = :de
# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
# Be sure to restart your server when you modify this file.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rake secret` to generate a secure secret key.

# Make sure your secret_key_base is kept private
# if you're sharing your code publicly.
Blog::Application.config.secret_key_base = 'e8aab50cec8a06a75694111a4cbaf6e22fc288ccbc6b268683aae7273043c69b15ca07d10c92a788dd6077a54762cbfcc55f19c3459f7531221b3169f8171a53'
# Be sure to restart your server when you modify this file.

Blog::Application.config.session_store :encrypted_cookie_store, key: '_blog_session'
# Be sure to restart your server when you modify this file.

# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
#  self.include_root_in_json = true
# end
Blog::Application.routes.draw do
  resources :posts do
    resources :comments
  end
 
  root to: "welcome#index"
end
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.text :text

      t.timestamps
    end
  end
end
class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :commenter
      t.text :body
      t.references :post, index: true

      t.timestamps
    end
  end
end
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20130122045842) do

  create_table "comments", force: true do |t|
    t.string   "commenter"
    t.text     "body"
    t.integer  "post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "comments", ["post_id"], name: "index_comments_on_post_id"

  create_table "posts", force: true do |t|
    t.string   "title"
    t.text     "text"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
#   Mayor.create(name: 'Emanuel', city: cities.first)
# ---------------------------------------------------------------------------
#
# This script generates the guides. It can be invoked via the
# guides:generate rake task within the guides directory.
#
# Guides are taken from the source directory, and the resulting HTML goes into the
# output directory. Assets are stored under files, and copied to output/files as
# part of the generation process.
#
# Some arguments may be passed via environment variables:
#
#   WARNINGS
#     If you are writing a guide, please work always with WARNINGS=1. Users can
#     generate the guides, and thus this flag is off by default.
#
#     Internal links (anchors) are checked. If a reference is broken levenshtein
#     distance is used to suggest an existing one. This is useful since IDs are
#     generated by Markdown from headers and thus edits alter them.
#
#     Also detects duplicated IDs. They happen if there are headers with the same
#     text. Please do resolve them, if any, so guides are valid XHTML.
#
#   ALL
#    Set to "1" to force the generation of all guides.
#
#   ONLY
#     Use ONLY if you want to generate only one or a set of guides. Prefixes are
#     enough:
#
#       # generates only association_basics.html
#       ONLY=assoc ruby rails_guides.rb
#
#     Separate many using commas:
#
#       # generates only association_basics.html and migrations.html
#       ONLY=assoc,migrations ruby rails_guides.rb
#
#     Note that if you are working on a guide generation will by default process
#     only that one, so ONLY is rarely used nowadays.
#
#   GUIDES_LANGUAGE
#     Use GUIDES_LANGUAGE when you want to generate translated guides in
#     <tt>source/<GUIDES_LANGUAGE></tt> folder (such as <tt>source/es</tt>).
#     Ignore it when generating English guides.
#
#   EDGE
#     Set to "1" to indicate generated guides should be marked as edge. This
#     inserts a badge and changes the preamble of the home page.
#
# ---------------------------------------------------------------------------

require 'set'
require 'fileutils'

require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/object/blank'
require 'action_controller'
require 'action_view'

require 'rails_guides/indexer'
require 'rails_guides/helpers'
require 'rails_guides/levenshtein'

module RailsGuides
  class Generator
    attr_reader :guides_dir, :source_dir, :output_dir, :edge, :warnings, :all

    GUIDES_RE = /\.(?:erb|md)\z/

    def initialize(output=nil)
      set_flags_from_environment

      if kindle?
        check_for_kindlegen
        register_kindle_mime_types
      end

      initialize_dirs(output)
      create_output_dir_if_needed
    end

    def set_flags_from_environment
      @edge     = ENV['EDGE']     == '1'
      @warnings = ENV['WARNINGS'] == '1'
      @all      = ENV['ALL']      == '1'
      @kindle   = ENV['KINDLE']   == '1'
      @version  = ENV['RAILS_VERSION'] || 'local'
      @lang     = ENV['GUIDES_LANGUAGE']
    end

    def register_kindle_mime_types
      Mime::Type.register_alias("application/xml", :opf, %w(opf))
      Mime::Type.register_alias("application/xml", :ncx, %w(ncx))
    end

    def generate
      generate_guides
      copy_assets
      generate_mobi if kindle?
    end

    private

    def kindle?
      @kindle
    end

    def check_for_kindlegen
      if `which kindlegen`.blank?
        raise "Can't create a kindle version without `kindlegen`."
      end
    end

    def generate_mobi
      require 'rails_guides/kindle'
      out = "#{output_dir}/kindlegen.out"
      Kindle.generate(output_dir, mobi, out)
      puts "(kindlegen log at #{out})."
    end

    def mobi
      "ruby_on_rails_guides_#@version%s.mobi" % (@lang.present? ? ".#@lang" : '')
    end

    def initialize_dirs(output)
      @guides_dir = File.join(File.dirname(__FILE__), '..')
      @source_dir = "#@guides_dir/source/#@lang"
      @output_dir = if output
        output
      elsif kindle?
        "#@guides_dir/output/kindle/#@lang"
      else
        "#@guides_dir/output/#@lang"
      end.sub(%r</$>, '')
    end

    def create_output_dir_if_needed
      FileUtils.mkdir_p(output_dir)
    end

    def generate_guides
      guides_to_generate.each do |guide|
        output_file = output_file_for(guide)
        generate_guide(guide, output_file) if generate?(guide, output_file)
      end
    end

    def guides_to_generate
      guides = Dir.entries(source_dir).grep(GUIDES_RE)

      if kindle?
        Dir.entries("#{source_dir}/kindle").grep(GUIDES_RE).map do |entry|
          next if entry == 'KINDLE.md'
          guides << "kindle/#{entry}"
        end
      end

      ENV.key?('ONLY') ? select_only(guides) : guides
    end

    def select_only(guides)
      prefixes = ENV['ONLY'].split(",").map(&:strip)
      guides.select do |guide|
        prefixes.any? { |p| guide.start_with?(p) || guide.start_with?("kindle") }
      end
    end

    def copy_assets
      FileUtils.cp_r(Dir.glob("#{guides_dir}/assets/*"), output_dir)
    end

    def output_file_for(guide)
      if guide.end_with?('.md')
        guide.sub(/md\z/, 'html')
      else
        guide.sub(/\.erb\z/, '')
      end
    end

    def output_path_for(output_file)
      File.join(output_dir, File.basename(output_file))
    end

    def generate?(source_file, output_file)
      fin  = File.join(source_dir, source_file)
      fout = output_path_for(output_file)
      all || !File.exists?(fout) || File.mtime(fout) < File.mtime(fin)
    end

    def generate_guide(guide, output_file)
      output_path = output_path_for(output_file)
      puts "Generating #{guide} as #{output_file}"
      layout = kindle? ? 'kindle/layout' : 'layout'

      File.open(output_path, 'w') do |f|
        view = ActionView::Base.new(source_dir, :edge => @edge, :version => @version, :mobi => "kindle/#{mobi}")
        view.extend(Helpers)

        if guide =~ /\.(\w+)\.erb$/
          # Generate the special pages like the home.
          # Passing a template handler in the template name is deprecated. So pass the file name without the extension.
          result = view.render(:layout => layout, :formats => [$1], :file => $`)
        else
          body = File.read(File.join(source_dir, guide))
          result = RailsGuides::Markdown.new(view, layout).render(body)

          warn_about_broken_links(result) if @warnings
        end

        f.write(result)
      end
    end

    def warn_about_broken_links(html)
      anchors = extract_anchors(html)
      check_fragment_identifiers(html, anchors)
    end

    def extract_anchors(html)
      # Markdown generates headers with IDs computed from titles.
      anchors = Set.new
      html.scan(/<h\d\s+id="([^"]+)/).flatten.each do |anchor|
        if anchors.member?(anchor)
          puts "*** DUPLICATE ID: #{anchor}, please make sure that there're no headings with the same name at the same level."
        else
          anchors << anchor
        end
      end

      # Footnotes.
      anchors += Set.new(html.scan(/<p\s+class="footnote"\s+id="([^"]+)/).flatten)
      anchors += Set.new(html.scan(/<sup\s+class="footnote"\s+id="([^"]+)/).flatten)
      return anchors
    end

    def check_fragment_identifiers(html, anchors)
      html.scan(/<a\s+href="#([^"]+)/).flatten.each do |fragment_identifier|
        next if fragment_identifier == 'mainCol' # in layout, jumps to some DIV
        unless anchors.member?(fragment_identifier)
          guess = anchors.min { |a, b|
            Levenshtein.distance(fragment_identifier, a) <=> Levenshtein.distance(fragment_identifier, b)
          }
          puts "*** BROKEN LINK: ##{fragment_identifier}, perhaps you meant ##{guess}."
        end
      end
    end
  end
end
module RailsGuides
  module Helpers
    def guide(name, url, options = {}, &block)
      link = content_tag(:a, :href => url) { name }
      result = content_tag(:dt, link)

      if options[:work_in_progress]
        result << content_tag(:dd, 'Work in progress', :class => 'work-in-progress')
      end

      result << content_tag(:dd, capture(&block))
      result
    end

    def documents_by_section
      @documents_by_section ||= YAML.load_file(File.expand_path('../../source/documents.yaml', __FILE__))
    end

    def documents_flat
      documents_by_section.map {|section| section['documents']}.flatten
    end

    def finished_documents(documents)
      documents.reject { |document| document['work_in_progress'] }
    end

    def docs_for_menu(position=nil)
      if position.nil?
        documents_by_section
      elsif position == 'L'
        documents_by_section.to(3)
      else
        documents_by_section.from(4)
      end
    end

    def author(name, nick, image = 'credits_pic_blank.gif', &block)
      image = "images/#{image}"

      result = content_tag(:img, nil, :src => image, :class => 'left pic', :alt => name, :width => 91, :height => 91)
      result << content_tag(:h3, name)
      result << content_tag(:p, capture(&block))
      content_tag(:div, result, :class => 'clearfix', :id => nick)
    end

    def code(&block)
      c = capture(&block)
      content_tag(:code, c)
    end
  end
end
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/inflections'

module RailsGuides
  class Indexer
    attr_reader :body, :result, :warnings, :level_hash

    def initialize(body, warnings)
      @body     = body
      @result   = @body.dup
      @warnings = warnings
    end

    def index
      @level_hash = process(body)
    end

    private

    def process(string, current_level=3, counters=[1])
      s = StringScanner.new(string)

      level_hash = {}

      while !s.eos?
        re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}
        s.match?(re)
        if matched = s.matched
          matched =~ re
          level, idx, title = $1.to_i, $2, $3.strip

          if level < current_level
            # This is needed. Go figure.
            return level_hash
          elsif level == current_level
            index = counters.join(".")
            idx ||= '#' + title_to_idx(title)

            raise "Parsing Fail" unless @result.sub!(matched, "h#{level}(#{idx}). #{index} #{title}")

            key = {
              :title => title,
              :id => idx
            }
            # Recurse
            counters << 1
            level_hash[key] = process(s.post_match, current_level + 1, counters)
            counters.pop

            # Increment the current level
            last = counters.pop
            counters << last + 1
          end
        end
        s.getch
      end
      level_hash
    end

    def title_to_idx(title)
      idx = title.strip.parameterize.sub(/^\d+/, '')
      if warnings && idx.blank?
        puts "BLANK ID: please put an explicit ID for section #{title}, as in h5(#my-id)"
      end
      idx
    end
  end
end
#!/usr/bin/env ruby

unless `which kindlerb` 
  abort "Please gem install kindlerb"
end

require 'nokogiri'
require 'fileutils'
require 'yaml'
require 'date'

module Kindle
  extend self

  def generate(output_dir, mobi_outfile, logfile)
    output_dir = File.absolute_path(output_dir)
    Dir.chdir output_dir do 
      puts "=> Using output dir: #{output_dir}"
      puts "=> Arranging html pages in document order"
      toc = File.read("toc.ncx")
      doc = Nokogiri::XML(toc).xpath("//ncx:content", 'ncx' => "http://www.daisy.org/z3986/2005/ncx/")
      html_pages = doc.select {|c| c[:src]}.map {|c| c[:src]}.uniq
     
      generate_front_matter(html_pages)

      generate_sections(html_pages)

      generate_document_metadata(mobi_outfile)

      puts "Creating MOBI document with kindlegen. This make take a while."
      cmd = "kindlerb . > #{File.absolute_path logfile} 2>&1"
      puts cmd
      system(cmd)
      puts "MOBI document generated at #{File.expand_path(mobi_outfile, output_dir)}"
    end
  end

  def generate_front_matter(html_pages)
    frontmatter = []
    html_pages.delete_if {|x| 
      if x =~ /(toc|welcome|credits|copyright).html/
        frontmatter << x unless x =~ /toc/
        true
      end
    }
    html = frontmatter.map {|x|
      Nokogiri::HTML(File.open(x)).at("body").inner_html
    }.join("\n")

    fdoc = Nokogiri::HTML(html)
    fdoc.search("h3").each do |h3|
      h3.name = 'h4'
    end
    fdoc.search("h2").each do |h2| 
      h2.name = 'h3'
      h2['id'] = h2.inner_text.gsub(/\s/, '-')
    end
    add_head_section fdoc, "Front Matter"
    File.open("frontmatter.html",'w') {|f| f.puts fdoc.to_html}
    html_pages.unshift "frontmatter.html"
  end

  def generate_sections(html_pages)
    FileUtils::rm_rf("sections/")
    html_pages.each_with_index do |page, section_idx|
      FileUtils::mkdir_p("sections/%03d" % section_idx)
      doc = Nokogiri::HTML(File.open(page))
      title = doc.at("title").inner_text.gsub("Ruby on Rails Guides: ", '')
      title = page.capitalize.gsub('.html', '') if title.strip == ''
      File.open("sections/%03d/_section.txt" % section_idx, 'w') {|f| f.puts title}
      doc.xpath("//h3[@id]").each_with_index do |h3,item_idx|
        subsection = h3.inner_text
        content = h3.xpath("./following-sibling::*").take_while {|x| x.name != "h3"}.map {|x| x.to_html}
        item = Nokogiri::HTML(h3.to_html + content.join("\n"))
        item_path = "sections/%03d/%03d.html" % [section_idx, item_idx] 
        add_head_section(item, subsection)
        item.search("img").each do |img|
          img['src'] = "#{Dir.pwd}/#{img['src']}"
        end
        item.xpath("//li/p").each {|p| p.swap(p.children); p.remove}
        File.open(item_path, 'w') {|f| f.puts item.to_html}
      end
    end
  end

  def generate_document_metadata(mobi_outfile)
    puts "=> Generating _document.yml"
    x = Nokogiri::XML(File.open("rails_guides.opf")).remove_namespaces!
    cover_jpg = "#{Dir.pwd}/images/rails_guides_kindle_cover.jpg"
    cover_gif = cover_jpg.sub(/jpg$/, 'gif')
    puts `convert #{cover_jpg} #{cover_gif}`
    document = {
      'doc_uuid' => x.at("package")['unique-identifier'],
      'title' => x.at("title").inner_text.gsub(/\(.*$/, " v2"),
      'publisher' => x.at("publisher").inner_text,
      'author' => x.at("creator").inner_text,
      'subject' => x.at("subject").inner_text,
      'date' => x.at("date").inner_text,
      'cover' => cover_gif,
      'masthead' => nil,
      'mobi_outfile' => mobi_outfile
    }
    puts document.to_yaml
    File.open("_document.yml", 'w'){|f| f.puts document.to_yaml}
  end

  def add_head_section(doc, title)
    head = Nokogiri::XML::Node.new "head", doc
    title_node = Nokogiri::XML::Node.new "title", doc
    title_node.content = title
    title_node.parent = head
    css = Nokogiri::XML::Node.new "link", doc
    css['rel'] = 'stylesheet'
    css['type'] = 'text/css'
    css['href'] = "#{Dir.pwd}/stylesheets/kindle.css"
    css.parent = head
    doc.at("body").before head
  end
end
module RailsGuides
  module Levenshtein
    # Based on the pseudocode in http://en.wikipedia.org/wiki/Levenshtein_distance
    def self.distance(s1, s2)
      s = s1.unpack('U*')
      t = s2.unpack('U*')
      m = s.length
      n = t.length

      # matrix initialization
      d = []
      0.upto(m) { |i| d << [i] }
      0.upto(n) { |j| d[0][j] = j }

      # distance computation
      1.upto(m) do |i|
        1.upto(n) do |j|
          cost = s[i] == t[j] ? 0 : 1
          d[i][j] = [
            d[i-1][j] + 1,      # deletion
            d[i][j-1] + 1,      # insertion
            d[i-1][j-1] + cost, # substitution
          ].min
        end
      end

      # all done
      return d[m][n]
    end
  end
end
module RailsGuides
  class Markdown
    class Renderer < Redcarpet::Render::HTML
      def initialize(options={})
        super
      end

      def block_code(code, language)
        <<-HTML
<div class="code_container">
<pre class="brush: #{brush_for(language)}; gutter: false; toolbar: false">
#{ERB::Util.h(code)}
</pre>
</div>
HTML
      end

      def header(text, header_level)
        # Always increase the heading level by, so we can use h1, h2 heading in the document
        header_level += 1

        %(<h#{header_level}>#{text}</h#{header_level}>)
      end

      def paragraph(text)
        if text =~ /^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:](.*?)/
          convert_notes(text)
        elsif text =~ /^\[<sup>(\d+)\]:<\/sup> (.+)$/
          linkback = %(<a href="#footnote-#{$1}-ref"><sup>#{$1}</sup></a>)
          %(<p class="footnote" id="footnote-#{$1}">#{linkback} #{$2}</p>)
        else
          text = convert_footnotes(text)
          "<p>#{text}</p>"
        end
      end

      private

        def convert_footnotes(text)
          text.gsub(/\[<sup>(\d+)\]<\/sup>/i) do
            %(<sup class="footnote" id="footnote-#{$1}-ref">) +
              %(<a href="#footnote-#{$1}">#{$1}</a></sup>)
          end
        end

        def brush_for(code_type)
          case code_type
            when 'ruby', 'sql', 'plain'
              code_type
            when 'erb'
              'ruby; html-script: true'
            when 'html'
              'xml' # html is understood, but there are .xml rules in the CSS
            else
              'plain'
          end
        end

        def convert_notes(body)
          # The following regexp detects special labels followed by a
          # paragraph, perhaps at the end of the document.
          #
          # It is important that we do not eat more than one newline
          # because formatting may be wrong otherwise. For example,
          # if a bulleted list follows the first item is not rendered
          # as a list item, but as a paragraph starting with a plain
          # asterisk.
          body.gsub(/^(TIP|IMPORTANT|CAUTION|WARNING|NOTE|INFO|TODO)[.:](.*?)(\n(?=\n)|\Z)/m) do |m|
            css_class = case $1
                        when 'CAUTION', 'IMPORTANT'
                          'warning'
                        when 'TIP'
                          'info'
                        else
                          $1.downcase
                        end
            %(<div class="#{css_class}"><p>#{$2.strip}</p></div>)
          end
        end
    end
  end
end
# encoding: utf-8

require 'redcarpet'
require 'nokogiri'
require 'rails_guides/markdown/renderer'

module RailsGuides
  class Markdown
    def initialize(view, layout)
      @view = view
      @layout = layout
      @index_counter = Hash.new(0)
      @raw_header = ''
      @node_ids = {}
    end

    def render(body)
      @raw_body = body
      extract_raw_header_and_body
      generate_header
      generate_title
      generate_body
      generate_structure
      generate_index
      render_page
    end

    private

      def dom_id(nodes)
        dom_id = dom_id_text(nodes.last.text)

        # Fix duplicate node by prefix with its parent node
        if @node_ids[dom_id]
          if @node_ids[dom_id].size > 1
            duplicate_nodes = @node_ids.delete(dom_id)
            new_node_id = "#{duplicate_nodes[-2][:id]}-#{duplicate_nodes.last[:id]}"
            duplicate_nodes.last[:id] = new_node_id
            @node_ids[new_node_id] = duplicate_nodes
          end

          dom_id = "#{nodes[-2][:id]}-#{dom_id}"
        end

        @node_ids[dom_id] = nodes
        dom_id
      end

      def dom_id_text(text)
        text.downcase.gsub(/\?/, '-questionmark').gsub(/!/, '-bang').gsub(/[^a-z0-9]+/, ' ')
          .strip.gsub(/\s+/, '-')
      end

      def engine
        @engine ||= Redcarpet::Markdown.new(Renderer, {
          no_intra_emphasis: true,
          fenced_code_blocks: true,
          autolink: true,
          strikethrough: true,
          superscript: true,
          tables: true
        })
      end

      def extract_raw_header_and_body
        if @raw_body =~ /^\-{40,}$/
          @raw_header, _, @raw_body = @raw_body.partition(/^\-{40,}$/).map(&:strip)
        end
      end

      def generate_body
        @body = engine.render(@raw_body)
      end

      def generate_header
        @header = engine.render(@raw_header).html_safe
      end

      def generate_structure
        @headings_for_index = []
        if @body.present?
          @body = Nokogiri::HTML(@body).tap do |doc|
            hierarchy = []

            doc.at('body').children.each do |node|
              if node.name =~ /^h[3-6]$/
                case node.name
                when 'h3'
                  hierarchy = [node]
                  @headings_for_index << [1, node, node.inner_html]
                when 'h4'
                  hierarchy = hierarchy[0, 1] + [node]
                  @headings_for_index << [2, node, node.inner_html]
                when 'h5'
                  hierarchy = hierarchy[0, 2] + [node]
                when 'h6'
                  hierarchy = hierarchy[0, 3] + [node]
                end

                node[:id] = dom_id(hierarchy)
                node.inner_html = "#{node_index(hierarchy)} #{node.inner_html}"
              end
            end
          end.to_html
        end
      end

      def generate_index
        if @headings_for_index.present?
          raw_index = ''
          @headings_for_index.each do |level, node, label|
            if level == 1
              raw_index += "1. [#{label}](##{node[:id]})\n"
            elsif level == 2
              raw_index += "    * [#{label}](##{node[:id]})\n"
            end
          end

          @index = Nokogiri::HTML(engine.render(raw_index)).tap do |doc|
            doc.at('ol')[:class] = 'chapters'
          end.to_html

          @index = <<-INDEX.html_safe
          <div id="subCol">
            <h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
            #{@index}
          </div>
          INDEX
        end
      end

      def generate_title
        if heading = Nokogiri::HTML(@header).at(:h2)
          @title = "#{heading.text} — Ruby on Rails Guides".html_safe
        else
          @title = "Ruby on Rails Guides"
        end
      end

      def node_index(hierarchy)
        case hierarchy.size
        when 1
          @index_counter[2] = @index_counter[3] = @index_counter[4] = 0
          "#{@index_counter[1] += 1}"
        when 2
          @index_counter[3] = @index_counter[4] = 0
          "#{@index_counter[1]}.#{@index_counter[2] += 1}"
        when 3
          @index_counter[4] = 0
          "#{@index_counter[1]}.#{@index_counter[2]}.#{@index_counter[3] += 1}"
        when 4
          "#{@index_counter[1]}.#{@index_counter[2]}.#{@index_counter[3]}.#{@index_counter[4] += 1}"
        end
      end

      def render_page
        @view.content_for(:header_section) { @header }
        @view.content_for(:page_title) { @title }
        @view.content_for(:index_section) { @index }
        @view.render(:layout => @layout, :text => @body)
      end
  end
end
pwd = File.dirname(__FILE__)
$:.unshift pwd

# This is a predicate useful for the doc:guides task of applications.
def bundler?
  # Note that rake sets the cwd to the one that contains the Rakefile
  # being executed.
  File.exists?('Gemfile')
end

begin
  # Guides generation in the Rails repo.
  as_lib = File.join(pwd, "../activesupport/lib")
  ap_lib = File.join(pwd, "../actionpack/lib")

  $:.unshift as_lib if File.directory?(as_lib)
  $:.unshift ap_lib if File.directory?(ap_lib)
rescue LoadError
  # Guides generation from gems.
  gem "actionpack", '>= 3.0'
end

begin
  require 'redcarpet'
rescue Gem::LoadError
  # This can happen if doc:guides is executed in an application.
  $stderr.puts('Generating guides requires Redcarpet 2.1.1+.')
  $stderr.puts(<<ERROR) if bundler?
Please add

  gem 'redcarpet', '~> 2.1.1'

to the Gemfile, run

  bundle install

and try again.
ERROR
  exit 1
end

require 'rails_guides/markdown'
require "rails_guides/generator"
RailsGuides::Generator.new.generate
# ---------------------------------------------------------------------------
#
# This script validates the generated guides against the W3C Validator.
#
# Guides are taken from the output directory, from where all .html files are
# submitted to the validator.
#
# This script is prepared to be launched from the guides directory as a rake task:
#
# rake guides:validate
#
# If nothing is specified, all files will be validated, but you can check just
# some of them using this environment variable:
#
#   ONLY
#     Use ONLY if you want to validate only one or a set of guides. Prefixes are
#     enough:
#
#       # validates only association_basics.html
#       rake guides:validate ONLY=assoc
#
#     Separate many using commas:
#
#       # validates only association_basics.html and migrations.html
#       rake guides:validate ONLY=assoc,migrations
#
# ---------------------------------------------------------------------------

require 'w3c_validators'
include W3CValidators

module RailsGuides
  class Validator

    def validate
      validator = MarkupValidator.new
      STDOUT.sync = true
      errors_on_guides = {}

      guides_to_validate.each do |f|
        begin
          results = validator.validate_file(f)
        rescue Exception => e
          puts "\nCould not validate #{f} because of #{e}"
          next
        end

        if results.validity
          print "."
        else
          print "E"
          errors_on_guides[f] = results.errors
        end
      end

      show_results(errors_on_guides)
    end

    private
    def guides_to_validate
      guides = Dir["./output/*.html"]
      guides.delete("./output/layout.html")
      ENV.key?('ONLY') ? select_only(guides) : guides
    end

    def select_only(guides)
      prefixes = ENV['ONLY'].split(",").map(&:strip)
      guides.select do |guide|
        prefixes.any? {|p| guide.start_with?("./output/#{p}")}
      end
    end

    def show_results(error_list)
      if error_list.size == 0
        puts "\n\nAll checked guides validate OK!"
      else
        error_summary = error_detail = ""

        error_list.each_pair do |name, errors|
          error_summary += "\n  #{name}"
          error_detail += "\n\n  #{name} has #{errors.size} validation error(s):\n"
          errors.each do |error|
            error_detail += "\n    "+error.to_s.delete("\n")
          end
        end

        puts "\n\nThere are #{error_list.size} guides with validation errors:\n" + error_summary
        puts "\nHere are the detailed errors for each guide:" + error_detail
      end
    end

  end
end

RailsGuides::Validator.new.validate
version = ARGV.pop

if version.nil?
  puts "Usage: ruby install.rb version"
  exit(64)
end

%w( activesupport activemodel activerecord actionpack actionmailer railties ).each do |framework|
  puts "Installing #{framework}..."
  `cd #{framework} && gem build #{framework}.gemspec && gem install #{framework}-#{version}.gem --local --no-ri --no-rdoc && rm #{framework}-#{version}.gem`
end

puts "Installing Rails..."
`gem build rails.gemspec`
`gem install rails-#{version}.gem --local --no-ri --no-rdoc `
`rm rails-#{version}.gem`
# bust gem prelude
require 'bundler'
Bundler.setup
require "rails"

%w(
  active_record
  action_controller
  action_mailer
  rails/test_unit
  sprockets
).each do |framework|
  begin
    require "#{framework}/railtie"
  rescue LoadError
  end
end
require 'pathname'

module Rails
  module AppRailsLoader
    RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"]
    EXECUTABLE = 'bin/rails'

    def self.exec_app_rails
      cwd = Dir.pwd
      return unless in_rails_application_or_engine? || in_rails_application_or_engine_subdirectory?
      exec RUBY, EXECUTABLE, *ARGV if in_rails_application_or_engine?
      Dir.chdir("..") do
        # Recurse in a chdir block: if the search fails we want to be sure
        # the application is generated in the original working directory.
        exec_app_rails unless cwd == Dir.pwd
      end
    rescue SystemCallError
      # could not chdir, no problem just return
    end

    def self.in_rails_application_or_engine?
      File.exists?(EXECUTABLE) && File.read(EXECUTABLE) =~ /(APP|ENGINE)_PATH/
    end

    def self.in_rails_application_or_engine_subdirectory?(path = Pathname.new(Dir.pwd))
      File.exists?(File.join(path, EXECUTABLE)) || !path.root? && in_rails_application_or_engine_subdirectory?(path.parent)
    end
  end
end
require "active_support/notifications"
require "active_support/dependencies"
require "active_support/descendants_tracker"

module Rails
  class Application
    module Bootstrap
      include Initializable

      initializer :load_environment_hook, group: :all do end

      initializer :load_active_support, group: :all do
        require "active_support/all" unless config.active_support.bare
      end

      initializer :set_eager_load, group: :all do
        if config.eager_load.nil?
          warn <<-INFO
config.eager_load is set to nil. Please update your config/environments/*.rb files accordingly:

  * development - set it to false
  * test - set it to false (unless you use a tool that preloads your test environment)
  * production - set it to true

INFO
          config.eager_load = config.cache_classes
        end
      end

      # Initialize the logger early in the stack in case we need to log some deprecation.
      initializer :initialize_logger, group: :all do
        Rails.logger ||= config.logger || begin
          path = config.paths["log"].first
          unless File.exist? File.dirname path
            FileUtils.mkdir_p File.dirname path
          end

          f = File.open path, 'a'
          f.binmode
          f.sync = config.autoflush_log # if true make sure every write flushes

          logger = ActiveSupport::Logger.new f
          logger.formatter = config.log_formatter
          logger = ActiveSupport::TaggedLogging.new(logger)
          logger.level = ActiveSupport::Logger.const_get(config.log_level.to_s.upcase)
          logger
        rescue StandardError
          logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDERR))
          logger.level = ActiveSupport::Logger::WARN
          logger.warn(
            "Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
            "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
          )
          logger
        end
      end

      # Initialize cache early in the stack so railties can make use of it.
      initializer :initialize_cache, group: :all do
        unless Rails.cache
          Rails.cache = ActiveSupport::Cache.lookup_store(config.cache_store)

          if Rails.cache.respond_to?(:middleware)
            config.middleware.insert_before("Rack::Runtime", Rails.cache.middleware)
          end
        end
      end

      # Sets the dependency loading mechanism.
      initializer :initialize_dependency_mechanism, group: :all do
        ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
      end

      initializer :bootstrap_hook, group: :all do |app|
        ActiveSupport.run_load_hooks(:before_initialize, app)
      end
    end
  end
end
require 'active_support/core_ext/kernel/reporting'
require 'active_support/file_update_checker'
require 'rails/engine/configuration'

module Rails
  class Application
    class Configuration < ::Rails::Engine::Configuration
      attr_accessor :asset_host, :assets, :autoflush_log,
                    :cache_classes, :cache_store, :consider_all_requests_local, :console,
                    :eager_load, :exceptions_app, :file_watcher, :filter_parameters,
                    :force_ssl, :helpers_paths, :logger, :log_formatter, :log_tags,
                    :railties_order, :relative_url_root, :secret_key_base, :secret_token,
                    :serve_static_assets, :ssl_options, :static_cache_control, :session_options,
                    :time_zone, :reload_classes_only_on_change,
                    :beginning_of_week, :filter_redirect

      attr_writer :log_level
      attr_reader :encoding

      def initialize(*)
        super
        self.encoding = "utf-8"
        @consider_all_requests_local   = false
        @filter_parameters             = []
        @filter_redirect               = []
        @helpers_paths                 = []
        @serve_static_assets           = true
        @static_cache_control          = nil
        @force_ssl                     = false
        @ssl_options                   = {}
        @session_store                 = :cookie_store
        @session_options               = {}
        @time_zone                     = "UTC"
        @beginning_of_week             = :monday
        @log_level                     = nil
        @middleware                    = app_middleware
        @generators                    = app_generators
        @cache_store                   = [ :file_store, "#{root}/tmp/cache/" ]
        @railties_order                = [:all]
        @relative_url_root             = ENV["RAILS_RELATIVE_URL_ROOT"]
        @reload_classes_only_on_change = true
        @file_watcher                  = ActiveSupport::FileUpdateChecker
        @exceptions_app                = nil
        @autoflush_log                 = true
        @log_formatter                 = ActiveSupport::Logger::SimpleFormatter.new
        @eager_load                    = nil
        @secret_token                  = nil
        @secret_key_base               = nil

        @assets = ActiveSupport::OrderedOptions.new
        @assets.enabled                  = true
        @assets.paths                    = []
        @assets.precompile               = [ Proc.new { |path, fn| fn =~ /app\/assets/ && !%w(.js .css).include?(File.extname(path)) },
                                             /(?:\/|\\|\A)application\.(css|js)$/ ]
        @assets.prefix                   = "/assets"
        @assets.version                  = '1.0'
        @assets.debug                    = false
        @assets.compile                  = true
        @assets.digest                   = false
        @assets.cache_store              = [ :file_store, "#{root}/tmp/cache/assets/#{Rails.env}/" ]
        @assets.js_compressor            = nil
        @assets.css_compressor           = nil
        @assets.initialize_on_precompile = true
        @assets.logger                   = nil
      end

      def encoding=(value)
        @encoding = value
        silence_warnings do
          Encoding.default_external = value
          Encoding.default_internal = value
        end
      end

      def paths
        @paths ||= begin
          paths = super
          paths.add "config/database",    with: "config/database.yml"
          paths.add "config/environment", with: "config/environment.rb"
          paths.add "lib/templates"
          paths.add "log",                with: "log/#{Rails.env}.log"
          paths.add "public"
          paths.add "public/javascripts"
          paths.add "public/stylesheets"
          paths.add "tmp"
          paths
        end
      end

      def threadsafe!
        message = "config.threadsafe! is deprecated. Rails applications " \
                  "behave by default as thread safe in production as long as config.cache_classes and " \
                  "config.eager_load are set to true"
        ActiveSupport::Deprecation.warn message
        @cache_classes = true
        @eager_load = true
        self
      end

      # Loads and returns the contents of the #database_configuration_file. The
      # contents of the file are processed via ERB before being sent through
      # YAML::load.
      def database_configuration
        require 'erb'
        YAML.load ERB.new(IO.read(paths["config/database"].first)).result
      rescue Psych::SyntaxError => e
        raise "YAML syntax error occurred while parsing #{paths["config/database"].first}. " \
              "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
              "Error: #{e.message}"
      end

      def log_level
        @log_level ||= Rails.env.production? ? :info : :debug
      end

      def colorize_logging
        ActiveSupport::LogSubscriber.colorize_logging
      end

      def colorize_logging=(val)
        ActiveSupport::LogSubscriber.colorize_logging = val
        self.generators.colorize_logging = val
      end

      def session_store(*args)
        if args.empty?
          case @session_store
          when :disabled
            nil
          when :active_record_store
            begin
              ActionDispatch::Session::ActiveRecordStore
            rescue NameError
              raise "`ActiveRecord::SessionStore` is extracted out of Rails into a gem. " \
                "Please add `activerecord-session_store` to your Gemfile to use it."
            end
          when Symbol
            ActionDispatch::Session.const_get(@session_store.to_s.camelize)
          else
            @session_store
          end
        else
          @session_store = args.shift
          @session_options = args.shift || {}
        end
      end

      def whiny_nils=(*)
        ActiveSupport::Deprecation.warn "config.whiny_nils option is deprecated and no longer works"
      end
    end
  end
end
module Rails
  class Application
    module Finisher
      include Initializable

      initializer :add_generator_templates do
        config.generators.templates.unshift(*paths["lib/templates"].existent)
      end

      initializer :ensure_autoload_once_paths_as_subset do
        extra = ActiveSupport::Dependencies.autoload_once_paths -
                ActiveSupport::Dependencies.autoload_paths

        unless extra.empty?
          abort <<-end_error
            autoload_once_paths must be a subset of the autoload_paths.
            Extra items in autoload_once_paths: #{extra * ','}
          end_error
        end
      end

      initializer :add_builtin_route do |app|
        if Rails.env.development?
          app.routes.append do
            get '/rails/info/properties' => "rails/info#properties"
            get '/rails/info/routes'     => "rails/info#routes"
            get '/rails/info'            => "rails/info#index"
            get '/'                      => "rails/welcome#index"
          end
        end
      end

      initializer :build_middleware_stack do
        build_middleware_stack
      end

      initializer :define_main_app_helper do |app|
        app.routes.define_mounted_helper(:main_app)
      end

      initializer :add_to_prepare_blocks do
        config.to_prepare_blocks.each do |block|
          ActionDispatch::Reloader.to_prepare(&block)
        end
      end

      # This needs to happen before eager load so it happens
      # in exactly the same point regardless of config.cache_classes
      initializer :run_prepare_callbacks do
        ActionDispatch::Reloader.prepare!
      end

      initializer :eager_load! do
        if config.eager_load
          ActiveSupport.run_load_hooks(:before_eager_load, self)
          config.eager_load_namespaces.each(&:eager_load!)
        end
      end

      # All initialization is done, including eager loading in production
      initializer :finisher_hook do
        ActiveSupport.run_load_hooks(:after_initialize, self)
      end

      # Set app reload just after the finisher hook to ensure
      # routes added in the hook are still loaded.
      initializer :set_routes_reloader_hook do
        reloader = routes_reloader
        reloader.execute_if_updated
        self.reloaders << reloader
        ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
      end

      # Set app reload just after the finisher hook to ensure
      # paths added in the hook are still loaded.
      initializer :set_clear_dependencies_hook, group: :all do
        callback = lambda do
          ActiveSupport::DescendantsTracker.clear
          ActiveSupport::Dependencies.clear
        end

        if config.reload_classes_only_on_change
          reloader = config.file_watcher.new(*watchable_args, &callback)
          self.reloaders << reloader
          # We need to set a to_prepare callback regardless of the reloader result, i.e.
          # models should be reloaded if any of the reloaders (i18n, routes) were updated.
          ActionDispatch::Reloader.to_prepare(prepend: true){ reloader.execute }
        else
          ActionDispatch::Reloader.to_cleanup(&callback)
        end
      end

      # Disable dependency loading during request cycle
      initializer :disable_dependency_loading do
        if config.eager_load && config.cache_classes
          ActiveSupport::Dependencies.unhook!
        end
      end
    end
  end
end
require "active_support/core_ext/module/delegation"

module Rails
  class Application
    class RoutesReloader
      attr_reader :route_sets, :paths
      delegate :execute_if_updated, :execute, :updated?, to: :updater

      def initialize
        @paths      = []
        @route_sets = []
      end

      def reload!
        clear!
        load_paths
        finalize!
      ensure
        revert
      end

    private

      def updater
        @updater ||= begin
          updater = ActiveSupport::FileUpdateChecker.new(paths) { reload! }
          updater.execute
          updater
        end
      end

      def clear!
        route_sets.each do |routes|
          routes.disable_clear_and_finalize = true
          routes.clear!
        end
      end

      def load_paths
        paths.each { |path| load(path) }
      end

      def finalize!
        route_sets.each do |routes|
          routes.finalize!
        end
      end

      def revert
        route_sets.each do |routes|
          routes.disable_clear_and_finalize = false
        end
      end
    end
  end
end
require 'fileutils'
# FIXME remove DummyKeyGenerator and this require in 4.1
require 'active_support/key_generator'
require 'rails/engine'

module Rails
  # In Rails 3.0, a Rails::Application object was introduced which is nothing more than
  # an Engine but with the responsibility of coordinating the whole boot process.
  #
  # == Initialization
  #
  # Rails::Application is responsible for executing all railties and engines
  # initializers. It also executes some bootstrap initializers (check
  # Rails::Application::Bootstrap) and finishing initializers, after all the others
  # are executed (check Rails::Application::Finisher).
  #
  # == Configuration
  #
  # Besides providing the same configuration as Rails::Engine and Rails::Railtie,
  # the application object has several specific configurations, for example
  # "cache_classes", "consider_all_requests_local", "filter_parameters",
  # "logger" and so forth.
  #
  # Check Rails::Application::Configuration to see them all.
  #
  # == Routes
  #
  # The application object is also responsible for holding the routes and reloading routes
  # whenever the files change in development.
  #
  # == Middlewares
  #
  # The Application is also responsible for building the middleware stack.
  #
  # == Booting process
  #
  # The application is also responsible for setting up and executing the booting
  # process. From the moment you require "config/application.rb" in your app,
  # the booting process goes like this:
  #
  #   1)  require "config/boot.rb" to setup load paths
  #   2)  require railties and engines
  #   3)  Define Rails.application as "class MyApp::Application < Rails::Application"
  #   4)  Run config.before_configuration callbacks
  #   5)  Load config/environments/ENV.rb
  #   6)  Run config.before_initialize callbacks
  #   7)  Run Railtie#initializer defined by railties, engines and application.
  #       One by one, each engine sets up its load paths, routes and runs its config/initializers/* files.
  #   9)  Custom Railtie#initializers added by railties, engines and applications are executed
  #   10) Build the middleware stack and run to_prepare callbacks
  #   11) Run config.before_eager_load and eager_load! if eager_load is true
  #   12) Run config.after_initialize callbacks
  #
  class Application < Engine
    autoload :Bootstrap,      'rails/application/bootstrap'
    autoload :Configuration,  'rails/application/configuration'
    autoload :Finisher,       'rails/application/finisher'
    autoload :Railties,       'rails/engine/railties'
    autoload :RoutesReloader, 'rails/application/routes_reloader'

    class << self
      def inherited(base)
        raise "You cannot have more than one Rails::Application" if Rails.application
        super
        Rails.application = base.instance
        Rails.application.add_lib_to_load_path!
        ActiveSupport.run_load_hooks(:before_configuration, base.instance)
      end
    end

    attr_accessor :assets, :sandbox
    alias_method :sandbox?, :sandbox
    attr_reader :reloaders

    delegate :default_url_options, :default_url_options=, to: :routes

    def initialize
      super
      @initialized      = false
      @reloaders        = []
      @routes_reloader  = nil
      @env_config       = nil
      @ordered_railties = nil
      @railties         = nil
    end

    # Returns true if the application is initialized.
    def initialized?
      @initialized
    end

    # Implements call according to the Rack API. It simply
    # dispatches the request to the underlying middleware stack.
    def call(env)
      env["ORIGINAL_FULLPATH"] = build_original_fullpath(env)
      super(env)
    end

    # Reload application routes regardless if they changed or not.
    def reload_routes!
      routes_reloader.reload!
    end


    # Return the application's KeyGenerator
    def key_generator
      # number of iterations selected based on consultation with the google security
      # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
      @caching_key_generator ||= begin
        if config.secret_key_base
          key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000)
          ActiveSupport::CachingKeyGenerator.new(key_generator)
        else
          ActiveSupport::DummyKeyGenerator.new(config.secret_token)
        end
      end
    end

    # Stores some of the Rails initial environment parameters which
    # will be used by middlewares and engines to configure themselves.
    # Currently stores:
    #
    #   * "action_dispatch.parameter_filter"             => config.filter_parameters
    #   * "action_dispatch.redirect_filter"              => config.filter_redirect
    #   * "action_dispatch.secret_token"                 => config.secret_token,
    #   * "action_dispatch.show_exceptions"              => config.action_dispatch.show_exceptions
    #   * "action_dispatch.show_detailed_exceptions"     => config.consider_all_requests_local
    #   * "action_dispatch.logger"                       => Rails.logger
    #   * "action_dispatch.backtrace_cleaner"            => Rails.backtrace_cleaner
    #   * "action_dispatch.key_generator"                => key_generator
    #   * "action_dispatch.http_auth_salt"               => config.action_dispatch.http_auth_salt
    #   * "action_dispatch.signed_cookie_salt"           => config.action_dispatch.signed_cookie_salt
    #   * "action_dispatch.encrypted_cookie_salt"        => config.action_dispatch.encrypted_cookie_salt
    #   * "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt
    #
    def env_config
      @env_config ||= begin
        if config.secret_key_base.nil?
          ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base in config/initializers/secret_token.rb file. " +
            "This should be used instead of the old deprecated config.secret_token in order to use the new EncryptedCookieStore. " +
            "To convert safely to the encrypted store (without losing existing cookies and sessions), see http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#action-pack"

          if config.secret_token.blank?
            raise "You must set config.secret_key_base in your app's config"
          end
        end

        super.merge({
          "action_dispatch.parameter_filter" => config.filter_parameters,
          "action_dispatch.redirect_filter" => config.filter_redirect,
          "action_dispatch.secret_token" => config.secret_token,
          "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions,
          "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local,
          "action_dispatch.logger" => Rails.logger,
          "action_dispatch.backtrace_cleaner" => Rails.backtrace_cleaner,
          "action_dispatch.key_generator" => key_generator,
          "action_dispatch.http_auth_salt" => config.action_dispatch.http_auth_salt,
          "action_dispatch.signed_cookie_salt" => config.action_dispatch.signed_cookie_salt,
          "action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
          "action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt
        })
      end
    end

    ## Rails internal API

    # This method is called just after an application inherits from Rails::Application,
    # allowing the developer to load classes in lib and use them during application
    # configuration.
    #
    #   class MyApplication < Rails::Application
    #     require "my_backend" # in lib/my_backend
    #     config.i18n.backend = MyBackend
    #   end
    #
    # Notice this method takes into consideration the default root path. So if you
    # are changing config.root inside your application definition or having a custom
    # Rails application, you will need to add lib to $LOAD_PATH on your own in case
    # you need to load files in lib/ during the application configuration as well.
    def add_lib_to_load_path! #:nodoc:
      path = File.join config.root, 'lib'
      $LOAD_PATH.unshift(path) if File.exists?(path)
    end

    def require_environment! #:nodoc:
      environment = paths["config/environment"].existent.first
      require environment if environment
    end

    def routes_reloader #:nodoc:
      @routes_reloader ||= RoutesReloader.new
    end

    # Returns an array of file paths appended with a hash of
    # directories-extensions suitable for ActiveSupport::FileUpdateChecker
    # API.
    def watchable_args #:nodoc:
      files, dirs = config.watchable_files.dup, config.watchable_dirs.dup

      ActiveSupport::Dependencies.autoload_paths.each do |path|
        dirs[path.to_s] = [:rb]
      end

      [files, dirs]
    end

    # Initialize the application passing the given group. By default, the
    # group is :default but sprockets precompilation passes group equals
    # to assets if initialize_on_precompile is false to avoid booting the
    # whole app.
    def initialize!(group=:default) #:nodoc:
      raise "Application has been already initialized." if @initialized
      run_initializers(group, self)
      @initialized = true
      self
    end

    def initializers #:nodoc:
      Bootstrap.initializers_for(self) +
      railties_initializers(super) +
      Finisher.initializers_for(self)
    end

    def config #:nodoc:
      @config ||= Application::Configuration.new(find_root_with_flag("config.ru", Dir.pwd))
    end

    def to_app #:nodoc:
      self
    end

    def helpers_paths #:nodoc:
      config.helpers_paths
    end

  protected

    alias :build_middleware_stack :app

    def run_tasks_blocks(app) #:nodoc:
      railties.each { |r| r.run_tasks_blocks(app) }
      super
      require "rails/tasks"
      config = self.config
      task :environment do
        config.eager_load = false
        require_environment!
      end
    end

    def run_generators_blocks(app) #:nodoc:
      railties.each { |r| r.run_generators_blocks(app) }
      super
    end

    def run_runner_blocks(app) #:nodoc:
      railties.each { |r| r.run_runner_blocks(app) }
      super
    end

    def run_console_blocks(app) #:nodoc:
      railties.each { |r| r.run_console_blocks(app) }
      super
    end

    # Returns the ordered railties for this application considering railties_order.
    def ordered_railties #:nodoc:
      @ordered_railties ||= begin
        order = config.railties_order.map do |railtie|
          if railtie == :main_app
            self
          elsif railtie.respond_to?(:instance)
            railtie.instance
          else
            railtie
          end
        end

        all = (railties - order)
        all.push(self)   unless (all + order).include?(self)
        order.push(:all) unless order.include?(:all)

        index = order.index(:all)
        order[index] = all
        order.reverse.flatten
      end
    end

    def railties_initializers(current) #:nodoc:
      initializers = []
      ordered_railties.each do |r|
        if r == self
          initializers += current
        else
          initializers += r.initializers
        end
      end
      initializers
    end

    def reload_dependencies? #:nodoc:
      config.reload_classes_only_on_change != true || reloaders.map(&:updated?).any?
    end

    def default_middleware_stack #:nodoc:
      ActionDispatch::MiddlewareStack.new.tap do |middleware|
        app = self
        if rack_cache = config.action_dispatch.rack_cache
          begin
            require 'rack/cache'
          rescue LoadError => error
            error.message << ' Be sure to add rack-cache to your Gemfile'
            raise
          end

          if rack_cache == true
            rack_cache = {
              metastore: "rails:/",
              entitystore: "rails:/",
              verbose: false
            }
          end

          require "action_dispatch/http/rack_cache"
          middleware.use ::Rack::Cache, rack_cache
        end

        if config.force_ssl
          middleware.use ::ActionDispatch::SSL, config.ssl_options
        end

        if config.action_dispatch.x_sendfile_header.present?
          middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
        end

        if config.serve_static_assets
          middleware.use ::ActionDispatch::Static, paths["public"].first, config.static_cache_control
        end

        middleware.use ::Rack::Lock unless config.cache_classes
        middleware.use ::Rack::Runtime
        middleware.use ::Rack::MethodOverride
        middleware.use ::ActionDispatch::RequestId
        middleware.use ::Rails::Rack::Logger, config.log_tags # must come after Rack::MethodOverride to properly log overridden methods
        middleware.use ::ActionDispatch::ShowExceptions, config.exceptions_app || ActionDispatch::PublicExceptions.new(Rails.public_path)
        middleware.use ::ActionDispatch::DebugExceptions, app
        middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies

        unless config.cache_classes
          middleware.use ::ActionDispatch::Reloader, lambda { app.reload_dependencies? }
        end

        middleware.use ::ActionDispatch::Callbacks
        middleware.use ::ActionDispatch::Cookies

        if config.session_store
          if config.force_ssl && !config.session_options.key?(:secure)
            config.session_options[:secure] = true
          end
          middleware.use config.session_store, config.session_options
          middleware.use ::ActionDispatch::Flash
        end

        middleware.use ::ActionDispatch::ParamsParser
        middleware.use ::Rack::Head
        middleware.use ::Rack::ConditionalGet
        middleware.use ::Rack::ETag, "no-cache"
      end
    end

    def build_original_fullpath(env) #:nodoc:
      path_info    = env["PATH_INFO"]
      query_string = env["QUERY_STRING"]
      script_name  = env["SCRIPT_NAME"]

      if query_string.present?
        "#{script_name}#{path_info}?#{query_string}"
      else
        "#{script_name}#{path_info}"
      end
    end
  end
end
require 'active_support/backtrace_cleaner'

module Rails
  class BacktraceCleaner < ActiveSupport::BacktraceCleaner
    APP_DIRS_PATTERN = /^\/?(app|config|lib|test)/
    RENDER_TEMPLATE_PATTERN = /:in `_render_template_\w*'/

    def initialize
      super
      add_filter   { |line| line.sub("#{Rails.root}/", '') }
      add_filter   { |line| line.sub(RENDER_TEMPLATE_PATTERN, '') }
      add_filter   { |line| line.sub('./', '/') } # for tests

      add_gem_filters
      add_silencer { |line| line !~ APP_DIRS_PATTERN }
    end

    private
      def add_gem_filters
        gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) }
        return if gems_paths.empty?

        gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
        add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') }
      end
  end
end
require 'rbconfig'
require 'rails/app_rails_loader'

# If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run.
#
# TODO: when we hit this, advise adding ./bin to $PATH instead. Then the
# app's `rails` executable is run immediately.
Rails::AppRailsLoader.exec_app_rails

require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit(1) }

if ARGV.first == 'plugin'
  ARGV.shift
  require 'rails/commands/plugin_new'
else
  require 'rails/commands/application'
end
class CodeStatistics #:nodoc:

  TEST_TYPES = ['Controller tests',
                'Helper tests',
                'Model tests',
                'Mailer tests',
                'Integration tests',
                'Functional tests (old)',
                'Unit tests (old)']

  def initialize(*pairs)
    @pairs      = pairs
    @statistics = calculate_statistics
    @total      = calculate_total if pairs.length > 1
  end

  def to_s
    print_header
    @pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
    print_splitter

    if @total
      print_line("Total", @total)
      print_splitter
    end

    print_code_test_stats
  end

  private
    def calculate_statistics
      Hash[@pairs.map{|pair| [pair.first, calculate_directory_statistics(pair.last)]}]
    end

    def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee)$/)
      stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }

      Dir.foreach(directory) do |file_name|
        if File.directory?(directory + "/" + file_name) and (/^\./ !~ file_name)
          newstats = calculate_directory_statistics(directory + "/" + file_name, pattern)
          stats.each { |k, v| stats[k] += newstats[k] }
        end

        next unless file_name =~ pattern

        comment_started = false
        
        case file_name
        when /.*\.js$/
          comment_pattern = /^\s*\/\//
        else
          comment_pattern = /^\s*#/
        end

        File.open(directory + "/" + file_name) do |f|
          while line = f.gets
            stats["lines"]     += 1
            if(comment_started)
              if line =~ /^=end/
                comment_started = false
              end
              next
            else
              if line =~ /^=begin/
                comment_started = true
                next
              end
            end
            stats["classes"]   += 1 if line =~ /^\s*class\s+[_A-Z]/
            stats["methods"]   += 1 if line =~ /^\s*def\s+[_a-z]/
            stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ comment_pattern
          end
        end
      end

      stats
    end

    def calculate_total
      total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
      @statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
      total
    end

    def calculate_code
      code_loc = 0
      @statistics.each { |k, v| code_loc += v['codelines'] unless TEST_TYPES.include? k }
      code_loc
    end

    def calculate_tests
      test_loc = 0
      @statistics.each { |k, v| test_loc += v['codelines'] if TEST_TYPES.include? k }
      test_loc
    end

    def print_header
      print_splitter
      puts "| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |"
      print_splitter
    end

    def print_splitter
      puts "+----------------------+-------+-------+---------+---------+-----+-------+"
    end

    def print_line(name, statistics)
      m_over_c   = (statistics["methods"] / statistics["classes"])   rescue m_over_c = 0
      loc_over_m = (statistics["codelines"] / statistics["methods"]) - 2 rescue loc_over_m = 0

      puts "| #{name.ljust(20)} " +
           "| #{statistics["lines"].to_s.rjust(5)} " +
           "| #{statistics["codelines"].to_s.rjust(5)} " +
           "| #{statistics["classes"].to_s.rjust(7)} " +
           "| #{statistics["methods"].to_s.rjust(7)} " +
           "| #{m_over_c.to_s.rjust(3)} " +
           "| #{loc_over_m.to_s.rjust(5)} |"
    end

    def print_code_test_stats
      code  = calculate_code
      tests = calculate_tests

      puts "  Code LOC: #{code}     Test LOC: #{tests}     Code to Test Ratio: 1:#{sprintf("%.1f", tests.to_f/code)}"
      puts ""
    end
end
require 'rails/version'

if ['--version', '-v'].include?(ARGV.first)
  puts "Rails #{Rails::VERSION::STRING}"
  exit(0)
end

if ARGV.first != "new"
  ARGV[0] = "--help"
else
  ARGV.shift
  unless ARGV.delete("--no-rc")
    customrc = ARGV.index{ |x| x.include?("--rc=") }
    railsrc = if customrc
                File.expand_path(ARGV.delete_at(customrc).gsub(/--rc=/, ""))
              else
                File.join(File.expand_path("~"), '.railsrc')
              end
    if File.exist?(railsrc)
      extra_args_string = File.read(railsrc)
      extra_args = extra_args_string.split(/\n+/).map {|l| l.split}.flatten
      puts "Using #{extra_args.join(" ")} from #{railsrc}"
      ARGV.insert(1, *extra_args)
    end
  end
end

require 'rails/generators'
require 'rails/generators/rails/app/app_generator'

module Rails
  module Generators
    class AppGenerator # :nodoc:
      # We want to exit on failure to be kind to other libraries
      # This is only when accessing via CLI
      def self.exit_on_failure?
        true
      end
    end
  end
end

Rails::Generators::AppGenerator.start
require 'optparse'
require 'irb'
require 'irb/completion'

module Rails
  class Console
    class << self
      def start(*args)
        new(*args).start
      end

      def parse_arguments(arguments)
        options = {}

        OptionParser.new do |opt|
          opt.banner = "Usage: rails console [environment] [options]"
          opt.on('-s', '--sandbox', 'Rollback database modifications on exit.') { |v| options[:sandbox] = v }
          opt.on("-e", "--environment=name", String,
                  "Specifies the environment to run this console under (test/development/production).",
                  "Default: development") { |v| options[:environment] = v.strip }
          opt.on("--debugger", 'Enable the debugger.') { |v| options[:debugger] = v }
          opt.parse!(arguments)
        end

        if arguments.first && arguments.first[0] != '-'
          env = arguments.first
          if available_environments.include? env
            options[:environment] = env
          else
            options[:environment] = %w(production development test).detect {|e| e =~ /^#{env}/} || env
          end
        end

        options
      end

      private

        def available_environments
          Dir['config/environments/*.rb'].map { |fname| File.basename(fname, '.*') }
        end
    end

    attr_reader :options, :app, :console

    def initialize(app, options={})
      @app     = app
      @options = options
      app.load_console
      @console = app.config.console || IRB
    end

    def sandbox?
      options[:sandbox]
    end

    def environment
      options[:environment] ||= ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
    end

    def environment?
      environment
    end

    def set_environment!
      Rails.env = environment
    end

    def debugger?
      options[:debugger]
    end

    def start
      app.sandbox = sandbox?
      require_debugger if debugger?
      set_environment! if environment?

      if sandbox?
        puts "Loading #{Rails.env} environment in sandbox (Rails #{Rails.version})"
        puts "Any modifications you make will be rolled back on exit"
      else
        puts "Loading #{Rails.env} environment (Rails #{Rails.version})"
      end

      if defined?(console::ExtendCommandBundle)
        console::ExtendCommandBundle.send :include, Rails::ConsoleMethods
      end
      console.start
    end

    def require_debugger
      require 'debugger'
      puts "=> Debugger enabled"
    rescue LoadError
      puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle, and try again."
      exit
    end
  end
end
require 'erb'
require 'yaml'
require 'optparse'
require 'rbconfig'

module Rails
  class DBConsole
    attr_reader :arguments

    def self.start
      new.start
    end

    def initialize(arguments = ARGV)
      @arguments = arguments
    end

    def start
      options = parse_arguments(arguments)
      ENV['RAILS_ENV'] = options[:environment] || environment

      case config["adapter"]
      when /^mysql/
        args = {
          'host'      => '--host',
          'port'      => '--port',
          'socket'    => '--socket',
          'username'  => '--user',
          'encoding'  => '--default-character-set',
          'sslca'     => '--ssl-ca',
          'sslcert'   => '--ssl-cert',
          'sslcapath' => '--ssl-capath',
          'sslcipher' => '--ssh-cipher',
          'sslkey'    => '--ssl-key'
        }.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact

        if config['password'] && options['include_password']
          args << "--password=#{config['password']}"
        elsif config['password'] && !config['password'].to_s.empty?
          args << "-p"
        end

        args << config['database']

        find_cmd_and_exec(['mysql', 'mysql5'], *args)

      when "postgresql", "postgres"
        ENV['PGUSER']     = config["username"] if config["username"]
        ENV['PGHOST']     = config["host"] if config["host"]
        ENV['PGPORT']     = config["port"].to_s if config["port"]
        ENV['PGPASSWORD'] = config["password"].to_s if config["password"] && options['include_password']
        find_cmd_and_exec('psql', config["database"])

      when "sqlite"
        find_cmd_and_exec('sqlite', config["database"])

      when "sqlite3"
        args = []

        args << "-#{options['mode']}" if options['mode']
        args << "-header" if options['header']
        args << File.expand_path(config['database'], Rails.respond_to?(:root) ? Rails.root : nil)

        find_cmd_and_exec('sqlite3', *args)

      when "oracle", "oracle_enhanced"
        logon = ""

        if config['username']
          logon = config['username']
          logon << "/#{config['password']}" if config['password'] && options['include_password']
          logon << "@#{config['database']}" if config['database']
        end

        find_cmd_and_exec('sqlplus', logon)

      else
        abort "Unknown command-line client for #{config['database']}. Submit a Rails patch to add support!"
      end
    end

    def config
      @config ||= begin
        cfg = begin
          YAML.load(ERB.new(IO.read("config/database.yml")).result)
        rescue SyntaxError, StandardError
          require APP_PATH
          Rails.application.config.database_configuration
        end

        cfg[environment] || abort("No database is configured for the environment '#{environment}'")
      end
    end

    def environment
      if Rails.respond_to?(:env)
        Rails.env
      else
        ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
      end
    end

    protected

    def parse_arguments(arguments)
      options = {}

      OptionParser.new do |opt|
        opt.banner = "Usage: rails dbconsole [environment] [options]"
        opt.on("-p", "--include-password", "Automatically provide the password from database.yml") do |v|
          options['include_password'] = true
        end

        opt.on("--mode [MODE]", ['html', 'list', 'line', 'column'],
          "Automatically put the sqlite3 database in the specified mode (html, list, line, column).") do |mode|
            options['mode'] = mode
        end

        opt.on("--header") do |h|
          options['header'] = h
        end

        opt.on("-h", "--help", "Show this help message.") do
          puts opt
          exit
        end

        opt.on("-e", "--environment=name", String,
          "Specifies the environment to run this console under (test/development/production).",
          "Default: development"
        ) { |v| options[:environment] = v.strip }

        opt.parse!(arguments)
        abort opt.to_s unless (0..1).include?(arguments.size)
      end

      if arguments.first && arguments.first[0] != '-'
        env = arguments.first
        if available_environments.include? env
          options[:environment] = env
        else
          options[:environment] = %w(production development test).detect {|e| e =~ /^#{env}/} || env
        end
      end

      options
    end

    def available_environments
      Dir['config/environments/*.rb'].map { |fname| File.basename(fname, '.*') }
    end

    def find_cmd_and_exec(commands, *args)
      commands = Array(commands)

      dirs_on_path = ENV['PATH'].to_s.split(File::PATH_SEPARATOR)
      commands += commands.map{|cmd| "#{cmd}.exe"} if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/

      full_path_command = nil
      found = commands.detect do |cmd|
        dirs_on_path.detect do |path|
          full_path_command = File.join(path, cmd)
          File.executable? full_path_command
        end
      end

      if found
        exec full_path_command, *args
      else
        abort("Couldn't find database client: #{commands.join(', ')}. Check your $PATH and try again.")
      end
    end
  end
end
require 'rails/generators'

if [nil, "-h", "--help"].include?(ARGV.first)
  Rails::Generators.help 'destroy'
  exit
end

name = ARGV.shift
Rails::Generators.invoke name, ARGV, behavior: :revoke, destination_root: Rails.root
require 'rails/generators'

if [nil, "-h", "--help"].include?(ARGV.first)
  Rails::Generators.help 'generate'
  exit
end

name = ARGV.shift

root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
Rails::Generators.invoke name, ARGV, behavior: :invoke, destination_root: root
if ARGV.first != "new"
  ARGV[0] = "--help"
else
  ARGV.shift
end

require 'rails/generators'
require 'rails/generators/rails/plugin_new/plugin_new_generator'
Rails::Generators::PluginNewGenerator.startrequire 'optparse'
require 'rbconfig'

options = { environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup }
code_or_file = nil

if ARGV.first.nil?
  ARGV.push "-h"
end

ARGV.clone.options do |opts|
  opts.banner = "Usage: rails runner [options] ('Some.ruby(code)' or a filename)"

  opts.separator ""

  opts.on("-e", "--environment=name", String,
          "Specifies the environment for the runner to operate under (test/development/production).",
          "Default: development") { |v| options[:environment] = v }

  opts.separator ""

  opts.on("-h", "--help",
          "Show this help message.") { $stdout.puts opts; exit }

  if RbConfig::CONFIG['host_os'] !~ /mswin|mingw/
    opts.separator ""
    opts.separator "You can also use runner as a shebang line for your executables:"
    opts.separator "-------------------------------------------------------------"
    opts.separator "#!/usr/bin/env #{File.expand_path($0)} runner"
    opts.separator ""
    opts.separator "Product.all.each { |p| p.price *= 2 ; p.save! }"
    opts.separator "-------------------------------------------------------------"
  end

  opts.order! { |o| code_or_file ||= o } rescue retry
end

ARGV.delete(code_or_file)

ENV["RAILS_ENV"] = options[:environment]

require APP_PATH
Rails.application.require_environment!
Rails.application.load_runner

if code_or_file.nil?
  $stderr.puts "Run '#{$0} -h' for help."
  exit 1
elsif File.exist?(code_or_file)
  $0 = code_or_file
  eval(File.read(code_or_file), nil, code_or_file)
else
  eval(code_or_file)
end
require 'fileutils'
require 'optparse'
require 'action_dispatch'

module Rails
  class Server < ::Rack::Server
    class Options
      def parse!(args)
        args, options = args.dup, {}

        opt_parser = OptionParser.new do |opts|
          opts.banner = "Usage: rails server [mongrel, thin, etc] [options]"
          opts.on("-p", "--port=port", Integer,
                  "Runs Rails on the specified port.", "Default: 3000") { |v| options[:Port] = v }
          opts.on("-b", "--binding=ip", String,
                  "Binds Rails to the specified ip.", "Default: 0.0.0.0") { |v| options[:Host] = v }
          opts.on("-c", "--config=file", String,
                  "Use custom rackup configuration file") { |v| options[:config] = v }
          opts.on("-d", "--daemon", "Make server run as a Daemon.") { options[:daemonize] = true }
          opts.on("-u", "--debugger", "Enable the debugger") { options[:debugger] = true }
          opts.on("-e", "--environment=name", String,
                  "Specifies the environment to run this server under (test/development/production).",
                  "Default: development") { |v| options[:environment] = v }
          opts.on("-P","--pid=pid",String,
                  "Specifies the PID file.",
                  "Default: tmp/pids/server.pid") { |v| options[:pid] = v }

          opts.separator ""

          opts.on("-h", "--help", "Show this help message.") { puts opts; exit }
        end

        opt_parser.parse! args

        options[:server] = args.shift
        options
      end
    end

    def initialize(*)
      super
      set_environment
    end

    def app
      @app ||= super.respond_to?(:to_app) ? super.to_app : super
    end

    def opt_parser
      Options.new
    end

    def set_environment
      ENV["RAILS_ENV"] ||= options[:environment]
    end

    def start
      url = "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}"
      puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
      puts "=> Rails #{Rails.version} application starting in #{Rails.env} on #{url}"
      puts "=> Call with -d to detach" unless options[:daemonize]
      trap(:INT) { exit }
      puts "=> Ctrl-C to shutdown server" unless options[:daemonize]

      #Create required tmp directories if not found
      %w(cache pids sessions sockets).each do |dir_to_make|
        FileUtils.mkdir_p(File.join(Rails.root, 'tmp', dir_to_make))
      end

      unless options[:daemonize]
        wrapped_app # touch the app so the logger is set up

        console = ActiveSupport::Logger.new($stdout)
        console.formatter = Rails.logger.formatter
        console.level = Rails.logger.level

        Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
      end

      super
    ensure
      # The '-h' option calls exit before @options is set.
      # If we call 'options' with it unset, we get double help banners.
      puts 'Exiting' unless @options && options[:daemonize]
    end

    def middleware
      middlewares = []
      middlewares << [Rails::Rack::Debugger]  if options[:debugger]
      middlewares << [::Rack::ContentLength]

      # FIXME: add Rack::Lock in the case people are using webrick.
      # This is to remain backwards compatible for those who are
      # running webrick in production. We should consider removing this
      # in development.
      if server.name == 'Rack::Handler::WEBrick'
        middlewares << [::Rack::Lock]
      end

      Hash.new(middlewares)
    end

    def log_path
      "log/#{options[:environment]}.log"
    end

    def default_options
      super.merge({
        Port:         3000,
        DoNotReverseLookup:  true,
        environment:  (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup,
        daemonize:    false,
        debugger:     false,
        pid:          File.expand_path("tmp/pids/server.pid"),
        config:       File.expand_path("config.ru")
      })
    end
  end
end
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'generators'))

if ARGV.size == 0
  Rails::Generators.help
  exit
end

name = ARGV.shift
Rails::Generators.invoke name, ARGV, behavior: :skip
ARGV << '--help' if ARGV.empty?

aliases = {
  "g"  => "generate",
  "d"  => "destroy",
  "c"  => "console",
  "s"  => "server",
  "db" => "dbconsole",
  "r"  => "runner"
}

help_message = <<-EOT
Usage: rails COMMAND [ARGS]

The most common rails commands are:
 generate    Generate new code (short-cut alias: "g")
 console     Start the Rails console (short-cut alias: "c")
 server      Start the Rails server (short-cut alias: "s")
 dbconsole   Start a console for the database specified in config/database.yml
             (short-cut alias: "db")
 new         Create a new Rails application. "rails new my_app" creates a
             new application called MyApp in "./my_app"

In addition to those, there are:
 application  Generate the Rails application code
 destroy      Undo code generated with "generate" (short-cut alias: "d")
 plugin new   Generates skeleton for developing a Rails plugin
 runner       Run a piece of code in the application environment (short-cut alias: "r")

All commands can be run with -h (or --help) for more information.
EOT


command = ARGV.shift
command = aliases[command] || command

case command
when 'generate', 'destroy', 'plugin'
  require 'rails/generators'

  if command == 'plugin' && ARGV.first == 'new'
    require "rails/commands/plugin_new"
  else
    require APP_PATH
    Rails.application.require_environment!

    Rails.application.load_generators

    require "rails/commands/#{command}"
  end

when 'console'
  require 'rails/commands/console'
  options = Rails::Console.parse_arguments(ARGV)

  # RAILS_ENV needs to be set before config/application is required
  ENV['RAILS_ENV'] = options[:environment] if options[:environment]

  # shift ARGV so IRB doesn't freak
  ARGV.shift if ARGV.first && ARGV.first[0] != '-'

  require APP_PATH
  Rails.application.require_environment!
  Rails::Console.start(Rails.application, options)

when 'server'
  # Change to the application's path if there is no config.ru file in current dir.
  # This allows us to run `rails server` from other directories, but still get
  # the main config.ru and properly set the tmp directory.
  Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))

  require 'rails/commands/server'
  Rails::Server.new.tap do |server|
    # We need to require application after the server sets environment,
    # otherwise the --environment option given to the server won't propagate.
    require APP_PATH
    Dir.chdir(Rails.application.root)
    server.start
  end

when 'dbconsole'
  require 'rails/commands/dbconsole'
  Rails::DBConsole.start

when 'application', 'runner'
  require "rails/commands/#{command}"

when 'new'
  if %w(-h --help).include?(ARGV.first)
    require 'rails/commands/application'
  else
    puts "Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.\n"
    puts "Type 'rails' for help."
    exit(1)
  end

when '--version', '-v'
  ARGV.unshift '--version'
  require 'rails/commands/application'

when '-h', '--help'
  puts help_message

else
  puts "Error: Command '#{command}' not recognized"
  if %x{rake #{command} --dry-run 2>&1 } && $?.success?
    puts "Did you mean: `$ rake #{command}` ?\n\n"
  end
  puts help_message
  exit(1)
end
require 'active_support/deprecation'
require 'active_support/ordered_options'
require 'active_support/core_ext/object'
require 'rails/paths'
require 'rails/rack'

module Rails
  module Configuration
    # MiddlewareStackProxy is a proxy for the Rails middleware stack that allows
    # you to configure middlewares in your application. It works basically as a
    # command recorder, saving each command to be applied after initialization
    # over the default middleware stack, so you can add, swap, or remove any
    # middleware in Rails.
    #
    # You can add your own middlewares by using the +config.middleware.use+ method:
    #
    #     config.middleware.use Magical::Unicorns
    #
    # This will put the <tt>Magical::Unicorns</tt> middleware on the end of the stack.
    # You can use +insert_before+ if you wish to add a middleware before another:
    #
    #     config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
    #
    # There's also +insert_after+ which will insert a middleware after another:
    #
    #     config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
    #
    # Middlewares can also be completely swapped out and replaced with others:
    #
    #     config.middleware.swap ActionDispatch::Flash, Magical::Unicorns
    #
    # And finally they can also be removed from the stack completely:
    #
    #     config.middleware.delete ActionDispatch::Flash
    #
    class MiddlewareStackProxy
      def initialize
        @operations = []
      end

      def insert_before(*args, &block)
        @operations << [__method__, args, block]
      end

      alias :insert :insert_before

      def insert_after(*args, &block)
        @operations << [__method__, args, block]
      end

      def swap(*args, &block)
        @operations << [__method__, args, block]
      end

      def use(*args, &block)
        @operations << [__method__, args, block]
      end

      def delete(*args, &block)
        @operations << [__method__, args, block]
      end

      def merge_into(other) #:nodoc:
        @operations.each do |operation, args, block|
          other.send(operation, *args, &block)
        end
        other
      end
    end

    class Generators #:nodoc:
      attr_accessor :aliases, :options, :templates, :fallbacks, :colorize_logging
      attr_reader :hidden_namespaces

      def initialize
        @aliases = Hash.new { |h,k| h[k] = {} }
        @options = Hash.new { |h,k| h[k] = {} }
        @fallbacks = {}
        @templates = []
        @colorize_logging = true
        @hidden_namespaces = []
      end

      def initialize_copy(source)
        @aliases = @aliases.deep_dup
        @options = @options.deep_dup
        @fallbacks = @fallbacks.deep_dup
        @templates = @templates.dup
      end

      def hide_namespace(namespace)
        @hidden_namespaces << namespace
      end

      def method_missing(method, *args)
        method = method.to_s.sub(/=$/, '').to_sym

        return @options[method] if args.empty?

        if method == :rails || args.first.is_a?(Hash)
          namespace, configuration = method, args.shift
        else
          namespace, configuration = args.shift, args.shift
          namespace = namespace.to_sym if namespace.respond_to?(:to_sym)
          @options[:rails][method] = namespace
        end

        if configuration
          aliases = configuration.delete(:aliases)
          @aliases[namespace].merge!(aliases) if aliases
          @options[namespace].merge!(configuration)
        end
      end
    end
  end
end
require 'active_support/all'
require 'action_controller'

module Rails
  module ConsoleMethods
    # reference the global "app" instance, created on demand. To recreate the
    # instance, pass a non-false value as the parameter.
    def app(create=false)
      @app_integration_instance = nil if create
      @app_integration_instance ||= new_session do |sess|
        sess.host! "www.example.com"
      end
    end

    # create a new session. If a block is given, the new session will be yielded
    # to the block before being returned.
    def new_session
      app = Rails.application
      session = ActionDispatch::Integration::Session.new(app)
      yield session if block_given?
      session
    end

    # reloads the environment
    def reload!(print=true)
      puts "Reloading..." if print
      ActionDispatch::Reloader.cleanup!
      ActionDispatch::Reloader.prepare!
      true
    end
  end
end
module Rails
  module ConsoleMethods
    def helper
      @helper ||= ApplicationController.helpers
    end

    def controller
      @controller ||= ApplicationController.new
    end
  end
end
require 'active_support/deprecation/proxy_wrappers'

module Rails
  class DeprecatedConstant < ActiveSupport::Deprecation::DeprecatedConstantProxy
    def self.deprecate(old, current)
      # double assignment is used to avoid "assigned but unused variable" warning
      constant = constant = new(old, current)
      eval "::#{old} = constant"
    end

    private

    def target
      ::Kernel.eval @new_const.to_s
    end
  end

  DeprecatedConstant.deprecate('RAILS_CACHE', '::Rails.cache')
end
ARGV << '--help' if ARGV.empty?

aliases = {
  "g" => "generate",
  "d" => "destroy"
}

command = ARGV.shift
command = aliases[command] || command

require ENGINE_PATH
engine = ::Rails::Engine.find(ENGINE_ROOT)

case command
when 'generate', 'destroy'
  require 'rails/generators'
  Rails::Generators.namespace = engine.railtie_namespace
  engine.load_generators
  require "rails/commands/#{command}"

when '--version', '-v'
  ARGV.unshift '--version'
  require 'rails/commands/application'

else
  puts "Error: Command not recognized" unless %w(-h --help).include?(command)
  puts <<-EOT
Usage: rails COMMAND [ARGS]

The common rails commands available for engines are:
 generate    Generate new code (short-cut alias: "g")
 destroy     Undo code generated with "generate" (short-cut alias: "d")

All commands can be run with -h for more information.

If you want to run any commands that need to be run in context
of the application, like `rails server` or `rails console`,
you should do it from application's directory (typically test/dummy).
  EOT
  exit(1)
end
require 'rails/railtie/configuration'

module Rails
  class Engine
    class Configuration < ::Rails::Railtie::Configuration
      attr_reader :root
      attr_writer :middleware, :autoload_once_paths, :autoload_paths

      def initialize(root=nil)
        super()
        @root = root
        @generators = app_generators.dup
      end

      # Returns the middleware stack for the engine.
      def middleware
        @middleware ||= Rails::Configuration::MiddlewareStackProxy.new
      end

      # Holds generators configuration:
      #
      #   config.generators do |g|
      #     g.orm             :data_mapper, migration: true
      #     g.template_engine :haml
      #     g.test_framework  :rspec
      #   end
      #
      # If you want to disable color in console, do:
      #
      #   config.generators.colorize_logging = false
      #
      def generators #:nodoc:
        @generators ||= Rails::Configuration::Generators.new
        yield(@generators) if block_given?
        @generators
      end

      def paths
        @paths ||= begin
          paths = Rails::Paths::Root.new(@root)

          paths.add "app",                 autoload: true, glob: "*"
          paths.add "app/assets",          glob: "*"
          paths.add "app/controllers",     autoload: true
          paths.add "app/helpers",         autoload: true
          paths.add "app/models",          autoload: true
          paths.add "app/mailers",         autoload: true
          paths.add "app/views"

          paths.add "app/controllers/concerns", autoload: true
          paths.add "app/models/concerns",      autoload: true

          paths.add "lib",                 load_path: true
          paths.add "lib/assets",          glob: "*"
          paths.add "lib/tasks",           glob: "**/*.rake"

          paths.add "config"
          paths.add "config/environments", glob: "#{Rails.env}.rb"
          paths.add "config/initializers", glob: "**/*.rb"
          paths.add "config/locales",      glob: "*.{rb,yml}"
          paths.add "config/routes.rb"

          paths.add "db"
          paths.add "db/migrate"
          paths.add "db/seeds.rb"

          paths.add "vendor",              load_path: true
          paths.add "vendor/assets",       glob: "*"

          paths
        end
      end

      def root=(value)
        @root = paths.path = Pathname.new(value).expand_path
      end

      def eager_load_paths
        ActiveSupport::Deprecation.warn "eager_load_paths is deprecated and all autoload_paths are now eagerly loaded."
        autoload_paths
      end

      def eager_load_paths=(paths)
        ActiveSupport::Deprecation.warn "eager_load_paths is deprecated and all autoload_paths are now eagerly loaded."
        self.autoload_paths = paths
      end

      def autoload_once_paths
        @autoload_once_paths ||= paths.autoload_once
      end

      def autoload_paths
        @autoload_paths ||= paths.autoload_paths
      end
    end
  end
end
module Rails
  class Engine < Railtie
    class Railties
      include Enumerable
      attr_reader :_all

      def initialize
        @_all ||= ::Rails::Railtie.subclasses.map(&:instance) +
          ::Rails::Engine.subclasses.map(&:instance)
      end

      def self.engines
        @engines ||= ::Rails::Engine.subclasses.map(&:instance)
      end

      def each(*args, &block)
        _all.each(*args, &block)
      end

      def -(others)
        _all - others
      end

      delegate :engines, to: "self.class"
    end
  end
end

ActiveSupport::Deprecation.deprecate_methods(Rails::Engine::Railties, :engines)
require 'rails/railtie'
require 'active_support/core_ext/module/delegation'
require 'pathname'
require 'rbconfig'

module Rails
  # <tt>Rails::Engine</tt> allows you to wrap a specific Rails application or subset of
  # functionality and share it with other applications or within a larger packaged application.
  # Since Rails 3.0, every <tt>Rails::Application</tt> is just an engine, which allows for simple
  # feature and application sharing.
  #
  # Any <tt>Rails::Engine</tt> is also a <tt>Rails::Railtie</tt>, so the same
  # methods (like <tt>rake_tasks</tt> and +generators+) and configuration
  # options that are available in railties can also be used in engines.
  #
  # == Creating an Engine
  #
  # In Rails versions prior to 3.0, your gems automatically behaved as engines, however,
  # this coupled Rails to Rubygems. Since Rails 3.0, if you want a gem to automatically
  # behave as an engine, you have to specify an +Engine+ for it somewhere inside
  # your plugin's +lib+ folder (similar to how we specify a +Railtie+):
  #
  #   # lib/my_engine.rb
  #   module MyEngine
  #     class Engine < Rails::Engine
  #     end
  #   end
  #
  # Then ensure that this file is loaded at the top of your <tt>config/application.rb</tt>
  # (or in your +Gemfile+) and it will automatically load models, controllers and helpers
  # inside +app+, load routes at <tt>config/routes.rb</tt>, load locales at
  # <tt>config/locales/*</tt>, and load tasks at <tt>lib/tasks/*</tt>.
  #
  # == Configuration
  #
  # Besides the +Railtie+ configuration which is shared across the application, in a
  # <tt>Rails::Engine</tt> you can access <tt>autoload_paths</tt> and <tt>autoload_once_paths</tt>,
  # which, differently from a <tt>Railtie</tt>, are scoped to the current engine.
  #
  #   class MyEngine < Rails::Engine
  #     # Add a load path for this specific Engine
  #     config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)
  #
  #     initializer "my_engine.add_middleware" do |app|
  #       app.middleware.use MyEngine::Middleware
  #     end
  #   end
  #
  # == Generators
  #
  # You can set up generators for engines with <tt>config.generators</tt> method:
  #
  #   class MyEngine < Rails::Engine
  #     config.generators do |g|
  #       g.orm             :active_record
  #       g.template_engine :erb
  #       g.test_framework  :test_unit
  #     end
  #   end
  #
  # You can also set generators for an application by using <tt>config.app_generators</tt>:
  #
  #   class MyEngine < Rails::Engine
  #     # note that you can also pass block to app_generators in the same way you
  #     # can pass it to generators method
  #     config.app_generators.orm :datamapper
  #   end
  #
  # == Paths
  #
  # Since Rails 3.0, applications and engines have more flexible path configuration (as
  # opposed to the previous hardcoded path configuration). This means that you are not
  # required to place your controllers at <tt>app/controllers</tt>, but in any place
  # which you find convenient.
  #
  # For example, let's suppose you want to place your controllers in <tt>lib/controllers</tt>.
  # You can set that as an option:
  #
  #   class MyEngine < Rails::Engine
  #     paths["app/controllers"] = "lib/controllers"
  #   end
  #
  # You can also have your controllers loaded from both <tt>app/controllers</tt> and
  # <tt>lib/controllers</tt>:
  #
  #   class MyEngine < Rails::Engine
  #     paths["app/controllers"] << "lib/controllers"
  #   end
  #
  # The available paths in an engine are:
  #
  #   class MyEngine < Rails::Engine
  #     paths["app"]                 # => ["app"]
  #     paths["app/controllers"]     # => ["app/controllers"]
  #     paths["app/helpers"]         # => ["app/helpers"]
  #     paths["app/models"]          # => ["app/models"]
  #     paths["app/views"]           # => ["app/views"]
  #     paths["lib"]                 # => ["lib"]
  #     paths["lib/tasks"]           # => ["lib/tasks"]
  #     paths["config"]              # => ["config"]
  #     paths["config/initializers"] # => ["config/initializers"]
  #     paths["config/locales"]      # => ["config/locales"]
  #     paths["config/routes"]       # => ["config/routes.rb"]
  #   end
  #
  # The <tt>Application</tt> class adds a couple more paths to this set. And as in your
  # <tt>Application</tt>, all folders under +app+ are automatically added to the load path.
  # If you have an <tt>app/services/tt> folder for example, it will be added by default.
  #
  # == Endpoint
  #
  # An engine can be also a rack application. It can be useful if you have a rack application that
  # you would like to wrap with +Engine+ and provide some of the +Engine+'s features.
  #
  # To do that, use the +endpoint+ method:
  #
  #   module MyEngine
  #     class Engine < Rails::Engine
  #       endpoint MyRackApplication
  #     end
  #   end
  #
  # Now you can mount your engine in application's routes just like that:
  #
  #   MyRailsApp::Application.routes.draw do
  #     mount MyEngine::Engine => "/engine"
  #   end
  #
  # == Middleware stack
  #
  # As an engine can now be a rack endpoint, it can also have a middleware
  # stack. The usage is exactly the same as in <tt>Application</tt>:
  #
  #   module MyEngine
  #     class Engine < Rails::Engine
  #       middleware.use SomeMiddleware
  #     end
  #   end
  #
  # == Routes
  #
  # If you don't specify an endpoint, routes will be used as the default
  # endpoint. You can use them just like you use an application's routes:
  #
  #   # ENGINE/config/routes.rb
  #   MyEngine::Engine.routes.draw do
  #     get "/" => "posts#index"
  #   end
  #
  # == Mount priority
  #
  # Note that now there can be more than one router in your application, and it's better to avoid
  # passing requests through many routers. Consider this situation:
  #
  #   MyRailsApp::Application.routes.draw do
  #     mount MyEngine::Engine => "/blog"
  #     get "/blog/omg" => "main#omg"
  #   end
  #
  # +MyEngine+ is mounted at <tt>/blog</tt>, and <tt>/blog/omg</tt> points to application's
  # controller. In such a situation, requests to <tt>/blog/omg</tt> will go through +MyEngine+,
  # and if there is no such route in +Engine+'s routes, it will be dispatched to <tt>main#omg</tt>.
  # It's much better to swap that:
  #
  #   MyRailsApp::Application.routes.draw do
  #     get "/blog/omg" => "main#omg"
  #     mount MyEngine::Engine => "/blog"
  #   end
  #
  # Now, +Engine+ will get only requests that were not handled by +Application+.
  #
  # == Engine name
  #
  # There are some places where an Engine's name is used:
  #
  # * routes: when you mount an Engine with <tt>mount(MyEngine::Engine => '/my_engine')</tt>,
  #   it's used as default <tt>:as</tt> option
  # * rake task for installing migrations <tt>my_engine:install:migrations</tt>
  #
  # Engine name is set by default based on class name. For <tt>MyEngine::Engine</tt> it will be
  # <tt>my_engine_engine</tt>. You can change it manually using the <tt>engine_name</tt> method:
  #
  #   module MyEngine
  #     class Engine < Rails::Engine
  #       engine_name "my_engine"
  #     end
  #   end
  #
  # == Isolated Engine
  #
  # Normally when you create controllers, helpers and models inside an engine, they are treated
  # as if they were created inside the application itself. This means that all helpers and
  # named routes from the application will be available to your engine's controllers as well.
  #
  # However, sometimes you want to isolate your engine from the application, especially if your engine
  # has its own router. To do that, you simply need to call +isolate_namespace+. This method requires
  # you to pass a module where all your controllers, helpers and models should be nested to:
  #
  #   module MyEngine
  #     class Engine < Rails::Engine
  #       isolate_namespace MyEngine
  #     end
  #   end
  #
  # With such an engine, everything that is inside the +MyEngine+ module will be isolated from
  # the application.
  #
  # Consider such controller:
  #
  #   module MyEngine
  #     class FooController < ActionController::Base
  #     end
  #   end
  #
  # If an engine is marked as isolated, +FooController+ has access only to helpers from +Engine+ and
  # <tt>url_helpers</tt> from <tt>MyEngine::Engine.routes</tt>.
  #
  # The next thing that changes in isolated engines is the behavior of routes. Normally, when you namespace
  # your controllers, you also need to do namespace all your routes. With an isolated engine,
  # the namespace is applied by default, so you can ignore it in routes:
  #
  #   MyEngine::Engine.routes.draw do
  #     resources :articles
  #   end
  #
  # The routes above will automatically point to <tt>MyEngine::ArticlesController</tt>. Furthermore, you don't
  # need to use longer url helpers like <tt>my_engine_articles_path</tt>. Instead, you should simply use
  # <tt>articles_path</tt> as you would do with your application.
  #
  # To make that behavior consistent with other parts of the framework, an isolated engine also has influence on
  # <tt>ActiveModel::Naming</tt>. When you use a namespaced model, like <tt>MyEngine::Article</tt>, it will normally
  # use the prefix "my_engine". In an isolated engine, the prefix will be omitted in url helpers and
  # form fields for convenience.
  #
  #   polymorphic_url(MyEngine::Article.new) # => "articles_path"
  #
  #   form_for(MyEngine::Article.new) do
  #     text_field :title # => <input type="text" name="article[title]" id="article_title" />
  #   end
  #
  # Additionally, an isolated engine will set its name according to namespace, so
  # MyEngine::Engine.engine_name will be "my_engine". It will also set MyEngine.table_name_prefix
  # to "my_engine_", changing the MyEngine::Article model to use the my_engine_articles table.
  #
  # == Using Engine's routes outside Engine
  #
  # Since you can now mount an engine inside application's routes, you do not have direct access to +Engine+'s
  # <tt>url_helpers</tt> inside +Application+. When you mount an engine in an application's routes, a special helper is
  # created to allow you to do that. Consider such a scenario:
  #
  #   # config/routes.rb
  #   MyApplication::Application.routes.draw do
  #     mount MyEngine::Engine => "/my_engine", as: "my_engine"
  #     get "/foo" => "foo#index"
  #   end
  #
  # Now, you can use the <tt>my_engine</tt> helper inside your application:
  #
  #   class FooController < ApplicationController
  #     def index
  #       my_engine.root_url #=> /my_engine/
  #     end
  #   end
  #
  # There is also a <tt>main_app</tt> helper that gives you access to application's routes inside Engine:
  #
  #   module MyEngine
  #     class BarController
  #       def index
  #         main_app.foo_path #=> /foo
  #       end
  #     end
  #   end
  #
  # Note that the <tt>:as</tt> option given to mount takes the <tt>engine_name</tt> as default, so most of the time
  # you can simply omit it.
  #
  # Finally, if you want to generate a url to an engine's route using
  # <tt>polymorphic_url</tt>, you also need to pass the engine helper. Let's
  # say that you want to create a form pointing to one of the engine's routes.
  # All you need to do is pass the helper as the first element in array with
  # attributes for url:
  #
  #   form_for([my_engine, @user])
  #
  # This code will use <tt>my_engine.user_path(@user)</tt> to generate the proper route.
  #
  # == Isolated engine's helpers
  #
  # Sometimes you may want to isolate engine, but use helpers that are defined for it.
  # If you want to share just a few specific helpers you can add them to application's
  # helpers in ApplicationController:
  #
  #   class ApplicationController < ActionController::Base
  #     helper MyEngine::SharedEngineHelper
  #   end
  #
  # If you want to include all of the engine's helpers, you can use #helper method on an engine's
  # instance:
  #
  #   class ApplicationController < ActionController::Base
  #     helper MyEngine::Engine.helpers
  #   end
  #
  # It will include all of the helpers from engine's directory. Take into account that this does
  # not include helpers defined in controllers with helper_method or other similar solutions,
  # only helpers defined in the helpers directory will be included.
  #
  # == Migrations & seed data
  #
  # Engines can have their own migrations. The default path for migrations is exactly the same
  # as in application: <tt>db/migrate</tt>
  #
  # To use engine's migrations in application you can use rake task, which copies them to
  # application's dir:
  #
  #   rake ENGINE_NAME:install:migrations
  #
  # Note that some of the migrations may be skipped if a migration with the same name already exists
  # in application. In such a situation you must decide whether to leave that migration or rename the
  # migration in the application and rerun copying migrations.
  #
  # If your engine has migrations, you may also want to prepare data for the database in
  # the <tt>db/seeds.rb</tt> file. You can load that data using the <tt>load_seed</tt> method, e.g.
  #
  #   MyEngine::Engine.load_seed
  #
  # == Loading priority
  #
  # In order to change engine's priority you can use +config.railties_order+ in main application.
  # It will affect the priority of loading views, helpers, assets and all the other files
  # related to engine or application.
  #
  #   # load Blog::Engine with highest priority, followed by application and other railties
  #   config.railties_order = [Blog::Engine, :main_app, :all]
  class Engine < Railtie
    autoload :Configuration, "rails/engine/configuration"

    class << self
      attr_accessor :called_from, :isolated

      alias :isolated? :isolated
      alias :engine_name :railtie_name

      delegate :eager_load!, to: :instance

      def inherited(base)
        unless base.abstract_railtie?
          Rails::Railtie::Configuration.eager_load_namespaces << base

          base.called_from = begin
            # Remove the line number from backtraces making sure we don't leave anything behind
            call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
            File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
          end
        end

        super
      end

      def endpoint(endpoint = nil)
        @endpoint ||= nil
        @endpoint = endpoint if endpoint
        @endpoint
      end

      def isolate_namespace(mod)
        engine_name(generate_railtie_name(mod))

        self.routes.default_scope = { module: ActiveSupport::Inflector.underscore(mod.name) }
        self.isolated = true

        unless mod.respond_to?(:railtie_namespace)
          name, railtie = engine_name, self

          mod.singleton_class.instance_eval do
            define_method(:railtie_namespace) { railtie }

            unless mod.respond_to?(:table_name_prefix)
              define_method(:table_name_prefix) { "#{name}_" }
            end

            unless mod.respond_to?(:use_relative_model_naming?)
              class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__
            end

            unless mod.respond_to?(:railtie_helpers_paths)
              define_method(:railtie_helpers_paths) { railtie.helpers_paths }
            end

            unless mod.respond_to?(:railtie_routes_url_helpers)
              define_method(:railtie_routes_url_helpers) { railtie.routes.url_helpers }
            end
          end
        end
      end

      # Finds engine with given path
      def find(path)
        expanded_path = File.expand_path path
        Rails::Engine.subclasses.each do |klass|
          engine = klass.instance
          return engine if File.expand_path(engine.root) == expanded_path
        end
        nil
      end
    end

    delegate :middleware, :root, :paths, to: :config
    delegate :engine_name, :isolated?, to: :class

    def initialize
      @_all_autoload_paths = nil
      @_all_load_paths     = nil
      @app                 = nil
      @config              = nil
      @env_config          = nil
      @helpers             = nil
      @routes              = nil
      super
    end

    # Load console and invoke the registered hooks.
    # Check <tt>Rails::Railtie.console</tt> for more info.
    def load_console(app=self)
      require "pp"
      require "rails/console/app"
      require "rails/console/helpers"
      run_console_blocks(app)
      self
    end

    # Load Rails runner and invoke the registered hooks.
    # Check <tt>Rails::Railtie.runner</tt> for more info.
    def load_runner(app=self)
      run_runner_blocks(app)
      self
    end

    # Load Rake, railties tasks and invoke the registered hooks.
    # Check <tt>Rails::Railtie.rake_tasks</tt> for more info.
    def load_tasks(app=self)
      require "rake"
      run_tasks_blocks(app)
      self
    end

    # Load rails generators and invoke the registered hooks.
    # Check <tt>Rails::Railtie.generators</tt> for more info.
    def load_generators(app=self)
      require "rails/generators"
      run_generators_blocks(app)
      Rails::Generators.configure!(app.config.generators)
      self
    end

    # Eager load the application by loading all ruby
    # files inside autoload_paths.
    def eager_load!
      config.autoload_paths.each do |load_path|
        matcher = /\A#{Regexp.escape(load_path)}\/(.*)\.rb\Z/
        Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
          require_dependency file.sub(matcher, '\1')
        end
      end
    end

    def railties
      @railties ||= self.class::Railties.new
    end

    # Returns a module with all the helpers defined for the engine.
    def helpers
      @helpers ||= begin
        helpers = Module.new
        all = ActionController::Base.all_helpers_from_path(helpers_paths)
        ActionController::Base.modules_for_helpers(all).each do |mod|
          helpers.send(:include, mod)
        end
        helpers
      end
    end

    # Returns all registered helpers paths.
    def helpers_paths
      paths["app/helpers"].existent
    end

    # Returns the underlying rack application for this engine.
    def app
      @app ||= begin
        config.middleware = config.middleware.merge_into(default_middleware_stack)
        config.middleware.build(endpoint)
      end
    end

    # Returns the endpoint for this engine. If none is registered,
    # defaults to an ActionDispatch::Routing::RouteSet.
    def endpoint
      self.class.endpoint || routes
    end

    # Define the Rack API for this engine.
    def call(env)
      env.merge!(env_config)
      if env['SCRIPT_NAME']
        env.merge! "ROUTES_#{routes.object_id}_SCRIPT_NAME" => env['SCRIPT_NAME'].dup
      end
      app.call(env)
    end

    # Defines additional Rack env configuration that is added on each call.
    def env_config
      @env_config ||= {
        'action_dispatch.routes' => routes
      }
    end

    # Defines the routes for this engine. If a block is given to
    # routes, it is appended to the engine.
    def routes
      @routes ||= ActionDispatch::Routing::RouteSet.new
      @routes.append(&Proc.new) if block_given?
      @routes
    end

    # Define the configuration object for the engine.
    def config
      @config ||= Engine::Configuration.new(find_root_with_flag("lib"))
    end

    # Load data from db/seeds.rb file. It can be used in to load engines'
    # seeds, e.g.:
    #
    # Blog::Engine.load_seed
    def load_seed
      seed_file = paths["db/seeds.rb"].existent.first
      load(seed_file) if seed_file
    end

    # Add configured load paths to ruby load paths and remove duplicates.
    initializer :set_load_path, before: :bootstrap_hook do
      _all_load_paths.reverse_each do |path|
        $LOAD_PATH.unshift(path) if File.directory?(path)
      end
      $LOAD_PATH.uniq!
    end

    # Set the paths from which Rails will automatically load source files,
    # and the load_once paths.
    #
    # This needs to be an initializer, since it needs to run once
    # per engine and get the engine as a block parameter
    initializer :set_autoload_paths, before: :bootstrap_hook do |app|
      ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths)
      ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths)

      # Freeze so future modifications will fail rather than do nothing mysteriously
      config.autoload_paths.freeze
      config.autoload_once_paths.freeze
    end

    initializer :add_routing_paths do |app|
      paths = self.paths["config/routes.rb"].existent

      if routes? || paths.any?
        app.routes_reloader.paths.unshift(*paths)
        app.routes_reloader.route_sets << routes
      end
    end

    # I18n load paths are a special case since the ones added
    # later have higher priority.
    initializer :add_locales do
      config.i18n.railties_load_path.concat(paths["config/locales"].existent)
    end

    initializer :add_view_paths do
      views = paths["app/views"].existent
      unless views.empty?
        ActiveSupport.on_load(:action_controller){ prepend_view_path(views) if respond_to?(:prepend_view_path) }
        ActiveSupport.on_load(:action_mailer){ prepend_view_path(views) }
      end
    end

    initializer :load_environment_config, before: :load_environment_hook, group: :all do
      paths["config/environments"].existent.each do |environment|
        require environment
      end
    end

    initializer :append_assets_path, group: :all do |app|
      app.config.assets.paths.unshift(*paths["vendor/assets"].existent_directories)
      app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
      app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
    end

    initializer :prepend_helpers_path do |app|
      if !isolated? || (app == self)
        app.config.helpers_paths.unshift(*paths["app/helpers"].existent)
      end
    end

    initializer :load_config_initializers do
      config.paths["config/initializers"].existent.sort.each do |initializer|
        load(initializer)
      end
    end

    initializer :engines_blank_point do
      # We need this initializer so all extra initializers added in engines are
      # consistently executed after all the initializers above across all engines.
    end

    rake_tasks do
      next if self.is_a?(Rails::Application)
      next unless has_migrations?

      namespace railtie_name do
        namespace :install do
          desc "Copy migrations from #{railtie_name} to application"
          task :migrations do
            ENV["FROM"] = railtie_name
            if Rake::Task.task_defined?("railties:install:migrations")
              Rake::Task["railties:install:migrations"].invoke
            else
              Rake::Task["app:railties:install:migrations"].invoke
            end
          end
        end
      end
    end

    protected

    def run_tasks_blocks(*) #:nodoc:
      super
      paths["lib/tasks"].existent.sort.each { |ext| load(ext) }
    end

    def routes? #:nodoc:
      @routes
    end

    def has_migrations? #:nodoc:
      paths["db/migrate"].existent.any?
    end

    def find_root_with_flag(flag, default=nil) #:nodoc:
      root_path = self.class.called_from

      while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
        parent = File.dirname(root_path)
        root_path = parent != root_path && parent
      end

      root = File.exist?("#{root_path}/#{flag}") ? root_path : default
      raise "Could not find root path for #{self}" unless root

      Pathname.new File.realpath root
    end

    def default_middleware_stack #:nodoc:
      ActionDispatch::MiddlewareStack.new
    end

    def _all_autoload_once_paths #:nodoc:
      config.autoload_once_paths
    end

    def _all_autoload_paths #:nodoc:
      @_all_autoload_paths ||= (config.autoload_paths + config.autoload_once_paths).uniq
    end

    def _all_load_paths #:nodoc:
      @_all_load_paths ||= (config.paths.load_paths + _all_autoload_paths).uniq
    end
  end
end
require 'open-uri'
require 'rbconfig'

module Rails
  module Generators
    module Actions
      def initialize(*) # :nodoc:
        super
        @in_group = nil
      end

      # Adds an entry into Gemfile for the supplied gem.
      #
      #   gem "rspec", group: :test
      #   gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/"
      #   gem "rails", "3.0", git: "git://github.com/rails/rails"
      def gem(*args)
        options = args.extract_options!
        name, version = args

        # Set the message to be shown in logs. Uses the git repo if one is given,
        # otherwise use name (version).
        parts, message = [ name.inspect ], name
        if version ||= options.delete(:version)
          parts   << version.inspect
          message << " (#{version})"
        end
        message = options[:git] if options[:git]

        log :gemfile, message

        options.each do |option, value|
          parts << "#{option}: #{value.inspect}"
        end

        in_root do
          str = "gem #{parts.join(", ")}"
          str = "  " + str if @in_group
          str = "\n" + str
          append_file "Gemfile", str, verbose: false
        end
      end

      # Wraps gem entries inside a group.
      #
      #   gem_group :development, :test do
      #     gem "rspec-rails"
      #   end
      def gem_group(*names, &block)
        name = names.map(&:inspect).join(", ")
        log :gemfile, "group #{name}"

        in_root do
          append_file "Gemfile", "\ngroup #{name} do", force: true

          @in_group = true
          instance_eval(&block)
          @in_group = false

          append_file "Gemfile", "\nend\n", force: true
        end
      end

      # Add the given source to Gemfile
      #
      #   add_source "http://gems.github.com/"
      def add_source(source, options={})
        log :source, source

        in_root do
          prepend_file "Gemfile", "source #{source.inspect}\n", verbose: false
        end
      end

      # Adds a line inside the Application class for config/application.rb.
      #
      # If options :env is specified, the line is appended to the corresponding
      # file in config/environments.
      #
      #   environment do
      #     "config.autoload_paths += %W(#{config.root}/extras)"
      #   end
      #
      #   environment(nil, env: "development") do
      #     "config.autoload_paths += %W(#{config.root}/extras)"
      #   end
      def environment(data=nil, options={}, &block)
        sentinel = /class [a-z_:]+ < Rails::Application/i
        env_file_sentinel = /::Application\.configure do/
        data = block.call if !data && block_given?

        in_root do
          if options[:env].nil?
            inject_into_file 'config/application.rb', "\n    #{data}", after: sentinel, verbose: false
          else
            Array(options[:env]).each do |env|
              inject_into_file "config/environments/#{env}.rb", "\n  #{data}", after: env_file_sentinel, verbose: false
            end
          end
        end
      end
      alias :application :environment

      # Run a command in git.
      #
      #   git :init
      #   git add: "this.file that.rb"
      #   git add: "onefile.rb", rm: "badfile.cxx"
      def git(commands={})
        if commands.is_a?(Symbol)
          run "git #{commands}"
        else
          commands.each do |cmd, options|
            run "git #{cmd} #{options}"
          end
        end
      end

      # Create a new file in the vendor/ directory. Code can be specified
      # in a block or a data string can be given.
      #
      #   vendor("sekrit.rb") do
      #     sekrit_salt = "#{Time.now}--#{3.years.ago}--#{rand}--"
      #     "salt = '#{sekrit_salt}'"
      #   end
      #
      #   vendor("foreign.rb", "# Foreign code is fun")
      def vendor(filename, data=nil, &block)
        log :vendor, filename
        create_file("vendor/#{filename}", data, verbose: false, &block)
      end

      # Create a new file in the lib/ directory. Code can be specified
      # in a block or a data string can be given.
      #
      #   lib("crypto.rb") do
      #     "crypted_special_value = '#{rand}--#{Time.now}--#{rand(1337)}--'"
      #   end
      #
      #   lib("foreign.rb", "# Foreign code is fun")
      def lib(filename, data=nil, &block)
        log :lib, filename
        create_file("lib/#{filename}", data, verbose: false, &block)
      end

      # Create a new Rakefile with the provided code (either in a block or a string).
      #
      #   rakefile("bootstrap.rake") do
      #     project = ask("What is the UNIX name of your project?")
      #
      #     <<-TASK
      #       namespace :#{project} do
      #         task :bootstrap do
      #           puts "I like boots!"
      #         end
      #       end
      #     TASK
      #   end
      #
      #   rakefile('seed.rake', 'puts "Planting seeds"')
      def rakefile(filename, data=nil, &block)
        log :rakefile, filename
        create_file("lib/tasks/#{filename}", data, verbose: false, &block)
      end

      # Create a new initializer with the provided code (either in a block or a string).
      #
      #   initializer("globals.rb") do
      #     data = ""
      #
      #     ['MY_WORK', 'ADMINS', 'BEST_COMPANY_EVAR'].each do |const|
      #       data << "#{const} = :entp\n"
      #     end
      #
      #     data
      #   end
      #
      #   initializer("api.rb", "API_KEY = '123456'")
      def initializer(filename, data=nil, &block)
        log :initializer, filename
        create_file("config/initializers/#{filename}", data, verbose: false, &block)
      end

      # Generate something using a generator from Rails or a plugin.
      # The second parameter is the argument string that is passed to
      # the generator or an Array that is joined.
      #
      #   generate(:authenticated, "user session")
      def generate(what, *args)
        log :generate, what
        argument = args.map {|arg| arg.to_s }.flatten.join(" ")

        in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) }
      end

      # Runs the supplied rake task
      #
      #   rake("db:migrate")
      #   rake("db:migrate", env: "production")
      #   rake("gems:install", sudo: true)
      def rake(command, options={})
        log :rake, command
        env  = options[:env] || ENV["RAILS_ENV"] || 'development'
        sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : ''
        in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", verbose: false) }
      end

      # Just run the capify command in root
      #
      #   capify!
      def capify!
        log :capify, ""
        in_root { run("#{extify(:capify)} .", verbose: false) }
      end

      # Make an entry in Rails routing file config/routes.rb
      #
      #   route "root :to => 'welcome#index'"
      def route(routing_code)
        log :route, routing_code
        sentinel = /\.routes\.draw do\s*$/

        in_root do
          inject_into_file 'config/routes.rb', "\n  #{routing_code}", { after: sentinel, verbose: false }
        end
      end

      # Reads the given file at the source root and prints it in the console.
      #
      #   readme "README"
      def readme(path)
        log File.read(find_in_source_paths(path))
      end

      protected

        # Define log for backwards compatibility. If just one argument is sent,
        # invoke say, otherwise invoke say_status. Differently from say and
        # similarly to say_status, this method respects the quiet? option given.
        def log(*args)
          if args.size == 1
            say args.first.to_s unless options.quiet?
          else
            args << (self.behavior == :invoke ? :green : :red)
            say_status(*args)
          end
        end

        # Add an extension to the given name based on the platform.
        def extify(name)
          if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
            "#{name}.bat"
          else
            name
          end
        end

    end
  end
end
require 'active_support/deprecation'

module Rails
  module Generators
    # ActiveModel is a class to be implemented by each ORM to allow Rails to
    # generate customized controller code.
    #
    # The API has the same methods as ActiveRecord, but each method returns a
    # string that matches the ORM API.
    #
    # For example:
    #
    #   ActiveRecord::Generators::ActiveModel.find(Foo, "params[:id]")
    #   # => "Foo.find(params[:id])"
    #
    #   DataMapper::Generators::ActiveModel.find(Foo, "params[:id]")
    #   # => "Foo.get(params[:id])"
    #
    # On initialization, the ActiveModel accepts the instance name that will
    # receive the calls:
    #
    #   builder = ActiveRecord::Generators::ActiveModel.new "@foo"
    #   builder.save # => "@foo.save"
    #
    # The only exception in ActiveModel for ActiveRecord is the use of self.build
    # instead of self.new.
    #
    class ActiveModel
      attr_reader :name

      def initialize(name)
        @name = name
      end

      # GET index
      def self.all(klass)
        "#{klass}.all"
      end

      # GET show
      # GET edit
      # PATCH/PUT update
      # DELETE destroy
      def self.find(klass, params=nil)
        "#{klass}.find(#{params})"
      end

      # GET new
      # POST create
      def self.build(klass, params=nil)
        if params
          "#{klass}.new(#{params})"
        else
          "#{klass}.new"
        end
      end

      # POST create
      def save
        "#{name}.save"
      end

      # PATCH/PUT update
      def update(params=nil)
        "#{name}.update(#{params})"
      end

      def update_attributes(*args) # :nodoc:
        ActiveSupport::Deprecation.warn("Calling '@orm_instance.update_attributes' " \
          "is deprecated, please use '@orm_instance.update' instead.")
        update(*args)
      end

      # POST create
      # PATCH/PUT update
      def errors
        "#{name}.errors"
      end

      # DELETE destroy
      def destroy
        "#{name}.destroy"
      end
    end
  end
end
require 'digest/md5'
require 'securerandom'
require 'active_support/core_ext/string/strip'
require 'rails/version' unless defined?(Rails::VERSION)
require 'rbconfig'
require 'open-uri'
require 'uri'

module Rails
  module Generators
    class AppBase < Base # :nodoc:
      DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver )
      JDBC_DATABASES = %w( jdbcmysql jdbcsqlite3 jdbcpostgresql jdbc )
      DATABASES.concat(JDBC_DATABASES)

      attr_accessor :rails_template
      add_shebang_option!

      argument :app_path, type: :string

      def self.add_shared_options_for(name)
        class_option :builder,            type: :string, aliases: '-b',
                                          desc: "Path to some #{name} builder (can be a filesystem path or URL)"

        class_option :template,           type: :string, aliases: '-m',
                                          desc: "Path to some #{name} template (can be a filesystem path or URL)"

        class_option :skip_gemfile,       type: :boolean, default: false,
                                          desc: "Don't create a Gemfile"

        class_option :skip_bundle,        type: :boolean, aliases: '-B', default: false,
                                          desc: "Don't run bundle install"

        class_option :skip_git,           type: :boolean, aliases: '-G', default: false,
                                          desc: 'Skip .gitignore file'

        class_option :skip_keeps,         type: :boolean, default: false,
                                          desc: 'Skip source control .keep files'

        class_option :skip_active_record, type: :boolean, aliases: '-O', default: false,
                                          desc: 'Skip Active Record files'

        class_option :skip_sprockets,     type: :boolean, aliases: '-S', default: false,
                                          desc: 'Skip Sprockets files'

        class_option :database,           type: :string, aliases: '-d', default: 'sqlite3',
                                          desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"

        class_option :javascript,         type: :string, aliases: '-j', default: 'jquery',
                                          desc: 'Preconfigure for selected JavaScript library'

        class_option :skip_javascript,    type: :boolean, aliases: '-J', default: false,
                                          desc: 'Skip JavaScript files'

        class_option :dev,                type: :boolean, default: false,
                                          desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"

        class_option :edge,               type: :boolean, default: false,
                                          desc: "Setup the #{name} with Gemfile pointing to Rails repository"

        class_option :skip_test_unit,     type: :boolean, aliases: '-T', default: false,
                                          desc: 'Skip Test::Unit files'

        class_option :rc,                 type: :string, default: false,
                                          desc: "Path to file containing extra configuration options for rails command"

        class_option :no_rc,              type: :boolean, default: false,
                                          desc: 'Skip loading of extra configuration options from .railsrc file'

        class_option :help,               type: :boolean, aliases: '-h', group: :rails,
                                          desc: 'Show this help message and quit'
      end

      def initialize(*args)
        @original_wd = Dir.pwd
        super
        convert_database_option_for_jruby
      end

    protected

      def builder
        @builder ||= begin
          if path = options[:builder]
            if URI(path).is_a?(URI::HTTP)
              contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
            else
              contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
            end

            prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
            instance_eval(&prok)
          end

          builder_class = get_builder_class
          builder_class.send(:include, ActionMethods)
          builder_class.new(self)
        end
      end

      def build(meth, *args)
        builder.send(meth, *args) if builder.respond_to?(meth)
      end

      def create_root
        self.destination_root = File.expand_path(app_path, destination_root)
        valid_const?

        empty_directory '.'
        set_default_accessors!
        FileUtils.cd(destination_root) unless options[:pretend]
      end

      def apply_rails_template
        apply rails_template if rails_template
      rescue Thor::Error, LoadError, Errno::ENOENT => e
        raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
      end

      def set_default_accessors!
        self.rails_template = case options[:template]
          when /^https?:\/\//
            options[:template]
          when String
            File.expand_path(options[:template], Dir.pwd)
          else
            options[:template]
        end
      end

      def database_gemfile_entry
        options[:skip_active_record] ? "" : "gem '#{gem_for_database}'"
      end

      def include_all_railties?
        !options[:skip_active_record] && !options[:skip_test_unit] && !options[:skip_sprockets]
      end

      def comment_if(value)
        options[value] ? '# ' : ''
      end

      def rails_gemfile_entry
        if options.dev?
          <<-GEMFILE.strip_heredoc
            gem 'rails',     path: '#{Rails::Generators::RAILS_DEV_PATH}'
            gem 'arel',      github: 'rails/arel'
            gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders'
          GEMFILE
        elsif options.edge?
          <<-GEMFILE.strip_heredoc
            gem 'rails',     github: 'rails/rails'
            gem 'arel',      github: 'rails/arel'
            gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders'
          GEMFILE
        else
          <<-GEMFILE.strip_heredoc
            # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
            gem 'rails', '#{Rails::VERSION::STRING}'
          GEMFILE
        end
      end

      def gem_for_database
        # %w( mysql oracle postgresql sqlite3 frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql )
        case options[:database]
        when "oracle"         then "ruby-oci8"
        when "postgresql"     then "pg"
        when "frontbase"      then "ruby-frontbase"
        when "mysql"          then "mysql2"
        when "sqlserver"      then "activerecord-sqlserver-adapter"
        when "jdbcmysql"      then "activerecord-jdbcmysql-adapter"
        when "jdbcsqlite3"    then "activerecord-jdbcsqlite3-adapter"
        when "jdbcpostgresql" then "activerecord-jdbcpostgresql-adapter"
        when "jdbc"           then "activerecord-jdbc-adapter"
        else options[:database]
        end
      end

      def convert_database_option_for_jruby
        if defined?(JRUBY_VERSION)
          case options[:database]
          when "oracle"     then options[:database].replace "jdbc"
          when "postgresql" then options[:database].replace "jdbcpostgresql"
          when "mysql"      then options[:database].replace "jdbcmysql"
          when "sqlite3"    then options[:database].replace "jdbcsqlite3"
          end
        end
      end

      def assets_gemfile_entry
        return if options[:skip_sprockets]

        gemfile = if options.dev? || options.edge?
          <<-GEMFILE
            # Gems used only for assets and not required
            # in production environments by default.
            group :assets do
              gem 'sprockets-rails', github: 'rails/sprockets-rails'
              gem 'sass-rails',   github: 'rails/sass-rails'
              gem 'coffee-rails', github: 'rails/coffee-rails'

              # See https://github.com/sstephenson/execjs#readme for more supported runtimes
              #{javascript_runtime_gemfile_entry}
              gem 'uglifier', '>= 1.0.3'
            end
          GEMFILE
        else
          <<-GEMFILE
            # Gems used only for assets and not required
            # in production environments by default.
            group :assets do
              gem 'sprockets-rails', '~> 2.0.0.rc1'
              gem 'sass-rails',   '~> 4.0.0.beta'
              gem 'coffee-rails', '~> 4.0.0.beta'

              # See https://github.com/sstephenson/execjs#readme for more supported runtimes
              #{javascript_runtime_gemfile_entry}
              gem 'uglifier', '>= 1.0.3'
            end
          GEMFILE
        end

        gemfile.strip_heredoc.gsub(/^[ \t]*$/, '')
      end

      def javascript_gemfile_entry
        unless options[:skip_javascript]
          <<-GEMFILE.strip_heredoc
            gem '#{options[:javascript]}-rails'

            # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
            gem 'turbolinks'
          GEMFILE
        end
      end

      def javascript_runtime_gemfile_entry
        if defined?(JRUBY_VERSION)
          "gem 'therubyrhino'\n"
        else
          "# gem 'therubyracer', platforms: :ruby\n"
        end
      end

      def bundle_command(command)
        say_status :run, "bundle #{command}"

        # We are going to shell out rather than invoking Bundler::CLI.new(command)
        # because `rails new` loads the Thor gem and on the other hand bundler uses
        # its own vendored Thor, which could be a different version. Running both
        # things in the same process is a recipe for a night with paracetamol.
        #
        # We use backticks and #print here instead of vanilla #system because it
        # is easier to silence stdout in the existing test suite this way. The
        # end-user gets the bundler commands called anyway, so no big deal.
        #
        # We unset temporary bundler variables to load proper bundler and Gemfile.
        #
        # Thanks to James Tucker for the Gem tricks involved in this call.
        _bundle_command = Gem.bin_path('bundler', 'bundle')

        require 'bundler'
        Bundler.with_clean_env do
          print `"#{Gem.ruby}" "#{_bundle_command}" #{command}`
        end
      end

      def run_bundle
        bundle_command('install') unless options[:skip_gemfile] || options[:skip_bundle] || options[:pretend]
      end

      def empty_directory_with_keep_file(destination, config = {})
        empty_directory(destination, config)
        keep_file(destination)
      end

      def keep_file(destination)
        create_file("#{destination}/.keep") unless options[:skip_keeps]
      end
    end
  end
end
begin
  require 'thor/group'
rescue LoadError
  puts "Thor is not available.\nIf you ran this command from a git checkout " \
       "of Rails, please make sure thor is installed,\nand run this command " \
       "as `ruby #{$0} #{(ARGV | ['--dev']).join(" ")}`"
  exit
end

require 'rails/generators/actions'

module Rails
  module Generators
    class Error < Thor::Error # :nodoc:
    end

    class Base < Thor::Group
      include Thor::Actions
      include Rails::Generators::Actions

      add_runtime_options!
      strict_args_position!

      # Returns the source root for this generator using default_source_root as default.
      def self.source_root(path=nil)
        @_source_root = path if path
        @_source_root ||= default_source_root
      end

      # Tries to get the description from a USAGE file one folder above the source
      # root otherwise uses a default description.
      def self.desc(description=nil)
        return super if description

        @desc ||= if usage_path
          ERB.new(File.read(usage_path)).result(binding)
        else
          "Description:\n    Create #{base_name.humanize.downcase} files for #{generator_name} generator."
        end
      end

      # Convenience method to get the namespace from the class name. It's the
      # same as Thor default except that the Generator at the end of the class
      # is removed.
      def self.namespace(name=nil)
        return super if name
        @namespace ||= super.sub(/_generator$/, '').sub(/:generators:/, ':')
      end

      # Convenience method to hide this generator from the available ones when
      # running rails generator command.
      def self.hide!
        Rails::Generators.hide_namespace self.namespace
      end

      # Invoke a generator based on the value supplied by the user to the
      # given option named "name". A class option is created when this method
      # is invoked and you can set a hash to customize it.
      #
      # ==== Examples
      #
      #   module Rails::Generators
      #     class ControllerGenerator < Base
      #       hook_for :test_framework, aliases: "-t"
      #     end
      #   end
      #
      # The example above will create a test framework option and will invoke
      # a generator based on the user supplied value.
      #
      # For example, if the user invoke the controller generator as:
      #
      #   rails generate controller Account --test-framework=test_unit
      #
      # The controller generator will then try to invoke the following generators:
      #
      #   "rails:test_unit", "test_unit:controller", "test_unit"
      #
      # Notice that "rails:generators:test_unit" could be loaded as well, what
      # Rails looks for is the first and last parts of the namespace. This is what
      # allows any test framework to hook into Rails as long as it provides any
      # of the hooks above.
      #
      # ==== Options
      #
      # The first and last part used to find the generator to be invoked are
      # guessed based on class invokes hook_for, as noticed in the example above.
      # This can be customized with two options: :base and :as.
      #
      # Let's suppose you are creating a generator that needs to invoke the
      # controller generator from test unit. Your first attempt is:
      #
      #   class AwesomeGenerator < Rails::Generators::Base
      #     hook_for :test_framework
      #   end
      #
      # The lookup in this case for test_unit as input is:
      #
      #   "test_unit:awesome", "test_unit"
      #
      # Which is not the desired lookup. You can change it by providing the
      # :as option:
      #
      #   class AwesomeGenerator < Rails::Generators::Base
      #     hook_for :test_framework, as: :controller
      #   end
      #
      # And now it will lookup at:
      #
      #   "test_unit:controller", "test_unit"
      #
      # Similarly, if you want it to also lookup in the rails namespace, you just
      # need to provide the :base value:
      #
      #   class AwesomeGenerator < Rails::Generators::Base
      #     hook_for :test_framework, in: :rails, as: :controller
      #   end
      #
      # And the lookup is exactly the same as previously:
      #
      #   "rails:test_unit", "test_unit:controller", "test_unit"
      #
      # ==== Switches
      #
      # All hooks come with switches for user interface. If you do not want
      # to use any test framework, you can do:
      #
      #   rails generate controller Account --skip-test-framework
      #
      # Or similarly:
      #
      #   rails generate controller Account --no-test-framework
      #
      # ==== Boolean hooks
      #
      # In some cases, you may want to provide a boolean hook. For example, webrat
      # developers might want to have webrat available on controller generator.
      # This can be achieved as:
      #
      #   Rails::Generators::ControllerGenerator.hook_for :webrat, type: :boolean
      #
      # Then, if you want webrat to be invoked, just supply:
      #
      #   rails generate controller Account --webrat
      #
      # The hooks lookup is similar as above:
      #
      #   "rails:generators:webrat", "webrat:generators:controller", "webrat"
      #
      # ==== Custom invocations
      #
      # You can also supply a block to hook_for to customize how the hook is
      # going to be invoked. The block receives two arguments, an instance
      # of the current class and the class to be invoked.
      #
      # For example, in the resource generator, the controller should be invoked
      # with a pluralized class name. But by default it is invoked with the same
      # name as the resource generator, which is singular. To change this, we
      # can give a block to customize how the controller can be invoked.
      #
      #   hook_for :resource_controller do |instance, controller|
      #     instance.invoke controller, [ instance.name.pluralize ]
      #   end
      #
      def self.hook_for(*names, &block)
        options = names.extract_options!
        in_base = options.delete(:in) || base_name
        as_hook = options.delete(:as) || generator_name

        names.each do |name|
          defaults = if options[:type] == :boolean
            { }
          elsif [true, false].include?(default_value_for_option(name, options))
            { banner: "" }
          else
            { desc: "#{name.to_s.humanize} to be invoked", banner: "NAME" }
          end

          unless class_options.key?(name)
            class_option(name, defaults.merge!(options))
          end

          hooks[name] = [ in_base, as_hook ]
          invoke_from_option(name, options, &block)
        end
      end

      # Remove a previously added hook.
      #
      #   remove_hook_for :orm
      def self.remove_hook_for(*names)
        remove_invocation(*names)

        names.each do |name|
          hooks.delete(name)
        end
      end

      # Make class option aware of Rails::Generators.options and Rails::Generators.aliases.
      def self.class_option(name, options={}) #:nodoc:
        options[:desc]    = "Indicates when to generate #{name.to_s.humanize.downcase}" unless options.key?(:desc)
        options[:aliases] = default_aliases_for_option(name, options)
        options[:default] = default_value_for_option(name, options)
        super(name, options)
      end

      # Returns the default source root for a given generator. This is used internally
      # by rails to set its generators source root. If you want to customize your source
      # root, you should use source_root.
      def self.default_source_root
        return unless base_name && generator_name
        return unless default_generator_root
        path = File.join(default_generator_root, 'templates')
        path if File.exists?(path)
      end

      # Returns the base root for a common set of generators. This is used to dynamically
      # guess the default source root.
      def self.base_root
        File.dirname(__FILE__)
      end

      # Cache source root and add lib/generators/base/generator/templates to
      # source paths.
      def self.inherited(base) #:nodoc:
        super

        # Invoke source_root so the default_source_root is set.
        base.source_root

        if base.name && base.name !~ /Base$/
          Rails::Generators.subclasses << base

          Rails::Generators.templates_path.each do |path|
            if base.name.include?('::')
              base.source_paths << File.join(path, base.base_name, base.generator_name)
            else
              base.source_paths << File.join(path, base.generator_name)
            end
          end
        end
      end

      protected

        # Check whether the given class names are already taken by user
        # application or Ruby on Rails.
        def class_collisions(*class_names) #:nodoc:
          return unless behavior == :invoke

          class_names.flatten.each do |class_name|
            class_name = class_name.to_s
            next if class_name.strip.empty?

            # Split the class from its module nesting
            nesting = class_name.split('::')
            last_name = nesting.pop

            # Extract the last Module in the nesting
            last = nesting.inject(Object) do |last_module, nest|
              break unless last_module.const_defined?(nest, false)
              last_module.const_get(nest)
            end

            if last && last.const_defined?(last_name.camelize, false)
              raise Error, "The name '#{class_name}' is either already used in your application " <<
                           "or reserved by Ruby on Rails. Please choose an alternative and run "  <<
                           "this generator again."
            end
          end
        end

        # Use Rails default banner.
        def self.banner
          "rails generate #{namespace.sub(/^rails:/,'')} #{self.arguments.map{ |a| a.usage }.join(' ')} [options]".gsub(/\s+/, ' ')
        end

        # Sets the base_name taking into account the current class namespace.
        def self.base_name
          @base_name ||= begin
            if base = name.to_s.split('::').first
              base.underscore
            end
          end
        end

        # Removes the namespaces and get the generator name. For example,
        # Rails::Generators::ModelGenerator will return "model" as generator name.
        def self.generator_name
          @generator_name ||= begin
            if generator = name.to_s.split('::').last
              generator.sub!(/Generator$/, '')
              generator.underscore
            end
          end
        end

        # Return the default value for the option name given doing a lookup in
        # Rails::Generators.options.
        def self.default_value_for_option(name, options)
          default_for_option(Rails::Generators.options, name, options, options[:default])
        end

        # Return default aliases for the option name given doing a lookup in
        # Rails::Generators.aliases.
        def self.default_aliases_for_option(name, options)
          default_for_option(Rails::Generators.aliases, name, options, options[:aliases])
        end

        # Return default for the option name given doing a lookup in config.
        def self.default_for_option(config, name, options, default)
          if generator_name and c = config[generator_name.to_sym] and c.key?(name)
            c[name]
          elsif base_name and c = config[base_name.to_sym] and c.key?(name)
            c[name]
          elsif config[:rails].key?(name)
            config[:rails][name]
          else
            default
          end
        end

        # Keep hooks configuration that are used on prepare_for_invocation.
        def self.hooks #:nodoc:
          @hooks ||= from_superclass(:hooks, {})
        end

        # Prepare class invocation to search on Rails namespace if a previous
        # added hook is being used.
        def self.prepare_for_invocation(name, value) #:nodoc:
          return super unless value.is_a?(String) || value.is_a?(Symbol)

          if value && constants = self.hooks[name]
            value = name if TrueClass === value
            Rails::Generators.find_by_namespace(value, *constants)
          elsif klass = Rails::Generators.find_by_namespace(value)
            klass
          else
            super
          end
        end

        # Small macro to add ruby as an option to the generator with proper
        # default value plus an instance helper method called shebang.
        def self.add_shebang_option!
          class_option :ruby, type: :string, aliases: "-r", default: Thor::Util.ruby_command,
                              desc: "Path to the Ruby binary of your choice", banner: "PATH"

          no_tasks {
            define_method :shebang do
              @shebang ||= begin
                command = if options[:ruby] == Thor::Util.ruby_command
                  "/usr/bin/env #{File.basename(Thor::Util.ruby_command)}"
                else
                  options[:ruby]
                end
                "#!#{command}"
              end
            end
          }
        end

        def self.usage_path
          paths = [
            source_root && File.expand_path("../USAGE", source_root),
            default_generator_root && File.join(default_generator_root, "USAGE")
          ]
          paths.compact.detect { |path| File.exists? path }
        end

        def self.default_generator_root
          path = File.expand_path(File.join(base_name, generator_name), base_root)
          path if File.exists?(path)
        end

    end
  end
end
require "rails/generators/named_base"

module Css # :nodoc:
  module Generators # :nodoc:
    class AssetsGenerator < Rails::Generators::NamedBase # :nodoc:
      source_root File.expand_path("../templates", __FILE__)

      def copy_stylesheet
        copy_file "stylesheet.css", File.join('app/assets/stylesheets', class_path, "#{file_name}.css")
      end
    end
  end
end
require "rails/generators/named_base"

module Css # :nodoc:
  module Generators # :nodoc:
    class ScaffoldGenerator < Rails::Generators::NamedBase # :nodoc:
      # In order to allow the Sass generators to pick up the default Rails CSS and
      # transform it, we leave it in a standard location for the CSS stylesheet
      # generators to handle. For the simple, default case, just copy it over.
      def copy_stylesheet
        dir = Rails::Generators::ScaffoldGenerator.source_root
        file = File.join(dir, "scaffold.css")
        create_file "app/assets/stylesheets/scaffold.css", File.read(file)
      end
    end
  end
end
require 'rails/generators/erb'

module Erb # :nodoc:
  module Generators # :nodoc:
    class ControllerGenerator < Base # :nodoc:
      argument :actions, type: :array, default: [], banner: "action action"

      def copy_view_files
        base_path = File.join("app/views", class_path, file_name)
        empty_directory base_path

        actions.each do |action|
          @action = action
          @path = File.join(base_path, filename_with_extensions(action))
          template filename_with_extensions(:view), @path
        end
      end
    end
  end
end
require 'rails/generators/erb/controller/controller_generator'

module Erb # :nodoc:
  module Generators # :nodoc:
    class MailerGenerator < ControllerGenerator # :nodoc:
      protected

      def format
        :text
      end
    end
  end
end
require 'rails/generators/erb'
require 'rails/generators/resource_helpers'

module Erb # :nodoc:
  module Generators # :nodoc:
    class ScaffoldGenerator < Base # :nodoc:
      include Rails::Generators::ResourceHelpers

      argument :attributes, type: :array, default: [], banner: "field:type field:type"

      def create_root_folder
        empty_directory File.join("app/views", controller_file_path)
      end

      def copy_view_files
        available_views.each do |view|
          filename = filename_with_extensions(view)
          template filename, File.join("app/views", controller_file_path, filename)
        end
      end

    protected

      def available_views
        %w(index edit show new _form)
      end
    end
  end
end
require 'rails/generators/named_base'

module Erb # :nodoc:
  module Generators # :nodoc:
    class Base < Rails::Generators::NamedBase #:nodoc:
      protected

      def format
        :html
      end

      def handler
        :erb
      end

      def filename_with_extensions(name)
        [name, format, handler].compact.join(".")
      end
    end
  end
end
require 'active_support/time'

module Rails
  module Generators
    class GeneratedAttribute # :nodoc:
      INDEX_OPTIONS = %w(index uniq)
      UNIQ_INDEX_OPTIONS = %w(uniq)

      attr_accessor :name, :type
      attr_reader   :attr_options
      attr_writer   :index_name

      class << self
        def parse(column_definition)
          name, type, has_index = column_definition.split(':')

          # if user provided "name:index" instead of "name:string:index"
          # type should be set blank so GeneratedAttribute's constructor
          # could set it to :string
          has_index, type = type, nil if INDEX_OPTIONS.include?(type)

          type, attr_options = *parse_type_and_options(type)
          type = type.to_sym if type

          if type && reference?(type)
            references_index = UNIQ_INDEX_OPTIONS.include?(has_index) ? { unique: true } : true
            attr_options[:index] = references_index
          end

          new(name, type, has_index, attr_options)
        end

        def reference?(type)
          [:references, :belongs_to].include? type
        end

        private

        # parse possible attribute options like :limit for string/text/binary/integer, :precision/:scale for decimals or :polymorphic for references/belongs_to
        # when declaring options curly brackets should be used
        def parse_type_and_options(type)
          case type
          when /(string|text|binary|integer)\{(\d+)\}/
            return $1, limit: $2.to_i
          when /decimal\{(\d+)[,.-](\d+)\}/
            return :decimal, precision: $1.to_i, scale: $2.to_i
          when /(references|belongs_to)\{polymorphic\}/
            return $1, polymorphic: true
          else
            return type, {}
          end
        end
      end

      def initialize(name, type=nil, index_type=false, attr_options={})
        @name           = name
        @type           = type || :string
        @has_index      = INDEX_OPTIONS.include?(index_type)
        @has_uniq_index = UNIQ_INDEX_OPTIONS.include?(index_type)
        @attr_options   = attr_options
      end

      def field_type
        @field_type ||= case type
          when :integer              then :number_field
          when :float, :decimal      then :text_field
          when :time                 then :time_select
          when :datetime, :timestamp then :datetime_select
          when :date                 then :date_select
          when :text                 then :text_area
          when :boolean              then :check_box
          else
            :text_field
        end
      end

      def default
        @default ||= case type
          when :integer                     then 1
          when :float                       then 1.5
          when :decimal                     then "9.99"
          when :datetime, :timestamp, :time then Time.now.to_s(:db)
          when :date                        then Date.today.to_s(:db)
          when :string                      then name == "type" ? "" : "MyString"
          when :text                        then "MyText"
          when :boolean                     then false
          when :references, :belongs_to     then nil
          else
            ""
        end
      end

      def plural_name
        name.sub(/_id$/, '').pluralize
      end

      def human_name
        name.humanize
      end

      def index_name
        @index_name ||= if polymorphic?
          %w(id type).map { |t| "#{name}_#{t}" }
        else
          column_name
        end
      end

      def column_name
        @column_name ||= reference? ? "#{name}_id" : name
      end

      def foreign_key?
        !!(name =~ /_id$/)
      end

      def reference?
        self.class.reference?(type)
      end

      def polymorphic?
        self.attr_options.has_key?(:polymorphic)
      end

      def has_index?
        @has_index
      end

      def has_uniq_index?
        @has_uniq_index
      end

      def inject_options
        "".tap { |s| @attr_options.each { |k,v| s << ", #{k}: #{v.inspect}" } }
      end

      def inject_index_options
        has_uniq_index? ? ", unique: true" : ""
      end
    end
  end
end
require "rails/generators/named_base"

module Js # :nodoc:
  module Generators # :nodoc:
    class AssetsGenerator < Rails::Generators::NamedBase # :nodoc:
      source_root File.expand_path("../templates", __FILE__)

      def copy_javascript
        copy_file "javascript.js", File.join('app/assets/javascripts', class_path, "#{file_name}.js")
      end
    end
  end
end
module Rails
  module Generators
    # Holds common methods for migrations. It assumes that migrations has the
    # [0-9]*_name format and can be used by another frameworks (like Sequel)
    # just by implementing the next migration version method.
    module Migration
      attr_reader :migration_number, :migration_file_name, :migration_class_name

      def self.included(base) #:nodoc:
        base.extend ClassMethods
      end

      module ClassMethods
        def migration_lookup_at(dirname) #:nodoc:
          Dir.glob("#{dirname}/[0-9]*_*.rb")
        end

        def migration_exists?(dirname, file_name) #:nodoc:
          migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).first
        end

        def current_migration_number(dirname) #:nodoc:
          migration_lookup_at(dirname).collect do |file|
            File.basename(file).split("_").first.to_i
          end.max.to_i
        end

        def next_migration_number(dirname) #:nodoc:
          raise NotImplementedError
        end
      end

      # Creates a migration template at the given destination. The difference
      # to the default template method is that the migration version is appended
      # to the destination file name.
      #
      # The migration version, migration file name, migration class name are
      # available as instance variables in the template to be rendered.
      #
      #   migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
      def migration_template(source, destination=nil, config={})
        destination = File.expand_path(destination || source, self.destination_root)

        migration_dir = File.dirname(destination)
        @migration_number     = self.class.next_migration_number(migration_dir)
        @migration_file_name  = File.basename(destination).sub(/\.rb$/, '')
        @migration_class_name = @migration_file_name.camelize

        destination = self.class.migration_exists?(migration_dir, @migration_file_name)

        if !(destination && options[:skip]) && behavior == :invoke
          if destination && options.force?
            remove_file(destination)
          elsif destination
            raise Error, "Another migration is already named #{@migration_file_name}: #{destination}. Use --force to remove the old migration file and replace it."
          end
          destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
        end

        template(source, destination, config)
      end
    end
  end
end
require 'active_support/core_ext/module/introspection'
require 'rails/generators/base'
require 'rails/generators/generated_attribute'

module Rails
  module Generators
    class NamedBase < Base
      argument :name, type: :string
      class_option :skip_namespace, type: :boolean, default: false,
                                    desc: "Skip namespace (affects only isolated applications)"

      def initialize(args, *options) #:nodoc:
        @inside_template = nil
        # Unfreeze name in case it's given as a frozen string
        args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
        super
        assign_names!(self.name)
        parse_attributes! if respond_to?(:attributes)
      end

      no_tasks do
        def template(source, *args, &block)
          inside_template do
            super
          end
        end
      end

      protected
        attr_reader :file_name
        alias :singular_name :file_name

        # Wrap block with namespace of current application
        # if namespace exists and is not skipped
        def module_namespacing(&block)
          content = capture(&block)
          content = wrap_with_namespace(content) if namespaced?
          concat(content)
        end

        def indent(content, multiplier = 2)
          spaces = " " * multiplier
          content = content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join
        end

        def wrap_with_namespace(content)
          content = indent(content).chomp
          "module #{namespace.name}\n#{content}\nend\n"
        end

        def inside_template
          @inside_template = true
          yield
        ensure
          @inside_template = false
        end

        def inside_template?
          @inside_template
        end

        def namespace
          Rails::Generators.namespace
        end

        def namespaced?
          !options[:skip_namespace] && namespace
        end

        def file_path
          @file_path ||= (class_path + [file_name]).join('/')
        end

        def class_path
          inside_template? || !namespaced? ? regular_class_path : namespaced_class_path
        end

        def regular_class_path
          @class_path
        end

        def namespaced_file_path
          @namespaced_file_path ||= namespaced_class_path.join("/")
        end

        def namespaced_class_path
          @namespaced_class_path ||= [namespaced_path] + @class_path
        end

        def namespaced_path
          @namespaced_path ||= namespace.name.split("::").map {|m| m.underscore }[0]
        end

        def class_name
          (class_path + [file_name]).map!{ |m| m.camelize }.join('::')
        end

        def human_name
          @human_name ||= singular_name.humanize
        end

        def plural_name
          @plural_name ||= singular_name.pluralize
        end

        def i18n_scope
          @i18n_scope ||= file_path.tr('/', '.')
        end

        def table_name
          @table_name ||= begin
            base = pluralize_table_names? ? plural_name : singular_name
            (class_path + [base]).join('_')
          end
        end

        def uncountable?
          singular_name == plural_name
        end

        def index_helper
          uncountable? ? "#{plural_table_name}_index" : plural_table_name
        end

        def singular_table_name
          @singular_table_name ||= (pluralize_table_names? ? table_name.singularize : table_name)
        end

        def plural_table_name
          @plural_table_name ||= (pluralize_table_names? ? table_name : table_name.pluralize)
        end

        def plural_file_name
          @plural_file_name ||= file_name.pluralize
        end

        def route_url
          @route_url ||= class_path.collect {|dname| "/" + dname }.join + "/" + plural_file_name
        end

        # Tries to retrieve the application name or simple return application.
        def application_name
          if defined?(Rails) && Rails.application
            Rails.application.class.name.split('::').first.underscore
          else
            "application"
          end
        end

        def assign_names!(name) #:nodoc:
          @class_path = name.include?('/') ? name.split('/') : name.split('::')
          @class_path.map! { |m| m.underscore }
          @file_name = @class_path.pop
        end

        # Convert attributes array into GeneratedAttribute objects.
        def parse_attributes! #:nodoc:
          self.attributes = (attributes || []).map do |attr|
            Rails::Generators::GeneratedAttribute.parse(attr)
          end
        end

        def attributes_names
          @attributes_names ||= attributes.each_with_object([]) do |a, names|
            names << a.column_name
            names << "#{a.name}_type" if a.polymorphic?
          end
        end

        def pluralize_table_names?
          !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
        end

        # Add a class collisions name to be checked on class initialization. You
        # can supply a hash with a :prefix or :suffix to be tested.
        #
        # ==== Examples
        #
        #   check_class_collision suffix: "Decorator"
        #
        # If the generator is invoked with class name Admin, it will check for
        # the presence of "AdminDecorator".
        #
        def self.check_class_collision(options={})
          define_method :check_class_collision do
            name = if self.respond_to?(:controller_class_name) # for ScaffoldBase
              controller_class_name
            else
              class_name
            end

            class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
          end
        end
    end
  end
end
require 'rails/generators/app_base'

module Rails
  module ActionMethods # :nodoc:
    attr_reader :options

    def initialize(generator)
      @generator = generator
      @options   = generator.options
    end

    private
      %w(template copy_file directory empty_directory inside
         empty_directory_with_keep_file create_file chmod shebang).each do |method|
        class_eval <<-RUBY, __FILE__, __LINE__ + 1
          def #{method}(*args, &block)
            @generator.send(:#{method}, *args, &block)
          end
        RUBY
      end

      # TODO: Remove once this is fully in place
      def method_missing(meth, *args, &block)
        @generator.send(meth, *args, &block)
      end
  end

  # The application builder allows you to override elements of the application
  # generator without being forced to reverse the operations of the default
  # generator.
  #
  # This allows you to override entire operations, like the creation of the
  # Gemfile, README, or JavaScript files, without needing to know exactly
  # what those operations do so you can create another template action.
  class AppBuilder
    def rakefile
      template "Rakefile"
    end

    def readme
      copy_file "README.rdoc", "README.rdoc"
    end

    def gemfile
      template "Gemfile"
    end

    def configru
      template "config.ru"
    end

    def gitignore
      copy_file "gitignore", ".gitignore"
    end

    def app
      directory 'app'

      keep_file  'app/mailers'
      keep_file  'app/models'

      keep_file  'app/controllers/concerns'
      keep_file  'app/models/concerns'
    end

    def bin
      directory "bin" do |content|
        "#{shebang}\n" + content
      end
      chmod "bin", 0755, verbose: false
    end

    def config
      empty_directory "config"

      inside "config" do
        template "routes.rb"
        template "application.rb"
        template "environment.rb"

        directory "environments"
        directory "initializers"
        directory "locales"
      end
    end

    def database_yml
      template "config/databases/#{options[:database]}.yml", "config/database.yml"
    end

    def db
      directory "db"
    end

    def lib
      empty_directory 'lib'
      empty_directory_with_keep_file 'lib/tasks'
      empty_directory_with_keep_file 'lib/assets'
    end

    def log
      empty_directory_with_keep_file 'log'
    end

    def public_directory
      directory "public", "public", recursive: false
    end

    def test
      empty_directory_with_keep_file 'test/fixtures'
      empty_directory_with_keep_file 'test/controllers'
      empty_directory_with_keep_file 'test/mailers'
      empty_directory_with_keep_file 'test/models'
      empty_directory_with_keep_file 'test/helpers'
      empty_directory_with_keep_file 'test/integration'

      template 'test/test_helper.rb'
    end

    def tmp
      empty_directory "tmp/cache"
      empty_directory "tmp/cache/assets"
    end

    def vendor
      vendor_javascripts
      vendor_stylesheets
    end

    def vendor_javascripts
      empty_directory_with_keep_file 'vendor/assets/javascripts'
    end

    def vendor_stylesheets
      empty_directory_with_keep_file 'vendor/assets/stylesheets'
    end
  end

  module Generators
    # We need to store the RAILS_DEV_PATH in a constant, otherwise the path
    # can change in Ruby 1.8.7 when we FileUtils.cd.
    RAILS_DEV_PATH = File.expand_path("../../../../../..", File.dirname(__FILE__))
    RESERVED_NAMES = %w[application destroy plugin runner test]

    class AppGenerator < AppBase # :nodoc:
      add_shared_options_for "application"

      # Add bin/rails options
      class_option :version, type: :boolean, aliases: "-v", group: :rails,
                             desc: "Show Rails version number and quit"

      def initialize(*args)
        raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?

        super

        if !options[:skip_active_record] && !DATABASES.include?(options[:database])
          raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
        end
      end

      public_task :create_root

      def create_root_files
        build(:readme)
        build(:rakefile)
        build(:configru)
        build(:gitignore) unless options[:skip_git]
        build(:gemfile)   unless options[:skip_gemfile]
      end

      def create_app_files
        build(:app)
      end

      def create_bin_files
        build(:bin)
      end

      def create_config_files
        build(:config)
      end

      def create_boot_file
        template "config/boot.rb"
      end

      def create_active_record_files
        return if options[:skip_active_record]
        build(:database_yml)
      end

      def create_db_files
        build(:db)
      end

      def create_lib_files
        build(:lib)
      end

      def create_log_files
        build(:log)
      end

      def create_public_files
        build(:public_directory)
      end

      def create_test_files
        build(:test) unless options[:skip_test_unit]
      end

      def create_tmp_files
        build(:tmp)
      end

      def create_vendor_files
        build(:vendor)
      end

      def finish_template
        build(:leftovers)
      end

      public_task :apply_rails_template, :run_bundle

    protected

      def self.banner
        "rails new #{self.arguments.map(&:usage).join(' ')} [options]"
      end

      # Define file as an alias to create_file for backwards compatibility.
      def file(*args, &block)
        create_file(*args, &block)
      end

      def app_name
        @app_name ||= (defined_app_const_base? ? defined_app_name : File.basename(destination_root)).tr(".", "_")
      end

      def defined_app_name
        defined_app_const_base.underscore
      end

      def defined_app_const_base
        Rails.respond_to?(:application) && defined?(Rails::Application) &&
          Rails.application.is_a?(Rails::Application) && Rails.application.class.name.sub(/::Application$/, "")
      end

      alias :defined_app_const_base? :defined_app_const_base

      def app_const_base
        @app_const_base ||= defined_app_const_base || app_name.gsub(/\W/, '_').squeeze('_').camelize
      end
      alias :camelized :app_const_base

      def app_const
        @app_const ||= "#{app_const_base}::Application"
      end

      def valid_const?
        if app_const =~ /^\d/
          raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
        elsif RESERVED_NAMES.include?(app_name)
          raise Error, "Invalid application name #{app_name}. Please give a name which does not match one of the reserved rails words."
        elsif Object.const_defined?(app_const_base)
          raise Error, "Invalid application name #{app_name}, constant #{app_const_base} is already in use. Please choose another application name."
        end
      end

      def app_secret
        SecureRandom.hex(64)
      end

      def mysql_socket
        @mysql_socket ||= [
          "/tmp/mysql.sock",                        # default
          "/var/run/mysqld/mysqld.sock",            # debian/gentoo
          "/var/tmp/mysql.sock",                    # freebsd
          "/var/lib/mysql/mysql.sock",              # fedora
          "/opt/local/lib/mysql/mysql.sock",        # fedora
          "/opt/local/var/run/mysqld/mysqld.sock",  # mac + darwinports + mysql
          "/opt/local/var/run/mysql4/mysqld.sock",  # mac + darwinports + mysql4
          "/opt/local/var/run/mysql5/mysqld.sock",  # mac + darwinports + mysql5
          "/opt/lampp/var/mysql/mysql.sock"         # xampp for linux
        ].find { |f| File.exist?(f) } unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
      end

      def get_builder_class
        defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
      end
    end
  end
end
module ApplicationHelper
end
require File.expand_path('../boot', __FILE__)

<% if include_all_railties? -%>
require 'rails/all'
<% else -%>
# Pick the frameworks you want:
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>

# Assets should be precompiled for production (so we don't need the gems loaded then)
Bundler.require(*Rails.groups(assets: %w(development test)))

module <%= app_const_base %>
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de
<% if options.skip_sprockets? -%>

    # Disable the asset pipeline.
    config.assets.enabled = false
<% end -%>
  end
end
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
# Load the rails application.
require File.expand_path('../application', __FILE__)

# Initialize the rails application.
<%= app_const %>.initialize!
# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# Be sure to restart your server when you modify this file.

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format. Inflections
# are locale specific, and you may define rules for as many different
# locales as you wish. All of these examples are active by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end

# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections(:en) do |inflect|
#   inflect.acronym 'RESTful'
# end
# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
<%= app_const %>.routes.draw do
  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
  # root to: 'welcome#index'

  # Example of regular route:
  #   get 'products/:id' => 'catalog#view'

  # Example of named route that can be invoked with purchase_url(id: product.id)
  #   get 'products/:id/purchase' => 'catalog#purchase', as: :purchase

  # Example resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Example resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Example resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Example resource route with more complex sub-resources:
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', on: :collection
  #     end
  #   end

  # Example resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end
end
module Rails
  module Generators
    class AssetsGenerator < NamedBase # :nodoc:
      class_option :javascripts, type: :boolean, desc: "Generate JavaScripts"
      class_option :stylesheets, type: :boolean, desc: "Generate Stylesheets"

      class_option :javascript_engine, desc: "Engine for JavaScripts"
      class_option :stylesheet_engine, desc: "Engine for Stylesheets"

      protected

      def asset_name
        file_name
      end

      hook_for :javascript_engine do |javascript_engine|
        invoke javascript_engine, [name] if options[:javascripts]
      end

      hook_for :stylesheet_engine do |stylesheet_engine|
        invoke stylesheet_engine, [name] if options[:stylesheets]
      end
    end
  end
end
module Rails
  module Generators
    class ControllerGenerator < NamedBase # :nodoc:
      argument :actions, type: :array, default: [], banner: "action action"
      check_class_collision suffix: "Controller"

      def create_controller_files
        template 'controller.rb', File.join('app/controllers', class_path, "#{file_name}_controller.rb")
      end

      def add_routes
        actions.reverse.each do |action|
          route %{get "#{file_name}/#{action}"}
        end
      end

      hook_for :template_engine, :test_framework, :helper, :assets
    end
  end
end
<% if namespaced? -%>
require_dependency "<%= namespaced_path %>/application_controller"

<% end -%>
<% module_namespacing do -%>
class <%= class_name %>Controller < ApplicationController
<% actions.each do |action| -%>
  def <%= action %>
  end
<%= "\n" unless action == actions.last -%>
<% end -%>
end
<% end -%>
module Rails
  module Generators
    class GeneratorGenerator < NamedBase # :nodoc:
      check_class_collision suffix: "Generator"

      class_option :namespace, type: :boolean, default: true,
                               desc: "Namespace generator under lib/generators/name"

      def create_generator_files
        directory '.', generator_dir
      end

      protected

        def generator_dir
          if options[:namespace]
            File.join("lib", "generators", regular_class_path, file_name)
          else
            File.join("lib", "generators", regular_class_path)
          end
        end

    end
  end
end
module Rails
  module Generators
    class HelperGenerator < NamedBase # :nodoc:
      check_class_collision suffix: "Helper"

      def create_helper_files
        template 'helper.rb', File.join('app/helpers', class_path, "#{file_name}_helper.rb")
      end

      hook_for :test_framework
    end
  end
end
<% module_namespacing do -%>
module <%= class_name %>Helper
end
<% end -%>
module Rails
  module Generators
    class IntegrationTestGenerator < NamedBase # :nodoc:
      hook_for :integration_tool, as: :integration
    end
  end
end
module Rails
  module Generators
    class MigrationGenerator < NamedBase # :nodoc:
      argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
      hook_for :orm, required: true
    end
  end
end
module Rails
  module Generators
    class ModelGenerator < NamedBase # :nodoc:
      argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
      hook_for :orm, required: true
    end
  end
end
require 'active_support/core_ext/hash/slice'
require "rails/generators/rails/app/app_generator"
require 'date'

module Rails
  # The plugin builder allows you to override elements of the plugin
  # generator without being forced to reverse the operations of the default
  # generator.
  #
  # This allows you to override entire operations, like the creation of the
  # Gemfile, README, or JavaScript files, without needing to know exactly
  # what those operations do so you can create another template action.
  class PluginBuilder
    def rakefile
      template "Rakefile"
    end

    def app
      if mountable?
        directory 'app'
        empty_directory_with_keep_file "app/assets/images/#{name}"
      elsif full?
        empty_directory_with_keep_file 'app/models'
        empty_directory_with_keep_file 'app/controllers'
        empty_directory_with_keep_file 'app/views'
        empty_directory_with_keep_file 'app/helpers'
        empty_directory_with_keep_file 'app/mailers'
        empty_directory_with_keep_file "app/assets/images/#{name}"
      end
    end

    def readme
      template "README.rdoc"
    end

    def gemfile
      template "Gemfile"
    end

    def license
      template "MIT-LICENSE"
    end

    def gemspec
      template "%name%.gemspec"
    end

    def gitignore
      template "gitignore", ".gitignore"
    end

    def lib
      template "lib/%name%.rb"
      template "lib/tasks/%name%_tasks.rake"
      template "lib/%name%/version.rb"
      template "lib/%name%/engine.rb" if engine?
    end

    def config
      template "config/routes.rb" if engine?
    end

    def test
      template "test/test_helper.rb"
      template "test/%name%_test.rb"
      append_file "Rakefile", <<-EOF
#{rakefile_test_tasks}

task default: :test
      EOF
      if engine?
        template "test/integration/navigation_test.rb"
      end
    end

    PASSTHROUGH_OPTIONS = [
      :skip_active_record, :skip_javascript, :database, :javascript, :quiet, :pretend, :force, :skip
    ]

    def generate_test_dummy(force = false)
      opts = (options || {}).slice(*PASSTHROUGH_OPTIONS)
      opts[:force] = force
      opts[:skip_bundle] = true

      invoke Rails::Generators::AppGenerator,
        [ File.expand_path(dummy_path, destination_root) ], opts
    end

    def test_dummy_config
      template "rails/boot.rb", "#{dummy_path}/config/boot.rb", force: true
      template "rails/application.rb", "#{dummy_path}/config/application.rb", force: true
      if mountable?
        template "rails/routes.rb", "#{dummy_path}/config/routes.rb", force: true
      end
    end

    def test_dummy_clean
      inside dummy_path do
        remove_file ".gitignore"
        remove_file "db/seeds.rb"
        remove_file "doc"
        remove_file "Gemfile"
        remove_file "lib/tasks"
        remove_file "app/assets/images/rails.png"
        remove_file "public/index.html"
        remove_file "public/robots.txt"
        remove_file "README"
        remove_file "test"
        remove_file "vendor"
      end
    end

    def stylesheets
      if mountable?
        copy_file "#{app_templates_dir}/app/assets/stylesheets/application.css",
                  "app/assets/stylesheets/#{name}/application.css"
      elsif full?
        empty_directory_with_keep_file "app/assets/stylesheets/#{name}"
      end
    end

    def javascripts
      return if options.skip_javascript?

      if mountable?
        template "#{app_templates_dir}/app/assets/javascripts/application.js.tt",
                  "app/assets/javascripts/#{name}/application.js"
      elsif full?
        empty_directory_with_keep_file "app/assets/javascripts/#{name}"
      end
    end

    def bin(force = false)
      return unless engine?

      directory "bin", force: force do |content|
        "#{shebang}\n" + content
      end
      chmod "bin", 0755, verbose: false
    end

    def gemfile_entry
      return unless inside_application?

      gemfile_in_app_path = File.join(rails_app_path, "Gemfile")
      if File.exist? gemfile_in_app_path
        entry = "gem '#{name}', path: '#{relative_path}'"
        append_file gemfile_in_app_path, entry
      end
    end
  end

  module Generators
    class PluginNewGenerator < AppBase # :nodoc:
      add_shared_options_for "plugin"

      alias_method :plugin_path, :app_path

      class_option :dummy_path,   type: :string, default: "test/dummy",
                                  desc: "Create dummy application at given path"

      class_option :full,         type: :boolean, default: false,
                                  desc: "Generate a rails engine with bundled Rails application for testing"

      class_option :mountable,    type: :boolean, default: false,
                                  desc: "Generate mountable isolated application"

      class_option :skip_gemspec, type: :boolean, default: false,
                                  desc: "Skip gemspec file"

      class_option :skip_gemfile_entry, type: :boolean, default: false,
                                        desc: "If creating plugin in application's directory " +
                                                 "skip adding entry to Gemfile"

      def initialize(*args)
        raise Error, "Options should be given after the plugin name. For details run: rails plugin new --help" if args[0].blank?

        @dummy_path = nil
        super
      end

      public_task :create_root

      def create_root_files
        build(:readme)
        build(:rakefile)
        build(:gemspec)   unless options[:skip_gemspec]
        build(:license)
        build(:gitignore) unless options[:skip_git]
        build(:gemfile)   unless options[:skip_gemfile]
      end

      def create_app_files
        build(:app)
      end

      def create_config_files
        build(:config)
      end

      def create_lib_files
        build(:lib)
      end

      def create_public_stylesheets_files
        build(:stylesheets)
      end

      def create_javascript_files
        build(:javascripts)
      end

      def create_images_directory
        build(:images)
      end

      def create_bin_files
        build(:bin)
      end

      def create_test_files
        build(:test) unless options[:skip_test_unit]
      end

      def create_test_dummy_files
        return unless with_dummy_app?
        create_dummy_app
      end

      def update_gemfile
        build(:gemfile_entry) unless options[:skip_gemfile_entry]
      end

      def finish_template
        build(:leftovers)
      end

      public_task :apply_rails_template, :run_bundle

      def name
        @name ||= begin
          # same as ActiveSupport::Inflector#underscore except not replacing '-'
          underscored = original_name.dup
          underscored.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
          underscored.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
          underscored.downcase!

          underscored
        end
      end

    protected

      def app_templates_dir
        "../../app/templates"
      end

      def create_dummy_app(path = nil)
        dummy_path(path) if path

        say_status :vendor_app, dummy_path
        mute do
          build(:generate_test_dummy)
          store_application_definition!
          build(:test_dummy_config)
          build(:test_dummy_clean)
          # ensure that bin/rails has proper dummy_path
          build(:bin, true)
        end
      end

      def engine?
        full? || mountable?
      end

      def full?
        options[:full]
      end

      def mountable?
        options[:mountable]
      end

      def with_dummy_app?
        options[:skip_test_unit].blank? || options[:dummy_path] != 'test/dummy'
      end

      def self.banner
        "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]"
      end

      def original_name
        @original_name ||= File.basename(destination_root)
      end

      def camelized
        @camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize
      end

      def valid_const?
        if original_name =~ /[^0-9a-zA-Z_]+/
          raise Error, "Invalid plugin name #{original_name}. Please give a name which use only alphabetic or numeric or \"_\" characters."
        elsif camelized =~ /^\d/
          raise Error, "Invalid plugin name #{original_name}. Please give a name which does not start with numbers."
        elsif RESERVED_NAMES.include?(name)
          raise Error, "Invalid plugin name #{original_name}. Please give a name which does not match one of the reserved rails words."
        elsif Object.const_defined?(camelized)
          raise Error, "Invalid plugin name #{original_name}, constant #{camelized} is already in use. Please choose another plugin name."
        end
      end

      def application_definition
        @application_definition ||= begin

          dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root)
          unless options[:pretend] || !File.exists?(dummy_application_path)
            contents = File.read(dummy_application_path)
            contents[(contents.index(/module ([\w]+)\n(.*)class Application/m))..-1]
          end
        end
      end
      alias :store_application_definition! :application_definition

      def get_builder_class
        defined?(::PluginBuilder) ? ::PluginBuilder : Rails::PluginBuilder
      end

      def rakefile_test_tasks
        <<-RUBY
require 'rake/testtask'

Rake::TestTask.new(:test) do |t|
  t.libs << 'lib'
  t.libs << 'test'
  t.pattern = 'test/**/*_test.rb'
  t.verbose = false
end
        RUBY
      end

      def dummy_path(path = nil)
        @dummy_path = path if path
        @dummy_path || options[:dummy_path]
      end

      def mute(&block)
        shell.mute(&block)
      end

      def rails_app_path
        APP_PATH.sub("/config/application", "") if defined?(APP_PATH)
      end

      def inside_application?
        rails_app_path && app_path =~ /^#{rails_app_path}/
      end

      def relative_path
        return unless inside_application?
        app_path.sub(/^#{rails_app_path}\//, '')
      end
    end
  end
end
<% if mountable? -%>
<%= camelized %>::Engine.routes.draw do
<% else -%>
Rails.application.routes.draw do
<% end -%>
end
module <%= camelized %>
  class Engine < ::Rails::Engine
<% if mountable? -%>
    isolate_namespace <%= camelized %>
<% end -%>
  end
end
module <%= camelized %>
  VERSION = "0.0.1"
end
<% if engine? -%>
require "<%= name %>/engine"

<% end -%>
module <%= camelized %>
end
require File.expand_path('../boot', __FILE__)

<% if include_all_railties? -%>
require 'rails/all'
<% else -%>
# Pick the frameworks you want:
<%= comment_if :skip_active_record %>require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test_unit %>require "rails/test_unit/railtie"
<% end -%>

Bundler.require(*Rails.groups)
require "<%= name %>"

<%= application_definition %>
gemfile = File.expand_path('../../../../Gemfile', __FILE__)

if File.exist?(gemfile)
  ENV['BUNDLE_GEMFILE'] = gemfile
  require 'bundler'
  Bundler.setup
end

$:.unshift File.expand_path('../../../../lib', __FILE__)Rails.application.routes.draw do

  mount <%= camelized %>::Engine => "/<%= name %>"
end
require 'rails/generators/resource_helpers'
require 'rails/generators/rails/model/model_generator'
require 'active_support/core_ext/object/blank'

module Rails
  module Generators
    class ResourceGenerator < ModelGenerator # :nodoc:
      include ResourceHelpers

      hook_for :resource_controller, required: true do |controller|
        invoke controller, [ controller_name, options[:actions] ]
      end

      class_option :actions, type: :array, banner: "ACTION ACTION", default: [],
                             desc: "Actions for the resource controller"

      hook_for :resource_route, required: true
    end
  end
end
module Rails
  module Generators
    class ResourceRouteGenerator < NamedBase # :nodoc:

      # Properly nests namespaces passed into a generator
      #
      #   $ rails generate resource admin/users/products
      #
      # should give you
      #
      #   namespace :admin do
      #     namespace :users
      #       resources :products
      #     end
      #   end
      def add_resource_route
        return if options[:actions].present?

        # iterates over all namespaces and opens up blocks
        regular_class_path.each_with_index do |namespace, index|
          write("namespace :#{namespace} do", index + 1)
        end

        # inserts the primary resource
        write("resources :#{file_name.pluralize}", route_length + 1)

        # ends blocks
        regular_class_path.each_index do |index|
          write("end", route_length - index)
        end

        # route prepends two spaces onto the front of the string that is passed, this corrects that
        route route_string[2..-1]
      end

      private
        def route_string
          @route_string ||= ""
        end

        def write(str, indent)
          route_string << "#{"  " * indent}#{str}\n"
        end

        def route_length
          regular_class_path.length
        end
    end
  end
end
require 'rails/generators/rails/resource/resource_generator'

module Rails
  module Generators
    class ScaffoldGenerator < ResourceGenerator # :nodoc:
      remove_hook_for :resource_controller
      remove_class_option :actions

      class_option :stylesheets, type: :boolean, desc: "Generate Stylesheets"
      class_option :stylesheet_engine, desc: "Engine for Stylesheets"

      def handle_skip
        @options = @options.merge(stylesheet_engine: false) unless options[:stylesheets]
      end

      hook_for :scaffold_controller, required: true

      hook_for :assets do |assets|
        invoke assets, [controller_name]
      end

      hook_for :stylesheet_engine do |stylesheet_engine|
        if behavior == :invoke
          invoke stylesheet_engine, [controller_name]
        end
      end
    end
  end
end
require 'rails/generators/resource_helpers'

module Rails
  module Generators
    class ScaffoldControllerGenerator < NamedBase # :nodoc:
      include ResourceHelpers

      check_class_collision suffix: "Controller"

      class_option :orm, banner: "NAME", type: :string, required: true,
                         desc: "ORM to generate the controller for"

      argument :attributes, type: :array, default: [], banner: "field:type field:type"

      def create_controller_files
        template "controller.rb", File.join('app/controllers', class_path, "#{controller_file_name}_controller.rb")
      end

      hook_for :template_engine, :test_framework, as: :scaffold

      # Invoke the helper using the controller name (pluralized)
      hook_for :helper, as: :scaffold do |invoked|
        invoke invoked, [ controller_name ]
      end
    end
  end
end
<% if namespaced? -%>
require_dependency "<%= namespaced_file_path %>/application_controller"

<% end -%>
<% module_namespacing do -%>
class <%= controller_class_name %>Controller < ApplicationController
  before_action :set_<%= singular_table_name %>, only: [:show, :edit, :update, :destroy]

  # GET <%= route_url %>
  def index
    @<%= plural_table_name %> = <%= orm_class.all(class_name) %>
  end

  # GET <%= route_url %>/1
  def show
  end

  # GET <%= route_url %>/new
  def new
    @<%= singular_table_name %> = <%= orm_class.build(class_name) %>
  end

  # GET <%= route_url %>/1/edit
  def edit
  end

  # POST <%= route_url %>
  def create
    @<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>

    if @<%= orm_instance.save %>
      redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %>
    else
      render action: 'new'
    end
  end

  # PATCH/PUT <%= route_url %>/1
  def update
    if @<%= orm_instance.update("#{singular_table_name}_params") %>
      redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>
    else
      render action: 'edit'
    end
  end

  # DELETE <%= route_url %>/1
  def destroy
    @<%= orm_instance.destroy %>
    redirect_to <%= index_helper %>_url, notice: <%= "'#{human_name} was successfully destroyed.'" %>
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_<%= singular_table_name %>
      @<%= singular_table_name %> = <%= orm_class.find(class_name, "params[:id]") %>
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def <%= "#{singular_table_name}_params" %>
      <%- if attributes_names.empty? -%>
      params[<%= ":#{singular_table_name}" %>]
      <%- else -%>
      params.require(<%= ":#{singular_table_name}" %>).permit(<%= attributes_names.map { |name| ":#{name}" }.join(', ') %>)
      <%- end -%>
    end
end
<% end -%>
module Rails
  module Generators
    class TaskGenerator < NamedBase # :nodoc:
      argument :actions, type: :array, default: [], banner: "action action"

      def create_task_files
        template 'task.rb', File.join('lib/tasks', "#{file_name}.rake")
      end

    end
  end
end
namespace :<%= file_name %> do
<% actions.each do |action| -%>
  desc "TODO"
  task <%= action %>: :environment do
  end

<% end -%>
end
require 'rails/generators/active_model'

module Rails
  module Generators
    # Deal with controller names on scaffold and add some helpers to deal with
    # ActiveModel.
    module ResourceHelpers # :nodoc:
      mattr_accessor :skip_warn

      def self.included(base) #:nodoc:
        base.class_option :force_plural, type: :boolean, desc: "Forces the use of a plural ModelName"
      end

      # Set controller variables on initialization.
      def initialize(*args) #:nodoc:
        super

        if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
          unless ResourceHelpers.skip_warn
            say "Plural version of the model detected, using singularized version. Override with --force-plural."
            ResourceHelpers.skip_warn = true
          end
          name.replace name.singularize
          assign_names!(name)
        end

        @controller_name = name.pluralize
      end

      protected

        attr_reader :controller_name

        def controller_class_path
          class_path
        end

        def controller_file_name
          @controller_file_name ||= file_name.pluralize
        end

        def controller_file_path
          @controller_file_path ||= (controller_class_path + [controller_file_name]).join('/')
        end

        def controller_class_name
          (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
        end

        def controller_i18n_scope
          @controller_i18n_scope ||= controller_file_path.tr('/', '.')
        end

        # Loads the ORM::Generators::ActiveModel class. This class is responsible
        # to tell scaffold entities how to generate an specific method for the
        # ORM. Check Rails::Generators::ActiveModel for more information.
        def orm_class
          @orm_class ||= begin
            # Raise an error if the class_option :orm was not defined.
            unless self.class.class_options[:orm]
              raise "You need to have :orm as class option to invoke orm_class and orm_instance"
            end

            begin
              "#{options[:orm].to_s.camelize}::Generators::ActiveModel".constantize
            rescue NameError
              Rails::Generators::ActiveModel
            end
          end
        end

        # Initialize ORM::Generators::ActiveModel to access instance methods.
        def orm_instance(name=singular_table_name)
          @orm_instance ||= orm_class.new(name)
        end
    end
  end
end
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/kernel/reporting'
require 'rails/generators'
require 'fileutils'

module Rails
  module Generators
    # Disable color in output. Easier to debug.
    no_color!

    # This class provides a TestCase for testing generators. To setup, you need
    # just to configure the destination and set which generator is being tested:
    #
    #   class AppGeneratorTest < Rails::Generators::TestCase
    #     tests AppGenerator
    #     destination File.expand_path("../tmp", File.dirname(__FILE__))
    #   end
    #
    # If you want to ensure your destination root is clean before running each test,
    # you can set a setup callback:
    #
    #   class AppGeneratorTest < Rails::Generators::TestCase
    #     tests AppGenerator
    #     destination File.expand_path("../tmp", File.dirname(__FILE__))
    #     setup :prepare_destination
    #   end
    class TestCase < ActiveSupport::TestCase
      include FileUtils

      class_attribute :destination_root, :current_path, :generator_class, :default_arguments

      # Generators frequently change the current path using +FileUtils.cd+.
      # So we need to store the path at file load and revert back to it after each test.
      self.current_path = File.expand_path(Dir.pwd)
      self.default_arguments = []

      def setup # :nodoc:
        destination_root_is_set?
        ensure_current_path
        super
      end

      def teardown # :nodoc:
        ensure_current_path
        super
      end

      # Sets which generator should be tested:
      #
      #   tests AppGenerator
      def self.tests(klass)
        self.generator_class = klass
      end

      # Sets default arguments on generator invocation. This can be overwritten when
      # invoking it.
      #
      #   arguments %w(app_name --skip-active-record)
      def self.arguments(array)
        self.default_arguments = array
      end

      # Sets the destination of generator files:
      #
      #   destination File.expand_path("../tmp", File.dirname(__FILE__))
      def self.destination(path)
        self.destination_root = path
      end

      # Asserts a given file exists. You need to supply an absolute path or a path relative
      # to the configured destination:
      #
      #   assert_file "config/environment.rb"
      #
      # You can also give extra arguments. If the argument is a regexp, it will check if the
      # regular expression matches the given file content. If it's a string, it compares the
      # file with the given string:
      #
      #   assert_file "config/environment.rb", /initialize/
      #
      # Finally, when a block is given, it yields the file content:
      #
      #   assert_file "app/controllers/products_controller.rb" do |controller|
      #     assert_instance_method :index, controller do |index|
      #       assert_match(/Product\.all/, index)
      #     end
      #   end
      def assert_file(relative, *contents)
        absolute = File.expand_path(relative, destination_root)
        assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"

        read = File.read(absolute) if block_given? || !contents.empty?
        yield read if block_given?

        contents.each do |content|
          case content
            when String
              assert_equal content, read
            when Regexp
              assert_match content, read
          end
        end
      end
      alias :assert_directory :assert_file

      # Asserts a given file does not exist. You need to supply an absolute path or a
      # path relative to the configured destination:
      #
      #   assert_no_file "config/random.rb"
      def assert_no_file(relative)
        absolute = File.expand_path(relative, destination_root)
        assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
      end
      alias :assert_no_directory :assert_no_file

      # Asserts a given migration exists. You need to supply an absolute path or a
      # path relative to the configured destination:
      #
      #   assert_migration "db/migrate/create_products.rb"
      #
      # This method manipulates the given path and tries to find any migration which
      # matches the migration name. For example, the call above is converted to:
      #
      #   assert_file "db/migrate/003_create_products.rb"
      #
      # Consequently, assert_migration accepts the same arguments has assert_file.
      def assert_migration(relative, *contents, &block)
        file_name = migration_file_name(relative)
        assert file_name, "Expected migration #{relative} to exist, but was not found"
        assert_file file_name, *contents, &block
      end

      # Asserts a given migration does not exist. You need to supply an absolute path or a
      # path relative to the configured destination:
      #
      #   assert_no_migration "db/migrate/create_products.rb"
      def assert_no_migration(relative)
        file_name = migration_file_name(relative)
        assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}"
      end

      # Asserts the given class method exists in the given content. This method does not detect
      # class methods inside (class << self), only class methods which starts with "self.".
      # When a block is given, it yields the content of the method.
      #
      #   assert_migration "db/migrate/create_products.rb" do |migration|
      #     assert_class_method :up, migration do |up|
      #       assert_match(/create_table/, up)
      #     end
      #   end
      def assert_class_method(method, content, &block)
        assert_instance_method "self.#{method}", content, &block
      end

      # Asserts the given method exists in the given content. When a block is given,
      # it yields the content of the method.
      #
      #   assert_file "app/controllers/products_controller.rb" do |controller|
      #     assert_instance_method :index, controller do |index|
      #       assert_match(/Product\.all/, index)
      #     end
      #   end
      def assert_instance_method(method, content)
        assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}"
        yield $3.strip if block_given?
      end
      alias :assert_method :assert_instance_method

      # Asserts the given attribute type gets translated to a field type
      # properly:
      #
      #   assert_field_type :date, :date_select
      def assert_field_type(attribute_type, field_type)
        assert_equal(field_type, create_generated_attribute(attribute_type).field_type)
      end

      # Asserts the given attribute type gets a proper default value:
      #
      #   assert_field_default_value :string, "MyString"
      def assert_field_default_value(attribute_type, value)
        assert_equal(value, create_generated_attribute(attribute_type).default)
      end

      # Runs the generator configured for this class. The first argument is an array like
      # command line arguments:
      #
      #   class AppGeneratorTest < Rails::Generators::TestCase
      #     tests AppGenerator
      #     destination File.expand_path("../tmp", File.dirname(__FILE__))
      #     teardown :cleanup_destination_root
      #
      #     test "database.yml is not created when skipping Active Record" do
      #       run_generator %w(myapp --skip-active-record)
      #       assert_no_file "config/database.yml"
      #     end
      #   end
      #
      # You can provide a configuration hash as second argument. This method returns the output
      # printed by the generator.
      def run_generator(args=self.default_arguments, config={})
        capture(:stdout) { self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) }
      end

      # Instantiate the generator.
      def generator(args=self.default_arguments, options={}, config={})
        @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root))
      end

      # Create a Rails::Generators::GeneratedAttribute by supplying the
      # attribute type and, optionally, the attribute name:
      #
      #   create_generated_attribute(:string, 'name')
      def create_generated_attribute(attribute_type, name = 'test', index = nil)
        Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':'))
      end

      protected

        def destination_root_is_set? # :nodoc:
          raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root
        end

        def ensure_current_path # :nodoc:
          cd current_path
        end

        def prepare_destination # :nodoc:
          rm_rf(destination_root)
          mkdir_p(destination_root)
        end

        def migration_file_name(relative) # :nodoc:
          absolute = File.expand_path(relative, destination_root)
          dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
          Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
        end
    end
  end
end
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class ControllerGenerator < Base # :nodoc:
      argument :actions, type: :array, default: [], banner: "action action"
      check_class_collision suffix: "ControllerTest"

      def create_test_files
        template 'functional_test.rb',
                 File.join('test/controllers', class_path, "#{file_name}_controller_test.rb")
      end
    end
  end
end
require 'test_helper'

<% module_namespacing do -%>
class <%= class_name %>ControllerTest < ActionController::TestCase
<% if actions.empty? -%>
  # test "the truth" do
  #   assert true
  # end
<% else -%>
<% actions.each do |action| -%>
  test "should get <%= action %>" do
    get :<%= action %>
    assert_response :success
  end

<% end -%>
<% end -%>
end
<% end -%>
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class HelperGenerator < Base # :nodoc:
      check_class_collision suffix: "HelperTest"

      def create_helper_files
        template 'helper_test.rb', File.join('test/helpers', class_path, "#{file_name}_helper_test.rb")
      end
    end
  end
end
require 'test_helper'

<% module_namespacing do -%>
class <%= class_name %>HelperTest < ActionView::TestCase
end
<% end -%>
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class IntegrationGenerator < Base # :nodoc:
      check_class_collision suffix: "Test"

      def create_test_files
        template 'integration_test.rb', File.join('test/integration', class_path, "#{file_name}_test.rb")
      end
    end
  end
end
require 'test_helper'

class <%= class_name %>Test < ActionDispatch::IntegrationTest
  # test "the truth" do
  #   assert true
  # end
end
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class MailerGenerator < Base # :nodoc:
      argument :actions, type: :array, default: [], banner: "method method"
      check_class_collision suffix: "Test"

      def create_test_files
        template "functional_test.rb", File.join('test/mailers', class_path, "#{file_name}_test.rb")
      end
    end
  end
end
require 'test_helper'

<% module_namespacing do -%>
class <%= class_name %>Test < ActionMailer::TestCase
<% actions.each do |action| -%>
  test "<%= action %>" do
    mail = <%= class_name %>.<%= action %>
    assert_equal <%= action.to_s.humanize.inspect %>, mail.subject
    assert_equal ["to@example.org"], mail.to
    assert_equal ["from@example.com"], mail.from
    assert_match "Hi", mail.body.encoded
  end

<% end -%>
<% if actions.blank? -%>
  # test "the truth" do
  #   assert true
  # end
<% end -%>
end
<% end -%>
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class ModelGenerator < Base # :nodoc:

      RESERVED_YAML_KEYWORDS = %w(y yes n no true false on off null)

      argument :attributes, type: :array, default: [], banner: "field:type field:type"
      class_option :fixture, type: :boolean

      check_class_collision suffix: "Test"

      def create_test_file
        template 'unit_test.rb', File.join('test/models', class_path, "#{file_name}_test.rb")
      end

      hook_for :fixture_replacement

      def create_fixture_file
        if options[:fixture] && options[:fixture_replacement].nil?
          template 'fixtures.yml', File.join('test/fixtures', class_path, "#{plural_file_name}.yml")
        end
      end

      private
        def yaml_key_value(key, value)
          if RESERVED_YAML_KEYWORDS.include?(key.downcase)
            "'#{key}': #{value}"
          else
            "#{key}: #{value}"
          end
        end
    end
  end
end
require 'test_helper'

<% module_namespacing do -%>
class <%= class_name %>Test < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end
<% end -%>
require 'rails/generators/test_unit'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class PluginGenerator < Base # :nodoc:
      check_class_collision suffix: "Test"

      def create_test_files
        directory '.', 'test'
      end
    end
  end
end
require 'active_support/testing/autorun'
require 'active_support'
require 'rails/generators/test_unit'
require 'rails/generators/resource_helpers'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class ScaffoldGenerator < Base # :nodoc:
      include Rails::Generators::ResourceHelpers

      check_class_collision suffix: "ControllerTest"

      argument :attributes, type: :array, default: [], banner: "field:type field:type"

      def create_test_files
        template "functional_test.rb",
                 File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
      end

      private

        def attributes_hash
          return if attributes_names.empty?

          attributes_names.map do |name|
            "#{name}: @#{singular_table_name}.#{name}"
          end.sort.join(', ')
        end
    end
  end
end
require 'test_helper'

<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
  setup do
    @<%= singular_table_name %> = <%= table_name %>(:one)
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:<%= table_name %>)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create <%= singular_table_name %>" do
    assert_difference('<%= class_name %>.count') do
      post :create, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
    end

    assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
  end

  test "should show <%= singular_table_name %>" do
    get :show, id: <%= "@#{singular_table_name}" %>
    assert_response :success
  end

  test "should get edit" do
    get :edit, id: <%= "@#{singular_table_name}" %>
    assert_response :success
  end

  test "should update <%= singular_table_name %>" do
    patch :update, id: <%= "@#{singular_table_name}" %>, <%= "#{singular_table_name}: { #{attributes_hash} }" %>
    assert_redirected_to <%= singular_table_name %>_path(assigns(:<%= singular_table_name %>))
  end

  test "should destroy <%= singular_table_name %>" do
    assert_difference('<%= class_name %>.count', -1) do
      delete :destroy, id: <%= "@#{singular_table_name}" %>
    end

    assert_redirected_to <%= index_helper %>_path
  end
end
<% end -%>
require 'rails/generators/named_base'

module TestUnit # :nodoc:
  module Generators # :nodoc:
    class Base < Rails::Generators::NamedBase # :nodoc:
    end
  end
end
activesupport_path = File.expand_path('../../../../activesupport/lib', __FILE__)
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)

require 'active_support'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/hash/deep_merge'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/string/inflections'

require 'rails/generators/base'

module Rails
  module Generators
    autoload :Actions,         'rails/generators/actions'
    autoload :ActiveModel,     'rails/generators/active_model'
    autoload :Migration,       'rails/generators/migration'
    autoload :NamedBase,       'rails/generators/named_base'
    autoload :ResourceHelpers, 'rails/generators/resource_helpers'
    autoload :TestCase,        'rails/generators/test_case'

    mattr_accessor :namespace

    DEFAULT_ALIASES = {
      rails: {
        actions: '-a',
        orm: '-o',
        javascripts: '-j',
        javascript_engine: '-je',
        resource_controller: '-c',
        scaffold_controller: '-c',
        stylesheets: '-y',
        stylesheet_engine: '-se',
        template_engine: '-e',
        test_framework: '-t'
      },

      test_unit: {
        fixture_replacement: '-r',
      }
    }

    DEFAULT_OPTIONS = {
      rails: {
        assets: true,
        force_plural: false,
        helper: true,
        integration_tool: nil,
        javascripts: true,
        javascript_engine: :js,
        orm: false,
        resource_controller: :controller,
        resource_route: true,
        scaffold_controller: :scaffold_controller,
        stylesheets: true,
        stylesheet_engine: :css,
        test_framework: false,
        template_engine: :erb
      }
    }

    def self.configure!(config) #:nodoc:
      no_color! unless config.colorize_logging
      aliases.deep_merge! config.aliases
      options.deep_merge! config.options
      fallbacks.merge! config.fallbacks
      templates_path.concat config.templates
      templates_path.uniq!
      hide_namespaces(*config.hidden_namespaces)
    end

    def self.templates_path #:nodoc:
      @templates_path ||= []
    end

    def self.aliases #:nodoc:
      @aliases ||= DEFAULT_ALIASES.dup
    end

    def self.options #:nodoc:
      @options ||= DEFAULT_OPTIONS.dup
    end

    # Hold configured generators fallbacks. If a plugin developer wants a
    # generator group to fallback to another group in case of missing generators,
    # they can add a fallback.
    #
    # For example, shoulda is considered a test_framework and is an extension
    # of test_unit. However, most part of shoulda generators are similar to
    # test_unit ones.
    #
    # Shoulda then can tell generators to search for test_unit generators when
    # some of them are not available by adding a fallback:
    #
    #   Rails::Generators.fallbacks[:shoulda] = :test_unit
    def self.fallbacks
      @fallbacks ||= {}
    end

    # Remove the color from output.
    def self.no_color!
      Thor::Base.shell = Thor::Shell::Basic
    end

    # Track all generators subclasses.
    def self.subclasses
      @subclasses ||= []
    end

    # Rails finds namespaces similar to thor, it only adds one rule:
    #
    # Generators names must end with "_generator.rb". This is required because Rails
    # looks in load paths and loads the generator just before it's going to be used.
    #
    #   find_by_namespace :webrat, :rails, :integration
    #
    # Will search for the following generators:
    #
    #   "rails:webrat", "webrat:integration", "webrat"
    #
    # Notice that "rails:generators:webrat" could be loaded as well, what
    # Rails looks for is the first and last parts of the namespace.
    def self.find_by_namespace(name, base=nil, context=nil) #:nodoc:
      lookups = []
      lookups << "#{base}:#{name}"    if base
      lookups << "#{name}:#{context}" if context

      unless base || context
        unless name.to_s.include?(?:)
          lookups << "#{name}:#{name}"
          lookups << "rails:#{name}"
        end
        lookups << "#{name}"
      end

      lookup(lookups)

      namespaces = Hash[subclasses.map { |klass| [klass.namespace, klass] }]

      lookups.each do |namespace|
        klass = namespaces[namespace]
        return klass if klass
      end

      invoke_fallbacks_for(name, base) || invoke_fallbacks_for(context, name)
    end

    # Receives a namespace, arguments and the behavior to invoke the generator.
    # It's used as the default entry point for generate, destroy and update
    # commands.
    def self.invoke(namespace, args=ARGV, config={})
      names = namespace.to_s.split(':')
      if klass = find_by_namespace(names.pop, names.any? && names.join(':'))
        args << "--help" if args.empty? && klass.arguments.any? { |a| a.required? }
        klass.start(args, config)
      else
        puts "Could not find generator #{namespace}."
      end
    end

    def self.hidden_namespaces
      @hidden_namespaces ||= begin
        orm      = options[:rails][:orm]
        test     = options[:rails][:test_framework]
        template = options[:rails][:template_engine]
        css      = options[:rails][:stylesheet_engine]

        [
          "rails",
          "resource_route",
          "#{orm}:migration",
          "#{orm}:model",
          "#{test}:controller",
          "#{test}:helper",
          "#{test}:integration",
          "#{test}:mailer",
          "#{test}:model",
          "#{test}:scaffold",
          "#{test}:view",
          "#{template}:controller",
          "#{template}:scaffold",
          "#{template}:mailer",
          "#{css}:scaffold",
          "#{css}:assets",
          "css:assets",
          "css:scaffold"
        ]
      end
    end

    class << self
      def hide_namespaces(*namespaces)
        hidden_namespaces.concat(namespaces)
      end
      alias hide_namespace hide_namespaces
    end

    # Show help message with available generators.
    def self.help(command = 'generate')
      lookup!

      namespaces = subclasses.map{ |k| k.namespace }
      namespaces.sort!

      groups = Hash.new { |h,k| h[k] = [] }
      namespaces.each do |namespace|
        base = namespace.split(':').first
        groups[base] << namespace
      end

      puts "Usage: rails #{command} GENERATOR [args] [options]"
      puts
      puts "General options:"
      puts "  -h, [--help]     # Print generator's options and usage"
      puts "  -p, [--pretend]  # Run but do not make any changes"
      puts "  -f, [--force]    # Overwrite files that already exist"
      puts "  -s, [--skip]     # Skip files that already exist"
      puts "  -q, [--quiet]    # Suppress status output"
      puts
      puts "Please choose a generator below."
      puts

      # Print Rails defaults first.
      rails = groups.delete("rails")
      rails.map! { |n| n.sub(/^rails:/, '') }
      rails.delete("app")
      rails.delete("plugin_new")
      print_list("rails", rails)

      hidden_namespaces.each { |n| groups.delete(n.to_s) }

      groups.sort.each { |b, n| print_list(b, n) }
    end

    protected

      # Prints a list of generators.
      def self.print_list(base, namespaces) #:nodoc:
        namespaces = namespaces.reject do |n|
          hidden_namespaces.include?(n)
        end

        return if namespaces.empty?
        puts "#{base.camelize}:"

        namespaces.each do |namespace|
          puts("  #{namespace}")
        end

        puts
      end

      # Try fallbacks for the given base.
      def self.invoke_fallbacks_for(name, base) #:nodoc:
        return nil unless base && fallbacks[base.to_sym]
        invoked_fallbacks = []

        Array(fallbacks[base.to_sym]).each do |fallback|
          next if invoked_fallbacks.include?(fallback)
          invoked_fallbacks << fallback

          klass = find_by_namespace(name, fallback)
          return klass if klass
        end

        nil
      end

      # Receives namespaces in an array and tries to find matching generators
      # in the load path.
      def self.lookup(namespaces) #:nodoc:
        paths = namespaces_to_paths(namespaces)

        paths.each do |raw_path|
          ["rails/generators", "generators"].each do |base|
            path = "#{base}/#{raw_path}_generator"

            begin
              require path
              return
            rescue LoadError => e
              raise unless e.message =~ /#{Regexp.escape(path)}$/
            rescue Exception => e
              warn "[WARNING] Could not load generator #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
            end
          end
        end
      end

      # This will try to load any generator in the load path to show in help.
      def self.lookup! #:nodoc:
        $LOAD_PATH.each do |base|
          Dir[File.join(base, "{rails/generators,generators}", "**", "*_generator.rb")].each do |path|
            begin
              path = path.sub("#{base}/", "")
              require path
            rescue Exception
              # No problem
            end
          end
        end
      end

      # Convert namespaces to paths by replacing ":" for "/" and adding
      # an extra lookup. For example, "rails:model" should be searched
      # in both: "rails/model/model_generator" and "rails/model_generator".
      def self.namespaces_to_paths(namespaces) #:nodoc:
        paths = []
        namespaces.each do |namespace|
          pieces = namespace.split(":")
          paths << pieces.dup.push(pieces.last).join("/")
          paths << pieces.join("/")
        end
        paths.uniq!
        paths
      end
  end
end
require "cgi"

module Rails
  module Info
    mattr_accessor :properties
    class << (@@properties = [])
      def names
        map {|val| val.first }
      end

      def value_for(property_name)
        if property = assoc(property_name)
          property.last
        end
      end
    end

    class << self #:nodoc:
      def property(name, value = nil)
        value ||= yield
        properties << [name, value] if value
      rescue Exception
      end

      def frameworks
        %w( active_record action_pack action_mailer active_support )
      end

      def framework_version(framework)
        if Object.const_defined?(framework.classify)
          require "#{framework}/version"
          "#{framework.classify}::VERSION::STRING".constantize
        end
      end

      def to_s
        column_width = properties.names.map {|name| name.length}.max
        info = properties.map do |name, value|
          value = value.join(", ") if value.is_a?(Array)
          "%-#{column_width}s   %s" % [name, value]
        end
        info.unshift "About your application's environment"
        info * "\n"
      end

      alias inspect to_s

      def to_html
        '<table>'.tap do |table|
          properties.each do |(name, value)|
            table << %(<tr><td class="name">#{CGI.escapeHTML(name.to_s)}</td>)
            formatted_value = if value.kind_of?(Array)
                  "<ul>" + value.map { |v| "<li>#{CGI.escapeHTML(v.to_s)}</li>" }.join + "</ul>"
                else
                  CGI.escapeHTML(value.to_s)
                end
            table << %(<td class="value">#{formatted_value}</td></tr>)
          end
          table << '</table>'
        end
      end
    end

    # The Ruby version and platform, e.g. "1.8.2 (powerpc-darwin8.2.0)".
    property 'Ruby version', "#{RUBY_VERSION} (#{RUBY_PLATFORM})"

    # The RubyGems version, if it's installed.
    property 'RubyGems version' do
      Gem::RubyGemsVersion
    end

    property 'Rack version' do
      ::Rack.release
    end

    # The Rails version.
    property 'Rails version' do
      Rails::VERSION::STRING
    end

    property 'JavaScript Runtime' do
      ExecJS.runtime.name
    end

    # Versions of each Rails framework (Active Record, Action Pack,
    # Action Mailer, and Active Support).
    frameworks.each do |framework|
      property "#{framework.titlecase} version" do
        framework_version(framework)
      end
    end

    property 'Middleware' do
      Rails.configuration.middleware.map(&:inspect)
    end

    # The application's location on the filesystem.
    property 'Application root' do
      File.expand_path(Rails.root)
    end

    # The current Rails environment (development, test, or production).
    property 'Environment' do
      Rails.env
    end

    # The name of the database adapter for the current environment.
    property 'Database adapter' do
      ActiveRecord::Base.configurations[Rails.env]['adapter']
    end

    property 'Database schema version' do
      ActiveRecord::Migrator.current_version rescue nil
    end
  end
end
require 'action_dispatch/routing/inspector'

class Rails::InfoController < ActionController::Base # :nodoc:
  self.view_paths = File.expand_path('../templates', __FILE__)
  prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH
  layout -> { request.xhr? ? nil : 'application' }

  before_filter :require_local!

  def index
    redirect_to action: :routes
  end

  def properties
    @info = Rails::Info.to_html
  end

  def routes
    @routes_inspector = ActionDispatch::Routing::RoutesInspector.new(_routes.routes)
  end

  protected

  def require_local!
    unless local_request?
      render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
    end
  end

  def local_request?
    Rails.application.config.consider_all_requests_local || request.local?
  end
end
require 'tsort'

module Rails
  module Initializable
    def self.included(base) #:nodoc:
      base.extend ClassMethods
    end

    class Initializer
      attr_reader :name, :block

      def initialize(name, context, options, &block)
        options[:group] ||= :default
        @name, @context, @options, @block = name, context, options, block
      end

      def before
        @options[:before]
      end

      def after
        @options[:after]
      end

      def belongs_to?(group)
        @options[:group] == group || @options[:group] == :all
      end

      def run(*args)
        @context.instance_exec(*args, &block)
      end

      def bind(context)
        return self if @context
        Initializer.new(@name, context, @options, &block)
      end
    end

    class Collection < Array
      include TSort

      alias :tsort_each_node :each
      def tsort_each_child(initializer, &block)
        select { |i| i.before == initializer.name || i.name == initializer.after }.each(&block)
      end

      def +(other)
        Collection.new(to_a + other.to_a)
      end
    end

    def run_initializers(group=:default, *args)
      return if instance_variable_defined?(:@ran)
      initializers.tsort_each do |initializer|
        initializer.run(*args) if initializer.belongs_to?(group)
      end
      @ran = true
    end

    def initializers
      @initializers ||= self.class.initializers_for(self)
    end

    module ClassMethods
      def initializers
        @initializers ||= Collection.new
      end

      def initializers_chain
        initializers = Collection.new
        ancestors.reverse_each do |klass|
          next unless klass.respond_to?(:initializers)
          initializers = initializers + klass.initializers
        end
        initializers
      end

      def initializers_for(binding)
        Collection.new(initializers_chain.map { |i| i.bind(binding) })
      end

      def initializer(name, opts = {}, &blk)
        raise ArgumentError, "A block must be passed when defining an initializer" unless blk
        opts[:after] ||= initializers.last.name unless initializers.empty? || initializers.find { |i| i.name == opts[:before] }
        initializers << Initializer.new(name, nil, opts, &blk)
      end
    end
  end
end
module Rails
  module Paths
    # This object is an extended hash that behaves as root of the <tt>Rails::Paths</tt> system.
    # It allows you to collect information about how you want to structure your application
    # paths by a Hash like API. It requires you to give a physical path on initialization.
    #
    #   root = Root.new "/rails"
    #   root.add "app/controllers", autoload: true
    #
    # The command above creates a new root object and add "app/controllers" as a path.
    # This means we can get a <tt>Rails::Paths::Path</tt> object back like below:
    #
    #   path = root["app/controllers"]
    #   path.autoload?                 # => true
    #   path.is_a?(Rails::Paths::Path) # => true
    #
    # The +Path+ object is simply an enumerable and allows you to easily add extra paths:
    #
    #   path.is_a?(Enumerable) # => true
    #   path.to_ary.inspect    # => ["app/controllers"]
    #
    #   path << "lib/controllers"
    #   path.to_ary.inspect    # => ["app/controllers", "lib/controllers"]
    #
    # Notice that when you add a path using +add+, the path object created already
    # contains the path with the same path value given to +add+. In some situations,
    # you may not want this behavior, so you can give :with as option.
    #
    #   root.add "config/routes", with: "config/routes.rb"
    #   root["config/routes"].inspect # => ["config/routes.rb"]
    #
    # The +add+ method accepts the following options as arguments:
    # autoload, autoload_once and glob.
    #
    # Finally, the +Path+ object also provides a few helpers:
    #
    #   root = Root.new "/rails"
    #   root.add "app/controllers"
    #
    #   root["app/controllers"].expanded # => ["/rails/app/controllers"]
    #   root["app/controllers"].existent # => ["/rails/app/controllers"]
    #
    # Check the <tt>Rails::Paths::Path</tt> documentation for more information.
    class Root
      attr_accessor :path

      def initialize(path)
        @current = nil
        @path = path
        @root = {}
      end

      def []=(path, value)
        glob = self[path] ? self[path].glob : nil
        add(path, with: value, glob: glob)
      end

      def add(path, options = {})
        with = Array(options.fetch(:with, path))
        @root[path] = Path.new(self, path, with, options)
      end

      def [](path)
        @root[path]
      end

      def values
        @root.values
      end

      def keys
        @root.keys
      end

      def values_at(*list)
        @root.values_at(*list)
      end

      def all_paths
        values.tap { |v| v.uniq! }
      end

      def autoload_once
        filter_by(:autoload_once?)
      end

      def eager_load
        ActiveSupport::Deprecation.warn "eager_load is deprecated and all autoload_paths are now eagerly loaded."
        filter_by(:autoload?)
      end

      def autoload_paths
        filter_by(:autoload?)
      end

      def load_paths
        filter_by(:load_path?)
      end

    protected

      def filter_by(constraint)
        all = []
        all_paths.each do |path|
          if path.send(constraint)
            paths  = path.existent
            paths -= path.children.map { |p| p.send(constraint) ? [] : p.existent }.flatten
            all.concat(paths)
          end
        end
        all.uniq!
        all
      end
    end

    class Path
      include Enumerable

      attr_accessor :glob

      def initialize(root, current, paths, options = {})
        @paths    = paths
        @current  = current
        @root     = root
        @glob     = options[:glob]

        options[:autoload_once] ? autoload_once! : skip_autoload_once!
        options[:autoload]      ? autoload!      : skip_autoload!
        options[:load_path]     ? load_path!     : skip_load_path!

        if !options.key?(:autoload) && options.key?(:eager_load)
          ActiveSupport::Deprecation.warn "the :eager_load option is deprecated and all :autoload paths are now eagerly loaded."
          options[:eager_load] ? autoload! : skip_autoload!
        end
      end

      def children
        keys = @root.keys.select { |k| k.include?(@current) }
        keys.delete(@current)
        @root.values_at(*keys.sort)
      end

      def first
        expanded.first
      end

      def last
        expanded.last
      end

      %w(autoload_once autoload load_path).each do |m|
        class_eval <<-RUBY, __FILE__, __LINE__ + 1
          def #{m}!        # def autoload!
            @#{m} = true   #   @autoload = true
          end              # end
                           #
          def skip_#{m}!   # def skip_autoload!
            @#{m} = false  #   @autoload = false
          end              # end
                           #
          def #{m}?        # def autoload?
            @#{m}          #   @autoload
          end              # end
        RUBY
      end

      def eager_load!
        ActiveSupport::Deprecation.warn "eager_load paths are deprecated and all autoload paths are now eagerly loaded."
        autoload!
      end

      def skip_eager_load!
        ActiveSupport::Deprecation.warn "eager_load paths are deprecated and all autoload paths are now eagerly loaded."
        skip_autoload!
      end

      def eager_load?
        ActiveSupport::Deprecation.warn "eager_load paths are deprecated and all autoload paths are now eagerly loaded."
        autoload?
      end

      def each(&block)
        @paths.each(&block)
      end

      def <<(path)
        @paths << path
      end
      alias :push :<<

      def concat(paths)
        @paths.concat paths
      end

      def unshift(path)
        @paths.unshift path
      end

      def to_ary
        @paths
      end

      # Expands all paths against the root and return all unique values.
      def expanded
        raise "You need to set a path root" unless @root.path
        result = []

        each do |p|
          path = File.expand_path(p, @root.path)

          if @glob && File.directory?(path)
            Dir.chdir(path) do
              result.concat(Dir.glob(@glob).map { |file| File.join path, file }.sort)
            end
          else
            result << path
          end
        end

        result.uniq!
        result
      end

      # Returns all expanded paths but only if they exist in the filesystem.
      def existent
        expanded.select { |f| File.exists?(f) }
      end

      def existent_directories
        expanded.select { |d| File.directory?(d) }
      end

      alias to_a expanded
    end
  end
end
module Rails
  module Rack
    class Debugger
      def initialize(app)
        @app = app

        ARGV.clear # clear ARGV so that rails server options aren't passed to IRB

        require 'debugger'

        ::Debugger.start
        ::Debugger.settings[:autoeval] = true if ::Debugger.respond_to?(:settings)
        puts "=> Debugger enabled"
      rescue LoadError
        puts "You're missing the 'debugger' gem. Add it to your Gemfile, bundle, and try again."
        exit
      end

      def call(env)
        @app.call(env)
      end
    end
  end
end
module Rails
  module Rack
    class LogTailer
      def initialize(app, log = nil)
        @app = app

        path = Pathname.new(log || "#{::File.expand_path(Rails.root)}/log/#{Rails.env}.log").cleanpath

        @cursor = @file = nil
        if ::File.exists?(path)
          @cursor = ::File.size(path)
          @file = ::File.open(path, 'r')
        end
      end

      def call(env)
        response = @app.call(env)
        tail!
        response
      end

      def tail!
        return unless @cursor
        @file.seek @cursor

        unless @file.eof?
          contents = @file.read
          @cursor = @file.tell
          $stdout.print contents
        end
      end
    end
  end
end
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/object/blank'
require 'active_support/log_subscriber'
require 'action_dispatch/http/request'
require 'rack/body_proxy'

module Rails
  module Rack
    # Sets log tags, logs the request, calls the app, and flushes the logs.
    class Logger < ActiveSupport::LogSubscriber
      def initialize(app, taggers = nil)
        @app          = app
        @taggers      = taggers || []
        @instrumenter = ActiveSupport::Notifications.instrumenter
      end

      def call(env)
        request = ActionDispatch::Request.new(env)

        if logger.respond_to?(:tagged)
          logger.tagged(compute_tags(request)) { call_app(request, env) }
        else
          call_app(request, env)
        end
      end

    protected

      def call_app(request, env)
        # Put some space between requests in development logs.
        if development?
          logger.debug ''
          logger.debug ''
        end

        @instrumenter.start 'action_dispatch.request', request: request
        logger.info started_request_message(request)
        resp = @app.call(env)
        resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
        resp
      rescue
        finish(request)
        raise
      ensure
        ActiveSupport::LogSubscriber.flush_all!
      end

      # Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
      def started_request_message(request)
        'Started %s "%s" for %s at %s' % [
          request.request_method,
          request.filtered_path,
          request.ip,
          Time.now.to_default_s ]
      end

      def compute_tags(request)
        @taggers.collect do |tag|
          case tag
          when Proc
            tag.call(request)
          when Symbol
            request.send(tag)
          else
            tag
          end
        end
      end

      private

      def finish(request)
        @instrumenter.finish 'action_dispatch.request', request: request
      end

      def development?
        Rails.env.development?
      end

      def logger
        Rails.logger
      end
    end
  end
end
module Rails
  module Rack
    autoload :Debugger,      "rails/rack/debugger"
    autoload :Logger,        "rails/rack/logger"
    autoload :LogTailer,     "rails/rack/log_tailer"
  end
end
require 'active_support/concern'

module Rails
  class Railtie
    module Configurable
      extend ActiveSupport::Concern

      module ClassMethods
        delegate :config, to: :instance

        def inherited(base)
          raise "You cannot inherit from a #{self.superclass.name} child"
        end

        def instance
          @instance ||= new
        end

        def respond_to?(*args)
          super || instance.respond_to?(*args)
        end

        def configure(&block)
          class_eval(&block)
        end

        protected

        def method_missing(*args, &block)
          instance.send(*args, &block)
        end
      end
    end
  end
end
require 'rails/configuration'

module Rails
  class Railtie
    class Configuration
      def initialize
        @@options ||= {}
      end

      # Expose the eager_load_namespaces at "module" level for convenience.
      def self.eager_load_namespaces #:nodoc:
        @@eager_load_namespaces ||= []
      end

      # All namespaces that are eager loaded
      def eager_load_namespaces
        @@eager_load_namespaces ||= []
      end

      # Add files that should be watched for change.
      def watchable_files
        @@watchable_files ||= []
      end

      # Add directories that should be watched for change.
      # The key of the hashes should be directories and the values should
      # be an array of extensions to match in each directory.
      def watchable_dirs
        @@watchable_dirs ||= {}
      end

      # This allows you to modify the application's middlewares from Engines.
      #
      # All operations you run on the app_middleware will be replayed on the
      # application once it is defined and the default_middlewares are
      # created
      def app_middleware
        @@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
      end

      # This allows you to modify application's generators from Railties.
      #
      # Values set on app_generators will become defaults for application, unless
      # application overwrites them.
      def app_generators
        @@app_generators ||= Rails::Configuration::Generators.new
        yield(@@app_generators) if block_given?
        @@app_generators
      end

      # First configurable block to run. Called before any initializers are run.
      def before_configuration(&block)
        ActiveSupport.on_load(:before_configuration, yield: true, &block)
      end

      # Third configurable block to run. Does not run if +config.cache_classes+
      # set to false.
      def before_eager_load(&block)
        ActiveSupport.on_load(:before_eager_load, yield: true, &block)
      end

      # Second configurable block to run. Called before frameworks initialize.
      def before_initialize(&block)
        ActiveSupport.on_load(:before_initialize, yield: true, &block)
      end

      # Last configurable block to run. Called after frameworks initialize.
      def after_initialize(&block)
        ActiveSupport.on_load(:after_initialize, yield: true, &block)
      end

      # Array of callbacks defined by #to_prepare.
      def to_prepare_blocks
        @@to_prepare_blocks ||= []
      end

      # Defines generic callbacks to run before #after_initialize. Useful for
      # Rails::Railtie subclasses.
      def to_prepare(&blk)
        to_prepare_blocks << blk if blk
      end

      def respond_to?(name)
        super || @@options.key?(name.to_sym)
      end

    private

      def method_missing(name, *args, &blk)
        if name.to_s =~ /=$/
          @@options[$`.to_sym] = args.first
        elsif @@options.key?(name)
          @@options[name]
        else
          super
        end
      end
    end
  end
end
require 'rails/initializable'
require 'rails/configuration'
require 'active_support/inflector'
require 'active_support/core_ext/module/introspection'
require 'active_support/core_ext/module/delegation'

module Rails
  # Railtie is the core of the Rails framework and provides several hooks to extend
  # Rails and/or modify the initialization process.
  #
  # Every major component of Rails (Action Mailer, Action Controller,
  # Action View and Active Record) is a Railtie. Each of
  # them is responsible for their own initialization. This makes Rails itself
  # absent of any component hooks, allowing other components to be used in
  # place of any of the Rails defaults.
  #
  # Developing a Rails extension does _not_ require any implementation of
  # Railtie, but if you need to interact with the Rails framework during
  # or after boot, then Railtie is needed.
  #
  # For example, an extension doing any of the following would require Railtie:
  #
  # * creating initializers
  # * configuring a Rails framework for the application, like setting a generator
  # * +adding config.*+ keys to the environment
  # * setting up a subscriber with ActiveSupport::Notifications
  # * adding rake tasks
  #
  # == Creating your Railtie
  #
  # To extend Rails using Railtie, create a Railtie class which inherits
  # from Rails::Railtie within your extension's namespace. This class must be
  # loaded during the Rails boot process.
  #
  # The following example demonstrates an extension which can be used with or without Rails.
  #
  #   # lib/my_gem/railtie.rb
  #   module MyGem
  #     class Railtie < Rails::Railtie
  #     end
  #   end
  #
  #   # lib/my_gem.rb
  #   require 'my_gem/railtie' if defined?(Rails)
  #
  # == Initializers
  #
  # To add an initialization step from your Railtie to Rails boot process, you just need
  # to create an initializer block:
  #
  #   class MyRailtie < Rails::Railtie
  #     initializer "my_railtie.configure_rails_initialization" do
  #       # some initialization behavior
  #     end
  #   end
  #
  # If specified, the block can also receive the application object, in case you
  # need to access some application specific configuration, like middleware:
  #
  #   class MyRailtie < Rails::Railtie
  #     initializer "my_railtie.configure_rails_initialization" do |app|
  #       app.middleware.use MyRailtie::Middleware
  #     end
  #   end
  #
  # Finally, you can also pass :before and :after as option to initializer, in case
  # you want to couple it with a specific step in the initialization process.
  #
  # == Configuration
  #
  # Inside the Railtie class, you can access a config object which contains configuration
  # shared by all railties and the application:
  #
  #   class MyRailtie < Rails::Railtie
  #     # Customize the ORM
  #     config.app_generators.orm :my_railtie_orm
  #
  #     # Add a to_prepare block which is executed once in production
  #     # and before each request in development
  #     config.to_prepare do
  #       MyRailtie.setup!
  #     end
  #   end
  #
  # == Loading rake tasks and generators
  #
  # If your railtie has rake tasks, you can tell Rails to load them through the method
  # rake_tasks:
  #
  #   class MyRailtie < Rails::Railtie
  #     rake_tasks do
  #       load "path/to/my_railtie.tasks"
  #     end
  #   end
  #
  # By default, Rails load generators from your load path. However, if you want to place
  # your generators at a different location, you can specify in your Railtie a block which
  # will load them during normal generators lookup:
  #
  #   class MyRailtie < Rails::Railtie
  #     generators do
  #       require "path/to/my_railtie_generator"
  #     end
  #   end
  #
  # == Application and Engine
  #
  # A Rails::Engine is nothing more than a Railtie with some initializers already set.
  # And since Rails::Application is an engine, the same configuration described here
  # can be used in both.
  #
  # Be sure to look at the documentation of those specific classes for more information.
  #
  class Railtie
    autoload :Configurable,  "rails/railtie/configurable"
    autoload :Configuration, "rails/railtie/configuration"

    include Initializable

    ABSTRACT_RAILTIES = %w(Rails::Railtie Rails::Engine Rails::Application)

    class << self
      private :new

      def subclasses
        @subclasses ||= []
      end

      def inherited(base)
        unless base.abstract_railtie?
          base.send(:include, Railtie::Configurable)
          subclasses << base
        end
      end

      def rake_tasks(&blk)
        @rake_tasks ||= []
        @rake_tasks << blk if blk
        @rake_tasks
      end

      def console(&blk)
        @load_console ||= []
        @load_console << blk if blk
        @load_console
      end

      def runner(&blk)
        @load_runner ||= []
        @load_runner << blk if blk
        @load_runner
      end

      def generators(&blk)
        @generators ||= []
        @generators << blk if blk
        @generators
      end

      def abstract_railtie?
        ABSTRACT_RAILTIES.include?(name)
      end

      def railtie_name(name = nil)
        @railtie_name = name.to_s if name
        @railtie_name ||= generate_railtie_name(self.name)
      end

      protected
        def generate_railtie_name(class_or_module)
          ActiveSupport::Inflector.underscore(class_or_module).tr("/", "_")
        end
    end

    delegate :railtie_name, to: :class

    def config
      @config ||= Railtie::Configuration.new
    end

    def railtie_namespace
      @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) }
    end

    protected

    def run_console_blocks(app) #:nodoc:
      self.class.console.each { |block| block.call(app) }
    end

    def run_generators_blocks(app) #:nodoc:
      self.class.generators.each { |block| block.call(app) }
    end

    def run_runner_blocks(app) #:nodoc:
      self.class.runner.each { |block| block.call(app) }
    end

    def run_tasks_blocks(app) #:nodoc:
      extend Rake::DSL
      self.class.rake_tasks.each { |block| instance_exec(app, &block) }

      # Load also tasks from all superclasses
      klass = self.class.superclass

      while klass.respond_to?(:rake_tasks)
        klass.rake_tasks.each { |t| instance_exec(app, &t) }
        klass = klass.superclass
      end
    end
  end
end
if RUBY_VERSION < '1.9.3'
  desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})"
  abort <<-end_message

    Rails 4 prefers to run on Ruby 2.0.

    You're running
      #{desc}

    Please upgrade to Ruby 1.9.3 or newer to continue.

  end_message
end
require 'prof'

module Prof #:nodoc:
  # Adapted from Shugo Maeda's unprof.rb
  def self.print_profile(results, io = $stderr)
    total = results.detect { |i|
      i.method_class.nil? && i.method_id == :"#toplevel"
    }.total_time
    total = 0.001 if total < 0.001

    io.puts "  %%   cumulative   self              self     total"
    io.puts " time   seconds   seconds    calls  ms/call  ms/call  name"

    sum = 0.0
    results.each do |r|
      sum += r.self_time

      name =  if r.method_class.nil?
                r.method_id.to_s
              elsif r.method_class.is_a?(Class)
                "#{r.method_class}##{r.method_id}"
              else
                "#{r.method_class}.#{r.method_id}"
              end
      io.printf "%6.2f %8.3f  %8.3f %8d %8.2f %8.2f  %s\n",
        r.self_time / total * 100,
        sum,
        r.self_time,
        r.count,
        r.self_time * 1000 / r.count,
        r.total_time * 1000 / r.count,
        name
    end
  end
end
# Implements the logic behind the rake tasks for annotations like
#
#   rake notes
#   rake notes:optimize
#
# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/tasks/annotations.rake</tt>.
#
# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
# represent the line where the annotation lives, its tag, and its text. Note
# the filename is not stored.
#
# Annotations are looked for in comments and modulus whitespace they have to
# start with the tag optionally followed by a colon. Everything up to the end
# of the line (or closing ERB comment tag) is considered to be their text.
class SourceAnnotationExtractor
  class Annotation < Struct.new(:line, :tag, :text)
    def self.directories
      @@directories ||= %w(app config db lib test) + (ENV['SOURCE_ANNOTATION_DIRECTORIES'] || '').split(',')
    end

    # Returns a representation of the annotation that looks like this:
    #
    #   [126] [TODO] This algorithm is simple and clearly correct, make it faster.
    #
    # If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above.
    # Otherwise the string contains just line and text.
    def to_s(options={})
      s = "[#{line.to_s.rjust(options[:indent])}] "
      s << "[#{tag}] " if options[:tag]
      s << text
    end
  end

  # Prints all annotations with tag +tag+ under the root directories +app+,
  # +config+, +db+, +lib+, and +test+ (recursively).
  #
  # Additional directories may be added using a comma-delimited list set using
  # <tt>ENV['SOURCE_ANNOTATION_DIRECTORIES']</tt>.
  #
  # Directories may also be explicitly set using the <tt>:dirs</tt> key in +options+.
  #
  #   SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
  #
  # If +options+ has a <tt>:tag</tt> flag, it will be passed to each annotation's +to_s+.
  #
  # See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
  #
  # This class method is the single entry point for the rake tasks.
  def self.enumerate(tag, options={})
    extractor = new(tag)
    dirs = options.delete(:dirs) || Annotation.directories
    extractor.display(extractor.find(dirs), options)
  end

  attr_reader :tag

  def initialize(tag)
    @tag = tag
  end

  # Returns a hash that maps filenames under +dirs+ (recursively) to arrays
  # with their annotations.
  def find(dirs)
    dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
  end

  # Returns a hash that maps filenames under +dir+ (recursively) to arrays
  # with their annotations. Only files with annotations are included. Files
  # with extension +.builder+, +.rb+, +.erb+, +.haml+, +.slim+, +.css+,
  # +.scss+, +.js+, +.coffee+, and +.rake+
  # are taken into account.
  def find_in(dir)
    results = {}

    Dir.glob("#{dir}/*") do |item|
      next if File.basename(item)[0] == ?.

      if File.directory?(item)
        results.update(find_in(item))
      else
        pattern =
            case item
            when /\.(builder|rb|coffee|rake)$/
              /#\s*(#{tag}):?\s*(.*)$/
            when /\.(css|scss|js)$/
              /\/\/\s*(#{tag}):?\s*(.*)$/
            when /\.erb$/
              /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/
            when /\.haml$/
              /-\s*#\s*(#{tag}):?\s*(.*)$/
            when /\.slim$/
              /\/\s*\s*(#{tag}):?\s*(.*)$/
            else nil
            end
        results.update(extract_annotations_from(item, pattern)) if pattern
      end
    end

    results
  end

  # If +file+ is the filename of a file that contains annotations this method returns
  # a hash with a single entry that maps +file+ to an array of its annotations.
  # Otherwise it returns an empty hash.
  def extract_annotations_from(file, pattern)
    lineno = 0
    result = File.readlines(file).inject([]) do |list, line|
      lineno += 1
      next list unless line =~ pattern
      list << Annotation.new(lineno, $1, $2)
    end
    result.empty? ? {} : { file => result }
  end

  # Prints the mapping from filenames to annotations in +results+ ordered by filename.
  # The +options+ hash is passed to each annotation's +to_s+.
  def display(results, options={})
    options[:indent] = results.map { |f, a| a.map(&:line) }.flatten.max.to_s.size
    results.keys.sort.each do |file|
      puts "#{file}:"
      results[file].each do |note|
        puts "  * #{note.to_s(options)}"
      end
      puts
    end
  end
end
$VERBOSE = nil

# Load Rails rakefile extensions
%w(
  annotations
  documentation
  framework
  log
  middleware
  misc
  routes
  statistics
  tmp
).each do |task|
  load "rails/tasks/#{task}.rake"
end
# Make double-sure the RAILS_ENV is not set to production,
# so fixtures aren't loaded into that environment
abort("Abort testing: Your Rails environment is running in production mode!") if Rails.env.production?

require 'active_support/testing/autorun'
require 'active_support/test_case'
require 'action_controller/test_case'
require 'action_dispatch/testing/integration'

# Config Rails backtrace in tests.
require 'rails/backtrace_cleaner'
MiniTest.backtrace_filter = Rails.backtrace_cleaner

if defined?(ActiveRecord::Base)
  class ActiveSupport::TestCase
    include ActiveRecord::TestFixtures
    self.fixture_path = "#{Rails.root}/test/fixtures/"
  end

  ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path

  def create_fixtures(*fixture_set_names, &block)
    FixtureSet.create_fixtures(ActiveSupport::TestCase.fixture_path, fixture_set_names, {}, &block)
  end
end

class ActionController::TestCase
  setup do
    @routes = Rails.application.routes
  end
end

class ActionDispatch::IntegrationTest
  setup do
    @routes = Rails.application.routes
  end
end
module Rails
  class TestUnitRailtie < Rails::Railtie
    config.app_generators do |c|
      c.test_framework :test_unit, fixture: true,
                                   fixture_replacement: nil

      c.integration_tool :test_unit
    end

    rake_tasks do
      load "rails/test_unit/testing.rake"
    end
  end
end
module Rails
  # Silence the default description to cut down on `rake -T` noise.
  class SubTestTask < Rake::TestTask
    def desc(string)
      # Ignore the description.
    end
  end
end
module Rails
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
class Rails::WelcomeController < ActionController::Base # :nodoc:
  self.view_paths = File.expand_path('../templates', __FILE__)
  layout nil

  def index
  end
end
require 'rails/ruby_version_check'

require 'pathname'

require 'active_support'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/array/extract_options'

require 'rails/application'
require 'rails/version'
require 'rails/deprecation'

require 'active_support/railtie'
require 'action_dispatch/railtie'

# For Ruby 1.9, UTF-8 is the default internal and external encoding.
silence_warnings do
  Encoding.default_external = Encoding::UTF_8
  Encoding.default_internal = Encoding::UTF_8
end

module Rails
  autoload :Info, 'rails/info'
  autoload :InfoController,    'rails/info_controller'
  autoload :WelcomeController, 'rails/welcome_controller'

  class << self
    attr_accessor :application, :cache, :logger

    # The Configuration instance used to configure the Rails environment
    def configuration
      application.config
    end

    def initialize!
      application.initialize!
    end

    def initialized?
      application.initialized?
    end

    def backtrace_cleaner
      @backtrace_cleaner ||= begin
        # Relies on Active Support, so we have to lazy load to postpone definition until AS has been loaded
        require 'rails/backtrace_cleaner'
        Rails::BacktraceCleaner.new
      end
    end

    def root
      application && application.config.root
    end

    def env
      @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development")
    end

    def env=(environment)
      @_env = ActiveSupport::StringInquirer.new(environment)
    end

    # Returns all rails groups for loading based on:
    #
    # * The Rails environment;
    # * The environment variable RAILS_GROUPS;
    # * The optional envs given as argument and the hash with group dependencies;
    #
    #   groups assets: [:development, :test]
    #
    #   # Returns
    #   # => [:default, :development, :assets] for Rails.env == "development"
    #   # => [:default, :production]           for Rails.env == "production"
    def groups(*groups)
      hash = groups.extract_options!
      env = Rails.env
      groups.unshift(:default, env)
      groups.concat ENV["RAILS_GROUPS"].to_s.split(",")
      groups.concat hash.map { |k,v| k if v.map(&:to_s).include?(env) }
      groups.compact!
      groups.uniq!
      groups
    end

    def version
      VERSION::STRING
    end

    def public_path
      application && Pathname.new(application.paths["public"].first)
    end
  end
end
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :reset_session instead.
  protect_from_forgery :with => :exception
endclass UsersController < ApplicationController
  # GET /users
  # GET /users.json
  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @users }
    end
  end

  # GET /users/1
  # GET /users/1.json
  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @user }
    end
  end

  # GET /users/new
  # GET /users/new.json
  def new
    @user = User.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @user }
    end
  end

  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end

  # POST /users
  # POST /users.json
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: "new" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /users/1
  # PATCH/PUT /users/1.json
  def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to @user, notice: 'User was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /users/1
  # DELETE /users/1.json
  def destroy
    @user = User.find(params[:id])
    @user.destroy

    respond_to do |format|
      format.html { redirect_to users_url }
      format.json { head :no_content }
    end
  end
end
module ApplicationHelper
end
module UsersHelper
end
class User < ActiveRecord::Base
  attr_accessible :password, :username
end
require File.expand_path('../boot', __FILE__)

require 'rails/all'

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line.
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line.
  # Bundler.require(:default, :assets, Rails.env)
end

module AppTemplate
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)

    # Activate observers that should always be running.
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Enable escaping HTML in JSON. The default is false.
    # config.active_support.escape_html_entities_in_json = true

    # Use SQL instead of Active Record's schema dumper when creating the database.
    # This is necessary if your schema can't be completely dumped by the schema dumper,
    # like if you have constraints or database-specific column types.
    # config.active_record.schema_format = :sql

    # Enforce whitelist mode for mass assignment.
    # This will create an empty whitelist of attributes available for mass-assignment for all models
    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
    # parameters by using an attr_accessible or attr_protected declaration.
    config.active_record.whitelist_attributes = true

    # Specifies whether or not has_many or has_one association option :dependent => :restrict raises
    # an exception. If set to true, then an ActiveRecord::DeleteRestrictionError exception would be
    # raised. If set to false, then an error will be added on the model instead.
    config.active_record.dependent_restrict_raises = false

    # Enable the asset pipeline.
    config.assets.enabled = true

    # Version of your assets, change this if you want to expire all your assets.
    config.assets.version = '1.0'
        config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
        config.session_store :cookie_store, :key => "_myapp_session"
        config.active_support.deprecation = :log
        config.action_controller.allow_forgery_protection = false


  end
end
Dir.chdir('/Users/murphy/ruby/rails') do
  require '/Users/murphy/ruby/rails/load_paths'
end
require 'rails/all'
# Load the rails application
require File.expand_path('../application', __FILE__)

# Initialize the rails application
AppTemplate::Application.initialize!
AppTemplate::Application.routes.draw do
  resources :users
  # The priority is based upon order of creation:
  # first created -> highest priority.

  # Sample of regular route:
  #   get 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  #   get 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)

  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', :on => :collection
  #     end
  #   end

  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => 'welcome#index'

  # See how all your routes lay out with "rake routes"
match ':controller(/:action(/:id))(.:format)', :via => :all

end
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :username
      t.string :password

      t.timestamps
    end
  end
end
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(:version => 20120513121623) do

  create_table "users", :force => true do |t|
    t.string   "username"
    t.string   "password"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

end
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
#   Mayor.create(name: 'Emanuel', city: cities.first)
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :reset_session instead.
  protect_from_forgery :with => :exception
endmodule ApplicationHelper
end
require File.expand_path('../boot', __FILE__)

require 'rails/all'

if defined?(Bundler)
  # If you precompile assets before deploying to production, use this line.
  Bundler.require(*Rails.groups(:assets => %w(development test)))
  # If you want your assets lazily compiled in production, use this line.
  # Bundler.require(:default, :assets, Rails.env)
end

module AppTemplate
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)

    # Activate observers that should always be running.
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password]

    # Enable escaping HTML in JSON. The default is false.
    # config.active_support.escape_html_entities_in_json = true

    # Use SQL instead of Active Record's schema dumper when creating the database.
    # This is necessary if your schema can't be completely dumped by the schema dumper,
    # like if you have constraints or database-specific column types.
    # config.active_record.schema_format = :sql

    # Enforce whitelist mode for mass assignment.
    # This will create an empty whitelist of attributes available for mass-assignment for all models
    # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
    # parameters by using an attr_accessible or attr_protected declaration.
    config.active_record.whitelist_attributes = true

    # Specifies whether or not has_many or has_one association option :dependent => :restrict raises
    # an exception. If set to true, then an ActiveRecord::DeleteRestrictionError exception would be
    # raised. If set to false, then an error will be added on the model instead.
    config.active_record.dependent_restrict_raises = false

    # Enable the asset pipeline.
    config.assets.enabled = true

    # Version of your assets, change this if you want to expire all your assets.
    config.assets.version = '1.0'
  end
end
Dir.chdir('/Users/murphy/ruby/rails') do
  require '/Users/murphy/ruby/rails/load_paths'
end
require 'rails/all'
# Load the rails application
require File.expand_path('../application', __FILE__)

# Initialize the rails application
AppTemplate::Application.initialize!
AppTemplate::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger.
  config.active_support.deprecation = :log

  # Only use best-standards-support built into browsers.
  config.action_dispatch.best_standards_support = :builtin

  # Raise exception on mass assignment protection for Active Record models.
  config.active_record.mass_assignment_sanitizer = :strict

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Do not compress assets.
  config.assets.compress = false

  # Expands the lines which load the assets.
  config.assets.debug = true

  # In development, use an in-memory queue for queueing
  config.queue = Rails::Queueing::Queue
end
AppTemplate::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # Code is not reloaded between requests.
  config.cache_classes = true

  # Full error reports are disabled and caching is turned on.
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Disable Rails's static asset server (Apache or nginx will already do this).
  config.serve_static_assets = false

  # Compress JavaScripts and CSS.
  config.assets.compress = true

  # Don't fallback to assets pipeline if a precompiled asset is missed.
  config.assets.compile = false

  # Generate digests for assets URLs.
  config.assets.digest = true

  # Defaults to nil and saved in location specified by config.assets.prefix
  # config.assets.manifest = YOUR_PATH

  # Specifies the header that your server uses for sending files.
  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  # config.force_ssl = true

  # Set to :debug to see everything in the log.
  config.log_level = :info

  # Prepend all log lines with the following tags.
  # config.log_tags = [ :subdomain, :uuid ]

  # Use a different logger for distributed setups.
  # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)

  # Use a different cache store in production.
  # config.cache_store = :mem_cache_store

  # Enable serving of images, stylesheets, and JavaScripts from an asset server.
  # config.action_controller.asset_host = "http://assets.example.com"

  # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added).
  # config.assets.precompile += %w( search.js )

  # Disable delivery errors, bad email addresses will be ignored.
  # config.action_mailer.raise_delivery_errors = false

  # Enable threaded mode.
  # config.threadsafe!

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found).
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners.
  config.active_support.deprecation = :notify

  # Log the query plan for queries taking more than this (works
  # with SQLite, MySQL, and PostgreSQL).
  # config.active_record.auto_explain_threshold_in_seconds = 0.5

  # Disable automatic flushing of the log to improve performance.
  # config.autoflush_log = false

  # Use default logging formatter so that PID and timestamp are not suppressed
  config.log_formatter = ::Logger::Formatter.new

  # Default the production mode queue to an in-memory queue. You will probably
  # want to replace this with an out-of-process queueing solution
  config.queue = Rails::Queueing::Queue
end
AppTemplate::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb.

  # The test environment is used exclusively to run your application's
  # test suite. You never need to work with it otherwise. Remember that
  # your test database is "scratch space" for the test suite and is wiped
  # and recreated between test runs. Don't rely on the data there!
  config.cache_classes = true

  # Configure static asset server for tests with Cache-Control for performance.
  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=3600"

  # Show full error reports and disable caching.
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Raise exceptions instead of rendering exception templates.
  config.action_dispatch.show_exceptions = false

  # Disable request forgery protection in test environment.
  config.action_controller.allow_forgery_protection = false

  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

  # Raise exception on mass assignment protection for Active Record models.
  config.active_record.mass_assignment_sanitizer = :strict

  # Print deprecation notices to the stderr.
  config.active_support.deprecation = :stderr

  # Use the testing queue
  config.queue = Rails::Queueing::TestQueue
end
# Be sure to restart your server when you modify this file.

# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }

# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# Be sure to restart your server when you modify this file.

# Add new inflection rules using the following format
# (all these examples are active by default):
# ActiveSupport::Inflector.inflections do |inflect|
#   inflect.plural /^(ox)$/i, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end
#
# These inflection rules are supported but not enabled by default:
# ActiveSupport::Inflector.inflections do |inflect|
#   inflect.acronym 'RESTful'
# end
# Be sure to restart your server when you modify this file.

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
# Be sure to restart your server when you modify this file.

# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# Make sure your secret_token is kept private
# if you're sharing your code publicly.
AppTemplate::Application.config.secret_token = '900e93eda3749848cd9837613d41c6c22672a03eb6895e1378d8a381272db1df2984a39ac91ad0bbd3a44925617c3eab3f9bd6b038958c7516686ac35770f578'
# Be sure to restart your server when you modify this file.

AppTemplate::Application.config.session_store :cookie_store, key: '_app_template_session'

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# AppTemplate::Application.config.session_store :active_record_store
# Be sure to restart your server when you modify this file.
#
# This file contains settings for ActionController::ParamsWrapper which
# is enabled by default.

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
  self.include_root_in_json = false
end
AppTemplate::Application.routes.draw do
  # The priority is based upon order of creation:
  # first created -> highest priority.

  # Sample of regular route:
  #   get 'products/:id' => 'catalog#view'
  # Keep in mind you can assign values other than :controller and :action

  # Sample of named route:
  #   get 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
  # This route can be invoked with purchase_url(:id => product.id)

  # Sample resource route (maps HTTP verbs to controller actions automatically):
  #   resources :products

  # Sample resource route with options:
  #   resources :products do
  #     member do
  #       get 'short'
  #       post 'toggle'
  #     end
  #
  #     collection do
  #       get 'sold'
  #     end
  #   end

  # Sample resource route with sub-resources:
  #   resources :products do
  #     resources :comments, :sales
  #     resource :seller
  #   end

  # Sample resource route with more complex sub-resources
  #   resources :products do
  #     resources :comments
  #     resources :sales do
  #       get 'recent', :on => :collection
  #     end
  #   end

  # Sample resource route within a namespace:
  #   namespace :admin do
  #     # Directs /admin/products/* to Admin::ProductsController
  #     # (app/controllers/admin/products_controller.rb)
  #     resources :products
  #   end

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  # root :to => 'welcome#index'

  # See how all your routes lay out with "rake routes"
end# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
#   cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
#   Mayor.create(name: 'Emanuel', city: cities.first)
FRAMEWORKS = %w( activesupport activemodel activerecord actionpack actionmailer railties )

root    = File.expand_path('../../', __FILE__)
version = File.read("#{root}/RAILS_VERSION").strip
tag     = "v#{version}"

directory "pkg"

(FRAMEWORKS + ['rails']).each do |framework|
  namespace framework do
    gem     = "pkg/#{framework}-#{version}.gem"
    gemspec = "#{framework}.gemspec"

    task :clean do
      rm_f gem
    end

    task :update_version_rb do
      glob = root.dup
      glob << "/#{framework}/lib/*" unless framework == "rails"
      glob << "/version.rb"

      file = Dir[glob].first
      ruby = File.read(file)

      major, minor, tiny, pre = version.split('.')
      pre = pre ? pre.inspect : "nil"

      ruby.gsub!(/^(\s*)MAJOR = .*?$/, "\\1MAJOR = #{major}")
      raise "Could not insert MAJOR in #{file}" unless $1

      ruby.gsub!(/^(\s*)MINOR = .*?$/, "\\1MINOR = #{minor}")
      raise "Could not insert MINOR in #{file}" unless $1

      ruby.gsub!(/^(\s*)TINY  = .*?$/, "\\1TINY  = #{tiny}")
      raise "Could not insert TINY in #{file}" unless $1

      ruby.gsub!(/^(\s*)PRE   = .*?$/, "\\1PRE   = #{pre}")
      raise "Could not insert PRE in #{file}" unless $1

      File.open(file, 'w') { |f| f.write ruby }
    end

    task gem => %w(update_version_rb pkg) do
      cmd = ""
      cmd << "cd #{framework} && " unless framework == "rails"
      cmd << "gem build #{gemspec} && mv #{framework}-#{version}.gem #{root}/pkg/"
      sh cmd
    end

    task :build => [:clean, gem]
    task :install => :build do
      sh "gem install #{gem}"
    end

    task :prep_release => [:ensure_clean_state, :build]

    task :push => :build do
      sh "gem push #{gem}"
    end
  end
end

namespace :changelog do
  task :release_date do
    FRAMEWORKS.each do |fw|
      require 'date'
      replace = '\1(' + Date.today.strftime('%B %d, %Y') + ')'
      fname = File.join fw, 'CHANGELOG.md'

      contents = File.read(fname).sub(/^([^(]*)\(unreleased\)/, replace)
      File.open(fname, 'wb') { |f| f.write contents }
    end
  end

  task :release_summary do
    FRAMEWORKS.each do |fw|
      puts "## #{fw}"
      fname    = File.join fw, 'CHANGELOG.md'
      contents = File.readlines fname
      contents.shift
      changes = []
      changes << contents.shift until contents.first =~ /^\*Rails \d+\.\d+\.\d+/
      puts changes.reject { |change| change.strip.empty? }.join
      puts
    end
  end
end

namespace :all do
  task :build   => FRAMEWORKS.map { |f| "#{f}:build"   } + ['rails:build']
  task :install => FRAMEWORKS.map { |f| "#{f}:install" } + ['rails:install']
  task :push    => FRAMEWORKS.map { |f| "#{f}:push"    } + ['rails:push']

  task :ensure_clean_state do
    unless `git status -s | grep -v RAILS_VERSION`.strip.empty?
      abort "[ABORTING] `git status` reports a dirty tree. Make sure all changes are committed"
    end

    unless ENV['SKIP_TAG'] || `git tag | grep #{tag}`.strip.empty?
      abort "[ABORTING] `git tag` shows that #{tag} already exists. Has this version already\n"\
            "           been released? Git tagging can be skipped by setting SKIP_TAG=1"
    end
  end

  task :commit do
    File.open('pkg/commit_message.txt', 'w') do |f|
      f.puts "# Preparing for #{version} release\n"
      f.puts
      f.puts "# UNCOMMENT THE LINE ABOVE TO APPROVE THIS COMMIT"
    end

    sh "git add . && git commit --verbose --template=pkg/commit_message.txt"
    rm_f "pkg/commit_message.txt"
  end

  task :tag do
    sh "git tag #{tag}"
    sh "git push --tags"
  end

  task :release => %w(ensure_clean_state build commit tag push)
end
module Rails
  module VERSION #:nodoc:
    MAJOR = 4
    MINOR = 0
    TINY  = 0
    PRE   = "beta"

    STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
  end
end
