/** Builds the set of paths between all the couple of vertexes */
  private void buildPaths() {

    logger.debug("IN");

    allGraphPaths = new HashSet<GraphPath<IModelEntity, Relationship>>();
    paths = new HashSet<EntitiesPath>();

    // build all the path between entities
    Iterator<IModelEntity> vertexesIter = entities.iterator();

    // First loop for the source of the path
    while (vertexesIter.hasNext()) {
      IModelEntity startVertex = vertexesIter.next();
      logger.debug("Building the list of path starting from " + startVertex.getName());
      // inner loop for the target of the path
      Iterator<IModelEntity> vertexesInnerIter = entities.iterator();
      while (vertexesInnerIter.hasNext()) {
        IModelEntity endVertex = vertexesInnerIter.next();
        if (!startVertex.equals(endVertex)) {
          EntitiesPath entitiesPath = new EntitiesPath(startVertex, endVertex);
          if (!this.paths.contains(entitiesPath)) {
            logger.debug(
                "Building the list of path between the vertexes ["
                    + startVertex.getName()
                    + ","
                    + endVertex.getName()
                    + "]");
            KShortestPaths<IModelEntity, Relationship> kshortestPath =
                new KShortestPaths<IModelEntity, Relationship>(graph, startVertex, maxPathLength);
            List<GraphPath<IModelEntity, Relationship>> graphPaths =
                kshortestPath.getPaths(endVertex);

            // if there is at least one path between the 2 vertex
            if (graphPaths != null) {
              entitiesPath.setPaths(graphPaths);

              // updating the class variables
              this.paths.add(entitiesPath);
              for (int i = 0; i < graphPaths.size(); i++) {
                GraphPath<IModelEntity, Relationship> path = graphPaths.get(i);
                if (!containsPath(this.allGraphPaths, path)) {
                  this.allGraphPaths.add(path);
                }
              }
            }
          }
        }
      }
    }
    logger.debug("OUT");
  }
  /**
   * gets the ambiguous paths: we have an ambiguous path where there is more than one path that
   * connects two entities.
   *
   * @return the ambiguous paths. If there is no ambiguous path the set is empty
   */
  private Set<EntitiesPath> getAmbiguousEntitiesPaths() {
    logger.debug("IN: finding the ambiguous paths");
    Set<EntitiesPath> ambiguouPaths = new HashSet<EntitiesPath>();
    if (paths != null) {
      logger.debug("Checking if there is more than one path between all the connected entities");
      Iterator<EntitiesPath> iter = paths.iterator();

      while (iter.hasNext()) {
        EntitiesPath path = iter.next();
        if (path.getPaths() != null && path.getPaths().size() > 1) {
          ambiguouPaths.add(path);
        }
      }
    }
    logger.debug("OUT");
    return ambiguouPaths;
  }
  /**
   * Gets the map where the key are ambiguous Entities and the values are all the paths that pass
   * through the ambiguous entities
   *
   * @return
   */
  public Map<IModelEntity, Set<GraphPath<IModelEntity, Relationship>>>
      getAmbiguousEntitiesAllPathsMap() {
    logger.debug("IN");
    Map<IModelEntity, Set<GraphPath<IModelEntity, Relationship>>> ambiguouPathsMap =
        new HashMap<IModelEntity, Set<GraphPath<IModelEntity, Relationship>>>();
    Set<EntitiesPath> ambiguouPaths = getAmbiguousEntitiesPaths();
    if (ambiguouPaths != null) {
      Iterator<EntitiesPath> iter = ambiguouPaths.iterator();

      // add the paths to the ambiguous path map
      while (iter.hasNext()) {
        EntitiesPath entitiesPath = iter.next();
        Set<GraphPath<IModelEntity, Relationship>> pathsInvolvingStartEntity;
        if (!ambiguouPathsMap.containsKey(entitiesPath.getEndPoints().get(0))) {
          pathsInvolvingStartEntity =
              getPathsOfAmbigousEntities(entitiesPath.getEndPoints().get(0));
          ambiguouPathsMap.put(entitiesPath.getEndPoints().get(0), pathsInvolvingStartEntity);
        }

        Set<GraphPath<IModelEntity, Relationship>> pathsInvolvingEndEntity;
        if (!ambiguouPathsMap.containsKey(entitiesPath.getEndPoints().get(1))) {
          pathsInvolvingEndEntity = getPathsOfAmbigousEntities(entitiesPath.getEndPoints().get(1));
          ambiguouPathsMap.put(entitiesPath.getEndPoints().get(1), pathsInvolvingEndEntity);
        }
      }
    }
    logger.debug("OUT");
    return ambiguouPathsMap;
  }