code: private boolean completeSatisfied( TestCaseDef testCase, VarTupleSet tuples, List<VarDef> vars)
      {
      List<VarDef> varsRemaining = getVarsRemaining( vars, testCase);
      VarDef varApplicable;
      boolean complete; 
  
      // Any variables remaining unbound?
      if( varsRemaining.isEmpty())
        {
        // No, this test case is complete.
        complete = true;
        }
      
      // Any variables remaining that are currently applicable to this test case?
      else if( (varApplicable = varsRemaining.stream().filter( v -> testCase.isApplicable(v)).findFirst().orElse( null)) == null)
        {
        // No, continue with an NA binding for the next variable
        testCase.addCompatible( getNaBindingFor( varsRemaining.get( 0)));
        complete = makeComplete( testCase, tuples, varsRemaining);
        }
  
      else
        {
        // Find an applicable binding that will lead to a complete test case
        int prevBindings = testCase.getBindingCount();
        Iterator<Tuple> bindingTuples = getBindingsFor( tuples, varApplicable);
        for( complete = false;
  
             // More tuples to try?
             bindingTuples.hasNext()
               && !(
                 // Compatible tuple found?
                 testCase.addCompatible( (bindingTuples.next())) != null
  
                 // Did this tuple create an infeasible combination?
                 && !testCase.isInfeasible()
  
                 // Can we complete bindings for remaining variables?
                 && (complete = makeComplete( testCase, tuples, varsRemaining)));
               
             // No path to completion with this tuple -- try the next one.
             testCase.revertBindings( prevBindings));
        }
      
      return complete;
      }
docs: Using selections from the given set of tuples, completes binding for all remaining variables.
  Returns true if all variables have been bound.