public static void computeOptimalOpenGoalOrdering(List optimizervariables, int numberofopengoals, List goalsequence, double priorcost, double priorfanout) {
    { Cons goalsequencecheckpoint = null;
      int choicepointunbindingoffset = Stella.NULL_INTEGER;
      double cumulativecost = Stella.NULL_FLOAT;
      double cumulativefanout = Stella.NULL_FLOAT;

      if (((Integer)(Logic.$OPTIMALGOALORDERINGRECURSIONS$.get())).intValue() >= Logic.$OPTIMAL_GOAL_ORDERING_CUTOFF$) {
        return;
      }
      else {
        Native.setIntSpecial(Logic.$OPTIMALGOALORDERINGRECURSIONS$, ((Integer)(Logic.$OPTIMALGOALORDERINGRECURSIONS$.get())).intValue() + 1);
      }
      if (optimizervariables.emptyP()) {
        KeyValueList.setDynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_GOAL_SEQUENCE, goalsequence, null);
        return;
      }
      { PatternVariable vbl = null;
        Cons iter000 = optimizervariables.theConsList;

        loop000 : for (;!(iter000 == Stella.NIL); iter000 = iter000.rest) {
          vbl = ((PatternVariable)(iter000.value));
          if (!PatternVariable.variableBoundP(vbl)) {
            { Proposition generatorgoal = null;
              double generatorcost = Stella.NULL_FLOAT;
              double generatorfanout = Stella.NULL_FLOAT;

              { Object [] caller_MV_returnarray = new Object[2];

                generatorgoal = PatternVariable.cheapestGeneratorGoal(vbl, caller_MV_returnarray);
                generatorcost = ((double)(((FloatWrapper)(caller_MV_returnarray[0])).wrapperValue));
                generatorfanout = ((double)(((FloatWrapper)(caller_MV_returnarray[1])).wrapperValue));
              }
              if (generatorgoal == null) {
                continue loop000;
              }
              cumulativefanout = priorfanout * generatorfanout;
              cumulativecost = priorcost + (cumulativefanout * generatorcost);
              if ((cumulativecost == Stella.NULL_FLOAT) ||
                  (cumulativecost < priorcost)) {
                continue loop000;
              }
              if ((((FloatWrapper)(KeyValueList.dynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_COST, Stella.NULL_FLOAT_WRAPPER))).wrapperValue != Stella.NULL_FLOAT) &&
                  (cumulativecost >= ((FloatWrapper)(KeyValueList.dynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_COST, Stella.NULL_FLOAT_WRAPPER))).wrapperValue)) {
                continue loop000;
              }
              goalsequencecheckpoint = goalsequence.theConsList;
              choicepointunbindingoffset = Logic.simulateCreateChoicePoint();
              goalsequence.push(generatorgoal);
              Proposition.bindAllVariablesInGeneratorGoal(generatorgoal, goalsequence);
            }
            if (goalsequence.length() == numberofopengoals) {
              if ((((FloatWrapper)(KeyValueList.dynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_COST, Stella.NULL_FLOAT_WRAPPER))).wrapperValue == Stella.NULL_FLOAT) ||
                  (cumulativecost < ((FloatWrapper)(KeyValueList.dynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_COST, Stella.NULL_FLOAT_WRAPPER))).wrapperValue)) {
                KeyValueList.setDynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_COST, FloatWrapper.wrapFloat(cumulativecost), Stella.NULL_FLOAT_WRAPPER);
                KeyValueList.setDynamicSlotValue(((QueryIterator)(Logic.$QUERYITERATOR$.get())).dynamicSlots, Logic.SYM_LOGIC_BEST_GOAL_SEQUENCE, goalsequence.copy(), null);
              }
            }
            else {
              Logic.computeOptimalOpenGoalOrdering(optimizervariables, numberofopengoals, goalsequence, cumulativecost, cumulativefanout);
            }
            goalsequence.theConsList = goalsequencecheckpoint;
            PatternRecord.unbindVariablesBeginningAt(((QueryIterator)(Logic.$QUERYITERATOR$.get())).currentPatternRecord, choicepointunbindingoffset);
          }
        }
      }
    }
  }