Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 2493)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 2494)
@@ -76,5 +76,5 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionCache;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
-import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
 import org.openstreetmap.josm.io.OsmServerObjectReader;
 import org.openstreetmap.josm.io.OsmTransferException;
@@ -87,5 +87,5 @@
  *
  */
-public class GenericRelationEditor extends RelationEditor {
+public class GenericRelationEditor extends RelationEditor  {
 
     static private final Logger logger = Logger.getLogger(GenericRelationEditor.class.getName());
@@ -1381,4 +1381,6 @@
         private OsmDataLayer curLayer;
         private MemberTableModel memberTableModel;
+        private OsmServerObjectReader objectReader;
+        private OsmServerBackreferenceReader parentReader;
 
         public DownloadTask(List<Relation> relations, OsmDataLayer curLayer, MemberTableModel memberTableModel, Dialog parent) {
@@ -1399,5 +1401,11 @@
         protected void cancel() {
             cancelled = true;
-            OsmApi.getOsmApi().cancel();
+            synchronized(this) {
+                if (objectReader != null) {
+                    objectReader.cancel();
+                } else if (parentReader != null) {
+                    parentReader.cancel();
+                }
+            }
         }
 
@@ -1419,11 +1427,40 @@
             try {
                 for (Relation relation : relations) {
-                    progressMonitor.indeterminateSubTask("");
-                    OsmServerObjectReader reader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.RELATION,
-                            true);
-                    final DataSet dataSet = reader.parseOsm(progressMonitor
+                    // download the relation
+                    //
+                    progressMonitor.indeterminateSubTask(tr("Downloading relation ''{0}''", relation.getDisplayName(DefaultNameFormatter.getInstance())));
+                    synchronized(this) {
+                        if (cancelled) return;
+                        objectReader = new OsmServerObjectReader(relation.getId(), OsmPrimitiveType.RELATION, true /* full download */);
+                    }
+                    final DataSet dataSet = objectReader.parseOsm(progressMonitor
                             .createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
                     if (dataSet == null)
                         return;
+                    synchronized (this) {
+                        if (cancelled) return;
+                        objectReader = null;
+                    }
+
+                    // download referring objects of the downloaded member objects
+                    //
+                    // asked for in #3999, but uncommented for the time being. Could be used
+                    // later, perhaps if user explicity requests so (for instance by checking
+                    // a checkbox)
+                    //                    for (OsmPrimitive p: relation.getMemberPrimitives()) {
+                    //                        synchronized(this) {
+                    //                            if (cancelled) return;
+                    //                            parentReader = new OsmServerBackreferenceReader(p);
+                    //                        }
+                    //                        DataSet parents = parentReader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
+                    //                        synchronized(this) {
+                    //                            if (cancelled) return;
+                    //                            parentReader = null;
+                    //                        }
+                    //                        DataSetMerger merger = new DataSetMerger(dataSet, parents);
+                    //                        merger.merge();
+                    //                    }
+                    //                    if (cancelled) return;
+
                     // has to run on the EDT because mergeFrom may trigger events
                     // which update the UI
@@ -1438,5 +1475,4 @@
                             }
                     );
-
                 }
             } catch (Exception e) {
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 2493)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 2494)
@@ -1,4 +1,10 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.dialogs.relation;
+
+import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.BACKWARD;
+import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.FORWARD;
+import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.NONE;
+import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.ROUNDABOUT_LEFT;
+import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.ROUNDABOUT_RIGHT;
 
 import java.util.ArrayList;
@@ -11,12 +17,11 @@
 import java.util.List;
 import java.util.Set;
-import java.util.Vector;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.swing.DefaultListSelectionModel;
 import javax.swing.ListSelectionModel;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
 import javax.swing.table.AbstractTableModel;
-import javax.swing.event.TableModelListener;
-import javax.swing.event.TableModelEvent;
 
 import org.openstreetmap.josm.Main;
@@ -30,6 +35,4 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 
-import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.*;
-
 public class MemberTableModel extends AbstractTableModel implements TableModelListener {
 
@@ -39,5 +42,5 @@
     private ArrayList<RelationMember> members;
     private ArrayList<WayConnectionType> connectionType = null;
-    
+
     private DefaultListSelectionModel listSelectionModel;
     private CopyOnWriteArrayList<IMemberModelListener> listeners;
@@ -98,10 +101,10 @@
     public Object getValueAt(int rowIndex, int columnIndex) {
         switch (columnIndex) {
-            case 0:
-                return members.get(rowIndex).getRole();
-            case 1:
-                return members.get(rowIndex).getMember();
-            case 2:
-                return wayConnection(rowIndex);
+        case 0:
+            return members.get(rowIndex).getRole();
+        case 1:
+            return members.get(rowIndex).getMember();
+        case 2:
+            return wayConnection(rowIndex);
         }
         // should not happen
@@ -582,5 +585,5 @@
         // current group of members that are linked among each other
         // Two successive members are always linked i.e. have a common node.
-        // 
+        //
         LinkedList<Integer> group;
 
@@ -619,5 +622,5 @@
 
         if (members.size() != newMembers.size()) throw new AssertionError();
-        
+
         members.clear();
         members.addAll(newMembers);
@@ -638,11 +641,9 @@
      **/
     private Direction determineDirection(int ref_i,Direction ref_direction, int k) {
-        if (ref_i < 0 || k < 0 || ref_i >= members.size() || k >= members.size()) {
+        if (ref_i < 0 || k < 0 || ref_i >= members.size() || k >= members.size())
             return NONE;
-        }
-        if (ref_direction == NONE) {
+        if (ref_direction == NONE)
             return NONE;
-        }
-        
+
         RelationMember m_ref = members.get(ref_i);
         RelationMember m = members.get(k);
@@ -656,8 +657,7 @@
             way = m.getWay();
         }
-        
-        if (way_ref == null || way == null) {
+
+        if (way_ref == null || way == null)
             return NONE;
-        }
 
         /** the list of nodes the way k can dock to */
@@ -665,35 +665,33 @@
 
         switch (ref_direction) {
-            case FORWARD:
-                refNodes.add(way_ref.lastNode());
-                break;
-            case BACKWARD:
-                refNodes.add(way_ref.firstNode());
-                break;
-            case ROUNDABOUT_LEFT:
-            case ROUNDABOUT_RIGHT:
-                refNodes = way_ref.getNodes();
-                break;
-        }
-                    
-        if (refNodes == null) {
+        case FORWARD:
+            refNodes.add(way_ref.lastNode());
+            break;
+        case BACKWARD:
+            refNodes.add(way_ref.firstNode());
+            break;
+        case ROUNDABOUT_LEFT:
+        case ROUNDABOUT_RIGHT:
+            refNodes = way_ref.getNodes();
+            break;
+        }
+
+        if (refNodes == null)
             return NONE;
-        }
 
         for (Node n : refNodes) {
-            if (n == null) continue;
+            if (n == null) {
+                continue;
+            }
             if (roundaboutType(k) != NONE) {
                 for (Node nn : way.getNodes()) {
-                    if (n == nn) {
+                    if (n == nn)
                         return roundaboutType(k);
-                    }
                 }
             } else {
-                if (n == way.firstNode()) {
+                if (n == way.firstNode())
                     return FORWARD;
-                }
-                if (n == way.lastNode()) {
+                if (n == way.lastNode())
                     return BACKWARD;
-                }
             }
         }
@@ -749,5 +747,7 @@
         ArrayList<WayConnectionType> con = new ArrayList<WayConnectionType>();
 
-        for (int i=0; i<members.size(); ++i) con.add(null);
+        for (int i=0; i<members.size(); ++i) {
+            con.add(null);
+        }
 
         int firstGroupIdx=0;
@@ -796,5 +796,5 @@
                     }
                 }
-                    
+
             }
 
@@ -817,7 +817,7 @@
         }
         connectionType = con;
-//        for (int i=0; i<con.size(); ++i) {
-//            System.err.println(con.get(i));
-//        }
+        //        for (int i=0; i<con.size(); ++i) {
+        //            System.err.println(con.get(i));
+        //        }
     }
 }
