class Gem::Resolver::InstallerSet

def add_always_install(dependency)

def add_always_install(dependency)
  request = Gem::Resolver::DependencyRequest.new dependency, nil
  found = find_all request
  found.delete_if do |s|
    s.version.prerelease? and not s.local?
  end unless dependency.prerelease?
  found = found.select do |s|
    Gem::Source::SpecificFile === s.source or
      Gem::Platform::RUBY == s.platform or
      Gem::Platform.local === s.platform
  end
  found = found.sort_by do |s|
    [s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
  end
  newest = found.last
  unless @force
    found_matching_metadata = found.select do |spec|
      metadata_satisfied?(spec)
    end
    if found_matching_metadata.empty?
      if newest
        ensure_required_ruby_version_met(newest.spec)
        ensure_required_rubygems_version_met(newest.spec)
      else
        exc = Gem::UnsatisfiableDependencyError.new request
        exc.errors = errors
        raise exc
      end
    else
      newest = found_matching_metadata.last
    end
  end
  @always_install << newest.spec
end

def add_local(dep_name, spec, source)

def add_local(dep_name, spec, source)
  @local[dep_name] = [spec, source]
end

def consider_local? # :nodoc:

:nodoc:
def consider_local? # :nodoc:
  @domain == :both or @domain == :local
end

def consider_remote? # :nodoc:

:nodoc:
def consider_remote? # :nodoc:
  @domain == :both or @domain == :remote
end

def ensure_required_ruby_version_met(spec) # :nodoc:

:nodoc:
def ensure_required_ruby_version_met(spec) # :nodoc:
  if rrv = spec.required_ruby_version
    ruby_version = Gem.ruby_version
    unless rrv.satisfied_by? ruby_version
      raise Gem::RuntimeRequirementNotMetError,
        "#{spec.full_name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
    end
  end
end

def ensure_required_rubygems_version_met(spec) # :nodoc:

:nodoc:
def ensure_required_rubygems_version_met(spec) # :nodoc:
  if rrgv = spec.required_rubygems_version
    unless rrgv.satisfied_by? Gem.rubygems_version
      rg_version = Gem::VERSION
      raise Gem::RuntimeRequirementNotMetError,
        "#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
        "Try 'gem update --system' to update RubyGems itself."
    end
  end
end

def errors

def errors
  @errors + @remote_set.errors
end

def find_all(req)

def find_all(req)
  res = []
  dep = req.dependency
  return res if @ignore_dependencies and
            @always_install.none? {|spec| dep.match? spec }
  name = dep.name
  dep.matching_specs.each do |gemspec|
    next if @always_install.any? {|spec| spec.name == gemspec.name }
    res << Gem::Resolver::InstalledSpecification.new(self, gemspec)
  end unless @ignore_installed
  if consider_local?
    matching_local = @local.values.select do |spec, _|
      req.match? spec
    end.map do |spec, source|
      Gem::Resolver::LocalSpecification.new self, spec, source
    end
    res.concat matching_local
    begin
      if local_spec = @local_source.find_gem(name, dep.requirement)
        res << Gem::Resolver::IndexSpecification.new(
          self, local_spec.name, local_spec.version,
          @local_source, local_spec.platform)
      end
    rescue Gem::Package::FormatError
      # ignore
    end
  end
  res.delete_if do |spec|
    spec.version.prerelease? and not dep.prerelease?
  end
  res.concat @remote_set.find_all req if consider_remote?
  res
end

def initialize(domain)

def initialize(domain)
  super()
  @domain = domain
  @f = Gem::SpecFetcher.fetcher
  @always_install      = []
  @ignore_dependencies = false
  @ignore_installed    = false
  @local               = {}
  @local_source        = Gem::Source::Local.new
  @remote_set          = Gem::Resolver::BestSet.new
  @force               = false
  @specs               = {}
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  always_install = @always_install.map {|s| s.full_name }
  '#<%s domain: %s specs: %p always install: %p>' % [
    self.class, @domain, @specs.keys, always_install
  ]
end

def load_spec(name, ver, platform, source) # :nodoc:

:nodoc:
def load_spec(name, ver, platform, source) # :nodoc:
  key = "#{name}-#{ver}-#{platform}"
  @specs.fetch key do
    tuple = Gem::NameTuple.new name, ver, platform
    @specs[key] = source.fetch_spec tuple
  end
end

def local?(dep_name) # :nodoc:

:nodoc:
def local?(dep_name) # :nodoc:
  spec, _ = @local[dep_name]
  spec
end

def metadata_satisfied?(spec)

def metadata_satisfied?(spec)
  spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
    spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
end

def prefetch(reqs)

def prefetch(reqs)
  @remote_set.prefetch(reqs) if consider_remote?
end

def prerelease=(allow_prerelease)

def prerelease=(allow_prerelease)
  super
  @remote_set.prerelease = allow_prerelease
end

def pretty_print(q) # :nodoc:

:nodoc:
def pretty_print(q) # :nodoc:
  q.group 2, '[InstallerSet', ']' do
    q.breakable
    q.text "domain: #{@domain}"
    q.breakable
    q.text 'specs: '
    q.pp @specs.keys
    q.breakable
    q.text 'always install: '
    q.pp @always_install
  end
end

def remote=(remote) # :nodoc:

:nodoc:
def remote=(remote) # :nodoc:
  case @domain
  when :local then
    @domain = :both if remote
  when :remote then
    @domain = nil unless remote
  when :both then
    @domain = :local unless remote
  end
end