class Bundler::Installer

def self.install(root, definition, options)

def self.install(root, definition, options)
  new(root, definition).run(options)
end

def actual_dependencies

def actual_dependencies
  @definition.actual_dependencies
end

def ambiguous?(dep)

def ambiguous?(dep)
  dep.requirement.requirements.any? { |op,_| op != '=' }
end

def cache_source

def cache_source
  Source::GemCache.new("path" => "#{root}/vendor/cache")
end

def dependencies

def dependencies
  @definition.dependencies
end

def index

def index
  @index ||= begin
    index = Index.new
    rg_sources = sources.select { |s| s.is_a?(Source::Rubygems) }
    other_sources = sources.select { |s| !s.is_a?(Source::Rubygems)   }
    other_sources.each do |source|
      i = source.specs
      Bundler.ui.debug "Source: Processing index"
      index = i.merge(index)
    end
    index = Index.from_installed_gems.merge(index)
    index = Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
    if File.directory?("#{root}/vendor/cache")
      index = cache_source.specs.merge(index)
    end
    rg_sources.each do |source|
      i = source.specs
      Bundler.ui.debug "Source: Processing index"
      index = i.merge(index)
    end
    index
  end
end

def local_index

def local_index
  @local_index ||= begin
    index = Index.new
    sources.each do |source|
      next unless source.respond_to?(:local_specs)
      index = source.local_specs.merge(index)
    end
    index = Index.from_installed_gems.merge(index)
    if File.directory?("#{root}/vendor/cache")
      index = cache_source.specs.merge(index).freeze
    end
    Index.from_cached_specs("#{Bundler.bundle_path}/cache").merge(index)
  end
end

def resolve_locally

def resolve_locally
  # Return unless all the dependencies have = version requirements
  return if actual_dependencies.any? { |d| ambiguous?(d) }
  source_requirements = {}
  actual_dependencies.each do |dep|
    next unless dep.source && dep.source.respond_to?(:local_specs)
    source_requirements[dep.name] = dep.source.local_specs
  end
  # Run a resolve against the locally available gems
  specs = Resolver.resolve(actual_dependencies, local_index, source_requirements)
  # Simple logic for now. Can improve later.
  specs.length == actual_dependencies.length && specs
rescue GemNotFound, PathError => e
  nil
end

def resolve_remotely

def resolve_remotely
  index # trigger building the index
  Bundler.ui.info "Resolving dependencies"
  source_requirements = {}
  actual_dependencies.each do |dep|
    next unless dep.source
    source_requirements[dep.name] = dep.source.specs
  end
  specs = Resolver.resolve(actual_dependencies, index, source_requirements)
  specs
end

def run(options)

def run(options)
  if actual_dependencies.empty?
    Bundler.ui.warn "The Gemfile specifies no dependencies"
    return
  end
  # Ensure that BUNDLE_PATH exists
  FileUtils.mkdir_p(Bundler.bundle_path)
  # Must install gems in the order that the resolver provides
  # as dependencies might actually affect the installation of
  # the gem.
  specs.each do |spec|
    spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
    if spec.groups & Bundler.settings.without == spec.groups
      Bundler.ui.debug "  * Not in requested group; skipping."
      next
    end
    # unless spec.source.is_a?(Source::SystemGems)
      Bundler.ui.info "Installing #{spec.name} (#{spec.version}) from #{spec.source} "
    # end
    spec.source.install(spec)
    Bundler.ui.info ""
  end
  Bundler.ui.confirm "Your bundle is complete!"
end

def sources

def sources
  @definition.sources
end

def specs

def specs
  @specs ||= group_specs(resolve_locally || resolve_remotely)
end