def simplified_deps_tree(leaf, processed = {})
      return {} unless leaf.dependencies

      return processed[leaf] if processed[leaf]
      processed[leaf] = dep_versions = {}

      # For each dependency, generate a deps tree for each available version
      leaf.dependencies.each do |p, spec|
        dep_versions[p] = {}
        spec.versions.each do |v, subleaf|
          dep_versions[p][v] =
            simplified_deps_tree(subleaf, processed)
        end
      end

      dep_versions
    end
def simplified_deps_tree(leaf, processed = {})
      return {} unless leaf.dependencies

      return processed[leaf] if processed[leaf]
      processed[leaf] = dep_versions = {}

      # For each dependency, generate a deps tree for each available version
      leaf.dependencies.each do |p, spec|
        dep_versions[p] = {}
        spec.versions.each do |v, subleaf|
          dep_versions[p][v] =
            simplified_deps_tree(subleaf, processed)
        end
      end

      dep_versions
    end
Converts the dependency tree into a simplified dependency tree of the form
 {
   <package name> =>
     <version> =>
       <package name> =>
         <version> => ...
         ...
       ...
     ...
   ...
 }
 The processed hash is used to deal with circular dependencies