@Override
 protected void parseWays(List<Osmformat.Way> osmWays) {
   if (exception == null) {
     try {
       for (Osmformat.Way w : osmWays) {
         final Info info = w.getInfo();
         if (!info.hasVersion()) discourageUpload = true;
         final Way way = new Way(w.getId(), info.hasVersion() ? info.getVersion() : 1);
         setMetadata(way, info);
         Map<String, String> keys = new HashMap<>();
         for (int i = 0; i < w.getKeysCount(); i++) {
           keys.put(getStringById(w.getKeys(i)), getStringById(w.getVals(i)));
         }
         way.setKeys(keys);
         long previousId = 0; // Node ids are delta coded
         Collection<Long> nodeIds = new ArrayList<>();
         for (Long id : w.getRefsList()) {
           nodeIds.add(previousId += id);
         }
         ways.put(way.getUniqueId(), nodeIds);
         externalIdMap.put(way.getPrimitiveId(), way);
       }
     } catch (IllegalDataException e) {
       exception = e;
     }
   }
 }
 @Override
 protected void parseRelations(List<Osmformat.Relation> osmRels) {
   if (exception == null) {
     try {
       for (Osmformat.Relation r : osmRels) {
         final Info info = r.getInfo();
         if (!info.hasVersion()) discourageUpload = true;
         final Relation rel = new Relation(r.getId(), info.hasVersion() ? info.getVersion() : 1);
         setMetadata(rel, info);
         Map<String, String> keys = new HashMap<>();
         for (int i = 0; i < r.getKeysCount(); i++) {
           keys.put(getStringById(r.getKeys(i)), getStringById(r.getVals(i)));
         }
         rel.setKeys(keys);
         long previousId = 0; // Member ids are delta coded
         Collection<RelationMemberData> members = new ArrayList<>();
         for (int i = 0; i < r.getMemidsCount(); i++) {
           members.add(
               new RelationMemberData(
                   getStringById(r.getRolesSid(i)),
                   mapOsmType(r.getTypes(i)),
                   previousId += r.getMemids(i)));
         }
         relations.put(rel.getUniqueId(), members);
         externalIdMap.put(rel.getPrimitiveId(), rel);
       }
     } catch (IllegalDataException e) {
       exception = e;
     }
   }
   if (discourageUpload) ds.setUploadDiscouraged(true);
 }
 private void setMetadata(OsmPrimitive osm, Info info) throws IllegalDataException {
   if (info.hasChangeset()) {
     checkChangesetId(info.getChangeset());
     osm.setChangesetId((int) info.getChangeset());
   }
   if (info.hasUid() && info.hasUserSid()) {
     osm.setUser(User.createOsmUser(info.getUid(), getStringById(info.getUserSid())));
   }
   if (info.hasTimestamp()) {
     checkTimestamp(info.getTimestamp());
     osm.setTimestamp(getDate(info));
   }
 }
 @Override
 protected void parseNodes(List<Osmformat.Node> osmNodes) {
   if (exception == null) {
     try {
       for (Osmformat.Node n : osmNodes) {
         final Info info = n.getInfo();
         if (!info.hasVersion()) discourageUpload = true;
         final Node node = new Node(n.getId(), info.hasVersion() ? info.getVersion() : 1);
         node.setCoor(
             new LatLon(parseLat(n.getLat()), parseLon(n.getLon())).getRoundedToOsmPrecision());
         checkCoordinates(node.getCoor());
         setMetadata(node, info);
         Map<String, String> keys = new HashMap<>();
         for (int i = 0; i < n.getKeysCount(); i++) {
           keys.put(getStringById(n.getKeys(i)), getStringById(n.getVals(i)));
         }
         node.setKeys(keys);
         externalIdMap.put(node.getPrimitiveId(), node);
       }
     } catch (IllegalDataException e) {
       exception = e;
     }
   }
 }