void C_DirectedGraph::depthFirstTopologicalSort (TC_UniqueArray <uint32_t> & outSortedNodes,
                                                 TC_UniqueArray <uint32_t> & outUnsortedNodes) const {
  outSortedNodes.setCountToZero () ;
  outUnsortedNodes.setCountToZero () ;
//--- Get working copies
  TC_UniqueArray <bool> nodes ; getNodeBoolArray (nodes) ;
  TC_UniqueArray <uint32_t> dependencyCount (mReverseEdges.count (), 0 COMMA_HERE) ;
  for (int32_t i=0 ; i<mReverseEdges.count () ; i++) {
    TC_UniqueArray <uint32_t> s ; mReverseEdges (i COMMA_HERE).getValueArray (s) ;
    for (int32_t j=0 ; j<s.count () ; j++) {
      dependencyCount.incrementAtIndex ((int32_t) s (j COMMA_HERE) COMMA_HERE) ;
    }
  }
//--- Loop
  TC_UniqueArray <uint32_t> workingArray ;
  TC_UniqueArray <uint32_t> s ;
  bool loop = true ;
  while (loop) {
  //--- Find a node without any dependence  
    for (int32_t i=0 ; (i<dependencyCount.count ()) && (workingArray.count () == 0) ; i++) {
      if (nodes (i COMMA_HERE) && (dependencyCount (i COMMA_HERE) == 0)) {
        nodes.setObjectAtIndex (false, i COMMA_HERE) ;
        workingArray.appendObject ((uint32_t) i) ;
      }
    }
    loop = workingArray.count () > 0 ;
    if (loop) {
      const uint32_t node = workingArray.lastObject (HERE) ;
      workingArray.removeLastObject (HERE) ;
      outSortedNodes.appendObject (node) ;
      mReverseEdges ((int32_t) node COMMA_HERE).getValueArray (s) ;
      for (int32_t j=0 ; j<s.count () ; j++) {
        const uint32_t candidate = s (j COMMA_HERE) ;
        dependencyCount.decrementAtIndex ((int32_t) candidate COMMA_HERE) ;
        if (dependencyCount ((int32_t) candidate COMMA_HERE) == 0) {
          workingArray.appendObject (candidate) ;
          nodes.setObjectAtIndex (false, (int32_t) candidate COMMA_HERE) ;
        }
      }
    }
  }
//--- Add unusorted nodes
  for (int32_t i=0 ; i<nodes.count () ; i++) {
    if (nodes (i COMMA_HERE)) {
      outUnsortedNodes.appendObject ((uint32_t) i) ;
    }
  }
}
void C_DirectedGraph::getNodesWithNoSuccessor (TC_UniqueArray <uint32_t> & outNodes) const {
  outNodes.setCountToZero () ;
  for (uint32_t i=0 ; i<(uint32_t) mEdges.count () ; i++) {
    if (isNodeDefined (i) && mEdges ((int32_t) i COMMA_HERE).isEmpty ()) {
      outNodes.appendObject (i) ;
    }
  }
}
void C_StringListCommandLineOption::getStringOptionNameList (TC_UniqueArray <C_String> & outArray) {
  C_StringListCommandLineOption * p = gFirstStringListOption ;
  while (p != NULL) {
    outArray.appendObject (p->mDomainName) ;
    outArray.appendObject (p->mIdentifier) ;
    p = p->mNext ;
  }
}
void C_DirectedGraph::getEdges (TC_UniqueArray <cEdge> & outEdges) const {
  outEdges.setCountToZero () ;
  for (int32_t i=0 ; i<mEdges.count () ; i++) {
    TC_UniqueArray <uint32_t> targetList ; mEdges (i COMMA_HERE).getValueArray (targetList) ;
    for (int32_t j=0 ; j<targetList.count () ; j++) {
      const cEdge edge = {(uint32_t) i, targetList (j COMMA_HERE)} ;
      outEdges.appendObject (edge) ;
    }
  }
}
void C_DirectedGraph::getNodesInvolvedInCircularities (TC_UniqueArray <uint32_t> & outNodes) const {
  outNodes.setCountToZero () ;
//--- Get working copies
  TC_UniqueArray <bool> nodes ; getNodeBoolArray (nodes) ;
  TC_UniqueArray <uint32_t> successorCount ;
  TC_UniqueArray <uint32_t> predecessorCount ;
  for (int32_t i=0 ; i<mEdges.count () ; i++) {
    successorCount.appendObject (mEdges (i COMMA_HERE).count ()) ;
  }
  for (int32_t i=0 ; i<mReverseEdges.count () ; i++) {
    predecessorCount.appendObject (mReverseEdges (i COMMA_HERE).count ()) ;
  }
//--- Eliminate nodes that have no successor or no predecessor
  bool loop = true ;
  while (loop) {
    loop = false ;
    for (int32_t i=0 ; i<nodes.count () ; i++) {
      if (nodes (i COMMA_HERE) && ((successorCount (i COMMA_HERE) == 0) || (predecessorCount (i COMMA_HERE) == 0))) {
        loop = true ;
        nodes.setObjectAtIndex (false, i COMMA_HERE) ;
        TC_UniqueArray <uint32_t> s ; mEdges (i COMMA_HERE).getValueArray (s) ;
        for (int32_t j=0 ; j<s.count () ; j++) {
          predecessorCount.decrementAtIndex ((int32_t) s (j COMMA_HERE) COMMA_HERE) ;
        }
        mReverseEdges (i COMMA_HERE).getValueArray (s) ;
        for (int32_t j=0 ; j<s.count () ; j++) {
          successorCount.decrementAtIndex ((int32_t) s (j COMMA_HERE) COMMA_HERE) ;
        }
      }
    }
  }

//--- Add circular nodes
  for (int32_t i=0 ; i<nodes.count () ; i++) {
    if (nodes (i COMMA_HERE)) {
      outNodes.appendObject ((uint32_t) i) ;
    }
  }
}
void C_DirectedGraph::topologicalSort (TC_UniqueArray <uint32_t> & outSortedNodes,
                                       TC_UniqueArray <uint32_t> & outUnsortedNodes) const {
  outSortedNodes.setCountToZero () ;
  outUnsortedNodes.setCountToZero () ;
//--- Get working copies
  TC_UniqueArray <bool> nodes ; getNodeBoolArray (nodes) ;
  TC_UniqueArray <uint32_t> dependencyCount (mReverseEdges.count (), 0 COMMA_HERE) ;
  for (int32_t i=0 ; i<mReverseEdges.count () ; i++) {
    TC_UniqueArray <uint32_t> s ; mReverseEdges (i COMMA_HERE).getValueArray (s) ;
    for (int32_t j=0 ; j<s.count () ; j++) {
      dependencyCount.incrementAtIndex ((int32_t) s (j COMMA_HERE) COMMA_HERE) ;
    }
  }
//--- Loop
  bool loop = true ;
  TC_UniqueArray <uint32_t> s ;
  while (loop) {
    loop = false ;
    for (int32_t i=0 ; i<nodes.count () ; i++) {
      if (nodes (i COMMA_HERE) && (dependencyCount (i COMMA_HERE) == 0)) {
        loop = true ;
        outSortedNodes.appendObject ((uint32_t) i) ;
        nodes.setObjectAtIndex (false, i COMMA_HERE) ;
        mReverseEdges (i COMMA_HERE).getValueArray (s) ;
        for (int32_t j=0 ; j<s.count () ; j++) {
          dependencyCount.decrementAtIndex ((int32_t) s (j COMMA_HERE) COMMA_HERE) ;
        }
      }
    }
  }
//--- Add unusorted nodes
  for (int32_t i=0 ; i<nodes.count () ; i++) {
    if (nodes (i COMMA_HERE)) {
      outUnsortedNodes.appendObject ((uint32_t) i) ;
    }
  }
}