docs: public ChannelData[] generateChildDataArray(ChannelData[] parentChannelData, boolean[] childrenCreated) {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(tc, "generateChildDataArray");
          }
          ChannelData newChannelDataArray[] = new ChannelData[parentChannelData.length];
          ChannelDataImpl parent = null;
          ChildChannelDataImpl child = null;
          ChainDataImpl runningChainData = null;
          List<ChainData> chainDataList = new ArrayList<ChainData>();
  
          for (int i = 0; i < parentChannelData.length; i++) {
              // Get the parent channel data object.
              parent = (ChannelDataImpl) channelDataMap.get(parentChannelData[i].getName());
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "Find or create a child for parent " + parent.getName());
              }
              // Check if it is in the runtime yet.
              if (parent.getNumChildren() == 0) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "Parent not in runtime");
                  }
                  // Channel not in runtime yet. Create it.
                  newChannelDataArray[i] = parent.createChild();
                  childrenCreated[i] = true;
                  // All next channels will either converge or need to be created.
                  for (int j = i + 1; j < newChannelDataArray.length; j++) {
                      // Get the parent channel data object.
                      parent = (ChannelDataImpl) channelDataMap.get(parentChannelData[j].getName());
                      // Create the child for use in this chain.
                      newChannelDataArray[j] = parent.createChild();
                      childrenCreated[j] = true;
                  }
                  // Children have all been created. Break out of for loop.
                  break;
              } else if (i == 0) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "Found connector channel");
                  }
                  // Get list of all running chain data using this channel ... for future
                  // interrogation
                  chainDataList = getRunningChains(parent);
                  // Found connector channel. Special case. Only ever zero or one instance
                  // in runtime
                  newChannelDataArray[i] = parent.getInboundChild();
                  if (newChannelDataArray[i] == null) {
                      newChannelDataArray[i] = parent.createChild();
                      childrenCreated[i] = true;
                  } else {
                      childrenCreated[i] = false;
                  }
              } else {
                  // Non connector channel found in runtime. Need to pick the right one.
                  // Weed chain data list down to those that include this channel as the
                  // i-th channel
                  boolean foundChild = false;
                  String inputChannelName = parentChannelData[i].getName();
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "Found non connector channel, " + inputChannelName);
                  }
                  while (chainDataList.size() > 0) {
                      runningChainData = (ChainDataImpl) chainDataList.get(0);
                      // Weed out outbound chains using this parent channel config.
                      if (runningChainData.getType().equals(FlowType.OUTBOUND)) {
                          // Can't consider this chain since it is outbound.
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "Removing chain that is outbound, " + runningChainData.getName());
                          }
                          chainDataList.remove(runningChainData);
                          continue;
                      }
                      // Extract the i-th channel from the current running chain data
                      if (i + 1 > runningChainData.getChannelList().length) {
                          // Chain doesn't have any more channels. Nothing at i-th position.
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "Removing chain that is too short, " + runningChainData.getName());
                          }
                          chainDataList.remove(runningChainData);
                          continue;
                      }
                      child = (ChildChannelDataImpl) runningChainData.getChannelList()[i];
                      // Check if the runtime channel is a child of the input parent.
                      if (!inputChannelName.equals(child.getExternalName())) {
                          // Child did not come from input parent. Remove divergent chain.
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "Removing divergent chain, " + runningChainData.getName());
                          }
                          chainDataList.remove(runningChainData);
                      } else {
                          // Found a match. Use it and break.
                          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                              Tr.debug(tc, "Found reusable channel from chain, " + runningChainData.getName());
                          }
                          newChannelDataArray[i] = child;
                          childrenCreated[i] = false;
                          foundChild = true;
                          break;
                      }
                  }
                  // At this point, chainDataList only includes the runtime chains that
                  // match
                  // up to the i-th channel of the input chain data.
                  // Example: if i=1 and we have ABX, the list may contain ABC and ABD.
                  // If the list is empty, create a new child.
                  if (!foundChild) {
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                          Tr.debug(tc, "Channel not in runtime so create it, " + parent.getName());
                      }
                      // Channel not in runtime yet. Create it.
                      newChannelDataArray[i] = parent.createChild();
                      childrenCreated[i] = true;
                      // All next channels will either converge or need to be created.
                      for (int j = i + 1; j < newChannelDataArray.length; j++) {
                          // Get the parent channel data object.
                          parent = (ChannelDataImpl) channelDataMap.get(parentChannelData[j].getName());
                          // Create the child for use in this chain.
                          newChannelDataArray[j] = parent.createChild();
                          childrenCreated[j] = true;
                      }
                      // Children have all been created. Break out of for loop.
                      break;
                  }
              }
          } // end for loop creating new channel array of children
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.exit(tc, "generateChildDataArray");
          }
          return newChannelDataArray;
      }