anchor.diff:      |> Seq.map (fun (k, xs) -> (k, xs |> Seq.map snd |> Set.ofSeq))
       |> Map.ofSeq
   
  -  let findUnsatisfied (solution : Solution) (dependencies : Constraints) = seq {
  -    yield! Set.difference
  -      (dependencies |> Map.keys |> Set.ofSeq)
  -      (solution.Resolutions |> Map.keys  |> Set.ofSeq)
  -  }
   
     let findConflicts (solution : Solution) (dependencies : Constraints) = seq {
        let maybeConflict =
  
positive.code:             | Result.Ok atom -> filterAtom state atom
              | _ -> true)
  
  
          for x in atomsToExplore do
            match x with
            | Result.Error e ->
              match e with
              | NotSatisfiable x ->
                // Package + Constraint is unresolvable
                // we need to skip every branch that requires Package + Constraint
                log("failed to retrive valid version for:" + x.ToString()|>text, LoggingLevel.Info)
                yield Resolution.Failure x
              | NoLocationAvaiable (p, c)  ->
                yield Resolution.Error (new System.Exception ("No location found for: " + p.ToString() + " that could satisfy: " + c.ToString()))
            | Result.Ok (package, (packageLock, versions)) ->
              log(("Exploring " |> text) + (PackageIdentifier.showRich package) + "...", LoggingLevel.Info)
  
              // We pre-emptively grab the lock
              let! lockTask =
                sourceExplorer.FetchLock (packageLock, versions)
                |> Async.StartChild
  
              log("Fetching manifest..." |> text, LoggingLevel.Info)
              let manifestFetchStart = System.DateTime.Now
              let! manifest = sourceExplorer.FetchManifest (packageLock, versions)
              let manifestFetchEnd = System.DateTime.Now
              log((success "success ") +
                  ("Manifest fetched in " |> text) +
                  (info ((manifestFetchEnd - manifestFetchStart).TotalSeconds.ToString("N3") + "s")),
                  LoggingLevel.Info)
              printManifestInfo log state manifest
  
              let! mergedLocations = async {
                return
                  match mergeLocations state.Locations manifest.Locations with
                  | Result.Ok xs -> xs
                  | Result.Error e -> raise (new System.Exception(e.ToString()))
              }
  
              let resolvedVersion = {
                Versions = versions;
                Lock = packageLock;
                Manifest = manifest;
              }
  
              let versionSetStr =
                packageLock
                |> PackageLock.toLocation
                |> PackageLocation.versionSetFromLocation
                |> Set.union versions
                |> Version.showRichSet
  
              log ( (success "success ") + (text "Resolved ") + (PackageIdentifier.showRich package) + (subtle " -> ") + versionSetStr, LoggingLevel.Info)
  
              let freshHints =
                asyncSeq {
                  try
                    log( (text "Fetching lock-file for ") + (PackageIdentifier.showRich package) + "...", LoggingLevel.Debug)
                    let! lock = lockTask
                    log( (success "success ") + (text "Fetched the lock-file for ") + (PackageIdentifier.showRich package), LoggingLevel.Info)
                    yield!
                      lock
                      |> lockToHints
                      |> Seq.filter (fun (atom, packageLock) ->
                        Set.contains (atom.Package, packageLock) state.Visited |> not &&
                        state.Solution.Resolutions |> Map.containsKey atom.Package |> not)
                      |> AsyncSeq.ofSeq
                  with error ->
                    log(string error|>text, LoggingLevel.Debug)
                    ()
                }
  
              let privatePackagesSolverState =
                {
                  Solution = Solution.empty;
                  Locations = Map.empty;
                  Visited = Set.empty;
                  Hints = state.Hints;
                  Depth = state.Depth + 1;
                  Constraints = constraintsOf manifest.PrivateDependencies
                }
  
              let privatePackagesSolutions =
                step context strategy privatePackagesSolverState
                |> AsyncSeq.choose (fun resolution ->
                  match resolution with
                  | Resolution.Ok solution -> Some solution
                  | _ -> None
                )
  
              yield!
                privatePackagesSolutions
                |> AsyncSeq.collect (fun privatePackagesSolution -> asyncSeq {
                  let nextState = {
                    state with
                      Solution =
                        {
                          state.Solution with
                            Resolutions =
                              state.Solution.Resolutions
                              |> Map.add package (resolvedVersion, privatePackagesSolution)
                        };
  
                      Constraints =
                        manifest.Dependencies
                        |> Seq.fold
                          (fun m (dep : Dependency) ->
                            Map.insertWith
                              Set.union
                              dep.Package
                              (Set[dep.Constraint])
                              m)
                          state.Constraints
  
                      Visited =
                        state.Visited
                        |> Set.add (package, packageLock);
                      Locations = mergedLocations;
                      Hints =
                        state.Hints
                        |> AsyncSeq.append freshHints;
                  }
  
                  // TODO: merge versionsets for non-conflicts
                  let conflicts =
                    findConflicts nextState.Solution nextState.Constraints
                    |> Seq.toList
  
                  // TODO: discuss backtracking stategy
                  if conflicts |> List.isEmpty
                  then yield! step context strategy nextState
                  else ()
                })
                |> recoverOrFail state log
    }
  
    let solutionCollector resolutions =
  
negative.code:        |> Seq.filter(snd >> not)
         |> Seq.map fst
     }
  
    let findUnsatisfied (solution : Solution) (dependencies : Constraints) = seq {
      yield! Set.difference
        (dependencies |> Map.keys |> Set.ofSeq)
        (solution.Resolutions |> Map.keys  |> Set.ofSeq)
  
      yield!
        findConflicts solution dependencies
  
    }
  
  
  
  
    let private lockToHints (lock : Lock) =
      lock.Packages
  