begin
  require "active_support/core_ext/enumerable"

  unless Array.instance_methods(true).include?(:sole)
    module ActiveSupport
      module EnumerableCoreExt # :nodoc:
        module Constants
          private

          def const_missing(name)
            if name == :SoleItemExpectedError
              ::ActiveSupport::EnumerableCoreExt::SoleItemExpectedError
            else
              super
            end
          end
        end
      end
    end

    module Enumerable
      # Error generated by +sole+ when called on an enumerable that doesn't have
      # exactly one item.
      class SoleItemExpectedError < StandardError; end

      # HACK: For performance reasons, Enumerable shouldn't have any constants of its own.
      # So we move SoleItemExpectedError into ActiveSupport::EnumerableCoreExt.
      ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError)
      singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants)

      def sole
        case count
        when 1 then return first # rubocop:disable Style/RedundantReturn
        when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
        when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
        end
      end
    end
  end
end
