/**
   * their way has a higher version and different nodes. My way is modified.
   *
   * <p>=> merge onto my way not possible, create a conflict
   */
  @Test
  public void waySimple_DifferentNodesAndMyIsModified() {

    // -- the target dataset

    Node n1 = new Node(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    my.addPrimitive(n1);

    Node n2 = new Node(new LatLon(1, 1));
    n2.setOsmId(2, 1);
    my.addPrimitive(n2);

    Way myWay = new Way();
    myWay.setOsmId(3, 1);

    myWay.addNode(n1);
    myWay.addNode(n2);
    myWay.setModified(true);
    myWay.put("key1", "value1");
    my.addPrimitive(myWay);

    // -- the source dataset

    Node n3 = new Node(new LatLon(0, 0));
    n3.setOsmId(1, 1);
    their.addPrimitive(n3);

    Node n5 = new Node(new LatLon(1, 1));
    n5.setOsmId(4, 1);
    their.addPrimitive(n5);

    Node n4 = new Node(new LatLon(2, 2));
    n4.setOsmId(2, 1);
    n4.put("key1", "value1");
    their.addPrimitive(n4);

    Way theirWay = new Way();
    theirWay.setOsmId(3, 2);

    theirWay.addNode(n3);
    theirWay.addNode(n5); // insert a node
    theirWay.addNode(n4); // this one is updated
    their.addPrimitive(theirWay);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY);
    assertEquals(1, visitor.getConflicts().size());
    assertEquals(3, merged.getId());
    assertEquals(1, merged.getVersion());
    assertEquals(2, merged.getNodesCount());
    assertEquals(1, merged.getNode(0).getId());
    assertEquals(2, merged.getNode(1).getId());
    assertEquals("value1", merged.get("key1"));
  }
 protected static void populateTestDataSetWithWays(DataSet ds) {
   for (int i = 0; i < 20; i++) {
     Way w = new Way();
     for (int j = 0; j < 10; j++) {
       w.addNode(lookupNode(ds, i + j));
     }
     w.put("name", "way-" + i);
     ds.addPrimitive(w);
   }
 }
  /**
   * builds a large data set to be used later for testing MULTI FETCH on the server
   *
   * @return a large data set
   */
  protected static DataSet buildTestDataSet() {
    DataSet ds = new DataSet();
    ds.setVersion("0.6");

    int numNodes = 1000;
    int numWays = 1000;
    int numRelations = 1000;

    ArrayList<Node> nodes = new ArrayList<>();
    ArrayList<Way> ways = new ArrayList<>();

    // create a set of nodes
    //
    for (int i = 0; i < numNodes; i++) {
      Node n = new Node();
      n.setCoor(new LatLon(-36.6, 47.6));
      n.put("name", "node-" + i);
      ds.addPrimitive(n);
      nodes.add(n);
    }

    // create a set of ways, each with a random number of nodes
    //
    for (int i = 0; i < numWays; i++) {
      Way w = new Way();
      int numNodesInWay = 2 + (int) Math.round(Math.random() * 5);
      int start = (int) Math.round(Math.random() * numNodes);
      for (int j = 0; j < numNodesInWay; j++) {
        int idx = (start + j) % numNodes;
        Node n = nodes.get(idx);
        w.addNode(n);
      }
      w.put("name", "way-" + i);
      ds.addPrimitive(w);
      ways.add(w);
    }

    // create a set of relations each with a random number of nodes, and ways
    //
    for (int i = 0; i < numRelations; i++) {
      Relation r = new Relation();
      r.put("name", "relation-" + i);
      int numNodesInRelation = (int) Math.round(Math.random() * 10);
      int start = (int) Math.round(Math.random() * numNodes);
      for (int j = 0; j < numNodesInRelation; j++) {
        int idx = (start + j) % 500;
        Node n = nodes.get(idx);
        r.addMember(new RelationMember("role-" + j, n));
      }
      int numWaysInRelation = (int) Math.round(Math.random() * 10);
      start = (int) Math.round(Math.random() * numWays);
      for (int j = 0; j < numWaysInRelation; j++) {
        int idx = (start + j) % 500;
        Way w = ways.get(idx);
        r.addMember(new RelationMember("role-" + j, w));
      }
      ds.addPrimitive(r);
    }

    return ds;
  }
  /**
   * their way has a higher version and different tags. the nodes are the same. My way is not
   * modified. Merge is possible. No conflict.
   *
   * <p>=> merge it onto my way.
   */
  @Test
  public void waySimple_IdenicalNodesDifferentTags() {

    // -- the target dataset

    Node n1 = new Node();
    n1.setCoor(new LatLon(0, 0));
    n1.setOsmId(1, 1);
    my.addPrimitive(n1);

    Node n2 = new Node();
    n2.setCoor(new LatLon(0, 0));
    n2.setOsmId(2, 1);

    my.addPrimitive(n2);

    Way myWay = new Way();
    myWay.setOsmId(3, 1);
    myWay.put("key1", "value1");
    myWay.addNode(n1);
    myWay.addNode(n2);
    my.addPrimitive(myWay);

    // -- the source data set

    Node n3 = new Node(new LatLon(0, 0));
    n3.setOsmId(1, 1);
    their.addPrimitive(n3);

    Node n4 = new Node(new LatLon(1, 1));
    n4.setOsmId(2, 1);
    their.addPrimitive(n4);

    Way theirWay = new Way();
    theirWay.setOsmId(3, 2);
    theirWay.put("key1", "value1");
    theirWay.put("key2", "value2");
    theirWay.addNode(n3);
    theirWay.addNode(n4);
    their.addPrimitive(theirWay);

    DataSetMerger visitor = new DataSetMerger(my, their);
    visitor.merge();

    // -- tests
    Way merged = (Way) my.getPrimitiveById(3, OsmPrimitiveType.WAY);
    assertEquals(0, visitor.getConflicts().size());
    assertEquals("value1", merged.get("key1"));
    assertEquals("value2", merged.get("key2"));
    assertEquals(3, merged.getId());
    assertEquals(2, merged.getVersion());
    assertEquals(2, merged.getNodesCount());
    assertEquals(1, merged.getNode(0).getId());
    assertEquals(2, merged.getNode(1).getId());
    assertSame(merged, myWay);
    assertSame(merged.getDataSet(), my);

    Node mergedNode = (Node) my.getPrimitiveById(1, OsmPrimitiveType.NODE);
    assertSame(mergedNode, n1);
    mergedNode = (Node) my.getPrimitiveById(2, OsmPrimitiveType.NODE);
    assertSame(mergedNode, n2);

    assertFalse(merged.isModified());
  }