/**
   * Checks consistency of the current node against all other collections in the group.
   *
   * @param comparisonNode The node to check consistency against
   * @param group The group against whcih to check.
   * @param cache Disjoint query cache
   * @return True if the node is consistent with all nodes in the group. False otherwise.
   */
  private boolean isConsistent(
      DAGNode comparisonNode, Collection<DAGNode> group, Map<String, QueryResult> cache) {
    String compID = comparisonNode.getIdentifier();
    for (DAGNode n : group) {
      if (n.equals(comparisonNode)) continue;

      // Create cache string to check for existing results.
      String nID = n.getIdentifier();
      String cacheStr = (nID.compareTo(compID) < 0) ? nID + compID : compID + nID;
      QueryResult result = null;
      if (!cache.containsKey(cacheStr)) {
        // Ask the disjoint query
        QueryObject qo =
            new QueryObject(
                false,
                false,
                QueryResult.TRUE,
                CommonConcepts.DISJOINTWITH.getNode(dag_),
                comparisonNode,
                n);
        result = queryModule_.prove(qo);
        cache.put(cacheStr, result);
      } else result = cache.get(cacheStr);
      if (result == QueryResult.TRUE) return false;
    }
    return true;
  }
  public synchronized void tagDAGObject(DAGNode dagObj, String tag, boolean coreTag) {
    String alterTag = TAG_PREFIX + tag;
    String nonCoreTag = NON_CORE_PREFIX + tag;
    String appliedTag = (coreTag) ? alterTag : nonCoreTag;
    if (coreTag && dagObj.getProperty(nonCoreTag) != null) {
      // Upgrade non-core to core
      removeTagDAGObject(dagObj, tag);
    } else if (!coreTag && dagObj.getProperty(alterTag) != null)
      // Do not revert to non-core
      return;

    dag_.addProperty(dagObj, appliedTag, "T");
    taggedNodes_.put(appliedTag, dagObj);
  }
 @Override
 public boolean initialisationComplete(
     TIndexedCollection<DAGNode> nodes, TIndexedCollection<DAGEdge> edges, boolean forceRebuild) {
   if (taggedNodes_ == null) {
     taggedNodes_ = MultiMap.createSortedSetMultiMap();
     TIntObjectIterator<DAGNode> iter = nodes.iterator();
     for (int i = nodes.size(); i-- > 0; ) {
       iter.advance();
       DAGNode n = iter.value();
       String[] props = n.getProperties();
       for (String prop : props) {
         if (prop.startsWith(TAG_PREFIX)) {
           taggedNodes_.put(prop, n);
         }
       }
     }
   }
   return super.initialisationComplete(nodes, edges, forceRebuild);
 }
  /**
   * Extracts a subDAG from the DAG, saving it into a given folder.
   *
   * @param folder The folder in which to save the subDAG.
   * @param tag The tag to extract the subDAG from.
   * @param distance The distance in which the subDAG reaches from tagged nodes.
   * @return True.
   */
  public boolean extractSubDAG(File folder, String tag, int distance) {
    tag = TAG_PREFIX + tag;

    // Create new DAG
    // TODO This seems like it would create a whole new DAG!
    logger.debug("Creating SubDAG");
    DirectedAcyclicGraph subDAG = createNewDAG(folder);
    subDAG.initialise();

    Collection<DAGEdge> edges = new HashSet<>();
    Collection<DAGNode> nodes = new HashSet<>();

    // Find the relevant nodes and edges.
    if (!getSubNodesAndEdges(tag, distance, edges, nodes)) return false;

    // Assert
    StringNode creator = new StringNode(tag);
    logger.debug("Asserting {} nodes.", nodes.size());
    for (DAGNode node : nodes) subDAG.findOrCreateNode(node.getName(), creator, true);
    logger.debug("Asserting {} edges.", edges.size());
    for (DAGEdge edge : edges) {
      Node[] edgeNodes = edge.getNodes();
      Node[] newEdgeNodes = new Node[edgeNodes.length];
      for (int i = 0; i < edgeNodes.length; i++) {
        newEdgeNodes[i] =
            subDAG.findOrCreateNode(edgeNodes[i].getIdentifier(true), creator, false, false);
      }
      subDAG.findOrCreateEdge(newEdgeNodes, creator, true);
    }

    // Serialise to folder
    logger.debug("Saving state.");
    subDAG.saveState();

    return true;
  }
 public boolean isTagged(DAGNode node, String tag) {
   String coreTag = TAG_PREFIX + tag;
   String nonCoreTag = NON_CORE_PREFIX + tag;
   return node.getProperty(coreTag) != null || node.getProperty(nonCoreTag) != null;
 }