code: def split(self):
          
          assert(self.status == SolverStatus.exhausted)
  
          scopes = []
          next_scopes = []
          split_i = None
  
          for i, scope in enumerate(self.scopes):
              if split_i is None:
                  r = scope.split()
                  if r is not None:
                      scope_, next_scope = r
                      scopes.append(scope_)
                      next_scopes.append(next_scope)
                      split_i = i
                      continue
  
              scopes.append(scope)
              next_scopes.append(scope)
  
          assert split_i is not None
  
          phase = copy.copy(self)
          phase.scopes = scopes
          phase.status = SolverStatus.pending
          phase.changed_scopes_i = set([split_i])
  
          # because a scope was narrowed by a split, other scopes need to be
          # reduced against it
          #for i in range(len(phase.scopes)):
          #    if i != split_i:
          #        phase.pending_reducts.add((i, split_i))
  
          next_phase = copy.copy(phase)
          next_phase.scopes = next_scopes
          return (phase, next_phase)
docs: Split the phase.
  
          When a phase is exhausted, it gets split into a pair of phases to be
          further solved. The split happens like so:
          1) Select the first unsolved package scope.
          2) Find some common dependency in the first N variants of the scope.
          3) Split the scope into two: [:N] and [N:].
          4) Create two copies of the phase, containing each half of the split
             scope.
  
          The result of this split is that we have a new phase (the first phase),
          which contains a package scope with a common dependency. This
          dependency can now be intersected with the current resolve, thus
          progressing it.
  
          Returns:
              A 2-tuple of _ResolvePhase objects, where the first phase is the
              best contender for resolving.