private void updateNodes(HierarchicalGraph graph) {
    Modeler nodeInit = engine.getModelClasses()[AbstractEngine.CLASS_NODE].getCurrentModeler();

    NodeIterable nodeIterable;
    nodeIterable = graph.getNodes();

    for (Node node : nodeIterable) {

      Model obj = node.getNodeData().getModel();
      if (obj == null) {
        // Model is null, ADD
        obj = nodeInit.initModel(node.getNodeData());
        engine.addObject(AbstractEngine.CLASS_NODE, (ModelImpl) obj);
      } else if (!obj.isValid()) {
        engine.addObject(AbstractEngine.CLASS_NODE, (ModelImpl) obj);
      }
      obj.setCacheMarker(cacheMarker);

      // Modeaction
      if (modeManager.getMode().equals(ModeManager.AVAILABLE_MODES.HIGHLIGHT)) {
        ModelImpl impl = (ModelImpl) obj;
        //                if (!node.isVisible()) {
        //                    ColorLayer.layerColor(impl, 0.8f, 0.8f, 0.8f);
        //                }
      }
    }
  }
  private void writeNodes(XMLStreamWriter xmlWriter, HierarchicalGraph graph) throws Exception {
    if (cancel) {
      return;
    }
    xmlWriter.writeStartElement(NODES);

    AttributeColumn dynamicCol =
        dynamicCol = attributeModel.getNodeTable().getColumn(DynamicModel.TIMEINTERVAL_COLUMN);

    NodeIterable nodeIterable = exportHierarchy ? graph.getNodesTree() : graph.getNodes();
    for (Node node : nodeIterable) {
      xmlWriter.writeStartElement(NODE);

      String id = node.getNodeData().getId();
      xmlWriter.writeAttribute(NODE_ID, id);
      if (node.getNodeData().getLabel() != null && !node.getNodeData().getLabel().isEmpty()) {
        xmlWriter.writeAttribute(NODE_LABEL, node.getNodeData().getLabel());
      }

      if (exportHierarchy) {
        Node parent = graph.getParent(node);
        if (parent != null) {
          xmlWriter.writeAttribute(NODE_PID, parent.getNodeData().getId());
        }
      }

      if (exportDynamic && dynamicCol != null && visibleInterval != null) {
        TimeInterval timeInterval =
            (TimeInterval) node.getNodeData().getAttributes().getValue(dynamicCol.getIndex());
        if (timeInterval != null) {
          writeTimeInterval(xmlWriter, timeInterval);
        }
      }

      if (exportAttributes && node.getNodeData().getAttributes() != null) {
        AttributeRow attributeRow = (AttributeRow) node.getNodeData().getAttributes();
        writeAttValues(xmlWriter, attributeRow, visibleInterval);
      }

      if (exportSize) {
        writeNodeSize(xmlWriter, node);
      }

      if (exportPosition) {
        writeNodePosition(xmlWriter, node);
      }

      if (exportColors) {
        writeNodeColor(xmlWriter, node);
      }

      xmlWriter.writeEndElement();
      Progress.progress(progress);
      if (cancel) {
        break;
      }
    }

    xmlWriter.writeEndElement();
  }
 public Graph filter(Graph[] graphs) {
   HierarchicalGraph minHGraph = (HierarchicalGraph) graphs[0];
   int minElements = Integer.MAX_VALUE;
   for (int i = 0; i < graphs.length; i++) {
     int count = ((HierarchicalGraph) graphs[i]).getNodeCount();
     if (count < minElements) {
       minHGraph = (HierarchicalGraph) graphs[i];
       minElements = count;
     }
   }
   for (Node n : minHGraph.getNodes().toArray()) {
     for (int i = 0; i < graphs.length; i++) {
       if ((HierarchicalGraph) graphs[i] != minHGraph) {
         if (!((HierarchicalGraph) graphs[i]).contains(n)) {
           minHGraph.removeNode(n);
           break;
         }
       }
     }
   }
   for (Edge e : minHGraph.getEdges().toArray()) {
     for (int i = 0; i < graphs.length; i++) {
       if ((HierarchicalGraph) graphs[i] != minHGraph) {
         if (!((HierarchicalGraph) graphs[i]).contains(e)) {
           minHGraph.removeEdge(e);
           break;
         }
       }
     }
   }
   return minHGraph;
 }
  public void updatePotatoes(HierarchicalGraph graph) {

    ModelClass potatoClass = engine.getModelClasses()[AbstractEngine.CLASS_POTATO];
    if (potatoClass.isEnabled()) {
      Modeler potInit = engine.getModelClasses()[AbstractEngine.CLASS_POTATO].getCurrentModeler();

      List<ModelImpl> hulls = new ArrayList<ModelImpl>();
      Node[] nodes = graph.getNodes().toArray();
      for (Node n : nodes) {
        Node parent = graph.getParent(n);
        if (parent != null) {
          Group group = (Group) parent;
          Model hullModel = group.getGroupData().getHullModel();
          if (hullModel != null && hullModel.isCacheMatching(cacheMarker)) {
            ConvexHull hull = (ConvexHull) hullModel.getObj();
            hull.addNode(n);
            hull.setModel(hullModel);
          } else if (hullModel != null) {
            // Its not the first time the hull exist
            ConvexHullModel model = (ConvexHullModel) hullModel;
            model.setScale(1f);
            hullModel.setCacheMarker(cacheMarker);
            hulls.add((ModelImpl) hullModel);
          } else {
            ConvexHull ch = new ConvexHull();
            ch.setMetaNode(parent);
            ch.addNode(n);
            ModelImpl obj = potInit.initModel(ch);
            group.getGroupData().setHullModel(obj);
            obj.setCacheMarker(cacheMarker);
            hulls.add(obj);
          }
        }
      }
      for (ModelImpl im : hulls) {
        ConvexHull hull = (ConvexHull) im.getObj();
        hull.recompute();
        engine.addObject(AbstractEngine.CLASS_POTATO, im);
      }
    }
  }
  @Override
  public void execute(GraphModel graphModel, AttributeModel attributeModel) {
    // Graph graph = graphModel.getGraphVisible();
    HierarchicalGraph graph = null;
    // get visible graph
    if (directed) {
      graph = graphModel.getHierarchicalDirectedGraphVisible();
    } else {
      graph = graphModel.getHierarchicalUndirectedGraphVisible();
    }

    // lock graph
    graph.readLock();
    try {
      Progress.start(progressTicket, graph.getNodeCount());
      // all coefficients
      nodeCoefficients = new double[graph.getNodeCount()];

      // attribute column
      AttributeTable nodeTable = attributeModel.getNodeTable();
      AttributeColumn clusteringColumn = nodeTable.getColumn("newClusteringCoefficient");
      if (clusteringColumn == null) {
        clusteringColumn =
            nodeTable.addColumn(
                "newClusteringCoefficient",
                "Local Clustering Coefficient",
                AttributeType.DOUBLE,
                AttributeOrigin.COMPUTED,
                0.0);
      }

      int i = 0;
      // for each node
      for (Node e : graph.getNodes()) {
        // compute coefficient
        double coeficient = 0.0;
        double denominator = (graph.getDegree(e) * (graph.getDegree(e) - 1));
        if (!directed) {
          denominator /= 2;
        }
        double numerator = 0.0;
        // get neighbors as list
        List<Node> n2 = Arrays.asList(graph.getNeighbors(e).toArray());
        List<Node> neighbors2 = new ArrayList<Node>(n2);
        for (Node neighbor1 : graph.getNeighbors(e)) {
          neighbors2.remove(neighbor1);
          // count edges betwwen neighbors
          for (Node neighbor2 : neighbors2) {
            if (graph.getEdge(neighbor1, neighbor2) != null
                || graph.getEdge(neighbor2, neighbor1) != null) {
              numerator++;
            }
          }
        }
        // compute coefficient
        if (denominator > 0) {
          coeficient = numerator / denominator;
        } else {
          coeficient = 0.0;
        }
        averageCoefficient += coeficient;
        nodeCoefficients[i] = coeficient;
        i++;
        // set attribute
        AttributeRow row = (AttributeRow) e.getNodeData().getAttributes();
        row.setValue(clusteringColumn, coeficient);
        Progress.progress(progressTicket);
        if (cancel) {
          break;
        }
      }
      if (graph.getNodeCount() > 0) {
        averageCoefficient = averageCoefficient / graph.getNodeCount();
      }

      graph.readUnlockAll();
    } catch (Exception e) {
      e.printStackTrace();
      // Unlock graph
      graph.readUnlockAll();
    }
  }
    public Graph filter(Graph graph, Filter[] filters) {
      HierarchicalGraph hgraph = (HierarchicalGraph) graph;
      List<NodeFilter> nodeFilters = new ArrayList<NodeFilter>();
      List<EdgeFilter> edgeFilters = new ArrayList<EdgeFilter>();
      for (Filter f : filters) {
        if (f instanceof NodeFilter) {
          nodeFilters.add((NodeFilter) f);
        } else if (f instanceof EdgeFilter) {
          edgeFilters.add((EdgeFilter) f);
        }
      }
      if (nodeFilters.size() > 0) {
        for (Iterator<NodeFilter> itr = nodeFilters.iterator(); itr.hasNext(); ) {
          NodeFilter nf = itr.next();
          if (!nf.init(hgraph)) {
            itr.remove();
          }
        }
        List<Node> nodesToRemove = new ArrayList<Node>();
        for (Node n : hgraph.getNodes()) {
          for (NodeFilter nf : nodeFilters) {
            if (!nf.evaluate(hgraph, n)) {
              nodesToRemove.add(n);
              break;
            }
          }
        }

        for (Node n : nodesToRemove) {
          hgraph.removeNode(n);
        }

        for (NodeFilter nf : nodeFilters) {
          nf.finish();
        }
      }
      if (edgeFilters.size() > 0) {
        for (Iterator<EdgeFilter> itr = edgeFilters.iterator(); itr.hasNext(); ) {
          EdgeFilter ef = itr.next();
          if (!ef.init(hgraph)) {
            itr.remove();
          }
        }
        List<Edge> edgesToRemove = new ArrayList<Edge>();
        for (Edge e : hgraph.getEdges()) {
          for (EdgeFilter ef : edgeFilters) {
            if (!ef.evaluate(hgraph, e)) {
              edgesToRemove.add(e);
              break;
            }
          }
        }

        for (Edge e : edgesToRemove) {
          hgraph.removeEdge(e);
        }

        for (EdgeFilter ef : edgeFilters) {
          ef.finish();
        }
      }
      return hgraph;
    }