class Gem::DependencyList

def self.from_specs

def self.from_specs
  list = new
  list.add(*Gem::Specification.to_a)
  list
end

def active_count(specs, ignored)

def active_count(specs, ignored)
  specs.count { |spec| ignored[spec.full_name].nil? }
end

def add(*gemspecs)

def add(*gemspecs)
  @specs.push(*gemspecs)
end

def clear

def clear
  @specs.clear
end

def dependency_order

def dependency_order
  sorted = strongly_connected_components.flatten
  result = []
  seen = {}
  sorted.each do |spec|
    if index = seen[spec.name] then
      if result[index].version < spec.version then
        result[index] = spec
      end
    else
      seen[spec.name] = result.length
      result << spec
    end
  end
  result.reverse
end

def each(&block)

def each(&block)
  dependency_order.each(&block)
end

def find_name(full_name)

def find_name(full_name)
  @specs.find { |spec| spec.full_name == full_name }
end

def initialize development = false

def initialize development = false
  @specs = []
  @development = development
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  "#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }]
end

def ok?

def ok?
  why_not_ok?(:quick).empty?
end

def ok_to_remove?(full_name, check_dev=true)

def ok_to_remove?(full_name, check_dev=true)
  gem_to_remove = find_name full_name
  siblings = @specs.find_all { |s|
    s.name == gem_to_remove.name &&
      s.full_name != gem_to_remove.full_name
  }
  deps = []
  @specs.each do |spec|
    check = check_dev ? spec.dependencies : spec.runtime_dependencies
    check.each do |dep|
      deps << dep if gem_to_remove.satisfies_requirement?(dep)
    end
  end
  deps.all? { |dep|
    siblings.any? { |s|
      s.satisfies_requirement? dep
    }
  }
end

def remove_by_name(full_name)

def remove_by_name(full_name)
  @specs.delete_if { |spec| spec.full_name == full_name }
end

def remove_specs_unsatisfied_by dependencies

def remove_specs_unsatisfied_by dependencies
  specs.reject! { |spec|
    dep = dependencies[spec.name]
    dep and not dep.requirement.satisfied_by? spec.version
  }
end

def spec_predecessors

def spec_predecessors
  result = Hash.new { |h,k| h[k] = [] }
  specs = @specs.sort.reverse
  specs.each do |spec|
    specs.each do |other|
      next if spec == other
      other.dependencies.each do |dep|
        if spec.satisfies_requirement? dep then
          result[spec] << other
        end
      end
    end
  end
  result
end

def tsort_each_child(node)

def tsort_each_child(node)
  specs = @specs.sort.reverse
  dependencies = node.runtime_dependencies
  dependencies.push(*node.development_dependencies) if @development
  dependencies.each do |dep|
    specs.each do |spec|
      if spec.satisfies_requirement? dep then
        begin
          yield spec
        rescue TSort::Cyclic
          # do nothing
        end
        break
      end
    end
  end
end

def tsort_each_node(&block)

def tsort_each_node(&block)
  @specs.each(&block)
end

def why_not_ok? quick = false

def why_not_ok? quick = false
  unsatisfied = Hash.new { |h,k| h[k] = [] }
  each do |spec|
    spec.runtime_dependencies.each do |dep|
      inst = Gem::Specification.any? { |installed_spec|
        dep.name == installed_spec.name and
          dep.requirement.satisfied_by? installed_spec.version
      }
      unless inst or @specs.find { |s| s.satisfies_requirement? dep } then
        unsatisfied[spec.name] << dep
        return unsatisfied if quick
      end
    end
  end
  unsatisfied
end