StreamInterface child = getHierarchicalChild(nChild);
    public void computeMinLatencySchedule(        SJSchedulingUtility utility,        int splitExecs,        int joinExecs,        int childrenExecs[],        int postSplitBuffers[],        int preJoinBuffers[])    {        // first pull all the data out of the split-join        // that needs to go (drain the join)        while (joinExecs > 0)        {            int splitterPhases = 0;            int joinerPhases = 0;            int phaseChildrenExecs[] = new int[getNumChildren()];            int joinerOverallPop[] = new int[getNumChildren()];            // compute how many times I need to execute the joiner            // before I get some output - this will be my phase            {                JoinFlow joinFlow;                do                {                    joinFlow = utility.getJoinSteadyPhaseFlow(joinerPhases);                    joinerPhases++;                    int nChild;                    for (nChild = 0; nChild < getNumChildren(); nChild++)                    {                        joinerOverallPop[nChild]                            += joinFlow.getPopWeight(nChild);                    }                }                while (joinFlow.getPushWeight() == 0);            }            int childOverallPeek[] = new int[getNumChildren()];            int childOverallPop[] = new int[getNumChildren()];            int childOverallPush[] = new int[getNumChildren()];            // figure out how many times to execute all the children            // to provide input for the joiner            {                int nChild;                for (nChild = 0; nChild < getNumChildren(); nChild++)                {                    while (preJoinBuffers[nChild]                        - joinerOverallPop[nChild]                        + childOverallPush[nChild]                        < 0)                    {                        StreamInterface child = getHierarchicalChild(nChild);                        PhasingSchedule childPhase =                            utility.getChildPhase(                                child,                                phaseChildrenExecs[nChild]);                        childOverallPeek[nChild] =                            MAX(                                childOverallPeek[nChild],                                childOverallPop[nChild]                                    + childPhase.getOverallPeek());                        childOverallPop[nChild] += childPhase.getOverallPop();                        childOverallPush[nChild]                            += childPhase.getOverallPush();                        phaseChildrenExecs[nChild]++;                    }                }            }            int splitterOverallPush[] = new int[getNumChildren()];            // figure out how many times to execute the splitter to            // supply enough data for all the children to go            {                int nChild;                for (nChild = 0; nChild < getNumChildren(); nChild++)                {                    int childSplitterPhases = 0;                    while (postSplitBuffers[nChild]                        + splitterOverallPush[nChild]                        - childOverallPeek[nChild]                        < 0)                    {                        SplitFlow splitFlow =                            utility.getSplitSteadyPhaseFlow(                                childSplitterPhases);                        childSplitterPhases++;                        splitterOverallPush[nChild]                            += splitFlow.getPushWeight(nChild);                    }                    splitterPhases = MAX(splitterPhases, childSplitterPhases);                }            }            // okay, now I know how many times I need to run the            // splitter, children and the joiner.  just run them :)            {                // get the phase                PhasingSchedule phase = utility.createPhase(splitterPhases, phaseChildrenExecs, joinerPhases, postSplitBuffers, preJoinBuffers);                                // and adjust counters of execution:                splitExecs -= splitterPhases;                for (int nChild = 0; nChild < getNumChildren(); nChild++)                {                    childrenExecs [nChild] -= phaseChildrenExecs[nChild];                }                joinExecs -= joinerPhases;                                utility.addSchedulePhase(phase);            }        }        // now execute all the components (other than the join, which        // is done initializing) until they're guaranteed to have been        // initialized        {            // create the phase            PhasingSchedule phase = utility.createPhase(splitExecs, childrenExecs, 0, postSplitBuffers, preJoinBuffers);            // add it to the init schedule, if necessary            if (phase.getNumPhases() != 0)            {                utility.addSchedulePhase(phase);            }        }    }