Tries to merge ways to closed polygons. The ordering of waynodes is preserved during the merge process.

@param ways An array of ways that should be merged. Ways may be given in any order and may already be closed.
543977
void mergePolygons(TDWay[] ways) {
        this.polygons = new ArrayList<>();
        this.dangling = new ArrayList<>();
        this.illegal = new ArrayList<>();

        Deque<TDWay> ungroupedWays = new ArrayDeque<>();

        // initially all ways are ungrouped
        for (TDWay tdWay : ways) {
            // reset reversed flag, may already be set when way is part of another relation
            tdWay.setReversedInRelation(false);

            // first extract all way that are closed polygons in their own right
            if (isClosedPolygon(tdWay)) {
                if (tdWay.getWayNodes().length < MIN_NODES_POLYGON) {
                    this.illegal.add(tdWay);
                } else {
                    Deque<TDWay> cluster = new ArrayDeque<>();
                    cluster.add(tdWay);
                    this.polygons.add(cluster);
                }
            } else {
                ungroupedWays.add(tdWay);
            }
        }

        // all ways have been polygons, nice!
        if (ungroupedWays.isEmpty()) {
            return;
        }

        if (ungroupedWays.size() == 1) {
            this.dangling.add(ungroupedWays.getFirst());
            return;
        }

        boolean startNewPolygon = true;

        while (true) {
            boolean merge = false;
            if (startNewPolygon) {
                // we start a new polygon either during first iteration or when
                // the previous iterations merged ways to a closed polygon and there
                // are still ungrouped ways left
                Deque<TDWay> cluster = new ArrayDeque<>();
                // get the first way of the yet ungrouped ways and form a new group
                cluster.add(ungroupedWays.removeFirst());
                this.polygons.add(cluster);
                startNewPolygon = false;
            }

            // test if we can merge the current polygon with an ungrouped way
            Iterator<TDWay> it = ungroupedWays.iterator();
            while (it.hasNext()) {
                TDWay current = it.next();

                Deque<TDWay> currentPolygonSegments = this.polygons.get(this.polygons.size() - 1);
                // first way in current polygon
                TDWay c1Start = currentPolygonSegments.getFirst();
                // last way in current polygon
                TDWay c1End = currentPolygonSegments.getLast();

                long startFirst = c1Start.isReversedInRelation() ? c1Start.getWayNodes()[c1Start.getWayNodes().length - 1]
                        .getId() : c1Start.getWayNodes()[0].getId();

                long endLast = c1End.isReversedInRelation() ? c1End.getWayNodes()[0].getId()
                        : c1End.getWayNodes()[c1End.getWayNodes().length - 1].getId();

                long currentFirst = current.getWayNodes()[0].getId();
                long currentLast = current.getWayNodes()[current.getWayNodes().length - 1].getId();

                // current way end connects to the start of the current polygon (correct direction)
                if (startFirst == currentLast) {
                    merge = true;
                    it.remove();
                    // add way to start of current polygon
                    currentPolygonSegments.offerFirst(current);
                }
                // // current way start connects to the start of the current polygon (reversed
                // direction)
                else if (startFirst == currentFirst) {
                    current.setReversedInRelation(true);
                    merge = true;
                    it.remove();
                    currentPolygonSegments.offerFirst(current);
                }
                // current way start connects to the end of the current polygon (correct direction)
                else if (endLast == currentFirst) {
                    merge = true;
                    it.remove();
                    // add way to end of current polygon
                    currentPolygonSegments.offerLast(current);
                }
                // // current way end connects to the end of the current polygon (reversed direction)
                else if (endLast == currentLast) {
                    current.setReversedInRelation(true);
                    merge = true;
                    it.remove();
                    // add way to end of current polygon
                    currentPolygonSegments.offerLast(current);
                }
            }

            Deque<TDWay> currentCluster = this.polygons.get(this.polygons.size() - 1);
            boolean closed = isClosedPolygon(currentCluster);
            // not a closed polygon and no more ways to merge
            if (!closed) {
                if (ungroupedWays.isEmpty() || !merge) {
                    this.dangling.addAll(this.polygons.get(this.polygons.size() - 1));
                    // may be a non operation when ungrouped is empty
                    this.dangling.addAll(ungroupedWays);
                    this.polygons.remove(this.polygons.size() - 1);
                    return;
                }
            } else {
                // built a closed polygon and no more ways left --> we are finished
                if (ungroupedWays.isEmpty()) {
                    return;
                }

                startNewPolygon = true;
            }

            // if we are here, the polygon is not yet closed, but there are also some ungrouped ways
            // which may be merge-able in the next iteration
        }
    }
1357638
protected Configurations merge(Configurations other) {
		Set<Class<?>> mergedClasses = new LinkedHashSet<>(getClasses());
		mergedClasses.addAll(other.getClasses());
		return merge(mergedClasses);
	}
601454
@SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public C merge(final C other) {
        return (C) ConfigurationUtils.defaultMerge((ConfigurationComponent) this, (ConfigurationComponent) other);
    }
1296770
Collection<EdgeIteratorState> addOSMWay(final LongIndexedContainer osmNodeIds, final IntsRef flags, final long wayOsmId) {
        PointList pointList = new PointList(osmNodeIds.size(), nodeAccess.is3D());
        List<EdgeIteratorState> newEdges = new ArrayList<>(5);
        int firstNode = -1;
        int lastIndex = osmNodeIds.size() - 1;
        int lastInBoundsPillarNode = -1;
        try {
            for (int i = 0; i < osmNodeIds.size(); i++) {
                long osmNodeId = osmNodeIds.get(i);
                int tmpNode = getNodeMap().get(osmNodeId);
                if (tmpNode == EMPTY_NODE)
                    continue;

                // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds)
                if (tmpNode == TOWER_NODE)
                    continue;

                if (tmpNode == PILLAR_NODE) {
                    // In some cases no node information is saved for the specified osmId.
                    // ie. a way references a <node> which does not exist in the current file.
                    // => if the node before was a pillar node then convert into to tower node (as it is also end-standing).
                    if (!pointList.isEmpty() && lastInBoundsPillarNode > -TOWER_NODE) {
                        // transform the pillar node to a tower node
                        tmpNode = lastInBoundsPillarNode;
                        tmpNode = handlePillarNode(tmpNode, osmNodeId, null, true);
                        tmpNode = -tmpNode - 3;
                        if (pointList.getSize() > 1 && firstNode >= 0) {
                            // TOWER node
                            newEdges.add(addEdge(firstNode, tmpNode, pointList, flags, wayOsmId));
                            pointList.clear();
                            pointList.add(nodeAccess, tmpNode);
                        }
                        firstNode = tmpNode;
                        lastInBoundsPillarNode = -1;
                    }
                    continue;
                }

                if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE)
                    throw new AssertionError("Mapped index not in correct bounds " + tmpNode + ", " + osmNodeId);

                if (tmpNode > -TOWER_NODE) {
                    boolean convertToTowerNode = i == 0 || i == lastIndex;
                    if (!convertToTowerNode) {
                        lastInBoundsPillarNode = tmpNode;
                    }

                    // PILLAR node, but convert to towerNode if end-standing
                    tmpNode = handlePillarNode(tmpNode, osmNodeId, pointList, convertToTowerNode);
                }

                if (tmpNode < TOWER_NODE) {
                    // TOWER node
                    tmpNode = -tmpNode - 3;

                    if (firstNode >= 0 && firstNode == tmpNode) {
                        // loop detected. See #1525 and #1533. Insert last OSM ID as tower node. Do this for all loops so that users can manipulate loops later arbitrarily.
                        long lastOsmNodeId = osmNodeIds.get(i - 1);
                        int lastGHNodeId = getNodeMap().get(lastOsmNodeId);
                        if (lastGHNodeId < TOWER_NODE) {
                            LOGGER.warn("Pillar node " + lastOsmNodeId + " is already a tower node and used in loop, see #1533. " +
                                    "Fix mapping for way " + wayOsmId + ", nodes:" + osmNodeIds);
                            break;
                        }

                        int newEndNode = -handlePillarNode(lastGHNodeId, lastOsmNodeId, pointList, true) - 3;
                        newEdges.add(addEdge(firstNode, newEndNode, pointList, flags, wayOsmId));
                        pointList.clear();
                        pointList.add(nodeAccess, newEndNode);
                        firstNode = newEndNode;
                    }

                    pointList.add(nodeAccess, tmpNode);
                    if (firstNode >= 0) {
                        newEdges.add(addEdge(firstNode, tmpNode, pointList, flags, wayOsmId));
                        pointList.clear();
                        pointList.add(nodeAccess, tmpNode);
                    }
                    firstNode = tmpNode;
                }
            }
        } catch (RuntimeException ex) {
            LOGGER.error("Couldn't properly add edge with osm ids:" + osmNodeIds, ex);
            if (exitOnlyPillarNodeException)
                throw ex;
        }
        return newEdges;
    }
217922
public static Coordinate[] removeDuplicatedCoordinates(Coordinate[] coords, boolean closeRing) {
        LinkedHashSet<Coordinate> finalCoords = new LinkedHashSet<Coordinate>();
        Coordinate prevCoord = coords[0];
        finalCoords.add(prevCoord);
        Coordinate firstCoord = prevCoord;
        int nbCoords = coords.length;
        for (int i = 1; i < nbCoords; i++) {
            Coordinate currentCoord = coords[i];
            if (currentCoord.equals2D(prevCoord)) {
                continue;
            }
            finalCoords.add(currentCoord);
            prevCoord = currentCoord;
        }
        if (closeRing) {
            Coordinate[] coordsFinal = finalCoords.toArray(new Coordinate[0]);
            Coordinate[] closedCoords = Arrays.copyOf(coordsFinal, coordsFinal.length + 1);
            closedCoords[closedCoords.length-1] = firstCoord;
            return closedCoords;
        }
        return finalCoords.toArray(new Coordinate[0]);

    }
870045
void mergeContiguousRegions( Collection<AbstractBlock> blocks ) {

		AbstractIgnorableInstruction initialInstr = null;
		List<AbstractBlock> toRemove = new ArrayList<> ();
		StringBuilder sb = new StringBuilder();

		// We only merge comments and blank regions to reduce their number
		for( AbstractBlock block : blocks ) {
			if( initialInstr == null ) {

				if( block.getInstructionType() == AbstractBlock.COMMENT
						|| block.getInstructionType() == AbstractBlock.BLANK ) {

					AbstractIgnorableInstruction currentInstr = (AbstractIgnorableInstruction) block;
					initialInstr = currentInstr;
					sb = new StringBuilder( currentInstr.getContent());
				}

			} else if( initialInstr.getInstructionType() == block.getInstructionType()) {
				toRemove.add( block );
				sb.append( System.getProperty( "line.separator" ));
				sb.append(((AbstractIgnorableInstruction) block).getContent());

			} else {
				initialInstr.setContent( sb.toString());
				initialInstr = null;
			}
		}

		// Remove the blocks that have been merged
		blocks.removeAll( toRemove );

		// In a second time, we can reduce facets and components too
		for( AbstractBlock block : blocks ) {
			if( block.getInstructionType() == AbstractBlock.COMPONENT
					|| block.getInstructionType() == AbstractBlock.FACET )
				mergeContiguousRegions(((AbstractBlockHolder) block).getInnerBlocks());
		}
	}
89424
public boolean hasDeadlock(List<? extends PlanNode> sinks) {
		this.g = new DeadlockGraph();
		
		for(PlanNode s : sinks) {
			s.accept(this);
		}
		
		if(g.hasCycle()) {
			return true;
		} else {
			return false;
		}
	}
1368527
public static <E extends Comparable<E>> void sortDescending(E[] intArray) {
        Merge.sort(intArray, 0, intArray.length-1, true);
    }
359075
public List<Way> getWays(Collection<Long> wayIds)
	{
		if(wayIds.isEmpty()) return Collections.emptyList();
		return getSomeElements(WAY + "s?" + WAY + "s=" + toCommaList(wayIds), Way.class);
	}
1146252
@MapMethod
    public Map<String,Object> merge(List<Map<String,Object>> args){
        return Objects.merge(args);
    }
764539
public void setGeometries(List<Geometry> geometries) {
        this.mGeometries.clear();
        if (geometries != null) {
            this.mGeometries.addAll(geometries);
        }
    }
564824
public final void merge(final Properties properties) {
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            setProperty(entry.getKey().toString(), entry.getValue().toString());
        }
    }
183889
private void checkMergeBtnEnabledState() {
		FeaturesSupported layer = (FeaturesSupported) mapPresenter.getLayersModel().getLayer(1);
		mergeBtn.setEnabled(layer.getSelectedFeatures() != null && layer.getSelectedFeatures().size() > 1);
	}
29697
public void merge(VersionRows other) {
		conceptRows.addAll(other.conceptRows);
		relationshipRows.addAll(other.relationshipRows);
		concreteDomainRows.addAll(other.getConcreteDomainRows());
                attributeDomainRows.addAll(other.getAttributeDomainRows());
		owlRows.addAll(other.getConcreteDomainRows());
	}
1001381
private void merge(final GeometryFunction callback) {
		GeometryOperationService operationService = new GeometryOperationServiceImpl();
		UnionInfo unionInfo = new UnionInfo();
		unionInfo.setUsePrecisionAsBuffer(true);
		unionInfo.setPrecision(precision);
		operationService.union(geometries, unionInfo, new Callback<Geometry, Throwable>() {

			public void onSuccess(Geometry result) {
				callback.execute(result);
			}

			public void onFailure(Throwable reason) {
				reason.printStackTrace();
			}
		});
	}
56844
private void mergeDocs(Hints hints) {
        if (docs != null) {
            if (hints.getDocs() != null && !docs.equals(hints.getDocs())) {
                throw SeedException.createNew(RestErrorCode.CANNOT_MERGE_RESOURCES_WITH_DIFFERENT_DOC)
                        .put("oldDoc", docs).put("newDoc", hints.getDocs());
            }
        } else {
            this.docs = hints.getDocs();
        }
    }
13645
public void merge(Resource resource) {
        if (resource == null) {
            return;
        }

        checkRel(resource);
        checkHrefs(resource);

        if (resource.templated()) {
            this.pathParams.putAll(resource.pathParams);
            this.queryParams.putAll(resource.queryParams);
        }
        if (resource.hints() != null) {
            this.hints.merge(resource.hints());
        }
    }