Index: trunk/src/org/openstreetmap/josm/gui/conflict/ConflictResolver.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/ConflictResolver.java	(revision 1903)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/ConflictResolver.java	(revision 1904)
@@ -7,4 +7,5 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
 import java.util.ArrayList;
 import java.util.logging.Logger;
@@ -35,6 +36,20 @@
  * An UI component for resolving conflicts between two {@see OsmPrimitive}s.
  * 
+ * This component emits {@see PropertyChangeEvent}s for three properties:
+ * <ul>
+ *   <li>{@see #RESOLVED_COMPLETELY_PROP} - new value is <code>true</code>, if the conflict is
+ *   completely resolved</li>
+ *   <li>{@see #MY_PRIMITIVE_PROP} - new value is the {@see OsmPrimitive} in the role of
+ *   my primitive</li>
+ *   <li>{@see #THEIR_PRIMITIVE_PROP} - new value is the {@see OsmPrimitive} in the role of
+ *   their primitive</li>
+ * </ul>
+ * 
  */
 public class ConflictResolver extends JPanel implements PropertyChangeListener  {
+    static public final String RESOLVED_COMPLETELY_PROP = ConflictResolver.class.getName() + ".resolvedCompletely";
+    static public final String MY_PRIMITIVE_PROP = ConflictResolver.class.getName() + ".myPrimitive";
+    static public final String THEIR_PRIMITIVE_PROP = ConflictResolver.class.getName() + ".theirPrimitive";
+
 
     private static final Logger logger = Logger.getLogger(ConflictResolver.class.getName());
@@ -51,4 +66,10 @@
     private ImageIcon mergeIncomplete;
 
+    /** the property change listeners */
+    private PropertyChangeSupport listeners;
+
+    /** indicates whether the current conflict is resolved completely */
+    private boolean resolvedCompletely;
+
     protected void loadIcons() {
         mergeComplete = ImageProvider.get("dialogs/conflict","mergecomplete.png" );
@@ -83,7 +104,63 @@
     }
 
+
     public ConflictResolver() {
+        listeners = new PropertyChangeSupport(this);
+        resolvedCompletely = false;
         build();
         loadIcons();
+    }
+
+
+    protected void setMy(OsmPrimitive my) {
+        OsmPrimitive old = this.my;
+        this.my = my;
+        if (old != this.my) {
+            fireMyPrimitive(old, this.my);
+        }
+    }
+
+    protected void setTheir(OsmPrimitive their) {
+        OsmPrimitive old = this.their;
+        this.their = their;
+        if (old != this.their) {
+            fireTheirPrimitive(old, this.their);
+        }
+    }
+
+    protected void fireResolvedCompletely(boolean oldValue,boolean newValue) {
+        if (listeners == null) return;
+        listeners.firePropertyChange(RESOLVED_COMPLETELY_PROP, oldValue, newValue);
+    }
+
+    protected void fireMyPrimitive(OsmPrimitive oldValue,OsmPrimitive newValue) {
+        if (listeners == null) return;
+        listeners.firePropertyChange(MY_PRIMITIVE_PROP, oldValue, newValue);
+    }
+
+    protected void fireTheirPrimitive(OsmPrimitive oldValue,OsmPrimitive newValue) {
+        if (listeners == null) return;
+        listeners.firePropertyChange(THEIR_PRIMITIVE_PROP, oldValue, newValue);
+    }
+
+    /**
+     * Adds a property change listener
+     * 
+     *  @param listener the listener
+     */
+    @Override
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        listeners.addPropertyChangeListener(listener);
+    }
+
+    /**
+     * Removes a property change listener
+     * 
+     *  @param listener the listener
+     */
+
+    @Override
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        listeners.removePropertyChangeListener(listener);
     }
 
@@ -100,4 +177,5 @@
                 tabbedPane.setIconAt(1, mergeIncomplete);
             }
+            updateResolvedCompletely();
         } else if (evt.getPropertyName().equals(ListMergeModel.FROZEN_PROP)) {
             boolean frozen = (Boolean)evt.getNewValue();
@@ -120,4 +198,5 @@
                 tabbedPane.setIconAt(3, mergeIncomplete);
             }
+            updateResolvedCompletely();
         } else if (evt.getPropertyName().equals(PropertiesMergeModel.RESOLVED_COMPLETELY_PROP)) {
             boolean resolved = (Boolean)evt.getNewValue();
@@ -131,4 +210,5 @@
                 tabbedPane.setIconAt(0, mergeIncomplete);
             }
+            updateResolvedCompletely();
         }
     }
@@ -143,6 +223,6 @@
      */
     public void populate(OsmPrimitive my, OsmPrimitive their) {
-        this.my = my;
-        this.their =  their;
+        setMy(my);
+        setTheir(their);
         propertiesMerger.getModel().populate(my, their);
         if (propertiesMerger.getModel().hasVisibleStateConflict()) {
@@ -172,9 +252,9 @@
             tabbedPane.setEnabledAt(3, true);
         }
-
-    }
-
-    /**
-     * Builds the resolution command(s) for for the resolved conflicts in this
+        updateResolvedCompletely();
+    }
+
+    /**
+     * Builds the resolution command(s) for the resolved conflicts in this
      * ConflictResolver
      * 
@@ -208,12 +288,13 @@
     }
 
-    public boolean isResolvedCompletely() {
+    protected void updateResolvedCompletely() {
+        boolean oldValueResolvedCompletely = resolvedCompletely;
         if (my instanceof Node) {
             // resolve the version conflict if this is a node and all tag
             // conflicts have been resolved
             //
-            if (tagMerger.getModel().isResolvedCompletely()
-                    && propertiesMerger.getModel().isResolvedCompletely())
-                return true;
+            this.resolvedCompletely =
+                tagMerger.getModel().isResolvedCompletely()
+                && propertiesMerger.getModel().isResolvedCompletely();
         } else if (my instanceof Way) {
             // resolve the version conflict if this is a way, all tag
@@ -221,8 +302,8 @@
             // have been resolved
             //
-            if (tagMerger.getModel().isResolvedCompletely()
-                    &&  propertiesMerger.getModel().isResolvedCompletely()
-                    && nodeListMerger.getModel().isFrozen())
-                return true;
+            this.resolvedCompletely =
+                tagMerger.getModel().isResolvedCompletely()
+                &&  propertiesMerger.getModel().isResolvedCompletely()
+                && nodeListMerger.getModel().isFrozen();
         }  else if (my instanceof Relation) {
             // resolve the version conflict if this is a relation, all tag
@@ -230,10 +311,21 @@
             // have been resolved
             //
-            if (tagMerger.getModel().isResolvedCompletely()
-                    &&  propertiesMerger.getModel().isResolvedCompletely()
-                    && relationMemberMerger.getModel().isFrozen())
-                return true;
-        }
-        return false;
+            this.resolvedCompletely =
+                tagMerger.getModel().isResolvedCompletely()
+                &&  propertiesMerger.getModel().isResolvedCompletely()
+                && relationMemberMerger.getModel().isFrozen();
+        }
+        if (this.resolvedCompletely != oldValueResolvedCompletely) {
+            fireResolvedCompletely(oldValueResolvedCompletely, this.resolvedCompletely);
+        }
+    }
+
+    /**
+     * Replies true all differences in this conflicts are resolved
+     * 
+     * @return true all differences in this conflicts are resolved
+     */
+    public boolean isResolvedCompletely() {
+        return resolvedCompletely;
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java	(revision 1903)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictResolutionDialog.java	(revision 1904)
@@ -10,4 +10,6 @@
 import java.awt.Point;
 import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.util.logging.Logger;
 
@@ -22,5 +24,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.OptionPaneUtil;
+import org.openstreetmap.josm.gui.PrimitiveNameFormatter;
 import org.openstreetmap.josm.gui.conflict.ConflictResolver;
 import org.openstreetmap.josm.gui.conflict.properties.OperationCancelledException;
@@ -28,9 +32,8 @@
 
 /**
- * This is an extended dialog for resolving conflict between {@see OsmPrimitive}.
- *
+ * This is an extended dialog for resolving conflict between {@see OsmPrimitive}s.
  *
  */
-public class ConflictResolutionDialog extends JDialog {
+public class ConflictResolutionDialog extends JDialog implements PropertyChangeListener {
     private static final Logger logger = Logger.getLogger(ConflictResolutionDialog.class.getName());
     public final static Dimension DEFAULT_SIZE = new Dimension(600,400);
@@ -114,5 +117,7 @@
         pnl.setLayout(new FlowLayout(FlowLayout.CENTER));
 
-        JButton btn = new JButton(new ApplyResolutionAction());
+        ApplyResolutionAction applyResolutionAction = new ApplyResolutionAction();
+        resolver.addPropertyChangeListener(applyResolutionAction);
+        JButton btn = new JButton(applyResolutionAction);
         btn.setName("button.apply");
         pnl.add(btn);
@@ -130,5 +135,5 @@
      */
     protected void build() {
-        setTitle(tr("Resolve conflicts"));
+        updateTitle();
         try {
             setAlwaysOnTop(true);
@@ -142,4 +147,6 @@
         getContentPane().add(resolver, BorderLayout.CENTER);
         getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
+
+        resolver.addPropertyChangeListener(this);
     }
 
@@ -154,4 +161,7 @@
     }
 
+    /**
+     * Action for canceling conflict resolution
+     */
     class CancelAction extends AbstractAction {
         public CancelAction() {
@@ -168,10 +178,18 @@
     }
 
-    class ApplyResolutionAction extends AbstractAction {
+    /**
+     * Action for applying resolved differences in a conflict
+     * 
+     */
+    class ApplyResolutionAction extends AbstractAction implements PropertyChangeListener {
         public ApplyResolutionAction() {
             putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts and close the dialog"));
             putValue(Action.NAME, tr("Apply Resolution"));
             putValue(Action.SMALL_ICON, ImageProvider.get("dialogs", "conflict"));
-            setEnabled(true);
+            updateEnabledState();
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(resolver.isResolvedCompletely());
         }
 
@@ -179,14 +197,16 @@
             if (! resolver.isResolvedCompletely()) {
                 Object[] options = {
-                        tr("Apply partial resolutions"),
+                        tr("Close anyway"),
                         tr("Continue resolving")};
-                int n = OptionPaneUtil.showOptionDialog(null,
-                        tr("<html>You didn''t finish to resolve all conflicts.<br>"
-                                + "Click <strong>{0}</strong> to apply already resolved conflicts anyway.<br>"
-                                + "You can resolve the remaining conflicts later.<br>"
+                int ret = OptionPaneUtil.showOptionDialog(Main.parent,
+                        tr("<html>You didn''t finish to merge the differences in this conflict.<br>"
+                                + "Conflict resolutions won't be applied unless all differences<br>"
+                                + "are resolved."
+                                + "Click <strong>{0}</strong> to close anyway.<strong>Already<br>"
+                                + "resolved differences won't be applied.</strong><br>"
                                 + "Click <strong>{1}</strong> to return to resolving conflicts.</html>"
                                 , options[0].toString(), options[1].toString()
                         ),
-                        tr("Warning"),
+                        tr("Conflict not resolved completely"),
                         JOptionPane.YES_NO_OPTION,
                         JOptionPane.WARNING_MESSAGE,
@@ -194,14 +214,44 @@
                         options[1]
                 );
-                if (n == JOptionPane.NO_OPTION || n == JOptionPane.CLOSED_OPTION)
+                switch(ret) {
+                case JOptionPane.YES_OPTION:
+                    setVisible(false);
+                    break;
+                default:
                     return;
+                }
             }
             try {
                 Command cmd = resolver.buildResolveCommand();
                 Main.main.undoRedo.add(cmd);
+                setVisible(false);
             } catch(OperationCancelledException e) {
                 // do nothing. Exception already reported
             }
-            setVisible(false);
+        }
+
+        public void propertyChange(PropertyChangeEvent evt) {
+            if (evt.getPropertyName().equals(ConflictResolver.RESOLVED_COMPLETELY_PROP)) {
+                updateEnabledState();
+            }
+        }
+    }
+
+    protected void updateTitle() {
+        updateTitle(null);
+    }
+
+    protected void updateTitle(OsmPrimitive my) {
+        if (my == null) {
+            setTitle(tr("Resolve conflicts"));
+        } else {
+            PrimitiveNameFormatter formatter = new PrimitiveNameFormatter();
+            setTitle(tr("Resolve conflicts for ''{0}''", formatter.getName(my)));
+        }
+    }
+
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt.getPropertyName().equals(ConflictResolver.MY_PRIMITIVE_PROP)) {
+            updateTitle((OsmPrimitive)evt.getNewValue());
         }
     }
