Index: trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 2615)
+++ trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 2616)
@@ -15,4 +15,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -78,25 +82,35 @@
     }
 
-    protected boolean confirmLaunchMultiple(int numPrimitives) {
+    public static boolean confirmLaunchMultiple(int numBrowsers) {
         String msg  = tr(
                 "You''re about to launch {0} browser windows.<br>"
                 + "This may both clutter your screen with browser windows<br>"
-                + "and take some time to finish.", numPrimitives);
+                + "and take some time to finish.", numBrowsers);
         msg = "<html>" + msg + "</html>";
-        String [] options = new String [] {
-                tr("Continue"),
-                tr("Cancel")
+        ButtonSpec[] spec = new ButtonSpec[] {
+                new ButtonSpec(
+                        tr("Continue"),
+                        ImageProvider.get("ok"),
+                        tr("Click to continue and to open {0} browsers", numBrowsers),
+                        null // no specific help topic
+                ),
+                new ButtonSpec(
+                        tr("Cancel"),
+                        ImageProvider.get("cancel"),
+                        tr("Click to abort launching external browsers"),
+                        null // no specific help topic
+                )
         };
-        int ret = JOptionPane.showOptionDialog(
+        int ret = HelpAwareOptionPane.showOptionDialog(
                 Main.parent,
                 msg,
                 tr("Warning"),
-                JOptionPane.YES_NO_OPTION,
                 JOptionPane.WARNING_MESSAGE,
                 null,
-                options,
-                options[0]
+                spec,
+                spec[0],
+                HelpUtil.ht("/WarningMessages#ToManyBrowsersToOpen")
         );
-        return ret == JOptionPane.YES_OPTION;
+        return ret == 0;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 2615)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 2616)
@@ -12,4 +12,5 @@
 import java.awt.event.MouseEvent;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.logging.Logger;
@@ -20,4 +21,5 @@
 import javax.swing.JList;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.JToolBar;
@@ -28,4 +30,6 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.AbstractInfoAction;
+import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.ChangesetCache;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -38,7 +42,22 @@
 import org.openstreetmap.josm.gui.dialogs.changeset.DownloadChangesetsTask;
 import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.io.CloseChangesetTask;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.tools.ImageProvider;
-
+import org.openstreetmap.josm.tools.OpenBrowser;
+
+/**
+ * ChangesetDialog is a toggle dialog which displays the current list of changesets.
+ * It either displays
+ * <ul>
+ *   <li>the list of changesets the currently selected objects are assigned to</li>
+ *   <li>the list of changesets objects in the current data layer are assigend to</li>
+ * </ul>
+ * 
+ * The dialog offers actions to download and to close changesets. It can also launch an external
+ * browser with information about a changeset. Furthermore, it can select all objects in
+ * the current data layer being assigned to a specific changeset.
+ * 
+ */
 public class ChangesetDialog extends ToggleDialog{
     static private final Logger logger = Logger.getLogger(ChangesetDialog.class.getName());
@@ -51,4 +70,11 @@
     private JPanel pnlList;
 
+    // the actions
+    private SelectObjectsAction selectObjectsAction;
+    private  ReadChangesetsAction readChangesetAction;
+    private ShowChangesetInfoAction showChangsetInfoAction;
+    private CloseOpenChangesetsAction closeChangesetAction;
+
+
     protected void buildChangesetsLists() {
         DefaultListSelectionModel selectionModel = new DefaultListSelectionModel();
@@ -77,4 +103,8 @@
         lstInSelection.addMouseListener(dblClickHandler);
         lstInActiveDataLayer.addMouseListener(dblClickHandler);
+
+        PopupMenuLauncher popupMenuLauncher = new PopupMenuLauncher();
+        lstInSelection.addMouseListener(popupMenuLauncher);
+        lstInActiveDataLayer.addMouseListener(popupMenuLauncher);
     }
 
@@ -114,5 +144,6 @@
         tp.setFloatable(false);
 
-        SelectObjectsAction selectObjectsAction = new SelectObjectsAction();
+        // -- select objects action
+        selectObjectsAction = new SelectObjectsAction();
         tp.add(selectObjectsAction);
         cbInSelectionOnly.addItemListener(selectObjectsAction);
@@ -120,9 +151,24 @@
         lstInSelection.getSelectionModel().addListSelectionListener(selectObjectsAction);
 
-        ReadChangesetsAction readChangesetAction = new ReadChangesetsAction();
+        // -- read changesets action
+        readChangesetAction = new ReadChangesetsAction();
         tp.add(readChangesetAction);
         cbInSelectionOnly.addItemListener(readChangesetAction);
         lstInActiveDataLayer.getSelectionModel().addListSelectionListener(readChangesetAction);
         lstInSelection.getSelectionModel().addListSelectionListener(readChangesetAction);
+
+        // -- close changesets action
+        closeChangesetAction = new CloseOpenChangesetsAction();
+        tp.add(closeChangesetAction);
+        cbInSelectionOnly.addItemListener(closeChangesetAction);
+        lstInActiveDataLayer.getSelectionModel().addListSelectionListener(closeChangesetAction);
+        lstInSelection.getSelectionModel().addListSelectionListener(closeChangesetAction);
+
+        // -- show info action
+        showChangsetInfoAction = new ShowChangesetInfoAction();
+        tp.add(showChangsetInfoAction);
+        cbInSelectionOnly.addItemListener(showChangsetInfoAction);
+        lstInActiveDataLayer.getSelectionModel().addListSelectionListener(showChangsetInfoAction);
+        lstInSelection.getSelectionModel().addListSelectionListener(showChangsetInfoAction);
 
         pnl.add(tp);
@@ -203,4 +249,7 @@
     }
 
+    /**
+     * Selects objects for the currently selected changesets.
+     */
     class SelectObjectsAction extends AbstractAction implements ListSelectionListener, ItemListener{
 
@@ -260,4 +309,8 @@
     }
 
+    /**
+     * Downloads selected changesets
+     * 
+     */
     class ReadChangesetsAction extends AbstractAction implements ListSelectionListener, ItemListener{
         public ReadChangesetsAction() {
@@ -291,3 +344,114 @@
     }
 
+    /**
+     * Closes the currently selected changesets
+     * 
+     */
+    class CloseOpenChangesetsAction extends AbstractAction implements ListSelectionListener, ItemListener {
+        public CloseOpenChangesetsAction() {
+            putValue(NAME, tr("Close open changesets"));
+            putValue(SHORT_DESCRIPTION, tr("Closes the selected open changesets"));
+            putValue(SMALL_ICON, ImageProvider.get("closechangeset"));
+            updateEnabledState();
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            List<Changeset> sel = getCurrentChangesetListModel().getSelectedOpenChangesets();
+            if (sel.isEmpty())
+                return;
+            Main.worker.submit(new CloseChangesetTask(sel));
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(getCurrentChangesetListModel().hasSelectedOpenChangesets());
+        }
+
+        public void itemStateChanged(ItemEvent arg0) {
+            updateEnabledState();
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+            updateEnabledState();
+        }
+    }
+
+    /**
+     * Show information about the currently selected changesets
+     * 
+     */
+    class ShowChangesetInfoAction extends AbstractAction implements ListSelectionListener, ItemListener {
+        public ShowChangesetInfoAction() {
+            putValue(NAME, tr("Show info"));
+            putValue(SHORT_DESCRIPTION, tr("Open a web page for each selected changeset"));
+            putValue(SMALL_ICON, ImageProvider.get("about"));
+            updateEnabledState();
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            Set<Changeset> sel = getCurrentChangesetListModel().getSelectedChangesets();
+            if (sel.isEmpty())
+                return;
+            if (sel.size() > 10 && ! AbstractInfoAction.confirmLaunchMultiple(sel.size()))
+                return;
+            String baseUrl = AbstractInfoAction.getBaseBrowseUrl();
+            for (Changeset cs: sel) {
+                String url = baseUrl + "/changeset/" + cs.getId();
+                OpenBrowser.displayUrl(
+                        url
+                );
+            }
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(getCurrentChangesetList().getSelectedIndices().length > 0);
+        }
+
+        public void itemStateChanged(ItemEvent arg0) {
+            updateEnabledState();
+        }
+
+        public void valueChanged(ListSelectionEvent e) {
+            updateEnabledState();
+        }
+    }
+
+    class PopupMenuLauncher extends MouseAdapter {
+        protected void showPopup(MouseEvent evt) {
+            if (!evt.isPopupTrigger())
+                return;
+            JList lst = getCurrentChangesetList();
+            if (lst.getSelectedIndices().length == 0) {
+                int idx = lst.locationToIndex(evt.getPoint());
+                if (idx >=0) {
+                    lst.getSelectionModel().addSelectionInterval(idx, idx);
+                }
+            }
+            ChangesetDialogPopup popup = new ChangesetDialogPopup();
+            popup.show(lst, evt.getX(), evt.getY());
+
+        }
+        @Override
+        public void mouseClicked(MouseEvent evt) {
+            showPopup(evt);
+        }
+        @Override
+        public void mousePressed(MouseEvent evt) {
+            showPopup(evt);
+        }
+        @Override
+        public void mouseReleased(MouseEvent evt) {
+            showPopup(evt);
+        }
+    }
+
+    class ChangesetDialogPopup extends JPopupMenu {
+        public ChangesetDialogPopup() {
+            add(selectObjectsAction);
+            addSeparator();
+            add(readChangesetAction);
+            add(closeChangesetAction);
+            addSeparator();
+            add(showChangsetInfoAction);
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetListModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetListModel.java	(revision 2615)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetListModel.java	(revision 2616)
@@ -162,4 +162,31 @@
     }
 
+    /**
+     * Replies true if  there is at least one selected open changeset
+     * 
+     * @return true if  there is at least one selected open changeset
+     */
+    public boolean hasSelectedOpenChangesets() {
+        return !getSelectedOpenChangesets().isEmpty();
+    }
+
+    /**
+     * Replies the selected open changesets
+     * 
+     * @return the selected open changesets
+     */
+    public List<Changeset> getSelectedOpenChangesets() {
+        List<Changeset> ret = new ArrayList<Changeset>();
+        for (int i=0; i< getSize(); i++) {
+            if (selectionModel.isSelectedIndex(i)) {
+                Changeset cs = data.get(i);
+                if (cs.isOpen()) {
+                    ret.add(cs);
+                }
+            }
+        }
+        return ret;
+    }
+
     /* ---------------------------------------------------------------------------- */
     /* Interface ChangesetCacheListener                                             */
