Index: trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java	(revision 1108)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java	(revision 1113)
@@ -14,6 +14,8 @@
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
+import java.lang.reflect.Array;
 import java.text.Collator;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -21,4 +23,5 @@
 import java.util.Map.Entry;
 
+import javax.swing.BoxLayout;
 import javax.swing.JButton;
 import javax.swing.JFrame;
@@ -70,4 +73,9 @@
 	private JLabel status;
 
+    /**
+     * True if the relation is ordered (API 0.6). False for API 0.5.
+     */
+    boolean ordered;
+
 	/**
 	 * The property data.
@@ -100,4 +108,7 @@
 	private final JTable memberTable = new JTable(memberData);
 
+    // =================== FIXME FIXME FIXME =====================
+    // As soon as API 0.5 is dead, drop all the collation stuff from here ...
+    
 	/**
 	 * Collator for sorting the roles and entries of the member table.
@@ -164,4 +175,7 @@
 	};
 
+    // =================== FIXME FIXME FIXME =====================
+    // ... until here, and also get rid of the "Collections.sort..." below.
+    
 	/**
 	 * Creates a new relation editor for the given relation. The relation
@@ -192,4 +206,6 @@
 		this.relation = relation;
 
+        ordered = Main.pref.get("osm-server.version", "0.5").equals("0.6");
+        
 		if (relation == null) {
 			// create a new relation
@@ -198,5 +214,5 @@
 			// edit an existing relation
 			this.clone = new Relation(relation);
-			Collections.sort(this.clone.members, memberComparator);
+			if (!ordered) Collections.sort(this.clone.members, memberComparator);
 		}
 
@@ -278,5 +294,4 @@
 		memberTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
 
-
 		// combine both tables and wrap them in a scrollPane
 		JPanel bothTables = new JPanel();
@@ -285,6 +300,30 @@
 		bothTables.add(new JScrollPane(propertyTable), GBC.eop().fill(GBC.BOTH));
 		bothTables.add(status = new JLabel(tr("Members")), GBC.eol().fill(GBC.HORIZONTAL));
-		bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH));
-
+        if (ordered) {
+            JPanel upDownPanel = new JPanel();
+            upDownPanel.setLayout(new BoxLayout(upDownPanel, BoxLayout.Y_AXIS));
+
+            
+
+            upDownPanel.add(createButton(null, "moveup", tr("Move the currently selected member(s) up"),
+                    KeyEvent.VK_U, new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    moveMembers(-1);
+                }
+            }));
+            upDownPanel.add(createButton(null, "movedown", tr("Move the currently selected member(s) down"),
+                    KeyEvent.VK_N, new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    moveMembers(1);
+                }
+            }));
+
+            
+            bothTables.add(new JScrollPane(memberTable), GBC.std().fill(GBC.BOTH));
+            bothTables.add(upDownPanel, GBC.eol().fill(GBC.VERTICAL));
+        } else {
+            bothTables.add(new JScrollPane(memberTable), GBC.eol().fill(GBC.BOTH));
+        }
+        
 		JPanel buttonPanel = new JPanel(new GridLayout(1,3));
 
@@ -297,5 +336,5 @@
 
 		buttonPanel.add(createButton(marktr("Delete Selected"),"deleteselected",
-		tr("Delete all currently selected objects from releation"), KeyEvent.VK_R, new ActionListener() {
+		tr("Delete all currently selected objects from relation"), KeyEvent.VK_R, new ActionListener() {
 			public void actionPerformed(ActionEvent e) {
 				deleteSelected();
@@ -406,17 +445,29 @@
 		for (OsmPrimitive p : Main.ds.getSelected()) {
 			boolean skip = false;
-			for (RelationMember rm : clone.members) {
-				if (rm.member == p || p == relation)
-				{
-					skip = true;
-					break;
-				}
-			}
-			if(!skip)
+            // ordered relations may have the same member multiple times.
+            // TODO: visual indication of the fact that one is there more than once?
+            if (!ordered)
+            {
+                for (RelationMember rm : clone.members) {
+                    if (rm.member == p || p == relation)
+                    {
+                        skip = true;
+                        break;
+                    }
+                }
+            }
+			if (!skip)
 			{
 				RelationMember em = new RelationMember();
 				em.member = p;
 				em.role = "";
-				clone.members.add(em);
+                // when working with ordered relations, we make an effort to
+                // add the element before the first selected member.
+                int[] rows = memberTable.getSelectedRows();
+                if (ordered && rows.length > 0) {
+                    clone.members.add(rows[0], em);
+                } else {
+                    clone.members.add(em);
+                }
 			}
 		}
@@ -438,4 +489,43 @@
 		}
 		refreshTables();
+	}
+
+	private void moveMembers(int direction) {
+	    int[] rows = memberTable.getSelectedRows();
+        if (rows.length == 0) return;
+        
+        // check if user attempted to move anything beyond the boundary of the list
+        if (rows[0] + direction < 0) return;
+        if (rows[rows.length-1] + direction >= clone.members.size()) return;
+        
+        RelationMember m[] = new RelationMember[clone.members.size()];
+        
+        // first move all selected rows from the member list into a new array,
+        // displaced by the move amount
+        for (Integer i: rows) {
+            m[i+direction] = clone.members.get(i);
+            clone.members.set(i, null);            
+        }
+        
+        // now fill the empty spots in the destination array with the remaining
+        // elements.
+        int i = 0;
+        for (RelationMember rm : clone.members) {
+            if (rm != null) {
+                while (m[i] != null) i++;
+                m[i++] = rm;
+            }
+        }
+        
+        // and write the array back into the member list.
+        clone.members.clear();
+        clone.members.addAll(Arrays.asList(m));        
+	    refreshTables();
+        ListSelectionModel lsm = memberTable.getSelectionModel();
+        lsm.setValueIsAdjusting(true);
+        for (Integer j: rows) {
+            lsm.addSelectionInterval(j + direction, j + direction);
+        }
+        lsm.setValueIsAdjusting(false);
 	}
 
