Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java	(revision 26843)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/SplittingMultipolygons.java	(revision 26844)
@@ -55,4 +55,5 @@
     
     public static List<Relation> process( Collection<Way> selectedWays, List<Command> commands ) {
+	System.out.println("---------------------------------------");
 	List<Relation> result = new ArrayList<Relation>();
 	List<Way> rings = new ArrayList<Way>();
@@ -279,11 +280,55 @@
     
     /**
-     * Find a way the tips of a segment, ensure it's in a multipolygon and try to close the relation.
-     */
-    public static Relation attachRingToNeighbours( Way segment, List<Command> resultingCommands ) {
-	if( !segment.isClosed() || segment.isIncomplete() )
+     * Make a multipolygon out of the ring, but split it to attach to neighboring multipolygons.
+     */
+    public static Relation attachRingToNeighbours( Way ring, List<Command> resultingCommands ) {
+	if( !ring.isClosed() || ring.isIncomplete() )
 	    return null;
-	
-	return null; // todo
+	Map<Way, Boolean> touchingWays = new HashMap<Way, Boolean>();
+	for( Node n : ring.getNodes() ) {
+	    for( OsmPrimitive p : n.getReferrers() ) {
+		if( p instanceof Way && !p.equals(ring) ) {
+		    for( OsmPrimitive r : p.getReferrers() ) {
+			if( r instanceof Relation && ((Relation)r).hasKey("type") && ((Relation)r).get("type").equals("multipolygon") ) {
+			    if( touchingWays.containsKey((Way)p) )
+				touchingWays.put((Way)p, Boolean.TRUE);
+			    else
+				touchingWays.put((Way)p, Boolean.FALSE);
+			    break;
+			}
+		    }
+		}
+	    }
+	}
+	
+	List<TheRing> otherWays = new ArrayList<TheRing>();
+	for( Way w : touchingWays.keySet() )
+	    if( touchingWays.get(w) ) {
+		otherWays.add(new TheRing(w));
+		System.out.println("Touching ring: " + otherWays.get(otherWays.size()-1));
+	    }
+	
+//	for( Iterator<Way> keys = touchingWays.keySet().iterator(); keys.hasNext(); ) {
+//	    if( !touchingWays.get(keys.next()) )
+//		keys.remove();
+//	}
+	
+	// now touchingWays has only ways that touch the ring twice
+	List<Command> commands = new ArrayList<Command>();
+	TheRing theRing = new TheRing(ring); // this is actually useful
+	
+	for( TheRing otherRing : otherWays )
+	    theRing.collide(otherRing);
+	
+	theRing.putSourceWayFirst();
+	for( TheRing otherRing : otherWays )
+	    otherRing.putSourceWayFirst();
+	
+	for( TheRing otherRing : otherWays )
+	    commands.addAll(otherRing.getCommands(false));
+	commands.addAll(theRing.getCommands());
+	resultingCommands.add(new SequenceCommand(tr("Complete multipolygon for way {0}",
+		DefaultNameFormatter.getInstance().format(ring)), commands));
+	return theRing.getRelation();
     }
 }
Index: /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java
===================================================================
--- /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java	(revision 26843)
+++ /applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java	(revision 26844)
@@ -81,79 +81,16 @@
 		    RingSegment segment2 = other.segments.get(j);
 		    if( !segment2.isReference() ) {
-			List<Node> nodes1 = segment1.getNodes();
-			List<Node> nodes2 = segment2.getNodes();
-			boolean isRing1 = segment1.isRing();
-			boolean isRing2 = segment2.isRing();
-
-			int pos = 0;
-			while( pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) )
-			    pos++;
-			boolean collideFound = pos == nodes1.size();
-			if( pos == 0 && isRing1 ) {
-			    // rewind a bit
-			    pos = nodes1.size() - 1;
-			    while( pos > 0 && nodes2.contains(nodes1.get(pos)) ) pos--;
-			    if( pos == 0 ) {
-				JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
-				return;
+			System.out.println("Comparing " + segment1 + " and " + segment2);
+			Node[] split = getSplitNodes(segment1.getNodes(), segment2.getNodes(), segment1.isRing(), segment2.isRing());
+			if( split != null ) {
+			    if( !collideNoted ) {
+				System.out.println("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
+				collideNoted = true;
 			    }
-			    pos = pos == nodes1.size() ? 0 : pos + 1;
-			}
-			System.out.println("Comparing " + segment1 + " and " + segment2);
-			int firstPos = isRing1 ? pos : nodes1.size();
-			while( !collideFound ) {
-			    System.out.println("pos="+pos);
-			    int start1 = pos;
-			    int start2 = nodes2.indexOf(nodes1.get(start1));
-			    int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
-			    int last2 = start2;
-			    int increment2 = 0;
-			    if( last1 >= 0 ) {
-				last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
-				if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
-				    increment2 = -1;
-				else {
-				    last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
-				    if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
-					increment2 = 1;
-				}
-			    }
-			    System.out.println("last1="+last1+" last2="+last2+" increment2="+increment2);
-			    if( increment2 != 0 ) {
-				if( !collideNoted ) {
-				    System.out.println("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
-				    collideNoted = true;
-				}
-				// find the first nodes
-				boolean reachedEnd = false;
-				while( !reachedEnd ) {
-				    int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
-				    int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
-				    if( newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) )
-					reachedEnd = true;
-				    else {
-					last1 = newLast1;
-					last2 = newLast2;
-				    }
-				}
-				System.out.println("last1=" + last1 + " last2=" + last2);
-				if( increment2 < 0 ) {
-				    int tmp = start2;
-				    start2 = last2;
-				    last2 = tmp;
-				}
-				RingSegment segment = splitRingAt(i, nodes1.get(start1), nodes1.get(last1));
-				RingSegment otherSegment = other.splitRingAt(j, nodes2.get(start2), nodes2.get(last2));
-				if( !areSegmentsEqual(segment, otherSegment) )
-				    throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
-				segment.makeReference(otherSegment);
-				collideFound = true;
-			    } else {
-				pos = last1;
-				while( pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) )
-				    pos = incrementBy(pos, 1, nodes1.size(), isRing1);
-				if( pos < 0 || !nodes2.contains(nodes1.get(pos)) )
-				    collideFound = true;
-			    }
+			    RingSegment segment = splitRingAt(i, split[0], split[1]);
+			    RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]);
+			    if( !areSegmentsEqual(segment, otherSegment) )
+				throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
+			    segment.makeReference(otherSegment);
 			}
 		    }
@@ -165,5 +102,74 @@
     }
     
-    private int incrementBy( int value, int increment, int limit1, boolean isRing ) {
+    /**
+     * Returns array of {start1, last1, start2, last2} or null if there is no common nodes.
+     */
+    public static Node[] getSplitNodes( List<Node> nodes1, List<Node> nodes2, boolean isRing1, boolean isRing2 ) {
+	int pos = 0;
+	while( pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) )
+	    pos++;
+	boolean collideFound = pos == nodes1.size();
+	if( pos == 0 && isRing1 ) {
+	    // rewind a bit
+	    pos = nodes1.size() - 1;
+	    while( pos > 0 && nodes2.contains(nodes1.get(pos)) )
+		pos--;
+	    if( pos == 0 ) {
+		JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
+		return null;
+	    }
+	    pos = pos == nodes1.size() - 1 ? 0 : pos + 1;
+	}
+	int firstPos = isRing1 ? pos : nodes1.size();
+	while( !collideFound ) {
+	    System.out.println("pos=" + pos);
+	    int start1 = pos;
+	    int start2 = nodes2.indexOf(nodes1.get(start1));
+	    int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
+	    int last2 = start2;
+	    int increment2 = 0;
+	    if( last1 >= 0 ) {
+		last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
+		if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
+		    increment2 = -1;
+		else {
+		    last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
+		    if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
+			increment2 = 1;
+		}
+	    }
+	    System.out.println("last1=" + last1 + " last2=" + last2 + " increment2=" + increment2);
+	    if( increment2 != 0 ) {
+		// find the first nodes
+		boolean reachedEnd = false;
+		while( !reachedEnd ) {
+		    int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
+		    int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
+		    if( newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) )
+			reachedEnd = true;
+		    else {
+			last1 = newLast1;
+			last2 = newLast2;
+		    }
+		}
+		System.out.println("last1=" + last1 + " last2=" + last2);
+		if( increment2 < 0 ) {
+		    int tmp = start2;
+		    start2 = last2;
+		    last2 = tmp;
+		}
+		return new Node[] {nodes1.get(start1), nodes1.get(last1), nodes2.get(start2), nodes2.get(last2)};
+	    } else {
+		pos = last1;
+		while( pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) )
+		    pos = incrementBy(pos, 1, nodes1.size(), isRing1);
+		if( pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) )
+		    collideFound = true;
+	    }
+	}
+	return null;
+    }
+    
+    private static int incrementBy( int value, int increment, int limit1, boolean isRing ) {
 	int result = value + increment;
 	if( result < 0 )
@@ -216,7 +222,5 @@
 	if( thirdPart != null )
 	    segments.add(pos++, thirdPart);
-	RingSegment result = isRing || secondPart == null ? segment : secondPart;
-//	System.out.println("Returning segment " + result);
-	return result;
+	return isRing || secondPart == null ? segment : secondPart;
     }
 
@@ -225,5 +229,5 @@
      * Also, sets source way for all rings.
      * 
-     * This method should be called, even if there is just one ring.
+     * If this method is not called, do not forget to call {@link #putSourceWayFirst()} for all rings.
      */
     public static void redistributeSegments( List<TheRing> rings ) {
@@ -263,5 +267,5 @@
     }
 
-    private void putSourceWayFirst() {
+    public void putSourceWayFirst() {
 	for( RingSegment seg : segments ) {
 	    if( !seg.isReference() ) {
@@ -271,19 +275,24 @@
 	}
     }
-
+    
+    public List<Command> getCommands() {
+	return getCommands(true);
+    }
+    
     /**
      * Returns a list of commands to make a new relation and all newly created ways.
      * The first way is copied from the source one, ChangeCommand is issued in this case.
      */
-    public List<Command> getCommands() {
-	System.out.println("Making ring " + this);
-	Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
-	relation = new Relation();
-	relation.put("type", "multipolygon");
+    public List<Command> getCommands( boolean createMultipolygon ) {
 	Way sourceCopy = new Way(source);
-	for( String key : sourceCopy.keySet() ) {
-	    if( !linearTags.contains(key) ) {
-		relation.put(key, sourceCopy.get(key));
-		sourceCopy.remove(key);
+	if( createMultipolygon ) {
+	    Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
+	    relation = new Relation();
+	    relation.put("type", "multipolygon");
+	    for( String key : sourceCopy.keySet() ) {
+		if( !linearTags.contains(key) ) {
+		    relation.put(key, sourceCopy.get(key));
+		    sourceCopy.remove(key);
+		}
 	    }
 	}
@@ -310,12 +319,8 @@
 		commands.add(new AddCommand(w));
 	    if( w.equals(source) ) {
-		if( segments.size() == 1 ) {
-		    // one segment means that it is a ring
-		    List<Node> segnodes = seg.getNodes();
-		    segnodes.add(segnodes.get(0));
-		    sourceCopy.setNodes(segnodes);
-		} else
-		    sourceCopy.setNodes(seg.getNodes());
-		commands.add(new ChangeCommand(source, sourceCopy));
+		if( createMultipolygon || !seg.getWayNodes().equals(source.getNodes()) ) {
+		    sourceCopy.setNodes(seg.getWayNodes());
+		    commands.add(new ChangeCommand(source, sourceCopy));
+		}
 		foundOwnWay = true;
 	    } else {
@@ -325,10 +330,12 @@
 		}
 	    }
-	    relation.addMember(new RelationMember("outer", w));
+	    if( createMultipolygon )
+		relation.addMember(new RelationMember("outer", w));
 	}
 	if( !foundOwnWay )
 	    commands.add(new DeleteCommand(source));
 	commands.addAll(relationCommands);
-	commands.add(new AddCommand(relation));
+	if( createMultipolygon )
+	    commands.add(new AddCommand(relation));
 	return commands;
     }
@@ -463,4 +470,13 @@
 	}
 
+	public List<Node> getWayNodes() {
+	    if( nodes == null )
+		throw new IllegalArgumentException("Won't give you wayNodes: it is a reference");
+	    List<Node> wayNodes = new ArrayList<Node>(nodes);
+	    if( isRing )
+		wayNodes.add(wayNodes.get(0));
+	    return wayNodes;
+	}
+
 	public boolean isReference() {
 	    return nodes == null;
@@ -493,5 +509,5 @@
 	    if( resultingWay == null ) {
 		resultingWay = new Way();
-		resultingWay.setNodes(nodes);
+		resultingWay.setNodes(getWayNodes());
 	    }
 	    if( template != null && !wasTemplateApplied ) {
