@Override
  public boolean evaluate(Graph graph, Edge edge) {
    DirectedGraph directedGraph = (DirectedGraph) graph;

    // Make sure the edge is not  self loop
    if (!edge.isSelfLoop()) {
      // Get the potential mutual edge
      Edge mutualEdge = directedGraph.getEdge(edge.getTarget(), edge.getSource());

      // Remove the mutual edge if exists
      // Make sure only one of the two mutual edges will bre removed
      if (mutualEdge != null && mutualEdge.getId() < edge.getId()) {
        return false;
      }
    }
    return true;
  }
  private void writeEdges(XMLStreamWriter xmlWriter, HierarchicalGraph graph) throws Exception {
    if (cancel) {
      return;
    }
    xmlWriter.writeStartElement(EDGES);

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

    EdgeIterable edgeIterable =
        exportHierarchy ? graph.getEdgesTree() : graph.getEdgesAndMetaEdges();
    for (Edge edge : edgeIterable) {
      xmlWriter.writeStartElement(EDGE);

      if (edge.getEdgeData().getId() != null
          && !edge.getEdgeData().getId().equals(Integer.toString(edge.getId()))) {
        xmlWriter.writeAttribute(EDGE_ID, edge.getEdgeData().getId());
      }
      xmlWriter.writeAttribute(EDGE_SOURCE, edge.getSource().getNodeData().getId());
      xmlWriter.writeAttribute(EDGE_TARGET, edge.getTarget().getNodeData().getId());

      if (edge.isDirected() && graphModel.isMixed()) {
        xmlWriter.writeAttribute(EDGE_TYPE, "directed");
      } else if (!edge.isDirected() && graphModel.isMixed()) {
        xmlWriter.writeAttribute(EDGE_TYPE, "undirected");
      }

      String label = edge.getEdgeData().getLabel();
      if (label != null && !label.isEmpty()) {
        xmlWriter.writeAttribute(EDGE_LABEL, label);
      }

      float weight = edge.getWeight();
      if (weight != 1f) {
        xmlWriter.writeAttribute(EDGE_WEIGHT, "" + weight);
      }

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

      if (exportColors) {
        writeEdgeColor(xmlWriter, edge);
      }

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

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

    xmlWriter.writeEndElement();
  }