void cLexiqueIntrospection::handleGetKeywordListOption (C_Compiler * inCompiler) {
  const C_String option = gOption_galgas_5F_builtin_5F_options_outputKeywordList.getter_value () ;
  if (option != "") {
    const C_String optionFormat = "lexique_name:list_name:columns:prefix:postfix:path" ;
    co << "Option \"--" << gOption_galgas_5F_builtin_5F_options_outputKeywordList.mCommandString
       << "=" << option << "\":\n" ;
    TC_UniqueArray <C_String> components ;
    option.componentsSeparatedByString (":", components) ;
    if (components.count () != 6) {
      C_String message = "invalid option ; should be \"--" ;
      message << gOption_galgas_5F_builtin_5F_options_outputKeywordList.mCommandString << "=" << optionFormat + "\"" ;
      inCompiler->onTheFlyRunTimeError (message COMMA_HERE) ;
    }else if (!components (2 COMMA_HERE).isUnsignedInteger ()) {
      C_String message = "invalid option ; in \"--" ;
      message << gOption_galgas_5F_builtin_5F_options_outputKeywordList.mCommandString << "=" << optionFormat + "\", "
              << "\"columns\" should be an decimal unsigned number" ;
      inCompiler->onTheFlyRunTimeError (message COMMA_HERE) ;
    }else{
      const uint32_t columns = components (2 COMMA_HERE).unsignedIntegerValue () ;
      const C_String prefix = components (3 COMMA_HERE) ;
      const C_String postfix = components (4 COMMA_HERE) ;
      const C_String identifier = components (0 COMMA_HERE) + ":" + components (1 COMMA_HERE) ;
      TC_UniqueArray <C_String> nameList ;
      bool found = false ;
      getKeywordListForIdentifier (identifier, found, nameList) ;
      if (!found) {
        C_String message = "invalid option ; in \"--" ;
        message << gOption_galgas_5F_builtin_5F_options_outputKeywordList.mCommandString << "=" << optionFormat + "\", "
                << "available values for \"lexique_name:list_name\" are:" ;
        TC_UniqueArray <C_String> keywordListNames ; getKeywordListNames (keywordListNames) ;
        for (int32_t i=0 ; i<keywordListNames.count () ; i++) {
          message << "  - " << keywordListNames (i COMMA_HERE) << "\n" ;
        }
        inCompiler->onTheFlyRunTimeError (message COMMA_HERE) ;
      }else{
        uint32_t idx = 0 ;
        C_String s ;
        for (int32_t i=0 ; i<nameList.count() ; i++) {
          s << "  " << prefix << nameList (i COMMA_HERE) << postfix << "  " ;
          idx ++ ;
          if (idx < columns) {
            s << "&" ;
          }else{
            s << " \\\\\n" ;
            idx = 0 ;
          }
        }
        if (idx > 0) {
          for (uint32_t i = idx+1 ; i<columns ; i++) {
            s << "  &  " ;
          }
          s << "  \\\\\n" ;
        }
        const C_String path = components (5 COMMA_HERE) ;
        C_FileManager::writeStringToFile (s, path) ;
      }
    }
  }
}
C_DirectedGraph C_DirectedGraph::subGraphFromNodes (const C_UIntSet & inStartNodes,
                                                    #ifdef USE_NODE_NAMES_WITH_SUBGRAPH_COMPUTATION
                                                      const TC_UniqueArray <C_String> & inNodeNames,
                                                    #endif
                                                    const C_UIntSet & inNodesToExclude) const {
  TC_UniqueArray <bool> nodeBoolArray ; mNodes.getBoolValueArray (nodeBoolArray) ;
  C_DirectedGraph result ;
  { C_UIntSet nodeSet = inStartNodes ;
    nodeSet -= inNodesToExclude ;
    result.addNodes (nodeSet) ;
  }
  #ifdef USE_NODE_NAMES_WITH_SUBGRAPH_COMPUTATION
    { TC_UniqueArray <uint32_t> sourceNodeArray ; result.getNodeValueArray (sourceNodeArray) ;
      printf ("START NODES (%d):\n", sourceNodeArray.count ()) ;
      for (int32_t i=0 ; i<sourceNodeArray.count () ; i++) {
        printf ("  - %d (%s)\n", sourceNodeArray (i COMMA_HERE), inNodeNames ((int32_t) sourceNodeArray (i COMMA_HERE) COMMA_HERE).cString (HERE)) ;
      }
    }
  #endif
  bool loop = true ;
  while (loop) {
    loop = false ;
    TC_UniqueArray <uint32_t> sourceNodeArray ; result.getNodeValueArray (sourceNodeArray) ;
    #ifdef USE_NODE_NAMES_WITH_SUBGRAPH_COMPUTATION
      printf ("********************* NODE COUNT %d\n", sourceNodeArray.count ()) ;
    #endif
    for (int32_t i=0 ; i<sourceNodeArray.count () ; i++) {
      const uint32_t sourceNodeIndex = sourceNodeArray (i COMMA_HERE) ;
      if (nodeBoolArray ((int32_t) sourceNodeIndex COMMA_HERE)) {
        #ifdef USE_NODE_NAMES_WITH_SUBGRAPH_COMPUTATION
          printf ("NEW NODE %d (%s):\n", sourceNodeIndex, inNodeNames ((int32_t) sourceNodeIndex COMMA_HERE).cString (HERE)) ;
        #endif
        loop = true ;
        nodeBoolArray.setObjectAtIndex (false, (int32_t) sourceNodeIndex COMMA_HERE) ;
        C_UIntSet s = mEdges ((int32_t) sourceNodeIndex COMMA_HERE) ;
        s -= inNodesToExclude ;
        TC_UniqueArray <uint32_t> targetNodeArray ; s.getValueArray (targetNodeArray) ;
        for (int32_t j=0 ; j<targetNodeArray.count () ; j++) {
          result.addEdge (sourceNodeIndex, targetNodeArray (j COMMA_HERE)) ;
          #ifdef USE_NODE_NAMES_WITH_SUBGRAPH_COMPUTATION
            printf ("  edge %d (%s)\n", targetNodeArray (j COMMA_HERE), inNodeNames ((int32_t) targetNodeArray (j COMMA_HERE) COMMA_HERE).cString (HERE)) ;
          #endif
        }
      }
    }
  }
  return result ;
}
GALGAS__32_stringlist GALGAS_application::constructor_boolOptionNameList (LOCATION_ARGS) {
  GALGAS__32_stringlist result = GALGAS__32_stringlist::constructor_emptyList (THERE) ;
  TC_UniqueArray <C_String> array ;
  C_BoolCommandLineOption::getBoolOptionNameList (array) ;
  for (int32_t i=0 ; i<array.count () ; i+=2) {
    result.addAssign_operation (GALGAS_string (array (i COMMA_THERE)), GALGAS_string (array (i+1 COMMA_THERE)) COMMA_THERE) ;
  }
  return result ;
}
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::print (void) const {
  for (int32_t i=0 ; i<mEdges.count () ; i++) {
    if (isNodeDefined ((uint32_t) i)) {
      printf ("Node %d:\n", i) ;
      TC_UniqueArray <uint32_t> s ; mEdges (i COMMA_HERE).getValueArray (s) ;
      for (int32_t j=0 ; j<s.count () ; j++) {
        printf ("  %d --> %d\n", i, s (j COMMA_HERE)) ;
      }
    }
  }
}
 void C_DirectedGraph::checkGraph (LOCATION_ARGS) const {
   MF_AssertThere (mEdges.count () == mReverseEdges.count (), "mEdges.count () %lld != mReverseEdges.count () %lld", mEdges.count (), mReverseEdges.count ()) ;
   MF_AssertThere (mNodes.firstValueNotIsSet () == (uint32_t) (mEdges.count ()), "mNodes.firstValueNotIsSet () %lld != mEdges.count () %lld", mNodes.firstValueNotIsSet (), mEdges.count ()) ;
 //---
   for (uint32_t i=0 ; i<(uint32_t) mEdges.count () ; i++) {
     TC_UniqueArray <uint32_t> targetList ; mEdges ((int32_t) i COMMA_HERE).getValueArray (targetList) ;
     for (int32_t j=0 ; j<targetList.count () ; j++) {
       const uint32_t target = targetList (j COMMA_HERE) ;
       MF_AssertThere (mReverseEdges ((int32_t) target COMMA_HERE).contains (i), "! mReverseEdges (%lld COMMA_HERE).contains (%lld)", target, i) ;
     }
   }
 //---
   for (uint32_t i=0 ; i<(uint32_t) mReverseEdges.count () ; i++) {
     TC_UniqueArray <uint32_t> sourceList ; mReverseEdges ((int32_t) i COMMA_HERE).getValueArray (sourceList) ;
     for (int32_t j=0 ; j<sourceList.count () ; j++) {
       const uint32_t source = sourceList (j COMMA_HERE) ;
       MF_AssertThere (mEdges ((int32_t) source COMMA_HERE).contains (i), "! mEdges (%lld COMMA_HERE).contains (%lld)", source, i) ;
     }
   }
 }
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) ;
    }
  }
}
C_String C_DirectedGraph::graphvizString (const TC_UniqueArray <C_String> & inNodeNameArray) const {
  C_String s = "digraph G {\n" ;
  for (int32_t i=0 ; i<mEdges.count () ; i++) {
    if (isNodeDefined ((uint32_t) i)) {
      s << "  \"" << inNodeNameArray (i COMMA_HERE) << "\" [shape=rectangle] ;\n" ;
      const C_UIntSet targetSet = mEdges (i COMMA_HERE) ;
      TC_UniqueArray <uint32_t> targetList ; targetSet.getValueArray (targetList) ;
      for (int32_t j=0 ; j<targetList.count () ; j++) {
        const uint32_t targetIndex = targetList (j COMMA_HERE) ;
        s << "  \"" << inNodeNameArray (i COMMA_HERE) << "\" -> \"" << inNodeNameArray ((int32_t) targetIndex COMMA_HERE) << "\" ;\n" ;
      }
    }
  }
  s << "}\n" ;
  return s ;
}
void C_DirectedGraph::removeEdgesToNode (const uint32_t inNodeIndex
                                         COMMA_LOCATION_ARGS) {
//--- get nodes that have edges to this node
  const C_UIntSet nodeSet = mReverseEdges ((int32_t) inNodeIndex COMMA_THERE) ;
//--- Remove edges in reverse egde array
  mReverseEdges.setObjectAtIndex (C_UIntSet (), (int32_t) inNodeIndex COMMA_THERE) ;
//--- Remove edge in direct edge array
  TC_UniqueArray <uint32_t> sourceNodeArray ; nodeSet.getValueArray (sourceNodeArray) ;
  for (int32_t i=0 ; i<sourceNodeArray.count () ; i++) {
    const uint32_t sourceNodeIndex = sourceNodeArray (i COMMA_HERE) ;
    mEdges ((int32_t) sourceNodeIndex COMMA_HERE).remove (inNodeIndex) ;
  }
//--- Check
  #ifndef DO_NOT_GENERATE_CHECKINGS
    checkGraph (HERE) ;
  #endif
}
void C_DirectedGraph::removeNode (const uint32_t inNodeIndex) {
  if (inNodeIndex < (uint32_t) mEdges.count ()) {
    mNodes.remove (inNodeIndex) ;
    const C_UIntSet targetSet = mEdges ((int32_t) inNodeIndex COMMA_HERE) ;
    TC_UniqueArray <uint32_t> targetList ; targetSet.getValueArray (targetList) ;
    for (int32_t i=0 ; i<targetList.count () ; i++) {
      const uint32_t targetIndex = targetList (i COMMA_HERE) ;
      mReverseEdges ((int32_t) targetIndex COMMA_HERE).remove (inNodeIndex) ;
    }
    mEdges.setObjectAtIndex (C_UIntSet (), (int32_t) inNodeIndex COMMA_HERE) ;
  }
  const uint32_t f = mNodes.firstValueNotIsSet () ;
  while (f < (uint32_t) mEdges.count ()) {
    mEdges.removeLastObject (HERE) ;
    mReverseEdges.removeLastObject (HERE) ;
  }
  #ifndef DO_NOT_GENERATE_CHECKINGS
    checkGraph (HERE) ;
  #endif
}
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) ;
    }
  }
}