code: private static Collection<Tuple> getTuples( List<VarDef> varDefs, int varStart, int varEnd, int tupleSize)
      {
      Collection<Tuple> tuples = new ArrayList<Tuple>();
  
      // For each variable up to the last included...
      for( int i = varStart; i < varEnd; i++)
        {
        // Combine each valid value...
        VarDef                nextVar   = varDefs.get(i);
        Iterator<VarValueDef> values    = nextVar.getValidValues();
        if( !values.hasNext())
          {
          throw new IllegalStateException( "Can't complete tuples -- no valid values defined for var=" + nextVar);
          }
  
        // With all subtuples from the remaining variables.
        Collection<Tuple> subTuples =
          tupleSize==1
          ? null
          : getTuples( varDefs, i + 1, varEnd + 1, tupleSize - 1);
  
        // Only one variable to combine?
        if( subTuples == null)
          {
          // Yes, return list of 1-tuples for this variable.
          while( values.hasNext())
            {
            tuples.add( new Tuple( new VarBindingDef( nextVar, values.next())));
            }
          }
  
        // Any compatible subtuples for remaining variables?
        else if( !subTuples.isEmpty())
          {
          // Yes, add all compatible combinations with values for this variable.
          while( values.hasNext())
            {
            VarBindingDef nextBinding = new VarBindingDef( nextVar, values.next());
            for( Tuple subTuple : subTuples)
              {
              Tuple nextTuple = new Tuple( nextBinding).addAll( subTuple);
              if( nextTuple.isCompatible())
                {
                tuples.add( nextTuple);
                }
              }
            }
          }
        }
      
      return tuples;
      }
docs: Returns all valid tuples of values for the given input variables.