def solve(workspace, solution_constraints, valid_packages, packages_to_include_in_solve)
      # map packages in packages_to_include_in_solve into
      # corresponding workspace packages and generate constraints
      # imposed by the dependency graph
      packages_in_solve = packages_to_include_in_solve.map{|pkg| workspace.package(pkg.name)}
      workspace.generate_gecode_wrapper_constraints(packages_in_solve)

      # validate solution_constraints and generate its constraints
      process_soln_constraints(workspace, solution_constraints, valid_packages)

      # solve and trim the solution down to only the
      workspace.gecode_wrapper.set_timeout(@time_bound * 1000)      
      soln = workspace.gecode_wrapper.solve
      trim_solution(solution_constraints, soln, workspace)
    end
def solve(workspace, solution_constraints, valid_packages, packages_to_include_in_solve)
      # map packages in packages_to_include_in_solve into
      # corresponding workspace packages and generate constraints
      # imposed by the dependency graph
      packages_in_solve = packages_to_include_in_solve.map{|pkg| workspace.package(pkg.name)}
      workspace.generate_gecode_wrapper_constraints(packages_in_solve)

      # validate solution_constraints and generate its constraints
      process_soln_constraints(workspace, solution_constraints, valid_packages)

      # solve and trim the solution down to only the
      workspace.gecode_wrapper.set_timeout(@time_bound * 1000)      
      soln = workspace.gecode_wrapper.solve
      trim_solution(solution_constraints, soln, workspace)
    end
Given a workspace (a clone of the dependency graph) and an array
 of SolutionConstraints, this method attempts to find a
 satisfiable set of <Package, Version> pairs.