utility.advanceChildSchedule(feedback);
    public void computeMinLatencySchedule(        FLoopSchedulingUtility utility,        int splitExecs,        int joinExecs,        int bodyExecs,        int loopExecs,        int preBodyBuffer[],        int postBodyBuffer[],        int preLoopBuffer[],        int postLoopBuffer[])    {        StreamInterface body = getHierarchicalBody();        StreamInterface feedback = getHierarchicalLoop();        // the original phase.  More will be created as needed        PhasingSchedule phase = new PhasingSchedule(this);        // basically, I will want to pull data from the loop as long as        // some of the elements still need to get executed:        // this loop will simply attempt moving some data forward.        // if this can be accomplished, it'll "continue" and see if        // some data can be pushed out.  This'll guarantee a proper pull        // schedule.        while (splitExecs > 0            || joinExecs > 0            || bodyExecs > 0            || loopExecs > 0)        {            // try to move some data through the splitter:            if (splitExecs > 0)            {                // figure out if I can run a phase of the splitter                SplitFlow splitFlow = utility.getSplitSteadyPhaseFlow(0);                if (splitFlow.getPopWeight() <= postBodyBuffer[0])                {                    // yes - add it to the schedule, update buffers                    // and, if phase outputs data, complete it                     // and start a new phase                    splitExecs--;                    phase.appendPhase(utility.getNextSplitSteadyPhase());                    postBodyBuffer[0] -= splitFlow.getPopWeight();                    preLoopBuffer[0] += splitFlow.getPushWeight(1);                    if (splitFlow.getPushWeight(0) > 0)                    {                        utility.addSchedulePhase(phase);                        phase = new PhasingSchedule(this);                    }                    continue;                }                // Okay, I don't have enough data to execute this phase                // of the split.  Check if the body will attempt to execute.                // If it will attempt, just fall through and let it try.                // If it won't (out of needed phases), force it to execute                // by asking it for another phase                if (bodyExecs == 0)                {                    bodyExecs = 1;                }            }            // try to move some data through the body            if (bodyExecs > 0)            {                // figure out if I can run a phase of the body                PhasingSchedule bodyPhase = utility.getChildNextPhase(body);                if (bodyPhase.getOverallPeek() <= preBodyBuffer[0])                {                    // yes - add this phase to the schedule, update buffers                    // and continue from the top                    bodyExecs--;                    phase.appendPhase(bodyPhase);                    preBodyBuffer[0] -= bodyPhase.getOverallPop();                    postBodyBuffer[0] += bodyPhase.getOverallPush();                    continue;                }                // I don't have enough data to advance the body                // if the joiner isn't planned to execute quite yet                // then I better force it to execute                if (joinExecs == 0)                {                    joinExecs = 1;                }            }            // try to move some data through the joiner:            if (joinExecs > 0)            {                // figure out if I can run a phase of the joiner                JoinFlow joinFlow = utility.getJoinSteadyPhaseFlow(0);                if (joinFlow.getPopWeight(1) <= postLoopBuffer[0])                {                    // yes - add it to the schedule, update buffers                    // and continue                    joinExecs--;                    phase.appendPhase(utility.getNextJoinSteadyPhase());                    postLoopBuffer[0] -= joinFlow.getPopWeight(1);                    preBodyBuffer[0] += joinFlow.getPushWeight();                    continue;                }                // Okay, I don't have enough data to execute this phase                // of the join.  Check if the loop will attempt to execute.                // If it will attempt, just fall through and let it try.                // If it won't (out of needed phases), force it to execute                // by asking it for another phase                if (loopExecs == 0)                {                    loopExecs = 1;                }            }            // try to move some data through the loop            if (loopExecs > 0)            {                // figure out if I can run a phase of the body                PhasingSchedule loopPhase =                    utility.getChildNextPhase(feedback);                if (loopPhase.getOverallPeek() <= preLoopBuffer[0])                {                    // yes - add this phase to the schedule, update buffers                    // and continue from the top                    loopExecs--;                    phase.appendPhase(loopPhase);                    preLoopBuffer[0] -= loopPhase.getOverallPop();                    postLoopBuffer[0] += loopPhase.getOverallPush();                    continue;                }                // I don't have enough data to advance the loop.                // Tough shit.  I cannot schedule this loop.  If the                // children can get a more fine-grained schedule, then                 // I may be able to schedule it if their schedules are                // relaxed.  But if not, I cannot do ANYTHING with this                // loop, as it is not possible to schedule it!            }            ERROR(                "Couldn't schedule a feedback loop (if need to find out name,\n"                    + "ask karczma, and I'll try to add the capability to display it.\n"                    + "This loop is not necessarily impossible to schedule, \n"                    + "but the children's schedules may need to be more fine-grained\n");        }        // okay, it is possible that I just added stuff to the phase, but        // it didn't get automagically added to the real schedule        // if the phase is not empty, add it        if (phase.getNumPhases() != 0)        {            utility.addSchedulePhase(phase);        }    }