Index: trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 428)
+++ trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 429)
@@ -38,5 +38,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.NodePair;
+import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.GBC;
 
@@ -53,24 +53,4 @@
 	}
 
-	private static class RelationRolePair {
-		public Relation rel;
-		public String role;
-
-		public RelationRolePair(Relation rel, String role) {
-			this.rel = rel;
-			this.role = role;
-		}
-
-		@Override public boolean equals(Object o) {
-			return o instanceof RelationRolePair
-				&& rel == ((RelationRolePair) o).rel
-				&& role.equals(((RelationRolePair) o).role);
-		}
-
-		@Override public int hashCode() {
-			return rel.hashCode() ^ role.hashCode();
-		}
-	}
-
 	public void actionPerformed(ActionEvent event) {
 		Collection<OsmPrimitive> selection = Main.ds.getSelected();
@@ -96,6 +76,6 @@
 		// Step 1, iterate over all relations and figure out which of our
 		// selected ways are members of a relation.
-		HashMap<RelationRolePair, HashSet<Way>> backlinks =
-			new HashMap<RelationRolePair, HashSet<Way>>();
+		HashMap<Pair<Relation,String>, HashSet<Way>> backlinks =
+			new HashMap<Pair<Relation,String>, HashSet<Way>>();
 		HashSet<Relation> relationsUsingWays = new HashSet<Relation>();
 		for (Relation r : Main.ds.relations) {
@@ -105,5 +85,5 @@
 					for(Way w : selectedWays) {
 						if (rm.member == w) {
-							RelationRolePair pair = new RelationRolePair(r, rm.role);
+							Pair<Relation,String> pair = new Pair<Relation,String>(r, rm.role);
 							HashSet<Way> waylinks = new HashSet<Way>();
 							if (backlinks.containsKey(pair)) {
@@ -238,5 +218,5 @@
 		//  4. Profit!
 
-		HashSet<NodePair> chunkSet = new HashSet<NodePair>();
+		HashSet<Pair<Node,Node>> chunkSet = new HashSet<Pair<Node,Node>>();
 		for (Way w : ways) {
 			if (w.nodes.size() == 0) continue;
@@ -248,7 +228,7 @@
 				}
 
-				NodePair np = new NodePair(lastN, n);
+				Pair<Node,Node> np = new Pair<Node,Node>(lastN, n);
 				if (ignoreDirection) {
-					np.sort();
+					Pair.sort(np);
 				}
 				chunkSet.add(np);
@@ -257,5 +237,5 @@
 			}
 		}
-		LinkedList<NodePair> chunks = new LinkedList<NodePair>(chunkSet);
+		LinkedList<Pair<Node,Node>> chunks = new LinkedList<Pair<Node,Node>>(chunkSet);
 
 		if (chunks.isEmpty()) {
@@ -263,10 +243,10 @@
 		}
 
-		List<Node> nodeList = chunks.poll().toArrayList();
+		List<Node> nodeList = Pair.toArrayList(chunks.poll());
 		while (!chunks.isEmpty()) {
-			ListIterator<NodePair> it = chunks.listIterator();
+			ListIterator<Pair<Node,Node>> it = chunks.listIterator();
 			boolean foundChunk = false;
 			while (it.hasNext()) {
-				NodePair curChunk = it.next();
+				Pair<Node,Node> curChunk = it.next();
 				if (curChunk.a == nodeList.get(nodeList.size() - 1)) { // append
 					nodeList.add(curChunk.b);
Index: trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 428)
+++ trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 429)
@@ -38,5 +38,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.NodePair;
+import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
 import org.openstreetmap.josm.tools.GBC;
@@ -97,24 +97,4 @@
 	}
 
-	private static class RelationRolePair {
-		public Relation rel;
-		public String role;
-
-		public RelationRolePair(Relation rel, String role) {
-			this.rel = rel;
-			this.role = role;
-		}
-
-		@Override public boolean equals(Object o) {
-			return o instanceof RelationRolePair
-				&& rel == ((RelationRolePair) o).rel
-				&& role.equals(((RelationRolePair) o).role);
-		}
-
-		@Override public int hashCode() {
-			return rel.hashCode() ^ role.hashCode();
-		}
-	}
-
 	/**
 	 * really do the merging - returns the node that is left
@@ -133,6 +113,6 @@
 		// Step 1, iterate over all relations and figure out which of our
 		// selected ways are members of a relation.
-		HashMap<RelationRolePair, HashSet<Node>> backlinks =
-			new HashMap<RelationRolePair, HashSet<Node>>();
+		HashMap<Pair<Relation,String>, HashSet<Node>> backlinks =
+			new HashMap<Pair<Relation,String>, HashSet<Node>>();
 		HashSet<Relation> relationsUsingNodes = new HashSet<Relation>();
 		for (Relation r : Main.ds.relations) {
@@ -142,5 +122,5 @@
 					for (Node n : allNodes) {
 						if (rm.member == n) {
-							RelationRolePair pair = new RelationRolePair(r, rm.role);
+							Pair<Relation,String> pair = new Pair<Relation,String>(r, rm.role);
 							HashSet<Node> nodelinks = new HashSet<Node>();
 							if (backlinks.containsKey(pair)) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 428)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 429)
@@ -30,5 +30,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.NodePair;
+import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
@@ -140,5 +140,5 @@
 				}
 
-				Set<NodePair> segSet = new HashSet<NodePair>();
+				Set<Pair<Node,Node>> segSet = new HashSet<Pair<Node,Node>>();
 
 				for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
@@ -150,5 +150,5 @@
 					pruneSuccsAndReverse(is);
 					for (int i : is) segSet.add(
-						new NodePair(w.nodes.get(i), w.nodes.get(i+1)).sort());
+						Pair.sort(new Pair<Node,Node>(w.nodes.get(i), w.nodes.get(i+1))));
 					for (int i : is) wnew.nodes.add(i + 1, n);
 
@@ -311,5 +311,5 @@
 	 * @param n the node to adjust
 	 */
-	private static void adjustNode(Collection<NodePair> segs, Node n) {
+	private static void adjustNode(Collection<Pair<Node,Node>> segs, Node n) {
 		
 		switch (segs.size()) {
@@ -320,6 +320,6 @@
 			// it by something else. All it does it compute the intersection between
 			// the two segments and adjust the node position. The code doesnt 
-			Iterator<NodePair> i = segs.iterator();
-			NodePair seg = i.next();
+			Iterator<Pair<Node,Node>> i = segs.iterator();
+			Pair<Node,Node> seg = i.next();
 			EastNorth A = seg.a.eastNorth;
 			EastNorth B = seg.b.eastNorth;
Index: trunk/src/org/openstreetmap/josm/data/osm/NodePair.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/NodePair.java	(revision 428)
+++ 	(revision )
@@ -1,41 +1,0 @@
-package org.openstreetmap.josm.data.osm;
-import java.util.ArrayList;
-
-/**
- * A pair of twe nodes.
- */
-public final class NodePair {
-	public Node a, b;
-
-	public NodePair(Node a, Node b) {
-		this.a = a;
-		this.b = b;
-	}
-
-	@Override public int hashCode() {
-		return a.hashCode() ^ b.hashCode();
-	}
-
-	@Override public boolean equals(Object o) {
-		if (o == null || !(o instanceof NodePair)) {
-			return false;
-		}
-		return a == ((NodePair) o).a && b == ((NodePair) o).b;
-	}
-
-	public ArrayList<Node> toArrayList() {
-		ArrayList<Node> l = new ArrayList<Node>(2);
-		l.add(a);
-		l.add(b);
-		return l;
-	}
-
-	public NodePair sort() {
-		if (b.hashCode() < a.hashCode()) {
-			Node tmp = a;
-			a = b;
-			b = tmp;
-		}
-		return this;
-	}
-}
Index: trunk/src/org/openstreetmap/josm/tools/Pair.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Pair.java	(revision 429)
+++ trunk/src/org/openstreetmap/josm/tools/Pair.java	(revision 429)
@@ -0,0 +1,40 @@
+package org.openstreetmap.josm.tools;
+import java.util.ArrayList;
+
+/**
+ * A pair.
+ */
+public final class Pair<A,B> {
+	public A a;
+	public B b;
+
+	public Pair(A a, B b) {
+		this.a = a;
+		this.b = b;
+	}
+
+	@Override public int hashCode() {
+		return a.hashCode() ^ b.hashCode();
+	}
+
+	@Override public boolean equals(Object o) {
+		return o == null ? o == null : o instanceof Pair
+			&& a.equals(((Pair) o).a) && b.equals(((Pair) o).b);
+	}
+
+	public static <T> ArrayList<T> toArrayList(Pair<T, T> p) {
+		ArrayList<T> l = new ArrayList<T>(2);
+		l.add(p.a);
+		l.add(p.b);
+		return l;
+	}
+
+	public static <T> Pair<T,T> sort(Pair<T,T> p) {
+		if (p.b.hashCode() < p.a.hashCode()) {
+			T tmp = p.a;
+			p.a = p.b;
+			p.b = tmp;
+		}
+		return p;
+	}
+}
