/**
   * Sets the Agent up to proceed along an Edge
   *
   * @param edge the GeomPlanarGraphEdge to traverse next
   */
  void setupEdge(GeomPlanarGraphEdge edge) {

    // clean up on old edge
    if (currentEdge != null) {
      ArrayList<AgentCopy> traffic = world.edgeTraffic.get(currentEdge);
      traffic.remove(this);
    }
    currentEdge = edge;

    // update new edge traffic
    if (world.edgeTraffic.get(currentEdge) == null) {
      world.edgeTraffic.put(currentEdge, new ArrayList<AgentCopy>());
    }
    world.edgeTraffic.get(currentEdge).add(this);

    // set up the new segment and index info
    LineString line = edge.getLine();
    segment = new LengthIndexedLine(line);
    startIndex = segment.getStartIndex();
    endIndex = segment.getEndIndex();
    linkDirection = 1;

    // check to ensure that Agent is moving in the right direction
    double distanceToStart = line.getStartPoint().distance(location.geometry),
        distanceToEnd = line.getEndPoint().distance(location.geometry);
    if (distanceToStart <= distanceToEnd) { // closer to start
      currentIndex = startIndex;
      linkDirection = 1;
    } else if (distanceToEnd < distanceToStart) { // closer to end
      currentIndex = endIndex;
      linkDirection = -1;
    }
  }
  private static List<SimpleFeature> processEdges(
      List<String> unvisited,
      Node startNode,
      GeometryFactory geometryFactory,
      SimpleFeatureType featureType,
      long startTime,
      int pathID,
      List<SimpleFeature> featuresList,
      double stepTime,
      int maxTime,
      int intersectionWait,
      int stepDistance) {

    LineString line;
    Node currentNode = startNode;
    int crossings = 0;
    int walkDistance = 0;
    long walkTime = startTime;
    while ((unvisited.size() > 0) && (walkTime <= maxTime)) {
      if (currentNode.getEdges().size() > 0) {
        int crossingWait = 0;
        if (currentNode.getEdges().size() > 2) {
          // This is an intersection - therefore delay for crossing
          crossingWait = intersectionWait;
          crossings++;
        }
        for (Edge edge : (List<Edge>) currentNode.getEdges()) {
          if (unvisited.contains(String.valueOf(edge.getID()))) {
            line = (LineString) edge.getObject();

            Coordinate pt = ((Point) currentNode.getObject()).getCoordinate();

            LengthIndexedLine lil = new LengthIndexedLine(line);

            if (lil.project(pt) == lil.getStartIndex()) {
              // start coordinate is at start of line
              for (int index = 0; index < lil.getEndIndex(); index += stepDistance) {
                Coordinate coordinate = lil.extractPoint(index);
                Point point = geometryFactory.createPoint(coordinate);
                SimpleFeature feature =
                    buildTimeFeatureFromGeometry(
                        featureType,
                        point,
                        walkTime,
                        crossings,
                        walkDistance,
                        String.valueOf(pathID));
                walkDistance += stepDistance;
                walkTime += stepTime + crossingWait;
                crossingWait = 0; // only perform wait once
                featuresList.add(feature);
              }
            } else if (lil.project(pt) == lil.getEndIndex()) {
              // start coordinate is at the end of the line
              for (int index = (int) lil.getEndIndex(); index >= 0; index -= stepDistance) {
                Coordinate coordinate = lil.extractPoint(index);
                Point point = geometryFactory.createPoint(coordinate);
                SimpleFeature feature =
                    buildTimeFeatureFromGeometry(
                        featureType,
                        point,
                        walkTime,
                        crossings,
                        walkDistance,
                        String.valueOf(pathID));
                walkDistance += stepDistance;
                walkTime += stepTime + crossingWait;
                crossingWait = 0; // only perform wait once
                featuresList.add(feature);
              }
            } else {
              LOGGER.error("Start coordinate did not match with Index!");
            }
            unvisited.remove(String.valueOf(edge.getID()));

            Node nextNode = edge.getOtherNode(currentNode);
            if (nextNode != null) {
              currentNode = nextNode;
            } else {
              break;
            }
          }
        }
      }
    }
    return featuresList;
  }