public boolean containsLatitude(Graph g, EdgeIterator iter, double latitude) {
   NodeAccess na = g.getNodeAccess();
   while (iter.next()) {
     if (Math.abs(na.getLatitude(iter.getAdjNode()) - latitude) < 1e-4) return true;
   }
   return false;
 }
  @Test
  public void testFlags() {
    graph = createGraph();
    graph.edge(0, 1).setDistance(10).setFlags(carEncoder.setProperties(100, true, true));
    graph.edge(2, 3).setDistance(10).setFlags(carEncoder.setProperties(10, true, false));

    EdgeIterator iter = carAllExplorer.setBaseNode(0);
    assertTrue(iter.next());
    assertEquals(carEncoder.setProperties(100, true, true), iter.getFlags());

    iter = carAllExplorer.setBaseNode(2);
    assertTrue(iter.next());
    assertEquals(carEncoder.setProperties(10, true, false), iter.getFlags());

    try {
      graph.edge(0, 1).setDistance(-1);
      assertTrue(false);
    } catch (IllegalArgumentException ex) {
    }
  }
  @Test
  public void testCreateDuplicateEdges() {
    graph = createGraph();
    graph.edge(2, 1, 12, true);
    graph.edge(2, 3, 12, true);
    graph.edge(2, 3, 13, false);
    assertEquals(3, GHUtility.count(carOutExplorer.setBaseNode(2)));

    // no exception
    graph.getEdgeProps(1, 3);

    // raise exception
    try {
      graph.getEdgeProps(4, 3);
      assertTrue(false);
    } catch (Exception ex) {
    }
    try {
      graph.getEdgeProps(-1, 3);
      assertTrue(false);
    } catch (Exception ex) {
    }

    EdgeIterator iter = carOutExplorer.setBaseNode(2);
    assertTrue(iter.next());
    EdgeIteratorState oneIter = graph.getEdgeProps(iter.getEdge(), 3);
    assertEquals(13, oneIter.getDistance(), 1e-6);
    assertEquals(2, oneIter.getBaseNode());
    assertTrue(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_FORWARD));
    assertFalse(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_BACKWARD));

    oneIter = graph.getEdgeProps(iter.getEdge(), 2);
    assertEquals(13, oneIter.getDistance(), 1e-6);
    assertEquals(3, oneIter.getBaseNode());
    assertFalse(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_FORWARD));
    assertTrue(carEncoder.isBool(oneIter.getFlags(), FlagEncoder.K_BACKWARD));

    graph.edge(3, 2, 14, true);
    assertEquals(4, GHUtility.count(carOutExplorer.setBaseNode(2)));
  }
  @Test
  public void testUpdateUnidirectional() {
    graph = createGraph();

    graph.edge(1, 2, 12, false);
    graph.edge(3, 2, 112, false);
    EdgeIterator i = carOutExplorer.setBaseNode(2);
    assertFalse(i.next());
    i = carOutExplorer.setBaseNode(3);
    assertTrue(i.next());
    assertEquals(2, i.getAdjNode());
    assertFalse(i.next());

    graph.edge(2, 3, 112, false);
    i = carOutExplorer.setBaseNode(2);
    assertTrue(i.next());
    assertEquals(3, i.getAdjNode());
    i = carOutExplorer.setBaseNode(3);
    i.next();
    assertEquals(2, i.getAdjNode());
    assertFalse(i.next());
  }
  @Test
  public void testSimpleDelete2() {
    graph = createGraph();
    NodeAccess na = graph.getNodeAccess();
    assertEquals(-1, getIdOf(graph, 12));
    na.setNode(9, 9, 1);
    assertEquals(-1, getIdOf(graph, 12));

    na.setNode(11, 11, 1);
    na.setNode(12, 12, 1);

    // mini subnetwork which gets completely removed:
    graph.edge(5, 10, 510, true);
    graph.markNodeRemoved(5);
    graph.markNodeRemoved(10);

    PointList pl = new PointList();
    pl.add(1, 2, Double.NaN);
    pl.add(1, 3, Double.NaN);
    graph.edge(9, 11, 911, true).setWayGeometry(pl);
    graph.edge(9, 12, 912, true).setWayGeometry(pl);

    assertEquals(13, graph.getNodes());
    assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph));

    // perform deletion
    graph.optimize();

    assertEquals(11, graph.getNodes());
    assertEquals(Arrays.<String>asList(), GHUtility.getProblems(graph));

    int id11 = getIdOf(graph, 11); // is now 10
    int id12 = getIdOf(graph, 12); // is now 5
    int id9 = getIdOf(graph, 9); // is now 9
    assertEquals(
        GHUtility.asSet(id12, id11), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id9)));
    assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id11)));
    assertEquals(GHUtility.asSet(id9), GHUtility.getNeighbors(carAllExplorer.setBaseNode(id12)));

    EdgeIterator iter = carAllExplorer.setBaseNode(id9);
    assertTrue(iter.next());
    assertEquals(id12, iter.getAdjNode());
    assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7);

    assertTrue(iter.next());
    assertEquals(id11, iter.getAdjNode());
    assertEquals(2, iter.fetchWayGeometry(0).getLongitude(0), 1e-7);
  }
  @Test
  public void testGetAllEdges() {
    graph = createGraph();
    graph.edge(0, 1, 2, true);
    graph.edge(3, 1, 1, false);
    graph.edge(3, 2, 1, false);

    EdgeIterator iter = graph.getAllEdges();
    assertTrue(iter.next());
    int edgeId = iter.getEdge();
    assertEquals(0, iter.getBaseNode());
    assertEquals(1, iter.getAdjNode());
    assertEquals(2, iter.getDistance(), 1e-6);

    assertTrue(iter.next());
    int edgeId2 = iter.getEdge();
    assertEquals(1, edgeId2 - edgeId);
    assertEquals(1, iter.getBaseNode());
    assertEquals(3, iter.getAdjNode());

    assertTrue(iter.next());
    assertEquals(2, iter.getBaseNode());
    assertEquals(3, iter.getAdjNode());

    assertFalse(iter.next());
  }
  @Test
  public void testPillarNodes() {
    graph = createGraph();
    NodeAccess na = graph.getNodeAccess();
    na.setNode(0, 0.01, 0.01);
    na.setNode(4, 0.4, 0.4);
    na.setNode(14, 0.14, 0.14);
    na.setNode(10, 0.99, 0.99);

    PointList pointList = Helper.createPointList(1, 1, 1, 2, 1, 3);
    graph
        .edge(0, 4)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);
    pointList = Helper.createPointList(1, 5, 1, 6, 1, 7, 1, 8, 1, 9);
    graph
        .edge(4, 10)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);
    pointList = Helper.createPointList(1, 13, 1, 12, 1, 11);
    graph
        .edge(14, 0)
        .setDistance(100)
        .setFlags(carEncoder.setProperties(10, true, false))
        .setWayGeometry(pointList);

    EdgeIterator iter = carAllExplorer.setBaseNode(0);
    assertTrue(iter.next());
    assertEquals(14, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 11, 1, 12, 1, 13.0), iter.fetchWayGeometry(0));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 11, 1, 12, 1, 13.0), iter.fetchWayGeometry(1));
    assertPList(
        Helper.createPointList(1, 11, 1, 12, 1, 13.0, 0.14, 0.14), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 11, 1, 12, 1, 13.0, 0.14, 0.14),
        iter.fetchWayGeometry(3));

    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(0));
    assertPList(Helper.createPointList(0.01, 0.01, 1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(1));
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3, 0.4, 0.4), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.01, 0.01, 1, 1, 1, 2, 1, 3, 0.4, 0.4), iter.fetchWayGeometry(3));

    assertFalse(iter.next());

    iter = carOutExplorer.setBaseNode(0);
    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 1, 1, 2, 1, 3), iter.fetchWayGeometry(0));
    assertFalse(iter.next());

    iter = carInExplorer.setBaseNode(10);
    assertTrue(iter.next());
    assertEquals(4, iter.getAdjNode());
    assertPList(Helper.createPointList(1, 9, 1, 8, 1, 7, 1, 6, 1, 5), iter.fetchWayGeometry(0));
    assertPList(
        Helper.createPointList(0.99, 0.99, 1, 9, 1, 8, 1, 7, 1, 6, 1, 5), iter.fetchWayGeometry(1));
    assertPList(
        Helper.createPointList(1, 9, 1, 8, 1, 7, 1, 6, 1, 5, 0.4, 0.4), iter.fetchWayGeometry(2));
    assertPList(
        Helper.createPointList(0.99, 0.99, 1, 9, 1, 8, 1, 7, 1, 6, 1, 5, 0.4, 0.4),
        iter.fetchWayGeometry(3));
    assertFalse(iter.next());
  }
  @Test
  public void testUnidirectionalEdgeFilter() {
    graph = createGraph();

    graph.edge(1, 2, 12, false);
    graph.edge(1, 11, 12, false);
    graph.edge(11, 1, 12, false);
    graph.edge(1, 12, 12, false);
    graph.edge(3, 2, 112, false);
    EdgeIterator i = carOutExplorer.setBaseNode(2);
    assertFalse(i.next());

    assertEquals(4, GHUtility.count(carAllExplorer.setBaseNode(1)));

    assertEquals(1, GHUtility.count(carInExplorer.setBaseNode(1)));
    assertEquals(2, GHUtility.count(carInExplorer.setBaseNode(2)));
    assertEquals(0, GHUtility.count(carInExplorer.setBaseNode(3)));

    assertEquals(3, GHUtility.count(carOutExplorer.setBaseNode(1)));
    assertEquals(0, GHUtility.count(carOutExplorer.setBaseNode(2)));
    assertEquals(1, GHUtility.count(carOutExplorer.setBaseNode(3)));
    i = carOutExplorer.setBaseNode(3);
    i.next();
    assertEquals(2, i.getAdjNode());

    i = carOutExplorer.setBaseNode(1);
    assertTrue(i.next());
    assertEquals(12, i.getAdjNode());
    assertTrue(i.next());
    assertEquals(11, i.getAdjNode());
    assertTrue(i.next());
    assertEquals(2, i.getAdjNode());
    assertFalse(i.next());
  }
  @Test
  public void testDetachEdge() {
    graph = createGraph();
    graph.edge(0, 1, 2, true);
    long flags = carEncoder.setProperties(10, true, false);
    graph.edge(0, 2, 2, true).setWayGeometry(Helper.createPointList(1, 2, 3, 4)).setFlags(flags);
    graph.edge(1, 2, 2, true);

    EdgeIterator iter = graph.createEdgeExplorer().setBaseNode(0);
    try {
      // currently not possible to detach without next, without introducing a new property inside
      // EdgeIterable
      iter.detach(false);
      assertTrue(false);
    } catch (Exception ex) {
    }

    iter.next();
    EdgeIteratorState edgeState2 = iter.detach(false);
    assertEquals(2, iter.getAdjNode());
    assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertEquals(2, edgeState2.getAdjNode());
    assertTrue(carEncoder.isBool(edgeState2.getFlags(), FlagEncoder.K_FORWARD));

    EdgeIteratorState edgeState3 = iter.detach(true);
    assertEquals(0, edgeState3.getAdjNode());
    assertEquals(2, edgeState3.getBaseNode());
    assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertFalse(carEncoder.isBool(edgeState3.getFlags(), FlagEncoder.K_FORWARD));
    assertEquals(GHUtility.getEdge(graph, 0, 2).getFlags(), edgeState2.getFlags());
    assertEquals(GHUtility.getEdge(graph, 2, 0).getFlags(), edgeState3.getFlags());

    iter.next();
    assertEquals(1, iter.getAdjNode());
    assertEquals(2, edgeState2.getAdjNode());
    assertEquals(2, edgeState3.getBaseNode());

    assertEquals(0, iter.fetchWayGeometry(0).size());
    assertEquals(1, edgeState2.fetchWayGeometry(0).getLatitude(0), 1e-1);
    assertEquals(3, edgeState3.fetchWayGeometry(0).getLatitude(0), 1e-1);

    // #162 a directed self referencing edge should be able to reverse its state too
    graph.edge(3, 3, 2, true).setFlags(flags);
    EdgeIterator iter2 = graph.createEdgeExplorer().setBaseNode(3);
    iter2.next();
    assertEquals(edgeState2.getFlags(), iter2.detach(false).getFlags());
    assertEquals(edgeState3.getFlags(), iter2.detach(true).getFlags());
  }