Index: trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorisationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorisationUI.java	(revision 2860)
+++ 	(revision )
@@ -1,126 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import org.openstreetmap.josm.data.Preferences;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-
-/**
- * This is the abstract base class for the three authorisation UIs.
- * 
- * 
- */
-public abstract class AbstractAuthorisationUI extends VerticallyScrollablePanel{
-    /**
-     * The property name for the Access Token property
-     */
-    static public final String ACCESS_TOKEN_PROP = AbstractAuthorisationUI.class.getName() + ".accessToken";
-
-    private String apiUrl;
-    private AdvancedOAuthPropertiesPanel pnlAdvancedProperties;
-    private OAuthToken accessToken;
-
-    protected void fireAccessTokenChanged(OAuthToken oldValue, OAuthToken newValue) {
-        firePropertyChange(ACCESS_TOKEN_PROP, oldValue, newValue);
-    }
-
-    public AbstractAuthorisationUI() {
-        pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel();
-    }
-
-    /**
-     * Replies the URL of the OSM API for which this UI is currently trying to retrieve an OAuth
-     * Access Token
-     * 
-     * @return the API URL
-     */
-    public String getApiUrl() {
-        return apiUrl;
-    }
-
-    /**
-     * Sets the URL of the OSM API for which this UI is currently trying to retrieve an OAuth
-     * Access Token
-     * 
-     * @param apiUrl the api URL
-     */
-    public void setApiUrl(String apiUrl) {
-        this.apiUrl = apiUrl;
-    }
-
-    /**
-     * Replies the panel for entering advanced OAuth parameters (see {@see OAuthParameters})
-     * 
-     * @return the panel for entering advanced OAuth parameters
-     * @see #getOAuthParameters()
-     */
-    protected AdvancedOAuthPropertiesPanel getAdvancedPropertiesPanel() {
-        return pnlAdvancedProperties;
-    }
-
-    /**
-     * Replies the current set of advanced OAuth parameters in this UI
-     * 
-     * @return the current set of advanced OAuth parameters in this UI
-     */
-    public OAuthParameters getOAuthParameters() {
-        return pnlAdvancedProperties.getAdvancedParameters();
-    }
-
-    /**
-     * Replies the retrieved Access Token. null, if no Access Token was retrieved.
-     * 
-     * @return the retrieved Access Token
-     */
-    public  OAuthToken getAccessToken() {
-        return accessToken;
-    }
-
-    /**
-     * Sets the current Access Token. This will fire a property change event for {@see #ACCESS_TOKEN_PROP}
-     * if the access token has changed
-     * 
-     * @param accessToken the new access token. null, to clear the current access token
-     */
-    protected void setAccessToken(OAuthToken accessToken) {
-        OAuthToken oldValue = this.accessToken;
-        this.accessToken = accessToken;
-        if (oldValue == null ^ this.accessToken == null) {
-            fireAccessTokenChanged(oldValue, this.accessToken);
-        } else if (oldValue == null && this.accessToken == null) {
-            // no change - don't fire an event
-        } else if (! oldValue.equals(this.accessToken)) {
-            fireAccessTokenChanged(oldValue, this.accessToken);
-        }
-    }
-
-    /**
-     * Replies true if this UI currently has an Access Token
-     * 
-     * @return true if this UI currently has an Access Token
-     */
-    public boolean hasAccessToken() {
-        return accessToken != null;
-    }
-
-    /**
-     * Replies whether the user has chosen to save the Access Token in the JOSM
-     * preferences or not.
-     * 
-     * @return true if the user has chosen to save the Access Token
-     */
-    public abstract boolean isSaveAccessTokenToPreferences();
-
-    /**
-     * Initializes the authorisation UI with preference values in <code>pref</code>.
-     * 
-     * @param pref the preferences. Must not be null.
-     * @throws IllegalArgumentException thrown if pref is null
-     */
-    public void initFromPreferences(Preferences pref) throws IllegalArgumentException{
-        CheckParameterUtil.ensureParameterNotNull(pref, "pref");
-        pnlAdvancedProperties.initFromPreferences(pref);
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java	(revision 2861)
@@ -0,0 +1,126 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.data.oauth.OAuthParameters;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * This is the abstract base class for the three authorisation UIs.
+ * 
+ * 
+ */
+public abstract class AbstractAuthorizationUI extends VerticallyScrollablePanel{
+    /**
+     * The property name for the Access Token property
+     */
+    static public final String ACCESS_TOKEN_PROP = AbstractAuthorizationUI.class.getName() + ".accessToken";
+
+    private String apiUrl;
+    private AdvancedOAuthPropertiesPanel pnlAdvancedProperties;
+    private OAuthToken accessToken;
+
+    protected void fireAccessTokenChanged(OAuthToken oldValue, OAuthToken newValue) {
+        firePropertyChange(ACCESS_TOKEN_PROP, oldValue, newValue);
+    }
+
+    public AbstractAuthorizationUI() {
+        pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel();
+    }
+
+    /**
+     * Replies the URL of the OSM API for which this UI is currently trying to retrieve an OAuth
+     * Access Token
+     * 
+     * @return the API URL
+     */
+    public String getApiUrl() {
+        return apiUrl;
+    }
+
+    /**
+     * Sets the URL of the OSM API for which this UI is currently trying to retrieve an OAuth
+     * Access Token
+     * 
+     * @param apiUrl the api URL
+     */
+    public void setApiUrl(String apiUrl) {
+        this.apiUrl = apiUrl;
+    }
+
+    /**
+     * Replies the panel for entering advanced OAuth parameters (see {@see OAuthParameters})
+     * 
+     * @return the panel for entering advanced OAuth parameters
+     * @see #getOAuthParameters()
+     */
+    protected AdvancedOAuthPropertiesPanel getAdvancedPropertiesPanel() {
+        return pnlAdvancedProperties;
+    }
+
+    /**
+     * Replies the current set of advanced OAuth parameters in this UI
+     * 
+     * @return the current set of advanced OAuth parameters in this UI
+     */
+    public OAuthParameters getOAuthParameters() {
+        return pnlAdvancedProperties.getAdvancedParameters();
+    }
+
+    /**
+     * Replies the retrieved Access Token. null, if no Access Token was retrieved.
+     * 
+     * @return the retrieved Access Token
+     */
+    public  OAuthToken getAccessToken() {
+        return accessToken;
+    }
+
+    /**
+     * Sets the current Access Token. This will fire a property change event for {@see #ACCESS_TOKEN_PROP}
+     * if the access token has changed
+     * 
+     * @param accessToken the new access token. null, to clear the current access token
+     */
+    protected void setAccessToken(OAuthToken accessToken) {
+        OAuthToken oldValue = this.accessToken;
+        this.accessToken = accessToken;
+        if (oldValue == null ^ this.accessToken == null) {
+            fireAccessTokenChanged(oldValue, this.accessToken);
+        } else if (oldValue == null && this.accessToken == null) {
+            // no change - don't fire an event
+        } else if (! oldValue.equals(this.accessToken)) {
+            fireAccessTokenChanged(oldValue, this.accessToken);
+        }
+    }
+
+    /**
+     * Replies true if this UI currently has an Access Token
+     * 
+     * @return true if this UI currently has an Access Token
+     */
+    public boolean hasAccessToken() {
+        return accessToken != null;
+    }
+
+    /**
+     * Replies whether the user has chosen to save the Access Token in the JOSM
+     * preferences or not.
+     * 
+     * @return true if the user has chosen to save the Access Token
+     */
+    public abstract boolean isSaveAccessTokenToPreferences();
+
+    /**
+     * Initializes the authorisation UI with preference values in <code>pref</code>.
+     * 
+     * @param pref the preferences. Must not be null.
+     * @throws IllegalArgumentException thrown if pref is null
+     */
+    public void initFromPreferences(Preferences pref) throws IllegalArgumentException{
+        CheckParameterUtil.ensureParameterNotNull(pref, "pref");
+        pnlAdvancedProperties.initFromPreferences(pref);
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AuthorisationProcedure.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AuthorisationProcedure.java	(revision 2860)
+++ 	(revision )
@@ -1,27 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-public enum AuthorisationProcedure {
-    /**
-     * Run a fully automatic procedure to get an access token from the OSM website.
-     * JOSM accesses the OSM website on behalf of the JOSM user and interacts
-     * with the site using an OSM session, form posting and screen scraping.
-     */
-    FULLY_AUTOMATIC,
-
-    /**
-     * Run a semi-automatic procedure to get an access token from the OSM website.
-     * JOSM submits the standards OAuth requests to get a Request Token and an
-     * Access Token. It dispatches the user to the OSM website in an external browser
-     * to authenticate itself and to accept the request token submitted by JOSM.
-     */
-    SEMI_AUTOMATIC,
-
-    /**
-     * Enter an Access Token manually. The Access Token could have been generated
-     * by another JOSM user and sent to the current JOSM user via email, i.e. in order
-     * to grant the current OSM user the right download its private GPS traces. Or it could
-     * have been generated in a former session and filed away in a secure place.
-     */
-    MANUALLY
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AuthorisationProcedureComboBox.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AuthorisationProcedureComboBox.java	(revision 2860)
+++ 	(revision )
@@ -1,103 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.Component;
-
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.ListCellRenderer;
-import javax.swing.UIManager;
-
-public class AuthorisationProcedureComboBox extends JComboBox {
-
-    public AuthorisationProcedureComboBox() {
-        setModel(new AuthorisationProcedureComboBoxModel());
-        setRenderer(new AuthorisationProcedureCellRenderer());
-        setSelectedItem(AuthorisationProcedure.FULLY_AUTOMATIC);
-    }
-
-    static private class AuthorisationProcedureComboBoxModel extends DefaultComboBoxModel {
-        @Override
-        public Object getElementAt(int index) {
-            switch(index) {
-            case 0: return AuthorisationProcedure.FULLY_AUTOMATIC;
-            case 1: return AuthorisationProcedure.SEMI_AUTOMATIC;
-            case 2: return AuthorisationProcedure.MANUALLY;
-            }
-            return null;
-        }
-
-        @Override
-        public int getSize() {
-            return 3;
-        }
-    }
-
-    static private class AuthorisationProcedureCellRenderer extends JLabel implements ListCellRenderer {
-        public AuthorisationProcedureCellRenderer() {
-            setOpaque(true);
-        }
-
-        protected void renderColors(boolean isSelected) {
-            if (isSelected) {
-                setForeground(UIManager.getColor("List.selectionForeground"));
-                setBackground(UIManager.getColor("List.selectionBackground"));
-            } else {
-                setForeground(UIManager.getColor("List.foreground"));
-                setBackground(UIManager.getColor("List.background"));
-            }
-        }
-
-        protected void renderText(AuthorisationProcedure value) {
-            switch(value) {
-            case FULLY_AUTOMATIC:
-                setText(tr("Fully automatic"));
-                break;
-            case SEMI_AUTOMATIC:
-                setText(tr("Semi-automatic"));
-                break;
-            case MANUALLY:
-                setText(tr("Manual"));
-                break;
-            }
-        }
-
-        protected void renderToolTipText(AuthorisationProcedure value) {
-            switch(value) {
-            case FULLY_AUTOMATIC:
-                setToolTipText(tr(
-                        "<html>Run a fully automatic procedure to get an access token from the OSM website.<br>"
-                        + "JOSM accesses the OSM website on behalf of the JOSM user and fully<br>"
-                        + "automatically authorises the user and retrieves an Access Token.</html>"
-                ));
-                break;
-            case SEMI_AUTOMATIC:
-                setToolTipText(tr(
-                        "<html>Run a semi-automatic procedure to get an access token from the OSM website.<br>"
-                        + "JOSM submits the standards OAuth requests to get a Request Token and an<br>"
-                        + "Access Token. It dispatches the user to the OSM website in an external browser<br>"
-                        + "to authenticate itself and to accept the request token submitted by JOSM.</html>"
-                ));
-                break;
-            case MANUALLY:
-                setToolTipText(tr(
-                        "<html>Enter an Access Token manually if it was generated and retrieved outside<br>"
-                        + "of JOSM.</html>"
-                ));
-                break;
-            }
-        }
-
-        public Component getListCellRendererComponent(JList list, Object value, int idx, boolean isSelected, boolean hasFocus) {
-            AuthorisationProcedure procedure = (AuthorisationProcedure)value;
-            renderColors(isSelected);
-            renderText(procedure);
-            renderToolTipText(procedure);
-            return this;
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedure.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedure.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedure.java	(revision 2861)
@@ -0,0 +1,27 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+public enum AuthorizationProcedure {
+    /**
+     * Run a fully automatic procedure to get an access token from the OSM website.
+     * JOSM accesses the OSM website on behalf of the JOSM user and interacts
+     * with the site using an OSM session, form posting and screen scraping.
+     */
+    FULLY_AUTOMATIC,
+
+    /**
+     * Run a semi-automatic procedure to get an access token from the OSM website.
+     * JOSM submits the standards OAuth requests to get a Request Token and an
+     * Access Token. It dispatches the user to the OSM website in an external browser
+     * to authenticate itself and to accept the request token submitted by JOSM.
+     */
+    SEMI_AUTOMATIC,
+
+    /**
+     * Enter an Access Token manually. The Access Token could have been generated
+     * by another JOSM user and sent to the current JOSM user via email, i.e. in order
+     * to grant the current OSM user the right download its private GPS traces. Or it could
+     * have been generated in a former session and filed away in a secure place.
+     */
+    MANUALLY
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedureComboBox.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedureComboBox.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/AuthorizationProcedureComboBox.java	(revision 2861)
@@ -0,0 +1,103 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
+
+public class AuthorizationProcedureComboBox extends JComboBox {
+
+    public AuthorizationProcedureComboBox() {
+        setModel(new AuthorisationProcedureComboBoxModel());
+        setRenderer(new AuthorisationProcedureCellRenderer());
+        setSelectedItem(AuthorizationProcedure.FULLY_AUTOMATIC);
+    }
+
+    static private class AuthorisationProcedureComboBoxModel extends DefaultComboBoxModel {
+        @Override
+        public Object getElementAt(int index) {
+            switch(index) {
+            case 0: return AuthorizationProcedure.FULLY_AUTOMATIC;
+            case 1: return AuthorizationProcedure.SEMI_AUTOMATIC;
+            case 2: return AuthorizationProcedure.MANUALLY;
+            }
+            return null;
+        }
+
+        @Override
+        public int getSize() {
+            return 3;
+        }
+    }
+
+    static private class AuthorisationProcedureCellRenderer extends JLabel implements ListCellRenderer {
+        public AuthorisationProcedureCellRenderer() {
+            setOpaque(true);
+        }
+
+        protected void renderColors(boolean isSelected) {
+            if (isSelected) {
+                setForeground(UIManager.getColor("List.selectionForeground"));
+                setBackground(UIManager.getColor("List.selectionBackground"));
+            } else {
+                setForeground(UIManager.getColor("List.foreground"));
+                setBackground(UIManager.getColor("List.background"));
+            }
+        }
+
+        protected void renderText(AuthorizationProcedure value) {
+            switch(value) {
+            case FULLY_AUTOMATIC:
+                setText(tr("Fully automatic"));
+                break;
+            case SEMI_AUTOMATIC:
+                setText(tr("Semi-automatic"));
+                break;
+            case MANUALLY:
+                setText(tr("Manual"));
+                break;
+            }
+        }
+
+        protected void renderToolTipText(AuthorizationProcedure value) {
+            switch(value) {
+            case FULLY_AUTOMATIC:
+                setToolTipText(tr(
+                        "<html>Run a fully automatic procedure to get an access token from the OSM website.<br>"
+                        + "JOSM accesses the OSM website on behalf of the JOSM user and fully<br>"
+                        + "automatically authorises the user and retrieves an Access Token.</html>"
+                ));
+                break;
+            case SEMI_AUTOMATIC:
+                setToolTipText(tr(
+                        "<html>Run a semi-automatic procedure to get an access token from the OSM website.<br>"
+                        + "JOSM submits the standards OAuth requests to get a Request Token and an<br>"
+                        + "Access Token. It dispatches the user to the OSM website in an external browser<br>"
+                        + "to authenticate itself and to accept the request token submitted by JOSM.</html>"
+                ));
+                break;
+            case MANUALLY:
+                setToolTipText(tr(
+                        "<html>Enter an Access Token manually if it was generated and retrieved outside<br>"
+                        + "of JOSM.</html>"
+                ));
+                break;
+            }
+        }
+
+        public Component getListCellRendererComponent(JList list, Object value, int idx, boolean isSelected, boolean hasFocus) {
+            AuthorizationProcedure procedure = (AuthorizationProcedure)value;
+            renderColors(isSelected);
+            renderText(procedure);
+            renderToolTipText(procedure);
+            return this;
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorisationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorisationUI.java	(revision 2860)
+++ 	(revision )
@@ -1,571 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.io.IOException;
-import java.net.PasswordAuthentication;
-import java.net.Authenticator.RequestorType;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JTabbedPane;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.JTextComponent;
-import javax.swing.text.html.HTMLEditorKit;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Preferences;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane;
-import org.openstreetmap.josm.gui.JMultilineLabel;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
-import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
-import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.io.auth.CredentialsManager;
-import org.openstreetmap.josm.io.auth.CredentialsManagerException;
-import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.xml.sax.SAXException;
-
-/**
- * This is an UI which supports a JOSM user to get an OAuth Access Token in a fully
- * automatic process.
- * 
- */
-public class FullyAutomaticAuthorisationUI extends AbstractAuthorisationUI {
-
-    private JTextField tfUserName;
-    private JPasswordField tfPassword;
-    private UserNameValidator valUserName;
-    private PasswordValidator valPassword;
-    private AccessTokenInfoPanel pnlAccessTokenInfo;
-    private OsmPrivilegesPanel pnlOsmPrivileges;
-    private JPanel pnlPropertiesPanel;
-    private JPanel pnlActionButtonsPanel;
-    private JPanel pnlResult;
-
-    /**
-     * Builds the panel with the three privileges the user can grant JOSM
-     * 
-     * @return
-     */
-    protected VerticallyScrollablePanel buildGrantsPanel() {
-        pnlOsmPrivileges = new OsmPrivilegesPanel();
-        return pnlOsmPrivileges;
-    }
-
-    /**
-     * Builds the panel for entering the username and password
-     * 
-     * @return
-     */
-    protected VerticallyScrollablePanel buildUserNamePasswordPanel() {
-        VerticallyScrollablePanel pnl = new VerticallyScrollablePanel(new GridBagLayout());
-        GridBagConstraints gc = new GridBagConstraints();
-        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 1.0;
-        gc.gridwidth = 2;
-        HtmlPanel pnlMessage = new HtmlPanel();
-        HTMLEditorKit kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit();
-        kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt; border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}");
-        kit.getStyleSheet().addRule("ol {margin-left: 1cm}");
-        pnlMessage.setText("<html><body>"
-                + "Please enter your OSM user name and password. The password will <strong>not</strong> be saved "
-                + "in clear text in the JOSM preferences and it will be submitted to the OSM server <strong>only once</strong>. "
-                + "Subsequent data upload requests don't use your password any more. "
-                + "</p>"
-                + "</body></html>"
-        );
-        pnl.add(pnlMessage, gc);
-
-        // the user name input field
-        gc.gridy = 1;
-        gc.gridwidth = 1;
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 0.0;
-        gc.insets = new Insets(0,0,3,3);
-        pnl.add(new JLabel(tr("Username: ")), gc);
-
-        gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfUserName = new JTextField(), gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfUserName);
-        valUserName = new UserNameValidator(tfUserName);
-        valUserName.validate();
-
-        // the password input field
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.gridy = 2;
-        gc.gridx = 0;
-        gc.weightx = 0.0;
-        pnl.add(new JLabel(tr("Password: ")), gc);
-
-        gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfPassword = new JPasswordField(), gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfPassword);
-        valPassword = new PasswordValidator(tfPassword);
-        valPassword.validate();
-
-        gc.gridy = 3;
-        gc.gridx = 0;
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 1.0;
-        gc.gridwidth = 2;
-        pnlMessage = new HtmlPanel();
-        kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit();
-        kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt; border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}");
-        kit.getStyleSheet().addRule("ol {margin-left: 1cm}");
-        pnlMessage.setText("<html><body>"
-                + "<p class=\"warning-body\">"
-                + "<strong>Warning:</strong> The password is transferred <strong>once</strong> in clear text "
-                + "to the OSM website. <strong>Do not</strong> use a sensitive "
-                + "password until the OSM server provides an encrypted communication channel (HTTPS)."
-                + "</p>"
-                + "</body></html>"
-        );
-        pnl.add(pnlMessage, gc);
-
-        // filler - grab remaining space
-        gc.gridy = 4;
-        gc.gridwidth = 2;
-        gc.fill = GridBagConstraints.BOTH;
-        gc.weightx = 1.0;
-        gc.weighty = 1.0;
-        pnl.add(new JPanel(), gc);
-
-        return pnl;
-    }
-
-    protected JPanel buildPropertiesPanel() {
-        JPanel pnl = new JPanel(new BorderLayout());
-
-        JTabbedPane tpProperties = new JTabbedPane();
-        tpProperties.add(VerticallyScrollablePanel.embed(buildUserNamePasswordPanel()));
-        tpProperties.add(VerticallyScrollablePanel.embed(buildGrantsPanel()));
-        tpProperties.add(VerticallyScrollablePanel.embed(getAdvancedPropertiesPanel()));
-        tpProperties.setTitleAt(0, tr("Basic"));
-        tpProperties.setTitleAt(1, tr("Granted rights"));
-        tpProperties.setTitleAt(2, tr("Advanced OAuth properties"));
-
-        pnl.add(tpProperties, BorderLayout.CENTER);
-        return pnl;
-    }
-
-    /**
-     * Initializes the panel with values from the preferences
-     */
-    @Override
-    public void initFromPreferences(Preferences pref) {
-        super.initFromPreferences(pref);
-        CredentialsManager cm = CredentialsManagerFactory.getCredentialManager();
-        try {
-            PasswordAuthentication pa = cm.lookup(RequestorType.SERVER);
-            if (pa == null) {
-                tfUserName.setText("");
-                tfPassword.setText("");
-            } else {
-                tfUserName.setText(pa.getUserName() == null ? "" : pa.getUserName());
-                tfPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));
-            }
-        } catch(CredentialsManagerException e) {
-            e.printStackTrace();
-            tfUserName.setText("");
-            tfPassword.setText("");
-        }
-    }
-
-    /**
-     * Builds the panel with the action button  for starting the authorisation
-     * 
-     * @return
-     */
-    protected JPanel buildActionButtonPanel() {
-        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-
-        RunAuthorisationAction runAuthorisationAction= new RunAuthorisationAction();
-        tfPassword.getDocument().addDocumentListener(runAuthorisationAction);
-        tfUserName.getDocument().addDocumentListener(runAuthorisationAction);
-        pnl.add(new SideButton(runAuthorisationAction));
-        return pnl;
-    }
-
-    /**
-     * Builds the panel which displays the generated Access Token.
-     * 
-     * @return
-     */
-    protected JPanel buildResultsPanel() {
-        JPanel pnl = new JPanel(new GridBagLayout());;
-        GridBagConstraints gc = new GridBagConstraints();
-        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-
-        // the message panel
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 1.0;
-        JMultilineLabel msg = new JMultilineLabel("");
-        msg.setFont(msg.getFont().deriveFont(Font.PLAIN));
-        String lbl = tr("Accept Access Token");
-        msg.setText(tr("<html>"
-                + "You have sucessfully retrieved an OAuth Access Token from the OSM website. "
-                + "Click on <strong>{0}</strong> to accept the token. JOSM will use it in "
-                + "subsequent requests to gain access to the OSM API."
-                + "</html>",
-                lbl
-        ));
-        pnl.add(msg, gc);
-
-        // infos about the access token
-        gc.gridy = 1;
-        gc.insets = new Insets(5,0,0,0);
-        pnl.add(pnlAccessTokenInfo = new AccessTokenInfoPanel(), gc);
-
-        // the actions
-        JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
-        pnl1.add(new SideButton(new BackAction()));
-        pnl1.add(new SideButton(new TestAccessTokenAction()));
-        gc.gridy = 2;
-        pnl.add(pnl1, gc);
-
-        // filler - grab the remaining space
-        gc.gridy = 3;
-        gc.fill = GridBagConstraints.BOTH;
-        gc.weightx = 1.0;
-        gc.weighty = 1.0;
-        pnl.add(new JPanel(), gc);
-
-        return pnl;
-    }
-
-    protected void build() {
-        setLayout(new BorderLayout());
-        pnlPropertiesPanel = buildPropertiesPanel();
-        pnlActionButtonsPanel = buildActionButtonPanel();
-        pnlResult = buildResultsPanel();
-
-        prepareUIForEnteringRequest();
-    }
-
-    /**
-     * Prepares the UI for the first step in the automatic process: entering the authentication
-     * and authorisation parameters.
-     * 
-     */
-    protected void prepareUIForEnteringRequest() {
-        removeAll();
-        add(pnlPropertiesPanel, BorderLayout.CENTER);
-        add(pnlActionButtonsPanel, BorderLayout.SOUTH);
-        pnlPropertiesPanel.revalidate();
-        pnlActionButtonsPanel.revalidate();
-        validate();
-        repaint();
-
-        setAccessToken(null);
-    }
-
-    /**
-     * Prepares the UI for the second step in the automatic process: displaying the access token
-     * 
-     */
-    protected void prepareUIForResultDisplay() {
-        removeAll();
-        add(pnlResult, BorderLayout.CENTER);
-        validate();
-        repaint();
-    }
-
-    protected String getOsmUserName() {
-        return tfUserName.getText();
-    }
-
-    protected String getOsmPassword() {
-        return String.valueOf(tfPassword.getPassword());
-    }
-
-    public FullyAutomaticAuthorisationUI() {
-        build();
-    }
-
-    @Override
-    public boolean isSaveAccessTokenToPreferences() {
-        return pnlAccessTokenInfo.isSaveToPreferences();
-    }
-
-    @Override
-    protected void setAccessToken(OAuthToken accessToken) {
-        super.setAccessToken(accessToken);
-        pnlAccessTokenInfo.setAccessToken(accessToken);
-    }
-
-    /**
-     * Starts the authorisation process
-     */
-    class RunAuthorisationAction extends AbstractAction implements DocumentListener{
-        public RunAuthorisationAction() {
-            putValue(NAME, tr("Authorise now"));
-            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
-            putValue(SHORT_DESCRIPTION, tr("Click to redirect you to the authorisation form on the JOSM web site"));
-            updateEnabledState();
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            Main.worker.submit(new FullyAutomaticAuthorisationTask(FullyAutomaticAuthorisationUI.this));
-        }
-
-        protected void updateEnabledState() {
-            setEnabled(valPassword.isValid() && valUserName.isValid());
-        }
-
-        public void changedUpdate(DocumentEvent e) {
-            updateEnabledState();
-        }
-
-        public void insertUpdate(DocumentEvent e) {
-            updateEnabledState();
-        }
-
-        public void removeUpdate(DocumentEvent e) {
-            updateEnabledState();
-        }
-    }
-
-    /**
-     * Action to go back to step 1 in the process
-     */
-    class BackAction extends AbstractAction {
-        public BackAction() {
-            putValue(NAME, tr("Back"));
-            putValue(SHORT_DESCRIPTION, tr("Run the automatic authorisation steps again"));
-            putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
-        }
-
-        public void actionPerformed(ActionEvent arg0) {
-            prepareUIForEnteringRequest();
-        }
-    }
-
-    /**
-     * Action to test an access token.
-     */
-    class TestAccessTokenAction extends AbstractAction {
-        public TestAccessTokenAction() {
-            putValue(NAME, tr("Test Access Token"));
-            /* putValue(SHORT_DESCRIPTION, ""); */
-            putValue(SMALL_ICON, ImageProvider.get("about"));
-        }
-
-        public void actionPerformed(ActionEvent arg0) {
-            Main.worker.submit(new TestAccessTokenTask(
-                    FullyAutomaticAuthorisationUI.this,
-                    getApiUrl(),
-                    getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    getAccessToken()
-            ));
-        }
-    }
-
-
-    static private class UserNameValidator extends AbstractTextComponentValidator {
-        public UserNameValidator(JTextComponent tc) {
-            super(tc);
-        }
-
-        @Override
-        public boolean isValid() {
-            return getComponent().getText().trim().length() > 0;
-        }
-
-        @Override
-        public void validate() {
-            if (isValid()) {
-                feedbackValid(tr("Please enter your OSM user name"));
-            } else {
-                feedbackInvalid(tr("The user name cannot be empty. Please enter your OSM user name"));
-            }
-        }
-    }
-
-    static private class PasswordValidator extends AbstractTextComponentValidator {
-
-        public PasswordValidator(JTextComponent tc) {
-            super(tc);
-        }
-
-        @Override
-        public boolean isValid() {
-            return getComponent().getText().trim().length() > 0;
-        }
-
-        @Override
-        public void validate() {
-            if (isValid()) {
-                feedbackValid(tr("Please enter your OSM password"));
-            } else {
-                feedbackInvalid(tr("The password cannot be empty. Please enter your OSM password"));
-            }
-        }
-    }
-
-    class FullyAutomaticAuthorisationTask extends PleaseWaitRunnable {
-        private boolean canceled;
-        private OsmOAuthAuthorisationClient authClient;
-
-        public FullyAutomaticAuthorisationTask(Component parent) {
-            super(parent, tr("Authorise JOSM to access the OSM API"), false /* don't ignore exceptions */);
-        }
-
-        @Override
-        protected void cancel() {
-            canceled = true;
-        }
-
-        @Override
-        protected void finish() {}
-
-        protected void alertAuthorisationFailed(OsmOAuthAuthorisationException e) {
-            HelpAwareOptionPane.showOptionDialog(
-                    FullyAutomaticAuthorisationUI.this,
-                    tr("<html>"
-                            + "The automatic process for retrieving an OAuth Access Token<br>"
-                            + "from the OSM server failed.<br><br>"
-                            + "Please try again or choose another kind of authorisation process,<br>"
-                            + "i.e. semi-automatic or manual authorisation."
-                            +"</html>"
-                    ),
-                    tr("OAuth authorisation failed"),
-                    JOptionPane.ERROR_MESSAGE,
-                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
-            );
-        }
-
-        protected void alertInvalidLoginUrl() {
-            HelpAwareOptionPane.showOptionDialog(
-                    FullyAutomaticAuthorisationUI.this,
-                    tr("<html>"
-                            + "The automatic process for retrieving an OAuth Access Token<br>"
-                            + "from the OSM server failed because JOSM was not able to build<br>"
-                            + "a valid login URL from the OAuth Authorise Endpoint URL ''{0}''.<br><br>"
-                            + "Please check your advanced setting and try again."
-                            + "</html>",
-                            getAdvancedPropertiesPanel().getAdvancedParameters().getAuthoriseUrl()
-                    ),
-                    tr("OAuth authorisation failed"),
-                    JOptionPane.ERROR_MESSAGE,
-                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
-            );
-        }
-
-        protected void alertLoginFailed(OsmLoginFailedException e) {
-            String loginUrl = null;
-            try {
-                loginUrl = authClient.buildOsmLoginUrl();
-            } catch(OsmOAuthAuthorisationException e1) {
-                alertInvalidLoginUrl();
-                return;
-            }
-            HelpAwareOptionPane.showOptionDialog(
-                    FullyAutomaticAuthorisationUI.this,
-                    tr("<html>"
-                            + "The automatic process for retrieving an OAuth Access Token<br>"
-                            + "from the OSM server failed. JOSM failed to log into {0}<br>"
-                            + "for user {1}.<br><br>"
-                            + "Please check username and password and try again."
-                            +"</html>",
-                            loginUrl,
-                            getOsmUserName()
-                    ),
-                    tr("OAuth authorisation failed"),
-                    JOptionPane.ERROR_MESSAGE,
-                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
-            );
-        }
-
-        protected void handleException(final OsmOAuthAuthorisationException e) {
-            Runnable r = new Runnable() {
-                public void run() {
-                    if (e instanceof OsmLoginFailedException) {
-                        alertLoginFailed((OsmLoginFailedException)e);
-                    } else {
-                        alertAuthorisationFailed(e);
-                    }
-                }
-            };
-            e.printStackTrace();
-            if (SwingUtilities.isEventDispatchThread()) {
-                r.run();
-            } else {
-                SwingUtilities.invokeLater(r);
-            }
-        }
-
-        @Override
-        protected void realRun() throws SAXException, IOException, OsmTransferException {
-            try {
-                getProgressMonitor().setTicksCount(3);
-                authClient = new OsmOAuthAuthorisationClient(
-                        getAdvancedPropertiesPanel().getAdvancedParameters()
-                );
-                OAuthToken requestToken = authClient.getRequestToken(
-                        getProgressMonitor().createSubTaskMonitor(1, false)
-                );
-                getProgressMonitor().worked(1);
-                if (canceled)return;
-                authClient.authorise(
-                        requestToken,
-                        getOsmUserName(),
-                        getOsmPassword(),
-                        pnlOsmPrivileges.getPrivileges(),
-                        getProgressMonitor().createSubTaskMonitor(1, false)
-                );
-                getProgressMonitor().worked(1);
-                if (canceled)return;
-                final OAuthToken accessToken = authClient.getAccessToken(
-                        getProgressMonitor().createSubTaskMonitor(1,false)
-                );
-                getProgressMonitor().worked(1);
-                if (canceled)return;
-                Runnable r = new Runnable() {
-                    public void run() {
-                        prepareUIForResultDisplay();
-                        setAccessToken(accessToken);
-                    }
-                };
-                if (SwingUtilities.isEventDispatchThread()) {
-                    r.run();
-                } else {
-                    SwingUtilities.invokeLater(r);
-                }
-            } catch(final OsmOAuthAuthorisationException e) {
-                handleException(e);
-            }
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 2861)
@@ -0,0 +1,571 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+import java.net.PasswordAuthentication;
+import java.net.Authenticator.RequestorType;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.html.HTMLEditorKit;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.gui.PleaseWaitRunnable;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
+import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
+import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.io.auth.CredentialsManagerException;
+import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.xml.sax.SAXException;
+
+/**
+ * This is an UI which supports a JOSM user to get an OAuth Access Token in a fully
+ * automatic process.
+ * 
+ */
+public class FullyAutomaticAuthorizationUI extends AbstractAuthorizationUI {
+
+    private JTextField tfUserName;
+    private JPasswordField tfPassword;
+    private UserNameValidator valUserName;
+    private PasswordValidator valPassword;
+    private AccessTokenInfoPanel pnlAccessTokenInfo;
+    private OsmPrivilegesPanel pnlOsmPrivileges;
+    private JPanel pnlPropertiesPanel;
+    private JPanel pnlActionButtonsPanel;
+    private JPanel pnlResult;
+
+    /**
+     * Builds the panel with the three privileges the user can grant JOSM
+     * 
+     * @return
+     */
+    protected VerticallyScrollablePanel buildGrantsPanel() {
+        pnlOsmPrivileges = new OsmPrivilegesPanel();
+        return pnlOsmPrivileges;
+    }
+
+    /**
+     * Builds the panel for entering the username and password
+     * 
+     * @return
+     */
+    protected VerticallyScrollablePanel buildUserNamePasswordPanel() {
+        VerticallyScrollablePanel pnl = new VerticallyScrollablePanel(new GridBagLayout());
+        GridBagConstraints gc = new GridBagConstraints();
+        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        gc.gridwidth = 2;
+        HtmlPanel pnlMessage = new HtmlPanel();
+        HTMLEditorKit kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit();
+        kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt; border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}");
+        kit.getStyleSheet().addRule("ol {margin-left: 1cm}");
+        pnlMessage.setText("<html><body>"
+                + "Please enter your OSM user name and password. The password will <strong>not</strong> be saved "
+                + "in clear text in the JOSM preferences and it will be submitted to the OSM server <strong>only once</strong>. "
+                + "Subsequent data upload requests don't use your password any more. "
+                + "</p>"
+                + "</body></html>"
+        );
+        pnl.add(pnlMessage, gc);
+
+        // the user name input field
+        gc.gridy = 1;
+        gc.gridwidth = 1;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 0.0;
+        gc.insets = new Insets(0,0,3,3);
+        pnl.add(new JLabel(tr("Username: ")), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 1.0;
+        pnl.add(tfUserName = new JTextField(), gc);
+        SelectAllOnFocusGainedDecorator.decorate(tfUserName);
+        valUserName = new UserNameValidator(tfUserName);
+        valUserName.validate();
+
+        // the password input field
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.gridy = 2;
+        gc.gridx = 0;
+        gc.weightx = 0.0;
+        pnl.add(new JLabel(tr("Password: ")), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 1.0;
+        pnl.add(tfPassword = new JPasswordField(), gc);
+        SelectAllOnFocusGainedDecorator.decorate(tfPassword);
+        valPassword = new PasswordValidator(tfPassword);
+        valPassword.validate();
+
+        gc.gridy = 3;
+        gc.gridx = 0;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        gc.gridwidth = 2;
+        pnlMessage = new HtmlPanel();
+        kit = (HTMLEditorKit)pnlMessage.getEditorPane().getEditorKit();
+        kit.getStyleSheet().addRule(".warning-body {background-color:rgb(253,255,221);padding: 10pt; border-color:rgb(128,128,128);border-style: solid;border-width: 1px;}");
+        kit.getStyleSheet().addRule("ol {margin-left: 1cm}");
+        pnlMessage.setText("<html><body>"
+                + "<p class=\"warning-body\">"
+                + "<strong>Warning:</strong> The password is transferred <strong>once</strong> in clear text "
+                + "to the OSM website. <strong>Do not</strong> use a sensitive "
+                + "password until the OSM server provides an encrypted communication channel (HTTPS)."
+                + "</p>"
+                + "</body></html>"
+        );
+        pnl.add(pnlMessage, gc);
+
+        // filler - grab remaining space
+        gc.gridy = 4;
+        gc.gridwidth = 2;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        pnl.add(new JPanel(), gc);
+
+        return pnl;
+    }
+
+    protected JPanel buildPropertiesPanel() {
+        JPanel pnl = new JPanel(new BorderLayout());
+
+        JTabbedPane tpProperties = new JTabbedPane();
+        tpProperties.add(VerticallyScrollablePanel.embed(buildUserNamePasswordPanel()));
+        tpProperties.add(VerticallyScrollablePanel.embed(buildGrantsPanel()));
+        tpProperties.add(VerticallyScrollablePanel.embed(getAdvancedPropertiesPanel()));
+        tpProperties.setTitleAt(0, tr("Basic"));
+        tpProperties.setTitleAt(1, tr("Granted rights"));
+        tpProperties.setTitleAt(2, tr("Advanced OAuth properties"));
+
+        pnl.add(tpProperties, BorderLayout.CENTER);
+        return pnl;
+    }
+
+    /**
+     * Initializes the panel with values from the preferences
+     */
+    @Override
+    public void initFromPreferences(Preferences pref) {
+        super.initFromPreferences(pref);
+        CredentialsManager cm = CredentialsManagerFactory.getCredentialManager();
+        try {
+            PasswordAuthentication pa = cm.lookup(RequestorType.SERVER);
+            if (pa == null) {
+                tfUserName.setText("");
+                tfPassword.setText("");
+            } else {
+                tfUserName.setText(pa.getUserName() == null ? "" : pa.getUserName());
+                tfPassword.setText(pa.getPassword() == null ? "" : String.valueOf(pa.getPassword()));
+            }
+        } catch(CredentialsManagerException e) {
+            e.printStackTrace();
+            tfUserName.setText("");
+            tfPassword.setText("");
+        }
+    }
+
+    /**
+     * Builds the panel with the action button  for starting the authorisation
+     * 
+     * @return
+     */
+    protected JPanel buildActionButtonPanel() {
+        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
+
+        RunAuthorisationAction runAuthorisationAction= new RunAuthorisationAction();
+        tfPassword.getDocument().addDocumentListener(runAuthorisationAction);
+        tfUserName.getDocument().addDocumentListener(runAuthorisationAction);
+        pnl.add(new SideButton(runAuthorisationAction));
+        return pnl;
+    }
+
+    /**
+     * Builds the panel which displays the generated Access Token.
+     * 
+     * @return
+     */
+    protected JPanel buildResultsPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout());;
+        GridBagConstraints gc = new GridBagConstraints();
+        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+
+        // the message panel
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        JMultilineLabel msg = new JMultilineLabel("");
+        msg.setFont(msg.getFont().deriveFont(Font.PLAIN));
+        String lbl = tr("Accept Access Token");
+        msg.setText(tr("<html>"
+                + "You have sucessfully retrieved an OAuth Access Token from the OSM website. "
+                + "Click on <strong>{0}</strong> to accept the token. JOSM will use it in "
+                + "subsequent requests to gain access to the OSM API."
+                + "</html>",
+                lbl
+        ));
+        pnl.add(msg, gc);
+
+        // infos about the access token
+        gc.gridy = 1;
+        gc.insets = new Insets(5,0,0,0);
+        pnl.add(pnlAccessTokenInfo = new AccessTokenInfoPanel(), gc);
+
+        // the actions
+        JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
+        pnl1.add(new SideButton(new BackAction()));
+        pnl1.add(new SideButton(new TestAccessTokenAction()));
+        gc.gridy = 2;
+        pnl.add(pnl1, gc);
+
+        // filler - grab the remaining space
+        gc.gridy = 3;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        pnl.add(new JPanel(), gc);
+
+        return pnl;
+    }
+
+    protected void build() {
+        setLayout(new BorderLayout());
+        pnlPropertiesPanel = buildPropertiesPanel();
+        pnlActionButtonsPanel = buildActionButtonPanel();
+        pnlResult = buildResultsPanel();
+
+        prepareUIForEnteringRequest();
+    }
+
+    /**
+     * Prepares the UI for the first step in the automatic process: entering the authentication
+     * and authorisation parameters.
+     * 
+     */
+    protected void prepareUIForEnteringRequest() {
+        removeAll();
+        add(pnlPropertiesPanel, BorderLayout.CENTER);
+        add(pnlActionButtonsPanel, BorderLayout.SOUTH);
+        pnlPropertiesPanel.revalidate();
+        pnlActionButtonsPanel.revalidate();
+        validate();
+        repaint();
+
+        setAccessToken(null);
+    }
+
+    /**
+     * Prepares the UI for the second step in the automatic process: displaying the access token
+     * 
+     */
+    protected void prepareUIForResultDisplay() {
+        removeAll();
+        add(pnlResult, BorderLayout.CENTER);
+        validate();
+        repaint();
+    }
+
+    protected String getOsmUserName() {
+        return tfUserName.getText();
+    }
+
+    protected String getOsmPassword() {
+        return String.valueOf(tfPassword.getPassword());
+    }
+
+    public FullyAutomaticAuthorizationUI() {
+        build();
+    }
+
+    @Override
+    public boolean isSaveAccessTokenToPreferences() {
+        return pnlAccessTokenInfo.isSaveToPreferences();
+    }
+
+    @Override
+    protected void setAccessToken(OAuthToken accessToken) {
+        super.setAccessToken(accessToken);
+        pnlAccessTokenInfo.setAccessToken(accessToken);
+    }
+
+    /**
+     * Starts the authorisation process
+     */
+    class RunAuthorisationAction extends AbstractAction implements DocumentListener{
+        public RunAuthorisationAction() {
+            putValue(NAME, tr("Authorise now"));
+            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
+            putValue(SHORT_DESCRIPTION, tr("Click to redirect you to the authorisation form on the JOSM web site"));
+            updateEnabledState();
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            Main.worker.submit(new FullyAutomaticAuthorisationTask(FullyAutomaticAuthorizationUI.this));
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(valPassword.isValid() && valUserName.isValid());
+        }
+
+        public void changedUpdate(DocumentEvent e) {
+            updateEnabledState();
+        }
+
+        public void insertUpdate(DocumentEvent e) {
+            updateEnabledState();
+        }
+
+        public void removeUpdate(DocumentEvent e) {
+            updateEnabledState();
+        }
+    }
+
+    /**
+     * Action to go back to step 1 in the process
+     */
+    class BackAction extends AbstractAction {
+        public BackAction() {
+            putValue(NAME, tr("Back"));
+            putValue(SHORT_DESCRIPTION, tr("Run the automatic authorisation steps again"));
+            putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            prepareUIForEnteringRequest();
+        }
+    }
+
+    /**
+     * Action to test an access token.
+     */
+    class TestAccessTokenAction extends AbstractAction {
+        public TestAccessTokenAction() {
+            putValue(NAME, tr("Test Access Token"));
+            /* putValue(SHORT_DESCRIPTION, ""); */
+            putValue(SMALL_ICON, ImageProvider.get("about"));
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            Main.worker.submit(new TestAccessTokenTask(
+                    FullyAutomaticAuthorizationUI.this,
+                    getApiUrl(),
+                    getAdvancedPropertiesPanel().getAdvancedParameters(),
+                    getAccessToken()
+            ));
+        }
+    }
+
+
+    static private class UserNameValidator extends AbstractTextComponentValidator {
+        public UserNameValidator(JTextComponent tc) {
+            super(tc);
+        }
+
+        @Override
+        public boolean isValid() {
+            return getComponent().getText().trim().length() > 0;
+        }
+
+        @Override
+        public void validate() {
+            if (isValid()) {
+                feedbackValid(tr("Please enter your OSM user name"));
+            } else {
+                feedbackInvalid(tr("The user name cannot be empty. Please enter your OSM user name"));
+            }
+        }
+    }
+
+    static private class PasswordValidator extends AbstractTextComponentValidator {
+
+        public PasswordValidator(JTextComponent tc) {
+            super(tc);
+        }
+
+        @Override
+        public boolean isValid() {
+            return getComponent().getText().trim().length() > 0;
+        }
+
+        @Override
+        public void validate() {
+            if (isValid()) {
+                feedbackValid(tr("Please enter your OSM password"));
+            } else {
+                feedbackInvalid(tr("The password cannot be empty. Please enter your OSM password"));
+            }
+        }
+    }
+
+    class FullyAutomaticAuthorisationTask extends PleaseWaitRunnable {
+        private boolean canceled;
+        private OsmOAuthAuthorizationClient authClient;
+
+        public FullyAutomaticAuthorisationTask(Component parent) {
+            super(parent, tr("Authorise JOSM to access the OSM API"), false /* don't ignore exceptions */);
+        }
+
+        @Override
+        protected void cancel() {
+            canceled = true;
+        }
+
+        @Override
+        protected void finish() {}
+
+        protected void alertAuthorisationFailed(OsmOAuthAuthorizationException e) {
+            HelpAwareOptionPane.showOptionDialog(
+                    FullyAutomaticAuthorizationUI.this,
+                    tr("<html>"
+                            + "The automatic process for retrieving an OAuth Access Token<br>"
+                            + "from the OSM server failed.<br><br>"
+                            + "Please try again or choose another kind of authorisation process,<br>"
+                            + "i.e. semi-automatic or manual authorisation."
+                            +"</html>"
+                    ),
+                    tr("OAuth authorisation failed"),
+                    JOptionPane.ERROR_MESSAGE,
+                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
+            );
+        }
+
+        protected void alertInvalidLoginUrl() {
+            HelpAwareOptionPane.showOptionDialog(
+                    FullyAutomaticAuthorizationUI.this,
+                    tr("<html>"
+                            + "The automatic process for retrieving an OAuth Access Token<br>"
+                            + "from the OSM server failed because JOSM was not able to build<br>"
+                            + "a valid login URL from the OAuth Authorise Endpoint URL ''{0}''.<br><br>"
+                            + "Please check your advanced setting and try again."
+                            + "</html>",
+                            getAdvancedPropertiesPanel().getAdvancedParameters().getAuthoriseUrl()
+                    ),
+                    tr("OAuth authorisation failed"),
+                    JOptionPane.ERROR_MESSAGE,
+                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
+            );
+        }
+
+        protected void alertLoginFailed(OsmLoginFailedException e) {
+            String loginUrl = null;
+            try {
+                loginUrl = authClient.buildOsmLoginUrl();
+            } catch(OsmOAuthAuthorizationException e1) {
+                alertInvalidLoginUrl();
+                return;
+            }
+            HelpAwareOptionPane.showOptionDialog(
+                    FullyAutomaticAuthorizationUI.this,
+                    tr("<html>"
+                            + "The automatic process for retrieving an OAuth Access Token<br>"
+                            + "from the OSM server failed. JOSM failed to log into {0}<br>"
+                            + "for user {1}.<br><br>"
+                            + "Please check username and password and try again."
+                            +"</html>",
+                            loginUrl,
+                            getOsmUserName()
+                    ),
+                    tr("OAuth authorisation failed"),
+                    JOptionPane.ERROR_MESSAGE,
+                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
+            );
+        }
+
+        protected void handleException(final OsmOAuthAuthorizationException e) {
+            Runnable r = new Runnable() {
+                public void run() {
+                    if (e instanceof OsmLoginFailedException) {
+                        alertLoginFailed((OsmLoginFailedException)e);
+                    } else {
+                        alertAuthorisationFailed(e);
+                    }
+                }
+            };
+            e.printStackTrace();
+            if (SwingUtilities.isEventDispatchThread()) {
+                r.run();
+            } else {
+                SwingUtilities.invokeLater(r);
+            }
+        }
+
+        @Override
+        protected void realRun() throws SAXException, IOException, OsmTransferException {
+            try {
+                getProgressMonitor().setTicksCount(3);
+                authClient = new OsmOAuthAuthorizationClient(
+                        getAdvancedPropertiesPanel().getAdvancedParameters()
+                );
+                OAuthToken requestToken = authClient.getRequestToken(
+                        getProgressMonitor().createSubTaskMonitor(1, false)
+                );
+                getProgressMonitor().worked(1);
+                if (canceled)return;
+                authClient.authorise(
+                        requestToken,
+                        getOsmUserName(),
+                        getOsmPassword(),
+                        pnlOsmPrivileges.getPrivileges(),
+                        getProgressMonitor().createSubTaskMonitor(1, false)
+                );
+                getProgressMonitor().worked(1);
+                if (canceled)return;
+                final OAuthToken accessToken = authClient.getAccessToken(
+                        getProgressMonitor().createSubTaskMonitor(1,false)
+                );
+                getProgressMonitor().worked(1);
+                if (canceled)return;
+                Runnable r = new Runnable() {
+                    public void run() {
+                        prepareUIForResultDisplay();
+                        setAccessToken(accessToken);
+                    }
+                };
+                if (SwingUtilities.isEventDispatchThread()) {
+                    r.run();
+                } else {
+                    SwingUtilities.invokeLater(r);
+                }
+            } catch(final OsmOAuthAuthorizationException e) {
+                handleException(e);
+            }
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorisationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorisationUI.java	(revision 2860)
+++ 	(revision )
@@ -1,257 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-import javax.swing.JTextField;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.JTextComponent;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
-import org.openstreetmap.josm.tools.ImageProvider;
-
-public class ManualAuthorisationUI extends AbstractAuthorisationUI{
-
-    private JTextField tfAccessTokenKey;
-    private AccessTokenKeyValidator valAccessTokenKey;
-    private JTextField tfAccessTokenSecret;
-    private AccessTokenSecretValidator valAccessTokenSecret;
-    private JCheckBox cbSaveToPreferences;
-    private HtmlPanel pnlMessage;
-
-    protected JPanel buildAccessTokenPanel() {
-        JPanel pnl = new JPanel(new GridBagLayout());
-        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-        GridBagConstraints gc = new GridBagConstraints();
-        AccessTokenBuilder accessTokenBuilder = new AccessTokenBuilder();
-
-        // the access token key input field
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 0.0;
-        gc.gridwidth = 2;
-        gc.insets = new Insets(0,0,5,0);
-        pnlMessage= new HtmlPanel();
-        pnlMessage.setText("<html><body>"
-                + tr("Please enter an OAuth Access Token which is authorised to access the OSM server "
-                + "''{0}''.",
-                getApiUrl()) + "</body></html>");
-        pnl.add(pnlMessage, gc);
-
-        // the access token key input field
-        gc.gridy = 1;
-        gc.weightx = 0.0;
-        gc.gridwidth = 1;
-        gc.insets = new Insets(0,0,0,3);
-        pnl.add(new JLabel(tr("Access Token Key:")), gc);
-
-        gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfAccessTokenKey = new JTextField(), gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenKey);
-        valAccessTokenKey = new AccessTokenKeyValidator(tfAccessTokenKey);
-        valAccessTokenKey.validate();
-        tfAccessTokenKey.getDocument().addDocumentListener(accessTokenBuilder);
-
-        // the access token key input field
-        gc.gridy = 2;
-        gc.gridx = 0;
-        gc.weightx = 0.0;
-        pnl.add(new JLabel(tr("Access Token Secret:")), gc);
-
-        gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfAccessTokenSecret = new JTextField(), gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenSecret);
-        valAccessTokenSecret = new AccessTokenSecretValidator(tfAccessTokenSecret);
-        valAccessTokenSecret.validate();
-        tfAccessTokenSecret.getDocument().addDocumentListener(accessTokenBuilder);
-
-        // the checkbox for saving to preferences
-        gc.gridy = 3;
-        gc.gridx = 0;
-        gc.gridwidth =2;
-        gc.weightx = 1.0;
-        pnl.add(cbSaveToPreferences = new JCheckBox(tr("Save Access Token to preferences")), gc);
-        cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences());
-
-        // filler - grab remaining space
-        gc.gridy = 3;
-        gc.gridx = 0;
-        gc.gridwidth =2;
-        gc.weightx = 1.0;
-        gc.weighty = 1.0;
-        gc.fill = GridBagConstraints.BOTH;
-        pnl.add(new JPanel(), gc);
-        return pnl;
-    }
-
-    protected JPanel buildTabbedPreferencesPanel() {
-        JPanel pnl = new JPanel(new BorderLayout());
-
-        JTabbedPane tp = new JTabbedPane();
-        tp.add(buildAccessTokenPanel());
-        tp.add(getAdvancedPropertiesPanel());
-
-        tp.setTitleAt(0, tr("Access Token"));
-        tp.setTitleAt(1, tr("Advanced OAuth parameters"));
-
-        tp.setToolTipTextAt(0, tr("Enter the OAuth Access Token"));
-        tp.setToolTipTextAt(1, tr("Enter advanced OAuth properties"));
-
-        pnl.add(tp, BorderLayout.CENTER);
-        return pnl;
-    }
-
-    protected JPanel buildActionsPanel() {
-        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-        TestAccessTokenAction actTestAccessToken = new TestAccessTokenAction();
-        pnl.add(new SideButton(actTestAccessToken));
-        this.addPropertyChangeListener(actTestAccessToken);
-        return pnl;
-    }
-
-    @Override
-    public void setApiUrl(String apiUrl) {
-        super.setApiUrl(apiUrl);
-        pnlMessage.setText(tr("<html><body>"
-                + "Please enter an OAuth Access Token which is authorised to access the OSM server "
-                + "''{0}''."
-                + "</body></html>",
-                getApiUrl()
-        ));
-    }
-
-    protected void build() {
-        setLayout(new BorderLayout());
-        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-        add(buildTabbedPreferencesPanel(), BorderLayout.CENTER);
-        add(buildActionsPanel(), BorderLayout.SOUTH);
-    }
-
-    public ManualAuthorisationUI() {
-        build();
-    }
-
-    @Override
-    public boolean isSaveAccessTokenToPreferences() {
-        return cbSaveToPreferences.isSelected();
-    }
-
-    static private class AccessTokenKeyValidator extends AbstractTextComponentValidator {
-
-        public AccessTokenKeyValidator(JTextComponent tc) throws IllegalArgumentException {
-            super(tc);
-        }
-
-        @Override
-        public boolean isValid() {
-            return ! getComponent().getText().trim().equals("");
-        }
-
-        @Override
-        public void validate() {
-            if (isValid()) {
-                feedbackValid(tr("Please enter an Access Token Key"));
-            } else {
-                feedbackInvalid(tr("The Access Token Key must not be empty. Please enter an Access Token Key"));
-            }
-        }
-    }
-
-    static private class AccessTokenSecretValidator extends AbstractTextComponentValidator {
-        public AccessTokenSecretValidator(JTextComponent tc) throws IllegalArgumentException {
-            super(tc);
-        }
-
-        @Override
-        public boolean isValid() {
-            return ! getComponent().getText().trim().equals("");
-        }
-
-        @Override
-        public void validate() {
-            if (isValid()) {
-                feedbackValid(tr("Please enter an Access Token Secret"));
-            } else {
-                feedbackInvalid(tr("The Access Token Secret must not be empty. Please enter an Access Token Secret"));
-            }
-        }
-    }
-
-    class AccessTokenBuilder implements DocumentListener {
-
-        public void build() {
-            if (! valAccessTokenKey.isValid() || !valAccessTokenSecret.isValid()) {
-                setAccessToken(null);
-            } else {
-                setAccessToken(new OAuthToken(tfAccessTokenKey.getText().trim(), tfAccessTokenSecret.getText().trim()));
-            }
-        }
-        public void changedUpdate(DocumentEvent e) {
-            build();
-        }
-
-        public void insertUpdate(DocumentEvent e) {
-            build();
-        }
-
-        public void removeUpdate(DocumentEvent e) {
-            build();
-        }
-    }
-
-    /**
-     * Action for testing an Access Token
-     */
-    class TestAccessTokenAction extends AbstractAction implements PropertyChangeListener {
-        public TestAccessTokenAction() {
-            putValue(NAME, tr("Test Access Token"));
-            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
-            putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
-            updateEnabledState();
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            TestAccessTokenTask task = new TestAccessTokenTask(
-                    ManualAuthorisationUI.this,
-                    getApiUrl(),
-                    getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    getAccessToken()
-            );
-            Main.worker.submit(task);
-        }
-
-        protected void updateEnabledState() {
-            setEnabled(hasAccessToken());
-        }
-
-        public void propertyChange(PropertyChangeEvent evt) {
-            if (! evt.getPropertyName().equals(AbstractAuthorisationUI.ACCESS_TOKEN_PROP))
-                return;
-            updateEnabledState();
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java	(revision 2861)
@@ -0,0 +1,257 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
+import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public class ManualAuthorizationUI extends AbstractAuthorizationUI{
+
+    private JTextField tfAccessTokenKey;
+    private AccessTokenKeyValidator valAccessTokenKey;
+    private JTextField tfAccessTokenSecret;
+    private AccessTokenSecretValidator valAccessTokenSecret;
+    private JCheckBox cbSaveToPreferences;
+    private HtmlPanel pnlMessage;
+
+    protected JPanel buildAccessTokenPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout());
+        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+        GridBagConstraints gc = new GridBagConstraints();
+        AccessTokenBuilder accessTokenBuilder = new AccessTokenBuilder();
+
+        // the access token key input field
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 0.0;
+        gc.gridwidth = 2;
+        gc.insets = new Insets(0,0,5,0);
+        pnlMessage= new HtmlPanel();
+        pnlMessage.setText("<html><body>"
+                + tr("Please enter an OAuth Access Token which is authorised to access the OSM server "
+                + "''{0}''.",
+                getApiUrl()) + "</body></html>");
+        pnl.add(pnlMessage, gc);
+
+        // the access token key input field
+        gc.gridy = 1;
+        gc.weightx = 0.0;
+        gc.gridwidth = 1;
+        gc.insets = new Insets(0,0,0,3);
+        pnl.add(new JLabel(tr("Access Token Key:")), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 1.0;
+        pnl.add(tfAccessTokenKey = new JTextField(), gc);
+        SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenKey);
+        valAccessTokenKey = new AccessTokenKeyValidator(tfAccessTokenKey);
+        valAccessTokenKey.validate();
+        tfAccessTokenKey.getDocument().addDocumentListener(accessTokenBuilder);
+
+        // the access token key input field
+        gc.gridy = 2;
+        gc.gridx = 0;
+        gc.weightx = 0.0;
+        pnl.add(new JLabel(tr("Access Token Secret:")), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 1.0;
+        pnl.add(tfAccessTokenSecret = new JTextField(), gc);
+        SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenSecret);
+        valAccessTokenSecret = new AccessTokenSecretValidator(tfAccessTokenSecret);
+        valAccessTokenSecret.validate();
+        tfAccessTokenSecret.getDocument().addDocumentListener(accessTokenBuilder);
+
+        // the checkbox for saving to preferences
+        gc.gridy = 3;
+        gc.gridx = 0;
+        gc.gridwidth =2;
+        gc.weightx = 1.0;
+        pnl.add(cbSaveToPreferences = new JCheckBox(tr("Save Access Token to preferences")), gc);
+        cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences());
+
+        // filler - grab remaining space
+        gc.gridy = 3;
+        gc.gridx = 0;
+        gc.gridwidth =2;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        gc.fill = GridBagConstraints.BOTH;
+        pnl.add(new JPanel(), gc);
+        return pnl;
+    }
+
+    protected JPanel buildTabbedPreferencesPanel() {
+        JPanel pnl = new JPanel(new BorderLayout());
+
+        JTabbedPane tp = new JTabbedPane();
+        tp.add(buildAccessTokenPanel());
+        tp.add(getAdvancedPropertiesPanel());
+
+        tp.setTitleAt(0, tr("Access Token"));
+        tp.setTitleAt(1, tr("Advanced OAuth parameters"));
+
+        tp.setToolTipTextAt(0, tr("Enter the OAuth Access Token"));
+        tp.setToolTipTextAt(1, tr("Enter advanced OAuth properties"));
+
+        pnl.add(tp, BorderLayout.CENTER);
+        return pnl;
+    }
+
+    protected JPanel buildActionsPanel() {
+        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
+        TestAccessTokenAction actTestAccessToken = new TestAccessTokenAction();
+        pnl.add(new SideButton(actTestAccessToken));
+        this.addPropertyChangeListener(actTestAccessToken);
+        return pnl;
+    }
+
+    @Override
+    public void setApiUrl(String apiUrl) {
+        super.setApiUrl(apiUrl);
+        pnlMessage.setText(tr("<html><body>"
+                + "Please enter an OAuth Access Token which is authorised to access the OSM server "
+                + "''{0}''."
+                + "</body></html>",
+                getApiUrl()
+        ));
+    }
+
+    protected void build() {
+        setLayout(new BorderLayout());
+        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+        add(buildTabbedPreferencesPanel(), BorderLayout.CENTER);
+        add(buildActionsPanel(), BorderLayout.SOUTH);
+    }
+
+    public ManualAuthorizationUI() {
+        build();
+    }
+
+    @Override
+    public boolean isSaveAccessTokenToPreferences() {
+        return cbSaveToPreferences.isSelected();
+    }
+
+    static private class AccessTokenKeyValidator extends AbstractTextComponentValidator {
+
+        public AccessTokenKeyValidator(JTextComponent tc) throws IllegalArgumentException {
+            super(tc);
+        }
+
+        @Override
+        public boolean isValid() {
+            return ! getComponent().getText().trim().equals("");
+        }
+
+        @Override
+        public void validate() {
+            if (isValid()) {
+                feedbackValid(tr("Please enter an Access Token Key"));
+            } else {
+                feedbackInvalid(tr("The Access Token Key must not be empty. Please enter an Access Token Key"));
+            }
+        }
+    }
+
+    static private class AccessTokenSecretValidator extends AbstractTextComponentValidator {
+        public AccessTokenSecretValidator(JTextComponent tc) throws IllegalArgumentException {
+            super(tc);
+        }
+
+        @Override
+        public boolean isValid() {
+            return ! getComponent().getText().trim().equals("");
+        }
+
+        @Override
+        public void validate() {
+            if (isValid()) {
+                feedbackValid(tr("Please enter an Access Token Secret"));
+            } else {
+                feedbackInvalid(tr("The Access Token Secret must not be empty. Please enter an Access Token Secret"));
+            }
+        }
+    }
+
+    class AccessTokenBuilder implements DocumentListener {
+
+        public void build() {
+            if (! valAccessTokenKey.isValid() || !valAccessTokenSecret.isValid()) {
+                setAccessToken(null);
+            } else {
+                setAccessToken(new OAuthToken(tfAccessTokenKey.getText().trim(), tfAccessTokenSecret.getText().trim()));
+            }
+        }
+        public void changedUpdate(DocumentEvent e) {
+            build();
+        }
+
+        public void insertUpdate(DocumentEvent e) {
+            build();
+        }
+
+        public void removeUpdate(DocumentEvent e) {
+            build();
+        }
+    }
+
+    /**
+     * Action for testing an Access Token
+     */
+    class TestAccessTokenAction extends AbstractAction implements PropertyChangeListener {
+        public TestAccessTokenAction() {
+            putValue(NAME, tr("Test Access Token"));
+            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
+            putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
+            updateEnabledState();
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            TestAccessTokenTask task = new TestAccessTokenTask(
+                    ManualAuthorizationUI.this,
+                    getApiUrl(),
+                    getAdvancedPropertiesPanel().getAdvancedParameters(),
+                    getAccessToken()
+            );
+            Main.worker.submit(task);
+        }
+
+        protected void updateEnabledState() {
+            setEnabled(hasAccessToken());
+        }
+
+        public void propertyChange(PropertyChangeEvent evt) {
+            if (! evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP))
+                return;
+            updateEnabledState();
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorisationWizard.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorisationWizard.java	(revision 2860)
+++ 	(revision )
@@ -1,386 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.logging.Logger;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.KeyStroke;
-import javax.swing.UIManager;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
-import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.WindowGeometry;
-
-/**
- * This wizard walks the user to the necessary steps to retrieve an OAuth Access Token which
- * allows JOSM to access the OSM API on the users behalf.
- * 
- */
-public class OAuthAuthorisationWizard extends JDialog {
-    static private final Logger logger = Logger.getLogger(OAuthAuthorisationWizard.class.getName());
-
-    private HtmlPanel pnlMessage;
-    private boolean canceled;
-    private String apiUrl;
-
-    private AuthorisationProcedureComboBox cbAuthorisationProcedure;
-    private FullyAutomaticAuthorisationUI pnlFullyAutomaticAuthorisationUI;
-    private SemiAutomaticAuthorisationUI pnlSemiAutomaticAuthorisationUI;
-    private ManualAuthorisationUI pnlManualAuthorisationUI;
-    private JScrollPane spAuthorisationProcedureUI;
-
-    /**
-     * Builds the row with the action buttons
-     * 
-     * @return
-     */
-    protected JPanel buildButtonRow(){
-        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
-
-        AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction();
-        pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
-        pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
-        pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
-
-        pnl.add(new SideButton(actAcceptAccessToken));
-        pnl.add(new SideButton(new CancelAction()));
-        pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"))));
-
-        return pnl;
-    }
-
-    /**
-     * Builds the panel with general information in the header
-     * 
-     * @return
-     */
-    protected JPanel buildHeaderInfoPanel() {
-        JPanel pnl = new JPanel(new GridBagLayout());
-        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-        GridBagConstraints gc = new GridBagConstraints();
-
-        // the oauth logo in the header
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.fill = GridBagConstraints.HORIZONTAL;
-        gc.weightx = 1.0;
-        gc.gridwidth = 2;
-        JLabel lbl = new JLabel();
-        lbl.setIcon(ImageProvider.get("oauth", "oauth-logo"));
-        lbl.setOpaque(true);
-        pnl.add(lbl, gc);
-
-        // OAuth in a nutshell ...
-        gc.gridy  = 1;
-        gc.insets = new Insets(5,0,0,5);
-        pnlMessage = new HtmlPanel();
-        pnlMessage.setText("<html><body>"
-                + "With OAuth you grant JOSM the right to upload map data and GPS tracks "
-                + "on your behalf (<a href=\"urn:josm-oauth-info\">more info...</a>)."
-                + "</body></html>"
-        );
-        pnl.add(pnlMessage, gc);
-
-        // the authorisation procedure
-        gc.gridy  = 2;
-        gc.gridwidth = 1;
-        gc.weightx = 0.0;
-        lbl = new JLabel(tr("Please select an authorisation procedure: "));
-        lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
-        pnl.add(lbl,gc);
-
-        gc.gridx = 1;
-        gc.gridwidth = 1;
-        gc.weightx = 1.0;
-        pnl.add(cbAuthorisationProcedure = new AuthorisationProcedureComboBox(),gc);
-        cbAuthorisationProcedure.addItemListener(new AuthorisationProcedureChangeListener());
-        return pnl;
-    }
-
-    /**
-     * Refreshes the view of the authorisation panel, depending on the authorisation procedure
-     * currently selected
-     */
-    protected void refreshAuthorisationProcedurePanel() {
-        AuthorisationProcedure procedure = (AuthorisationProcedure)cbAuthorisationProcedure.getSelectedItem();
-        switch(procedure) {
-        case FULLY_AUTOMATIC:
-            spAuthorisationProcedureUI.getViewport().setView(pnlFullyAutomaticAuthorisationUI);
-            pnlFullyAutomaticAuthorisationUI.revalidate();
-            break;
-        case SEMI_AUTOMATIC:
-            spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);
-            pnlSemiAutomaticAuthorisationUI.revalidate();
-            break;
-        case MANUALLY:
-            spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI);
-            pnlManualAuthorisationUI.revalidate();
-            break;
-        }
-        validate();
-        repaint();
-    }
-
-    /**
-     * builds the UI
-     */
-    protected void build() {
-        getContentPane().setLayout(new BorderLayout());
-        getContentPane().add(buildHeaderInfoPanel(), BorderLayout.NORTH);
-
-        pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorisationUI();
-        pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
-
-        pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorisationUI();
-        pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
-
-        pnlManualAuthorisationUI = new ManualAuthorisationUI();
-        pnlManualAuthorisationUI.setApiUrl(apiUrl);
-
-        spAuthorisationProcedureUI = new JScrollPane(new JPanel());
-        spAuthorisationProcedureUI.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-        spAuthorisationProcedureUI.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
-        spAuthorisationProcedureUI.getVerticalScrollBar().addComponentListener(
-                new ComponentListener() {
-                    public void componentShown(ComponentEvent e) {
-                        spAuthorisationProcedureUI.setBorder(UIManager.getBorder("ScrollPane.border"));
-                    }
-
-                    public void componentHidden(ComponentEvent e) {
-                        spAuthorisationProcedureUI.setBorder(null);
-                    }
-
-                    public void componentResized(ComponentEvent e) {}
-                    public void componentMoved(ComponentEvent e) {}
-                }
-        );
-        getContentPane().add(spAuthorisationProcedureUI, BorderLayout.CENTER);
-        getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
-
-        addWindowListener(new WindowEventHandler());
-        getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
-        getRootPane().getActionMap().put("cancel", new CancelAction());
-
-        refreshAuthorisationProcedurePanel();
-
-        HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"));
-    }
-
-    /**
-     * Creates the wizard.
-     * 
-     * @param apiUrl the API URL. Must not be null.
-     * @throws IllegalArgumentException thrown if apiUrl is null
-     */
-    public OAuthAuthorisationWizard(String apiUrl) throws IllegalArgumentException {
-        super(JOptionPane.getFrameForComponent(Main.parent),true /* modal */);
-        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
-        build();
-        setApiUrl(apiUrl);
-    }
-
-    /**
-     * Creates the wizard.
-     * 
-     * @param parent the component relative to which the dialog is displayed
-     * @param apiUrl the API URL. Must not be null.
-     * @throws IllegalArgumentException thrown if apiUrl is null
-     */
-    public OAuthAuthorisationWizard(Component parent, String apiUrl) {
-        super(JOptionPane.getFrameForComponent(parent),true /* modal */);
-        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
-        build();
-        setApiUrl(apiUrl);
-    }
-
-    /**
-     * Sets the API URL for the API for which this wizard is generating
-     * an Access Token.
-     * 
-     * @param apiUrl the API URL. Must not be null.
-     * @throws IllegalArgumentException thrown if apiUrl is null
-     */
-    public void setApiUrl(String apiUrl) throws IllegalArgumentException{
-        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
-        this.apiUrl = apiUrl;
-        setTitle(tr("Get an Access Token for ''{0}''", apiUrl));
-        if (pnlFullyAutomaticAuthorisationUI != null) {
-            pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
-        }
-        if (pnlSemiAutomaticAuthorisationUI != null) {
-            pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
-        }
-        if (pnlManualAuthorisationUI != null) {
-            pnlManualAuthorisationUI.setApiUrl(apiUrl);
-        }
-
-    }
-
-    /**
-     * Replies true if the dialog was cancelled
-     * 
-     * @return true if the dialog was cancelled
-     */
-    public boolean isCanceled() {
-        return canceled;
-    }
-
-    protected AbstractAuthorisationUI getCurrentAuthorisationUI() {
-        switch((AuthorisationProcedure)cbAuthorisationProcedure.getSelectedItem()) {
-        case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI;
-        case MANUALLY: return pnlManualAuthorisationUI;
-        case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;
-        default: return null;
-        }
-    }
-
-    /**
-     * Replies the Access Token entered using the wizard
-     * 
-     * @return the access token. May be null if the wizard was canceled.
-     */
-    public OAuthToken getAccessToken() {
-        return getCurrentAuthorisationUI().getAccessToken();
-    }
-
-    /**
-     * Replies the current OAuth parameters.
-     * 
-     * @return the current OAuth parameters.
-     */
-    public OAuthParameters getOAuthParameters() {
-        return getCurrentAuthorisationUI().getOAuthParameters();
-    }
-
-    /**
-     * Replies true if the currently selected Access Token shall be saved to
-     * the preferences.
-     * 
-     * @return true if the currently selected Access Token shall be saved to
-     * the preferences
-     */
-    public boolean isSaveAccessTokenToPreferences() {
-        return getCurrentAuthorisationUI().isSaveAccessTokenToPreferences();
-    }
-
-    /**
-     * Initializes the dialog with values from the preferences
-     * 
-     */
-    public void initFromPreferences() {
-        pnlFullyAutomaticAuthorisationUI.initFromPreferences(Main.pref);
-        pnlSemiAutomaticAuthorisationUI.initFromPreferences(Main.pref);
-        pnlManualAuthorisationUI.initFromPreferences(Main.pref);
-    }
-
-    @Override
-    public void setVisible(boolean visible) {
-        if (visible) {
-            new WindowGeometry(
-                    getClass().getName() + ".geometry",
-                    WindowGeometry.centerInWindow(
-                            Main.parent,
-                            new Dimension(400,400)
-                    )
-            ).applySafe(this);
-            initFromPreferences();
-        } else if (!visible && isShowing()){
-            new WindowGeometry(this).remember(getClass().getName() + ".geometry");
-        }
-        super.setVisible(visible);
-    }
-
-    protected void setCanceled(boolean canceled) {
-        this.canceled = canceled;
-    }
-
-    class AuthorisationProcedureChangeListener implements ItemListener {
-        public void itemStateChanged(ItemEvent arg0) {
-            refreshAuthorisationProcedurePanel();
-        }
-    }
-
-    class CancelAction extends AbstractAction {
-        public CancelAction() {
-            putValue(NAME, tr("Cancel"));
-            putValue(SMALL_ICON, ImageProvider.get("cancel"));
-            putValue(SHORT_DESCRIPTION, tr("Close the dialog and cancel authorisation"));
-        }
-
-        public void cancel() {
-            setCanceled(true);
-            setVisible(false);
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            cancel();
-        }
-    }
-
-    class AcceptAccessTokenAction extends AbstractAction implements PropertyChangeListener {
-        private OAuthToken token;
-
-        public AcceptAccessTokenAction() {
-            putValue(NAME, tr("Accept Access Token"));
-            putValue(SMALL_ICON, ImageProvider.get("ok"));
-            putValue(SHORT_DESCRIPTION, tr("Close the dialog and accept the Access Token"));
-            updateEnabledState(null);
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            setCanceled(false);
-            setVisible(false);
-        }
-
-        public void updateEnabledState(OAuthToken token) {
-            setEnabled(token != null);
-        }
-
-        public void propertyChange(PropertyChangeEvent evt) {
-            if (!evt.getPropertyName().equals(AbstractAuthorisationUI.ACCESS_TOKEN_PROP))
-                return;
-            token = (OAuthToken)evt.getNewValue();
-            updateEnabledState(token);
-        }
-    }
-
-    class WindowEventHandler extends WindowAdapter {
-        @Override
-        public void windowClosing(WindowEvent arg0) {
-            new CancelAction().cancel();
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java	(revision 2861)
@@ -0,0 +1,386 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.KeyStroke;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.oauth.OAuthParameters;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.WindowGeometry;
+
+/**
+ * This wizard walks the user to the necessary steps to retrieve an OAuth Access Token which
+ * allows JOSM to access the OSM API on the users behalf.
+ * 
+ */
+public class OAuthAuthorizationWizard extends JDialog {
+    static private final Logger logger = Logger.getLogger(OAuthAuthorizationWizard.class.getName());
+
+    private HtmlPanel pnlMessage;
+    private boolean canceled;
+    private String apiUrl;
+
+    private AuthorizationProcedureComboBox cbAuthorisationProcedure;
+    private FullyAutomaticAuthorizationUI pnlFullyAutomaticAuthorisationUI;
+    private SemiAutomaticAuthorizationUI pnlSemiAutomaticAuthorisationUI;
+    private ManualAuthorizationUI pnlManualAuthorisationUI;
+    private JScrollPane spAuthorisationProcedureUI;
+
+    /**
+     * Builds the row with the action buttons
+     * 
+     * @return
+     */
+    protected JPanel buildButtonRow(){
+        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
+
+        AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction();
+        pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
+        pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
+        pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
+
+        pnl.add(new SideButton(actAcceptAccessToken));
+        pnl.add(new SideButton(new CancelAction()));
+        pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"))));
+
+        return pnl;
+    }
+
+    /**
+     * Builds the panel with general information in the header
+     * 
+     * @return
+     */
+    protected JPanel buildHeaderInfoPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout());
+        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+        GridBagConstraints gc = new GridBagConstraints();
+
+        // the oauth logo in the header
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        gc.gridwidth = 2;
+        JLabel lbl = new JLabel();
+        lbl.setIcon(ImageProvider.get("oauth", "oauth-logo"));
+        lbl.setOpaque(true);
+        pnl.add(lbl, gc);
+
+        // OAuth in a nutshell ...
+        gc.gridy  = 1;
+        gc.insets = new Insets(5,0,0,5);
+        pnlMessage = new HtmlPanel();
+        pnlMessage.setText("<html><body>"
+                + "With OAuth you grant JOSM the right to upload map data and GPS tracks "
+                + "on your behalf (<a href=\"urn:josm-oauth-info\">more info...</a>)."
+                + "</body></html>"
+        );
+        pnl.add(pnlMessage, gc);
+
+        // the authorisation procedure
+        gc.gridy  = 2;
+        gc.gridwidth = 1;
+        gc.weightx = 0.0;
+        lbl = new JLabel(tr("Please select an authorisation procedure: "));
+        lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
+        pnl.add(lbl,gc);
+
+        gc.gridx = 1;
+        gc.gridwidth = 1;
+        gc.weightx = 1.0;
+        pnl.add(cbAuthorisationProcedure = new AuthorizationProcedureComboBox(),gc);
+        cbAuthorisationProcedure.addItemListener(new AuthorisationProcedureChangeListener());
+        return pnl;
+    }
+
+    /**
+     * Refreshes the view of the authorisation panel, depending on the authorisation procedure
+     * currently selected
+     */
+    protected void refreshAuthorisationProcedurePanel() {
+        AuthorizationProcedure procedure = (AuthorizationProcedure)cbAuthorisationProcedure.getSelectedItem();
+        switch(procedure) {
+        case FULLY_AUTOMATIC:
+            spAuthorisationProcedureUI.getViewport().setView(pnlFullyAutomaticAuthorisationUI);
+            pnlFullyAutomaticAuthorisationUI.revalidate();
+            break;
+        case SEMI_AUTOMATIC:
+            spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);
+            pnlSemiAutomaticAuthorisationUI.revalidate();
+            break;
+        case MANUALLY:
+            spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI);
+            pnlManualAuthorisationUI.revalidate();
+            break;
+        }
+        validate();
+        repaint();
+    }
+
+    /**
+     * builds the UI
+     */
+    protected void build() {
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(buildHeaderInfoPanel(), BorderLayout.NORTH);
+
+        pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI();
+        pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
+
+        pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorizationUI();
+        pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
+
+        pnlManualAuthorisationUI = new ManualAuthorizationUI();
+        pnlManualAuthorisationUI.setApiUrl(apiUrl);
+
+        spAuthorisationProcedureUI = new JScrollPane(new JPanel());
+        spAuthorisationProcedureUI.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        spAuthorisationProcedureUI.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        spAuthorisationProcedureUI.getVerticalScrollBar().addComponentListener(
+                new ComponentListener() {
+                    public void componentShown(ComponentEvent e) {
+                        spAuthorisationProcedureUI.setBorder(UIManager.getBorder("ScrollPane.border"));
+                    }
+
+                    public void componentHidden(ComponentEvent e) {
+                        spAuthorisationProcedureUI.setBorder(null);
+                    }
+
+                    public void componentResized(ComponentEvent e) {}
+                    public void componentMoved(ComponentEvent e) {}
+                }
+        );
+        getContentPane().add(spAuthorisationProcedureUI, BorderLayout.CENTER);
+        getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
+
+        addWindowListener(new WindowEventHandler());
+        getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
+        getRootPane().getActionMap().put("cancel", new CancelAction());
+
+        refreshAuthorisationProcedurePanel();
+
+        HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/OAuthAuthorisationWizard"));
+    }
+
+    /**
+     * Creates the wizard.
+     * 
+     * @param apiUrl the API URL. Must not be null.
+     * @throws IllegalArgumentException thrown if apiUrl is null
+     */
+    public OAuthAuthorizationWizard(String apiUrl) throws IllegalArgumentException {
+        super(JOptionPane.getFrameForComponent(Main.parent),true /* modal */);
+        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
+        build();
+        setApiUrl(apiUrl);
+    }
+
+    /**
+     * Creates the wizard.
+     * 
+     * @param parent the component relative to which the dialog is displayed
+     * @param apiUrl the API URL. Must not be null.
+     * @throws IllegalArgumentException thrown if apiUrl is null
+     */
+    public OAuthAuthorizationWizard(Component parent, String apiUrl) {
+        super(JOptionPane.getFrameForComponent(parent),true /* modal */);
+        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
+        build();
+        setApiUrl(apiUrl);
+    }
+
+    /**
+     * Sets the API URL for the API for which this wizard is generating
+     * an Access Token.
+     * 
+     * @param apiUrl the API URL. Must not be null.
+     * @throws IllegalArgumentException thrown if apiUrl is null
+     */
+    public void setApiUrl(String apiUrl) throws IllegalArgumentException{
+        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
+        this.apiUrl = apiUrl;
+        setTitle(tr("Get an Access Token for ''{0}''", apiUrl));
+        if (pnlFullyAutomaticAuthorisationUI != null) {
+            pnlFullyAutomaticAuthorisationUI.setApiUrl(apiUrl);
+        }
+        if (pnlSemiAutomaticAuthorisationUI != null) {
+            pnlSemiAutomaticAuthorisationUI.setApiUrl(apiUrl);
+        }
+        if (pnlManualAuthorisationUI != null) {
+            pnlManualAuthorisationUI.setApiUrl(apiUrl);
+        }
+
+    }
+
+    /**
+     * Replies true if the dialog was cancelled
+     * 
+     * @return true if the dialog was cancelled
+     */
+    public boolean isCanceled() {
+        return canceled;
+    }
+
+    protected AbstractAuthorizationUI getCurrentAuthorisationUI() {
+        switch((AuthorizationProcedure)cbAuthorisationProcedure.getSelectedItem()) {
+        case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI;
+        case MANUALLY: return pnlManualAuthorisationUI;
+        case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;
+        default: return null;
+        }
+    }
+
+    /**
+     * Replies the Access Token entered using the wizard
+     * 
+     * @return the access token. May be null if the wizard was canceled.
+     */
+    public OAuthToken getAccessToken() {
+        return getCurrentAuthorisationUI().getAccessToken();
+    }
+
+    /**
+     * Replies the current OAuth parameters.
+     * 
+     * @return the current OAuth parameters.
+     */
+    public OAuthParameters getOAuthParameters() {
+        return getCurrentAuthorisationUI().getOAuthParameters();
+    }
+
+    /**
+     * Replies true if the currently selected Access Token shall be saved to
+     * the preferences.
+     * 
+     * @return true if the currently selected Access Token shall be saved to
+     * the preferences
+     */
+    public boolean isSaveAccessTokenToPreferences() {
+        return getCurrentAuthorisationUI().isSaveAccessTokenToPreferences();
+    }
+
+    /**
+     * Initializes the dialog with values from the preferences
+     * 
+     */
+    public void initFromPreferences() {
+        pnlFullyAutomaticAuthorisationUI.initFromPreferences(Main.pref);
+        pnlSemiAutomaticAuthorisationUI.initFromPreferences(Main.pref);
+        pnlManualAuthorisationUI.initFromPreferences(Main.pref);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            new WindowGeometry(
+                    getClass().getName() + ".geometry",
+                    WindowGeometry.centerInWindow(
+                            Main.parent,
+                            new Dimension(400,400)
+                    )
+            ).applySafe(this);
+            initFromPreferences();
+        } else if (!visible && isShowing()){
+            new WindowGeometry(this).remember(getClass().getName() + ".geometry");
+        }
+        super.setVisible(visible);
+    }
+
+    protected void setCanceled(boolean canceled) {
+        this.canceled = canceled;
+    }
+
+    class AuthorisationProcedureChangeListener implements ItemListener {
+        public void itemStateChanged(ItemEvent arg0) {
+            refreshAuthorisationProcedurePanel();
+        }
+    }
+
+    class CancelAction extends AbstractAction {
+        public CancelAction() {
+            putValue(NAME, tr("Cancel"));
+            putValue(SMALL_ICON, ImageProvider.get("cancel"));
+            putValue(SHORT_DESCRIPTION, tr("Close the dialog and cancel authorisation"));
+        }
+
+        public void cancel() {
+            setCanceled(true);
+            setVisible(false);
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            cancel();
+        }
+    }
+
+    class AcceptAccessTokenAction extends AbstractAction implements PropertyChangeListener {
+        private OAuthToken token;
+
+        public AcceptAccessTokenAction() {
+            putValue(NAME, tr("Accept Access Token"));
+            putValue(SMALL_ICON, ImageProvider.get("ok"));
+            putValue(SHORT_DESCRIPTION, tr("Close the dialog and accept the Access Token"));
+            updateEnabledState(null);
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            setCanceled(false);
+            setVisible(false);
+        }
+
+        public void updateEnabledState(OAuthToken token) {
+            setEnabled(token != null);
+        }
+
+        public void propertyChange(PropertyChangeEvent evt) {
+            if (!evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP))
+                return;
+            token = (OAuthToken)evt.getNewValue();
+            updateEnabledState(token);
+        }
+    }
+
+    class WindowEventHandler extends WindowAdapter {
+        @Override
+        public void windowClosing(WindowEvent arg0) {
+            new CancelAction().cancel();
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java	(revision 2860)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java	(revision 2861)
@@ -2,5 +2,5 @@
 package org.openstreetmap.josm.gui.oauth;
 
-public class OsmLoginFailedException extends OsmOAuthAuthorisationException{
+public class OsmLoginFailedException extends OsmOAuthAuthorizationException{
 
     public OsmLoginFailedException() {
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorisationClient.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorisationClient.java	(revision 2860)
+++ 	(revision )
@@ -1,517 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Field;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.logging.Logger;
-
-import oauth.signpost.OAuth;
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.OAuthProvider;
-import oauth.signpost.basic.DefaultOAuthProvider;
-import oauth.signpost.exception.OAuthCommunicationException;
-import oauth.signpost.exception.OAuthException;
-
-import org.openstreetmap.josm.data.Version;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.data.oauth.OsmPrivileges;
-import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
-import org.openstreetmap.josm.gui.progress.ProgressMonitor;
-import org.openstreetmap.josm.io.OsmTransferCancelledException;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-
-public class OsmOAuthAuthorisationClient {
-    static private final Logger logger = Logger.getLogger(OsmOAuthAuthorisationClient.class.getName());
-
-    private OAuthParameters oauthProviderParameters;
-    private OAuthConsumer consumer;
-    private OAuthProvider provider;
-    private boolean canceled;
-    private HttpURLConnection connection;
-
-    /**
-     * Creates a new authorisation client with default OAuth parameters
-     * 
-     */
-    public OsmOAuthAuthorisationClient() {
-        oauthProviderParameters = OAuthParameters.createDefault();
-        consumer = oauthProviderParameters.buildConsumer();
-        provider = oauthProviderParameters.buildProvider(consumer);
-    }
-
-    /**
-     * Creates a new authorisation client with the parameters <code>parameters</code>.
-     * 
-     * @param parameters the OAuth parameters. Must not be null.
-     * @throws IllegalArgumentException thrown if parameters is null
-     */
-    public OsmOAuthAuthorisationClient(OAuthParameters parameters) throws IllegalArgumentException {
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        oauthProviderParameters = new OAuthParameters(parameters);
-        consumer = oauthProviderParameters.buildConsumer();
-        provider = oauthProviderParameters.buildProvider(consumer);
-    }
-
-    /**
-     * Creates a new authorisation client with the parameters <code>parameters</code>
-     * and an already known Request Token.
-     * 
-     * @param parameters the OAuth parameters. Must not be null.
-     * @param requestToken the request token. Must not be null.
-     * @throws IllegalArgumentException thrown if parameters is null
-     * @throws IllegalArgumentException thrown if requestToken is null
-     */
-    public OsmOAuthAuthorisationClient(OAuthParameters parameters, OAuthToken requestToken) throws IllegalArgumentException {
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        oauthProviderParameters = new OAuthParameters(parameters);
-        consumer = oauthProviderParameters.buildConsumer();
-        provider = oauthProviderParameters.buildProvider(consumer);
-        consumer.setTokenWithSecret(requestToken.getKey(), requestToken.getSecret());
-    }
-
-    public void cancel() {
-        DefaultOAuthProvider p  = (DefaultOAuthProvider)provider;
-        canceled = true;
-        if (p != null) {
-            try {
-                Field f =  p.getClass().getDeclaredField("connection");
-                f.setAccessible(true);
-                HttpURLConnection con = (HttpURLConnection)f.get(p);
-                if (con != null) {
-                    con.disconnect();
-                }
-            } catch(NoSuchFieldException e) {
-                e.printStackTrace();
-                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
-            } catch(SecurityException e) {
-                e.printStackTrace();
-                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
-            } catch(IllegalAccessException e) {
-                e.printStackTrace();
-                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
-            }
-        }
-        synchronized(this) {
-            if (connection != null) {
-                connection.disconnect();
-            }
-        }
-    }
-
-    /**
-     * Submits a request for a Request Token to the Request Token Endpoint Url of the OAuth Service
-     * Provider and replies the request token.
-     * 
-     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
-     * @return the OAuth Request Token
-     * @throws OsmOAuthAuthorisationException thrown if something goes wrong when retrieving the request token
-     */
-    public OAuthToken getRequestToken(ProgressMonitor monitor) throws OsmOAuthAuthorisationException, OsmTransferCancelledException {
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask("");
-            monitor.indeterminateSubTask(tr("Retrieving OAuth Request Token from ''{0}''", oauthProviderParameters.getRequestTokenUrl()));
-            provider.retrieveRequestToken(null);
-            return OAuthToken.createToken(consumer);
-        } catch(OAuthCommunicationException e){
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            throw new OsmOAuthAuthorisationException(e);
-        } catch(OAuthException e){
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            throw new OsmOAuthAuthorisationException(e);
-        } finally {
-            monitor.finishTask();
-        }
-    }
-
-    /**
-     * Submits a request for an Access Token to the Access Token Endpoint Url of the OAuth Service
-     * Provider and replies the request token.
-     * 
-     * You must have requested a Request Token using {@see #getRequestToken(ProgressMonitor)} first.
-     * 
-     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
-     * @return the OAuth Access Token
-     * @throws OsmOAuthAuthorisationException thrown if something goes wrong when retrieving the request token
-     * @see #getRequestToken(ProgressMonitor)
-     */
-    public OAuthToken getAccessToken(ProgressMonitor monitor) throws OsmOAuthAuthorisationException, OsmTransferCancelledException {
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask("");
-            monitor.indeterminateSubTask(tr("Retrieving OAuth Access Token from ''{0}''", oauthProviderParameters.getAccessTokenUrl()));
-            provider.retrieveAccessToken(null);
-            return OAuthToken.createToken(consumer);
-        } catch(OAuthCommunicationException e){
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            throw new OsmOAuthAuthorisationException(e);
-        } catch(OAuthException e){
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            throw new OsmOAuthAuthorisationException(e);
-        } finally {
-            monitor.finishTask();
-        }
-    }
-
-    /**
-     * Builds the authorise URL for a given Request Token. Users can be redirected to this URL.
-     * There they can login to OSM and authorise the request.
-     * 
-     * @param requestToken  the request token
-     * @return  the authorise URL for this request
-     */
-    public String getAuthoriseUrl(OAuthToken requestToken) {
-        StringBuilder sb = new StringBuilder();
-
-        // OSM is an OAuth 1.0 provider and JOSM isn't a web app. We just add the oauth request token to
-        // the authorisation request, no callback parameter.
-        //
-        sb.append(oauthProviderParameters.getAuthoriseUrl()).append("?")
-        .append(OAuth.OAUTH_TOKEN).append("=").append(requestToken.getKey());
-        return sb.toString();
-    }
-
-    protected String extractOsmSession(HttpURLConnection connection) {
-        List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
-        if (setCookies == null)
-            // no cookies set
-            return null;
-
-        for (String setCookie: setCookies) {
-            String[] kvPairs = setCookie.split(";");
-            if (kvPairs == null || kvPairs.length == 0) {
-                continue;
-            }
-            for (String kvPair : kvPairs) {
-                kvPair = kvPair.trim();
-                String [] kv = kvPair.split("=");
-                if (kv == null || kv.length != 2) {
-                    continue;
-                }
-                if (kv[0].equals("_osm_session"))
-                    // osm session cookie found
-                    return kv[1];
-            }
-        }
-        return null;
-    }
-
-    protected String buildPostRequest(Map<String,String> parameters) throws OsmOAuthAuthorisationException {
-        try {
-            StringBuilder sb = new StringBuilder();
-
-            for(Iterator<Entry<String,String>> it = parameters.entrySet().iterator(); it.hasNext();) {
-                Entry<String,String> entry = it.next();
-                String value = entry.getValue();
-                value = (value == null) ? "" : value;
-                sb.append(entry.getKey()).append("=").append(URLEncoder.encode(value, "UTF-8"));
-                if (it.hasNext()) {
-                    sb.append("&");
-                }
-            }
-            return sb.toString();
-        } catch(UnsupportedEncodingException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        }
-    }
-
-    /**
-     * Derives the OSM login URL from the OAuth Authorization Website URL
-     * 
-     * @return the OSM login URL
-     * @throws OsmOAuthAuthorisationException thrown if something went wrong, in particular if the
-     * URLs are malformed
-     */
-    public String buildOsmLoginUrl() throws OsmOAuthAuthorisationException{
-        try {
-            URL autUrl = new URL(oauthProviderParameters.getAuthoriseUrl());
-            // FIXME: as soon as the OSM website provides HTTPS protected access to the login
-            // page we can replace the protocol with https
-            //
-            URL url = new URL("http", autUrl.getHost(), autUrl.getPort(), "/login");
-            return url.toString();
-        } catch(MalformedURLException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        }
-    }
-
-    /**
-     * Derives the OSM logout URL from the OAuth Authorization Website URL
-     * 
-     * @return the OSM logout URL
-     * @throws OsmOAuthAuthorisationException thrown if something went wrong, in particular if the
-     * URLs are malformed
-     */
-    protected String buildOsmLogoutUrl() throws OsmOAuthAuthorisationException{
-        try {
-            URL autUrl = new URL(oauthProviderParameters.getAuthoriseUrl());
-            URL url = new URL("http", autUrl.getHost(), autUrl.getPort(), "/logout");
-            return url.toString();
-        } catch(MalformedURLException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        }
-    }
-
-    /**
-     * Submits a request to the OSM website for a login form. The OSM website replies a session ID in
-     * a cookie.
-     * 
-     * @return the session ID
-     * @throws OsmOAuthAuthorisationException thrown if something went wrong
-     */
-    protected String fetchOsmWebsiteSessionId() throws OsmOAuthAuthorisationException {
-        try {
-            StringBuilder sb = new StringBuilder();
-            sb.append(buildOsmLoginUrl()).append("?cookie_test=true");
-            URL url = new URL(sb.toString());
-            synchronized(this) {
-                connection = (HttpURLConnection)url.openConnection();
-            }
-            connection.setRequestMethod("GET");
-            connection.setDoInput(true);
-            connection.setDoOutput(false);
-            setHttpRequestParameters(connection);
-            connection.connect();
-            String sessionId = extractOsmSession(connection);
-            if (sessionId == null)
-                throw new OsmOAuthAuthorisationException(tr("OSM website did not return a session cookie in response to ''{0}'',", url.toString()));
-            return sessionId;
-        } catch(IOException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        } finally {
-            synchronized(this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void authenticateOsmSession(String sessionId, String userName, String password) throws OsmLoginFailedException {
-        DataOutputStream dout = null;
-        try {
-            URL url = new URL(buildOsmLoginUrl());
-            synchronized(this) {
-                connection = (HttpURLConnection)url.openConnection();
-            }
-            connection.setRequestMethod("POST");
-            connection.setDoInput(true);
-            connection.setDoOutput(true);
-            connection.setUseCaches(false);
-
-            Map<String,String> parameters = new HashMap<String, String>();
-            parameters.put("user[email]", userName);
-            parameters.put("user[password]", password);
-            parameters.put("referer", "/");
-            parameters.put("commit", "Login");
-
-            String request = buildPostRequest(parameters);
-
-            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
-            connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
-            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
-            // make sure we can catch 302 Moved Temporarily below
-            connection.setInstanceFollowRedirects(false);
-            setHttpRequestParameters(connection);
-
-            connection.connect();
-
-            dout = new DataOutputStream(connection.getOutputStream());
-            dout.writeBytes(request);
-            dout.flush();
-            dout.close();
-
-            // after a successful login the OSM website sends a redirect to a follow up page. Everything
-            // else, including a 200 OK, is a failed login. A 200 OK is replied if the login form with
-            // an error page is sent to back to the user.
-            //
-            int retCode = connection.getResponseCode();
-            if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)
-                throw new OsmOAuthAuthorisationException(tr("Failed to authenticate user ''{0}'' with password ''***'' as OAuth user", userName));
-        } catch(OsmOAuthAuthorisationException e) {
-            throw new OsmLoginFailedException(e.getCause());
-        } catch(IOException e) {
-            throw new OsmLoginFailedException(e);
-        } finally {
-            if (dout != null) {
-                try {
-                    dout.close();
-                } catch(IOException e) { /* ignore */ }
-            }
-            synchronized(this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void logoutOsmSession(String sessionId) throws OsmOAuthAuthorisationException {
-        try {
-            URL url = new URL(buildOsmLogoutUrl());
-            synchronized(this) {
-                connection = (HttpURLConnection)url.openConnection();
-            }
-            connection.setRequestMethod("GET");
-            connection.setDoInput(true);
-            connection.setDoOutput(false);
-            setHttpRequestParameters(connection);
-            connection.connect();
-        }catch(MalformedURLException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        } catch(IOException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        }  finally {
-            synchronized(this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void sendAuthorisationRequest(String sessionId, OAuthToken requestToken, OsmPrivileges privileges) throws OsmOAuthAuthorisationException {
-        Map<String, String> parameters = new HashMap<String, String>();
-        parameters.put("oauth_token", requestToken.getKey());
-        parameters.put("oauth_callback", "");
-        if (privileges.isAllowWriteApi()) {
-            parameters.put("allow_write_api", "yes");
-        }
-        if (privileges.isAllowWriteGpx()) {
-            parameters.put("allow_write_gpx", "yes");
-        }
-        if (privileges.isAllowReadGpx()) {
-            parameters.put("allow_read_gpx", "yes");
-        }
-        if (privileges.isAllowWritePrefs()) {
-            parameters.put("allow_write_prefs", "yes");
-        }
-        if (privileges.isAllowReadPrefs()) {
-            parameters.put("allow_read_prefs", "yes");
-        }
-
-        parameters.put("commit", "Save changes");
-
-        String request = buildPostRequest(parameters);
-        DataOutputStream dout = null;
-        try {
-            URL url = new URL(oauthProviderParameters.getAuthoriseUrl());
-            synchronized(this) {
-                connection = (HttpURLConnection)url.openConnection();
-            }
-            connection.setRequestMethod("POST");
-            connection.setDoInput(true);
-            connection.setDoOutput(true);
-            connection.setUseCaches(false);
-            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
-            connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
-            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
-            connection.setInstanceFollowRedirects(false);
-            setHttpRequestParameters(connection);
-
-            connection.connect();
-
-            dout = new DataOutputStream(connection.getOutputStream());
-            dout.writeBytes(request);
-            dout.flush();
-            dout.close();
-
-            int retCode = connection.getResponseCode();
-            if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)
-                throw new OsmOAuthAuthorisationException(tr("Failed to authorise OAuth request  ''{0}''", requestToken.getKey()));
-        } catch(MalformedURLException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        } catch(IOException e) {
-            throw new OsmOAuthAuthorisationException(e);
-        } finally {
-            if (dout != null) {
-                try {
-                    dout.close();
-                } catch(IOException e) { /* ignore */ }
-            }
-            synchronized(this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void setHttpRequestParameters(HttpURLConnection connection) {
-        connection.setRequestProperty("User-Agent", Version.getInstance().getAgentString());
-        connection.setRequestProperty("Host", connection.getURL().getHost());
-    }
-
-    /**
-     * Automatically authorises a request token for a set of privileges.
-     * 
-     * @param requestToken the request token. Must not be null.
-     * @param osmUserName the OSM user name. Must not be null.
-     * @param osmPassword the OSM password. Must not be null.
-     * @param privileges the set of privileges. Must not be null.
-     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
-     * @throws IllegalArgumentException thrown if requestToken is null
-     * @throws IllegalArgumentException thrown if osmUserName is null
-     * @throws IllegalArgumentException thrown if osmPassword is null
-     * @throws IllegalArgumentException thrown if privileges is null
-     * @throws OsmOAuthAuthorisationException thrown if the authorisation fails
-     * @throws OsmTransferCancelledException thrown if the task is cancelled by the user
-     */
-    public void authorise(OAuthToken requestToken, String osmUserName, String osmPassword, OsmPrivileges privileges, ProgressMonitor monitor) throws IllegalArgumentException, OsmOAuthAuthorisationException, OsmTransferCancelledException{
-        CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");
-        CheckParameterUtil.ensureParameterNotNull(osmUserName, "osmUserName");
-        CheckParameterUtil.ensureParameterNotNull(osmPassword, "osmPassword");
-        CheckParameterUtil.ensureParameterNotNull(privileges, "privileges");
-
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask(tr("Authorising OAuth Request token ''{0}'' at the OSM website ...", requestToken.getKey()));
-            monitor.setTicksCount(4);
-            monitor.indeterminateSubTask(tr("Initializing a session at the OSM website..."));
-            String sessionId = fetchOsmWebsiteSessionId();
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Authenticating the session for user ''{0}''...", osmUserName));
-            authenticateOsmSession(sessionId, osmUserName, osmPassword);
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Authorising request token ''{0}''...", requestToken.getKey()));
-            sendAuthorisationRequest(sessionId, requestToken, privileges);
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Logging out session ''{0}''...", sessionId));
-            logoutOsmSession(sessionId);
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            monitor.worked(1);
-        } catch(OsmOAuthAuthorisationException e) {
-            if (canceled)
-                throw new OsmTransferCancelledException();
-            throw e;
-        } finally {
-            monitor.finishTask();
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorisationException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorisationException.java	(revision 2860)
+++ 	(revision )
@@ -1,21 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-public class OsmOAuthAuthorisationException extends Exception {
-
-    public OsmOAuthAuthorisationException() {
-        super();
-    }
-
-    public OsmOAuthAuthorisationException(String arg0, Throwable arg1) {
-        super(arg0, arg1);
-    }
-
-    public OsmOAuthAuthorisationException(String arg0) {
-        super(arg0);
-    }
-
-    public OsmOAuthAuthorisationException(Throwable arg0) {
-        super(arg0);
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 2861)
@@ -0,0 +1,517 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+
+import oauth.signpost.OAuth;
+import oauth.signpost.OAuthConsumer;
+import oauth.signpost.OAuthProvider;
+import oauth.signpost.basic.DefaultOAuthProvider;
+import oauth.signpost.exception.OAuthCommunicationException;
+import oauth.signpost.exception.OAuthException;
+
+import org.openstreetmap.josm.data.Version;
+import org.openstreetmap.josm.data.oauth.OAuthParameters;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.data.oauth.OsmPrivileges;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.OsmTransferCancelledException;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+public class OsmOAuthAuthorizationClient {
+    static private final Logger logger = Logger.getLogger(OsmOAuthAuthorizationClient.class.getName());
+
+    private OAuthParameters oauthProviderParameters;
+    private OAuthConsumer consumer;
+    private OAuthProvider provider;
+    private boolean canceled;
+    private HttpURLConnection connection;
+
+    /**
+     * Creates a new authorisation client with default OAuth parameters
+     * 
+     */
+    public OsmOAuthAuthorizationClient() {
+        oauthProviderParameters = OAuthParameters.createDefault();
+        consumer = oauthProviderParameters.buildConsumer();
+        provider = oauthProviderParameters.buildProvider(consumer);
+    }
+
+    /**
+     * Creates a new authorisation client with the parameters <code>parameters</code>.
+     * 
+     * @param parameters the OAuth parameters. Must not be null.
+     * @throws IllegalArgumentException thrown if parameters is null
+     */
+    public OsmOAuthAuthorizationClient(OAuthParameters parameters) throws IllegalArgumentException {
+        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
+        oauthProviderParameters = new OAuthParameters(parameters);
+        consumer = oauthProviderParameters.buildConsumer();
+        provider = oauthProviderParameters.buildProvider(consumer);
+    }
+
+    /**
+     * Creates a new authorisation client with the parameters <code>parameters</code>
+     * and an already known Request Token.
+     * 
+     * @param parameters the OAuth parameters. Must not be null.
+     * @param requestToken the request token. Must not be null.
+     * @throws IllegalArgumentException thrown if parameters is null
+     * @throws IllegalArgumentException thrown if requestToken is null
+     */
+    public OsmOAuthAuthorizationClient(OAuthParameters parameters, OAuthToken requestToken) throws IllegalArgumentException {
+        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
+        oauthProviderParameters = new OAuthParameters(parameters);
+        consumer = oauthProviderParameters.buildConsumer();
+        provider = oauthProviderParameters.buildProvider(consumer);
+        consumer.setTokenWithSecret(requestToken.getKey(), requestToken.getSecret());
+    }
+
+    public void cancel() {
+        DefaultOAuthProvider p  = (DefaultOAuthProvider)provider;
+        canceled = true;
+        if (p != null) {
+            try {
+                Field f =  p.getClass().getDeclaredField("connection");
+                f.setAccessible(true);
+                HttpURLConnection con = (HttpURLConnection)f.get(p);
+                if (con != null) {
+                    con.disconnect();
+                }
+            } catch(NoSuchFieldException e) {
+                e.printStackTrace();
+                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
+            } catch(SecurityException e) {
+                e.printStackTrace();
+                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
+            } catch(IllegalAccessException e) {
+                e.printStackTrace();
+                System.err.println(tr("Warning: failed to cancel running OAuth operation"));
+            }
+        }
+        synchronized(this) {
+            if (connection != null) {
+                connection.disconnect();
+            }
+        }
+    }
+
+    /**
+     * Submits a request for a Request Token to the Request Token Endpoint Url of the OAuth Service
+     * Provider and replies the request token.
+     * 
+     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
+     * @return the OAuth Request Token
+     * @throws OsmOAuthAuthorizationException thrown if something goes wrong when retrieving the request token
+     */
+    public OAuthToken getRequestToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCancelledException {
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            monitor.beginTask("");
+            monitor.indeterminateSubTask(tr("Retrieving OAuth Request Token from ''{0}''", oauthProviderParameters.getRequestTokenUrl()));
+            provider.retrieveRequestToken(null);
+            return OAuthToken.createToken(consumer);
+        } catch(OAuthCommunicationException e){
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            throw new OsmOAuthAuthorizationException(e);
+        } catch(OAuthException e){
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            throw new OsmOAuthAuthorizationException(e);
+        } finally {
+            monitor.finishTask();
+        }
+    }
+
+    /**
+     * Submits a request for an Access Token to the Access Token Endpoint Url of the OAuth Service
+     * Provider and replies the request token.
+     * 
+     * You must have requested a Request Token using {@see #getRequestToken(ProgressMonitor)} first.
+     * 
+     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
+     * @return the OAuth Access Token
+     * @throws OsmOAuthAuthorizationException thrown if something goes wrong when retrieving the request token
+     * @see #getRequestToken(ProgressMonitor)
+     */
+    public OAuthToken getAccessToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCancelledException {
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            monitor.beginTask("");
+            monitor.indeterminateSubTask(tr("Retrieving OAuth Access Token from ''{0}''", oauthProviderParameters.getAccessTokenUrl()));
+            provider.retrieveAccessToken(null);
+            return OAuthToken.createToken(consumer);
+        } catch(OAuthCommunicationException e){
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            throw new OsmOAuthAuthorizationException(e);
+        } catch(OAuthException e){
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            throw new OsmOAuthAuthorizationException(e);
+        } finally {
+            monitor.finishTask();
+        }
+    }
+
+    /**
+     * Builds the authorise URL for a given Request Token. Users can be redirected to this URL.
+     * There they can login to OSM and authorise the request.
+     * 
+     * @param requestToken  the request token
+     * @return  the authorise URL for this request
+     */
+    public String getAuthoriseUrl(OAuthToken requestToken) {
+        StringBuilder sb = new StringBuilder();
+
+        // OSM is an OAuth 1.0 provider and JOSM isn't a web app. We just add the oauth request token to
+        // the authorisation request, no callback parameter.
+        //
+        sb.append(oauthProviderParameters.getAuthoriseUrl()).append("?")
+        .append(OAuth.OAUTH_TOKEN).append("=").append(requestToken.getKey());
+        return sb.toString();
+    }
+
+    protected String extractOsmSession(HttpURLConnection connection) {
+        List<String> setCookies = connection.getHeaderFields().get("Set-Cookie");
+        if (setCookies == null)
+            // no cookies set
+            return null;
+
+        for (String setCookie: setCookies) {
+            String[] kvPairs = setCookie.split(";");
+            if (kvPairs == null || kvPairs.length == 0) {
+                continue;
+            }
+            for (String kvPair : kvPairs) {
+                kvPair = kvPair.trim();
+                String [] kv = kvPair.split("=");
+                if (kv == null || kv.length != 2) {
+                    continue;
+                }
+                if (kv[0].equals("_osm_session"))
+                    // osm session cookie found
+                    return kv[1];
+            }
+        }
+        return null;
+    }
+
+    protected String buildPostRequest(Map<String,String> parameters) throws OsmOAuthAuthorizationException {
+        try {
+            StringBuilder sb = new StringBuilder();
+
+            for(Iterator<Entry<String,String>> it = parameters.entrySet().iterator(); it.hasNext();) {
+                Entry<String,String> entry = it.next();
+                String value = entry.getValue();
+                value = (value == null) ? "" : value;
+                sb.append(entry.getKey()).append("=").append(URLEncoder.encode(value, "UTF-8"));
+                if (it.hasNext()) {
+                    sb.append("&");
+                }
+            }
+            return sb.toString();
+        } catch(UnsupportedEncodingException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        }
+    }
+
+    /**
+     * Derives the OSM login URL from the OAuth Authorization Website URL
+     * 
+     * @return the OSM login URL
+     * @throws OsmOAuthAuthorizationException thrown if something went wrong, in particular if the
+     * URLs are malformed
+     */
+    public String buildOsmLoginUrl() throws OsmOAuthAuthorizationException{
+        try {
+            URL autUrl = new URL(oauthProviderParameters.getAuthoriseUrl());
+            // FIXME: as soon as the OSM website provides HTTPS protected access to the login
+            // page we can replace the protocol with https
+            //
+            URL url = new URL("http", autUrl.getHost(), autUrl.getPort(), "/login");
+            return url.toString();
+        } catch(MalformedURLException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        }
+    }
+
+    /**
+     * Derives the OSM logout URL from the OAuth Authorization Website URL
+     * 
+     * @return the OSM logout URL
+     * @throws OsmOAuthAuthorizationException thrown if something went wrong, in particular if the
+     * URLs are malformed
+     */
+    protected String buildOsmLogoutUrl() throws OsmOAuthAuthorizationException{
+        try {
+            URL autUrl = new URL(oauthProviderParameters.getAuthoriseUrl());
+            URL url = new URL("http", autUrl.getHost(), autUrl.getPort(), "/logout");
+            return url.toString();
+        } catch(MalformedURLException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        }
+    }
+
+    /**
+     * Submits a request to the OSM website for a login form. The OSM website replies a session ID in
+     * a cookie.
+     * 
+     * @return the session ID
+     * @throws OsmOAuthAuthorizationException thrown if something went wrong
+     */
+    protected String fetchOsmWebsiteSessionId() throws OsmOAuthAuthorizationException {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append(buildOsmLoginUrl()).append("?cookie_test=true");
+            URL url = new URL(sb.toString());
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+            }
+            connection.setRequestMethod("GET");
+            connection.setDoInput(true);
+            connection.setDoOutput(false);
+            setHttpRequestParameters(connection);
+            connection.connect();
+            String sessionId = extractOsmSession(connection);
+            if (sessionId == null)
+                throw new OsmOAuthAuthorizationException(tr("OSM website did not return a session cookie in response to ''{0}'',", url.toString()));
+            return sessionId;
+        } catch(IOException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        } finally {
+            synchronized(this) {
+                connection = null;
+            }
+        }
+    }
+
+    protected void authenticateOsmSession(String sessionId, String userName, String password) throws OsmLoginFailedException {
+        DataOutputStream dout = null;
+        try {
+            URL url = new URL(buildOsmLoginUrl());
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+            }
+            connection.setRequestMethod("POST");
+            connection.setDoInput(true);
+            connection.setDoOutput(true);
+            connection.setUseCaches(false);
+
+            Map<String,String> parameters = new HashMap<String, String>();
+            parameters.put("user[email]", userName);
+            parameters.put("user[password]", password);
+            parameters.put("referer", "/");
+            parameters.put("commit", "Login");
+
+            String request = buildPostRequest(parameters);
+
+            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
+            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
+            // make sure we can catch 302 Moved Temporarily below
+            connection.setInstanceFollowRedirects(false);
+            setHttpRequestParameters(connection);
+
+            connection.connect();
+
+            dout = new DataOutputStream(connection.getOutputStream());
+            dout.writeBytes(request);
+            dout.flush();
+            dout.close();
+
+            // after a successful login the OSM website sends a redirect to a follow up page. Everything
+            // else, including a 200 OK, is a failed login. A 200 OK is replied if the login form with
+            // an error page is sent to back to the user.
+            //
+            int retCode = connection.getResponseCode();
+            if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)
+                throw new OsmOAuthAuthorizationException(tr("Failed to authenticate user ''{0}'' with password ''***'' as OAuth user", userName));
+        } catch(OsmOAuthAuthorizationException e) {
+            throw new OsmLoginFailedException(e.getCause());
+        } catch(IOException e) {
+            throw new OsmLoginFailedException(e);
+        } finally {
+            if (dout != null) {
+                try {
+                    dout.close();
+                } catch(IOException e) { /* ignore */ }
+            }
+            synchronized(this) {
+                connection = null;
+            }
+        }
+    }
+
+    protected void logoutOsmSession(String sessionId) throws OsmOAuthAuthorizationException {
+        try {
+            URL url = new URL(buildOsmLogoutUrl());
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+            }
+            connection.setRequestMethod("GET");
+            connection.setDoInput(true);
+            connection.setDoOutput(false);
+            setHttpRequestParameters(connection);
+            connection.connect();
+        }catch(MalformedURLException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        } catch(IOException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        }  finally {
+            synchronized(this) {
+                connection = null;
+            }
+        }
+    }
+
+    protected void sendAuthorisationRequest(String sessionId, OAuthToken requestToken, OsmPrivileges privileges) throws OsmOAuthAuthorizationException {
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("oauth_token", requestToken.getKey());
+        parameters.put("oauth_callback", "");
+        if (privileges.isAllowWriteApi()) {
+            parameters.put("allow_write_api", "yes");
+        }
+        if (privileges.isAllowWriteGpx()) {
+            parameters.put("allow_write_gpx", "yes");
+        }
+        if (privileges.isAllowReadGpx()) {
+            parameters.put("allow_read_gpx", "yes");
+        }
+        if (privileges.isAllowWritePrefs()) {
+            parameters.put("allow_write_prefs", "yes");
+        }
+        if (privileges.isAllowReadPrefs()) {
+            parameters.put("allow_read_prefs", "yes");
+        }
+
+        parameters.put("commit", "Save changes");
+
+        String request = buildPostRequest(parameters);
+        DataOutputStream dout = null;
+        try {
+            URL url = new URL(oauthProviderParameters.getAuthoriseUrl());
+            synchronized(this) {
+                connection = (HttpURLConnection)url.openConnection();
+            }
+            connection.setRequestMethod("POST");
+            connection.setDoInput(true);
+            connection.setDoOutput(true);
+            connection.setUseCaches(false);
+            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            connection.setRequestProperty("Content-Length", Integer.toString(request.length()));
+            connection.setRequestProperty("Cookie", "_osm_session=" + sessionId);
+            connection.setInstanceFollowRedirects(false);
+            setHttpRequestParameters(connection);
+
+            connection.connect();
+
+            dout = new DataOutputStream(connection.getOutputStream());
+            dout.writeBytes(request);
+            dout.flush();
+            dout.close();
+
+            int retCode = connection.getResponseCode();
+            if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)
+                throw new OsmOAuthAuthorizationException(tr("Failed to authorise OAuth request  ''{0}''", requestToken.getKey()));
+        } catch(MalformedURLException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        } catch(IOException e) {
+            throw new OsmOAuthAuthorizationException(e);
+        } finally {
+            if (dout != null) {
+                try {
+                    dout.close();
+                } catch(IOException e) { /* ignore */ }
+            }
+            synchronized(this) {
+                connection = null;
+            }
+        }
+    }
+
+    protected void setHttpRequestParameters(HttpURLConnection connection) {
+        connection.setRequestProperty("User-Agent", Version.getInstance().getAgentString());
+        connection.setRequestProperty("Host", connection.getURL().getHost());
+    }
+
+    /**
+     * Automatically authorises a request token for a set of privileges.
+     * 
+     * @param requestToken the request token. Must not be null.
+     * @param osmUserName the OSM user name. Must not be null.
+     * @param osmPassword the OSM password. Must not be null.
+     * @param privileges the set of privileges. Must not be null.
+     * @param monitor a progress monitor. Defaults to {@see NullProgressMonitor#INSTANCE} if null
+     * @throws IllegalArgumentException thrown if requestToken is null
+     * @throws IllegalArgumentException thrown if osmUserName is null
+     * @throws IllegalArgumentException thrown if osmPassword is null
+     * @throws IllegalArgumentException thrown if privileges is null
+     * @throws OsmOAuthAuthorizationException thrown if the authorisation fails
+     * @throws OsmTransferCancelledException thrown if the task is cancelled by the user
+     */
+    public void authorise(OAuthToken requestToken, String osmUserName, String osmPassword, OsmPrivileges privileges, ProgressMonitor monitor) throws IllegalArgumentException, OsmOAuthAuthorizationException, OsmTransferCancelledException{
+        CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");
+        CheckParameterUtil.ensureParameterNotNull(osmUserName, "osmUserName");
+        CheckParameterUtil.ensureParameterNotNull(osmPassword, "osmPassword");
+        CheckParameterUtil.ensureParameterNotNull(privileges, "privileges");
+
+        if (monitor == null) {
+            monitor = NullProgressMonitor.INSTANCE;
+        }
+        try {
+            monitor.beginTask(tr("Authorising OAuth Request token ''{0}'' at the OSM website ...", requestToken.getKey()));
+            monitor.setTicksCount(4);
+            monitor.indeterminateSubTask(tr("Initializing a session at the OSM website..."));
+            String sessionId = fetchOsmWebsiteSessionId();
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            monitor.worked(1);
+
+            monitor.indeterminateSubTask(tr("Authenticating the session for user ''{0}''...", osmUserName));
+            authenticateOsmSession(sessionId, osmUserName, osmPassword);
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            monitor.worked(1);
+
+            monitor.indeterminateSubTask(tr("Authorising request token ''{0}''...", requestToken.getKey()));
+            sendAuthorisationRequest(sessionId, requestToken, privileges);
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            monitor.worked(1);
+
+            monitor.indeterminateSubTask(tr("Logging out session ''{0}''...", sessionId));
+            logoutOsmSession(sessionId);
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            monitor.worked(1);
+        } catch(OsmOAuthAuthorizationException e) {
+            if (canceled)
+                throw new OsmTransferCancelledException();
+            throw e;
+        } finally {
+            monitor.finishTask();
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationException.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationException.java	(revision 2861)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+public class OsmOAuthAuthorizationException extends Exception {
+
+    public OsmOAuthAuthorizationException() {
+        super();
+    }
+
+    public OsmOAuthAuthorizationException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+    }
+
+    public OsmOAuthAuthorizationException(String arg0) {
+        super(arg0);
+    }
+
+    public OsmOAuthAuthorizationException(Throwable arg0) {
+        super(arg0);
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java	(revision 2860)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java	(revision 2861)
@@ -28,5 +28,5 @@
     private OAuthToken accessToken;
     private OAuthParameters parameters;
-    private OsmOAuthAuthorisationClient client;
+    private OsmOAuthAuthorizationClient client;
     private OAuthToken requestToken;
     private Component parent;
@@ -64,5 +64,5 @@
     protected void finish() { /* not used in this task */}
 
-    protected void alertRetrievingAccessTokenFailed(OsmOAuthAuthorisationException e) {
+    protected void alertRetrievingAccessTokenFailed(OsmOAuthAuthorizationException e) {
         HelpAwareOptionPane.showOptionDialog(
                 parent,
@@ -81,10 +81,10 @@
         try {
             synchronized(this) {
-                client = new OsmOAuthAuthorisationClient(parameters, requestToken);
+                client = new OsmOAuthAuthorizationClient(parameters, requestToken);
             }
             accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false));
         } catch(OsmTransferCancelledException e) {
             return;
-        } catch (OsmOAuthAuthorisationException e) {
+        } catch (OsmOAuthAuthorizationException e) {
             e.printStackTrace();
             alertRetrievingAccessTokenFailed(e);
Index: trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java	(revision 2860)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java	(revision 2861)
@@ -27,5 +27,5 @@
     private OAuthToken requestToken;
     private OAuthParameters parameters;
-    private OsmOAuthAuthorisationClient client;
+    private OsmOAuthAuthorizationClient client;
     private Component parent;
 
@@ -58,5 +58,5 @@
     protected void finish() { /* not used in this task */}
 
-    protected void alertRetrievingRequestTokenFailed(OsmOAuthAuthorisationException e) {
+    protected void alertRetrievingRequestTokenFailed(OsmOAuthAuthorizationException e) {
         HelpAwareOptionPane.showOptionDialog(
                 parent,
@@ -75,10 +75,10 @@
         try {
             synchronized(this) {
-                client = new OsmOAuthAuthorisationClient(parameters);
+                client = new OsmOAuthAuthorizationClient(parameters);
             }
             requestToken = client.getRequestToken(getProgressMonitor().createSubTaskMonitor(0, false));
         } catch(OsmTransferCancelledException e) {
             return;
-        } catch (OsmOAuthAuthorisationException e) {
+        } catch (OsmOAuthAuthorizationException e) {
             e.printStackTrace();
             alertRetrievingRequestTokenFailed(e);
Index: trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorisationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorisationUI.java	(revision 2860)
+++ 	(revision )
@@ -1,451 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.Font;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.JMultilineLabel;
-import org.openstreetmap.josm.gui.SideButton;
-import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.OpenBrowser;
-
-/**
- * This is the UI for running a semic-automic authorisation procedure.
- * 
- * In contrast to the fully-automatic procedure the user is dispatched to an
- * external browser for login and authorisation.
- */
-public class SemiAutomaticAuthorisationUI extends AbstractAuthorisationUI {
-    private AccessTokenInfoPanel pnlAccessTokenInfo;
-    private OAuthToken requestToken;
-
-    private RetrieveRequestTokenPanel pnlRetrieveRequestToken;
-    private RetrieveAccessTokenPanel pnlRetrieveAccessToken;
-    private ShowAccessTokenPanel pnlShowAccessToken;
-
-    /**
-     * build the UI
-     */
-    protected void build() {
-        setLayout(new BorderLayout());
-        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
-        pnlRetrieveRequestToken = new RetrieveRequestTokenPanel();
-        pnlRetrieveAccessToken = new RetrieveAccessTokenPanel();
-        pnlShowAccessToken = new ShowAccessTokenPanel();
-        add(pnlRetrieveRequestToken, BorderLayout.CENTER);
-    }
-
-    public SemiAutomaticAuthorisationUI() {
-        build();
-    }
-
-    @Override
-    public boolean isSaveAccessTokenToPreferences() {
-        return pnlAccessTokenInfo.isSaveToPreferences();
-    }
-
-    protected void transitionToRetrieveAccessToken() {
-        OsmOAuthAuthorisationClient client = new OsmOAuthAuthorisationClient(
-                getAdvancedPropertiesPanel().getAdvancedParameters()
-        );
-        String authoriseUrl = client.getAuthoriseUrl(requestToken);
-        OpenBrowser.displayUrl(authoriseUrl);
-
-        removeAll();
-        pnlRetrieveAccessToken.setAuthoriseUrl(authoriseUrl);
-        add(pnlRetrieveAccessToken, BorderLayout.CENTER);
-        pnlRetrieveAccessToken.invalidate();
-        validate();
-        repaint();
-    }
-
-    protected void transitionToRetrieveRequestToken() {
-        requestToken = null;
-        setAccessToken(null);
-        removeAll();
-        add(pnlRetrieveRequestToken, BorderLayout.CENTER);
-        pnlRetrieveRequestToken.invalidate();
-        validate();
-        repaint();
-    }
-
-    protected void transitionToShowAccessToken() {
-        removeAll();
-        add(pnlShowAccessToken, BorderLayout.CENTER);
-        pnlShowAccessToken.invalidate();
-        validate();
-        repaint();
-        pnlShowAccessToken.setAccessToken(getAccessToken());
-    }
-
-    /**
-     * This is the panel displayed in the first step of the semi-automatic authorisation
-     * process.
-     */
-    private class RetrieveRequestTokenPanel extends JPanel {
-        private JCheckBox cbShowAdvancedParameters;
-
-        protected JPanel buildAdvancedParametersPanel() {
-            JPanel pnl = new JPanel(new GridBagLayout());
-            GridBagConstraints gc= new GridBagConstraints();
-
-            gc.anchor = GridBagConstraints.NORTHWEST;
-            gc.fill = GridBagConstraints.HORIZONTAL;
-            gc.weightx = 0.0;
-            gc.insets = new Insets(0,0,0,3);
-            pnl.add(cbShowAdvancedParameters = new JCheckBox(), gc);
-            cbShowAdvancedParameters.setSelected(false);
-            cbShowAdvancedParameters.addItemListener(
-                    new ItemListener() {
-                        public void itemStateChanged(ItemEvent evt) {
-                            getAdvancedPropertiesPanel().setVisible(evt.getStateChange() == ItemEvent.SELECTED);
-                        }
-                    }
-            );
-
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            JMultilineLabel lbl = new JMultilineLabel(tr("Display Advanced OAuth Parameters"));
-            lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
-            pnl.add(lbl, gc);
-
-            gc.gridy = 1;
-            gc.gridx = 1;
-            gc.insets = new Insets(3,0,3,0);
-            gc.fill = GridBagConstraints.BOTH;
-            gc.weightx = 1.0;
-            gc.weighty = 1.0;
-            pnl.add(getAdvancedPropertiesPanel(), gc);
-            getAdvancedPropertiesPanel().setBorder(
-                    BorderFactory.createCompoundBorder(
-                            BorderFactory.createLineBorder(Color.GRAY, 1),
-                            BorderFactory.createEmptyBorder(3,3,3,3)
-                    )
-            );
-            getAdvancedPropertiesPanel().setVisible(false);
-            return pnl;
-        }
-
-        protected JPanel buildCommandPanel() {
-            JPanel pnl = new JPanel(new GridBagLayout());
-            GridBagConstraints gc= new GridBagConstraints();
-
-            gc.anchor = GridBagConstraints.NORTHWEST;
-            gc.fill = GridBagConstraints.BOTH;
-            gc.weightx = 1.0;
-            gc.weighty = 1.0;
-            gc.insets = new Insets(0,0,0,3);
-
-
-            HtmlPanel h = new HtmlPanel();
-            h.setText(tr("<html>"
-                    + "Please click on <strong>{0}</strong> to retrieve an OAuth Request Token from "
-                    + "''{1}''.</html>",
-                    tr("Retrieve Request Token"),
-                    getAdvancedPropertiesPanel().getAdvancedParameters().getRequestTokenUrl()
-            ));
-            pnl.add(h, gc);
-
-            JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            pnl1.add(new SideButton(new RetrieveRequestTokenAction()));
-            gc.fill = GridBagConstraints.HORIZONTAL;
-            gc.weightx = 1.0;
-            gc.gridy = 1;
-            pnl.add(pnl1, gc);
-            return pnl;
-
-        }
-        protected void build() {
-            setLayout(new BorderLayout(0,5));
-            JLabel lbl = new JLabel(tr("<html>Step 1/3: Retrieve an OAuth Request Token</html>"));
-            lbl.setFont(lbl.getFont().deriveFont(16f));
-            add(lbl, BorderLayout.NORTH);
-            add(buildAdvancedParametersPanel(), BorderLayout.CENTER);
-            add(buildCommandPanel(), BorderLayout.SOUTH);
-        }
-
-        public RetrieveRequestTokenPanel() {
-            build();
-        }
-    }
-
-
-    /**
-     * This is the panel displayed in the second step of the semi-automatic authorization
-     * process.
-     */
-    private class RetrieveAccessTokenPanel extends JPanel {
-
-        private JTextField tfAuthoriseUrl;
-
-        protected JPanel buildTitlePanel() {
-            JPanel pnl = new JPanel(new BorderLayout());
-            JLabel lbl = new JLabel(tr("<html>Step 2/3: Authorise and retrieve an Access Token</html>"));
-            lbl.setFont(lbl.getFont().deriveFont(16f));
-            pnl.add(lbl, BorderLayout.CENTER);
-            return pnl;
-        }
-
-        protected JPanel buildContentPanel() {
-            JPanel pnl = new JPanel(new GridBagLayout());
-            GridBagConstraints gc = new GridBagConstraints();
-
-            gc.anchor= GridBagConstraints.NORTHWEST;
-            gc.fill = GridBagConstraints.HORIZONTAL;
-            gc.weightx = 1.0;
-            gc.gridwidth = 2;
-            HtmlPanel html = new HtmlPanel();
-            html.setText(tr("<html>"
-                    + "JOSM successfully retrieved a Request Token. "
-                    + "JOSM is now launching an authorisation page in an external browser. "
-                    + "Please login with your OSM username and password and follow the instructions "
-                    + "to authorise the Request Token. Then switch back to this dialog and click on "
-                    + "<strong>{0}</strong><br><br>"
-                    + "If launching the external browser fails you can copy the following authorise URL "
-                    + "and paste it into the address field of your browser.</html>",
-                    tr("Request Access Token")
-            ));
-            pnl.add(html, gc);
-
-            gc.gridx = 0;
-            gc.gridy = 1;
-            gc.weightx = 0.0;
-            gc.gridwidth = 1;
-            pnl.add(new JLabel(tr("Authorise URL:")), gc);
-
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            pnl.add(tfAuthoriseUrl = new JTextField(), gc);
-            tfAuthoriseUrl.setEditable(false);
-
-            return pnl;
-        }
-
-        protected JPanel buildActionPanel() {
-            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-
-            pnl.add(new SideButton(new BackAction()));
-            pnl.add(new SideButton(new RetrieveAccessTokenAction()));
-            return pnl;
-        }
-
-        protected void build() {
-            setLayout(new BorderLayout());
-            add(buildTitlePanel(), BorderLayout.NORTH);
-            add(buildContentPanel(), BorderLayout.CENTER);
-            add(buildActionPanel(), BorderLayout.SOUTH);
-        }
-
-        public RetrieveAccessTokenPanel() {
-            build();
-        }
-
-        public void setAuthoriseUrl(String url) {
-            tfAuthoriseUrl.setText(url);
-        }
-
-        /**
-         * Action to go back to step 1 in the process
-         */
-        class BackAction extends AbstractAction {
-            public BackAction() {
-                putValue(NAME, tr("Back"));
-                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
-                putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
-            }
-
-            public void actionPerformed(ActionEvent arg0) {
-                transitionToRetrieveRequestToken();
-            }
-        }
-    }
-
-    /**
-     * Displays the retrieved Access Token in step 3.
-     */
-    class ShowAccessTokenPanel extends JPanel {
-
-        protected JPanel buildTitlePanel() {
-            JPanel pnl = new JPanel(new BorderLayout());
-            JLabel lbl = new JLabel(tr("<html>Step 3/3: Successfully retrieved an Access Token</html>"));
-            lbl.setFont(lbl.getFont().deriveFont(16f));
-            pnl.add(lbl, BorderLayout.CENTER);
-            return pnl;
-        }
-
-        protected JPanel buildContentPanel() {
-            JPanel pnl = new JPanel(new GridBagLayout());
-            GridBagConstraints gc = new GridBagConstraints();
-
-            gc.anchor= GridBagConstraints.NORTHWEST;
-            gc.fill = GridBagConstraints.HORIZONTAL;
-            gc.weightx = 1.0;
-            HtmlPanel html = new HtmlPanel();
-            html.setText(tr("<html>"
-                    + "JOSM has successfully retrieved an Access Token. "
-                    + "You can now accept this token. JOSM will use it in the future for authentication "
-                    + "and authorisation to the OSM server.<br><br>"
-                    + "The access token is: </html>"
-            ));
-            pnl.add(html, gc);
-
-            gc.gridx = 0;
-            gc.gridy = 1;
-            gc.weightx = 1.0;
-            gc.gridwidth = 1;
-            pnl.add(pnlAccessTokenInfo = new AccessTokenInfoPanel(), gc);
-            pnlAccessTokenInfo.setSaveToPreferences(
-                    OAuthAccessTokenHolder.getInstance().isSaveToPreferences()
-            );
-            return pnl;
-        }
-
-        protected JPanel buildActionPanel() {
-            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            pnl.add(new SideButton(new RestartAction()));
-            pnl.add(new SideButton(new TestAccessTokenAction()));
-            return pnl;
-        }
-
-        protected void build() {
-            setLayout(new BorderLayout());
-            add(buildTitlePanel(), BorderLayout.NORTH);
-            add(buildContentPanel(), BorderLayout.CENTER);
-            add(buildActionPanel(), BorderLayout.SOUTH);
-        }
-
-        public ShowAccessTokenPanel() {
-            build();
-        }
-
-        /**
-         * Action to go back to step 1 in the process
-         */
-        class RestartAction extends AbstractAction {
-            public RestartAction() {
-                putValue(NAME, tr("Restart"));
-                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
-                putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
-            }
-
-            public void actionPerformed(ActionEvent arg0) {
-                transitionToRetrieveRequestToken();
-            }
-        }
-
-        public void setAccessToken(OAuthToken accessToken) {
-            pnlAccessTokenInfo.setAccessToken(accessToken);
-        }
-    }
-
-    /**
-     * Action for retrieving a request token
-     */
-    class RetrieveRequestTokenAction extends AbstractAction{
-
-        public RetrieveRequestTokenAction() {
-            putValue(NAME, tr("Retrieve Request Token"));
-            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
-            putValue(SHORT_DESCRIPTION, tr("Click to retrieve a Request Token"));
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            final RetrieveRequestTokenTask task = new RetrieveRequestTokenTask(
-                    SemiAutomaticAuthorisationUI.this,
-                    getAdvancedPropertiesPanel().getAdvancedParameters()
-            );
-            Main.worker.submit(task);
-            Runnable r  = new Runnable() {
-                public void run() {
-                    if (task.isCanceled()) return;
-                    if (task.getRequestToken() == null) return;
-                    requestToken = task.getRequestToken();
-                    SwingUtilities.invokeLater(new Runnable() {
-                        public void run() {
-                            transitionToRetrieveAccessToken();
-                        }
-                    });
-                }
-            };
-            Main.worker.submit(r);
-        }
-    }
-
-    /**
-     * Action for retrieving an Access Token
-     */
-    class RetrieveAccessTokenAction extends AbstractAction {
-
-        public RetrieveAccessTokenAction() {
-            putValue(NAME, tr("Retrieve Access Token"));
-            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
-            putValue(SHORT_DESCRIPTION, tr("Click to retrieve an Access Token"));
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            final RetrieveAccessTokenTask task = new RetrieveAccessTokenTask(
-                    SemiAutomaticAuthorisationUI.this,
-                    getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    requestToken
-            );
-            Main.worker.submit(task);
-            Runnable r  = new Runnable() {
-                public void run() {
-                    if (task.isCanceled()) return;
-                    if (task.getAccessToken() == null) return;
-                    setAccessToken(task.getAccessToken());
-                    SwingUtilities.invokeLater(new Runnable() {
-                        public void run() {
-                            transitionToShowAccessToken();
-                        }
-                    });
-                }
-            };
-            Main.worker.submit(r);
-        }
-    }
-
-    /**
-     * Action for testing an Access Token
-     */
-    class TestAccessTokenAction extends AbstractAction {
-
-        public TestAccessTokenAction() {
-            putValue(NAME, tr("Test Access Token"));
-            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
-            putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
-        }
-
-        public void actionPerformed(ActionEvent evt) {
-            TestAccessTokenTask task = new TestAccessTokenTask(
-                    SemiAutomaticAuthorisationUI.this,
-                    getApiUrl(),
-                    getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    getAccessToken()
-            );
-            Main.worker.submit(task);
-        }
-    }
-}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java	(revision 2861)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java	(revision 2861)
@@ -0,0 +1,451 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.oauth;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
+import org.openstreetmap.josm.gui.widgets.HtmlPanel;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.OpenBrowser;
+
+/**
+ * This is the UI for running a semic-automic authorisation procedure.
+ * 
+ * In contrast to the fully-automatic procedure the user is dispatched to an
+ * external browser for login and authorisation.
+ */
+public class SemiAutomaticAuthorizationUI extends AbstractAuthorizationUI {
+    private AccessTokenInfoPanel pnlAccessTokenInfo;
+    private OAuthToken requestToken;
+
+    private RetrieveRequestTokenPanel pnlRetrieveRequestToken;
+    private RetrieveAccessTokenPanel pnlRetrieveAccessToken;
+    private ShowAccessTokenPanel pnlShowAccessToken;
+
+    /**
+     * build the UI
+     */
+    protected void build() {
+        setLayout(new BorderLayout());
+        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+        pnlRetrieveRequestToken = new RetrieveRequestTokenPanel();
+        pnlRetrieveAccessToken = new RetrieveAccessTokenPanel();
+        pnlShowAccessToken = new ShowAccessTokenPanel();
+        add(pnlRetrieveRequestToken, BorderLayout.CENTER);
+    }
+
+    public SemiAutomaticAuthorizationUI() {
+        build();
+    }
+
+    @Override
+    public boolean isSaveAccessTokenToPreferences() {
+        return pnlAccessTokenInfo.isSaveToPreferences();
+    }
+
+    protected void transitionToRetrieveAccessToken() {
+        OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(
+                getAdvancedPropertiesPanel().getAdvancedParameters()
+        );
+        String authoriseUrl = client.getAuthoriseUrl(requestToken);
+        OpenBrowser.displayUrl(authoriseUrl);
+
+        removeAll();
+        pnlRetrieveAccessToken.setAuthoriseUrl(authoriseUrl);
+        add(pnlRetrieveAccessToken, BorderLayout.CENTER);
+        pnlRetrieveAccessToken.invalidate();
+        validate();
+        repaint();
+    }
+
+    protected void transitionToRetrieveRequestToken() {
+        requestToken = null;
+        setAccessToken(null);
+        removeAll();
+        add(pnlRetrieveRequestToken, BorderLayout.CENTER);
+        pnlRetrieveRequestToken.invalidate();
+        validate();
+        repaint();
+    }
+
+    protected void transitionToShowAccessToken() {
+        removeAll();
+        add(pnlShowAccessToken, BorderLayout.CENTER);
+        pnlShowAccessToken.invalidate();
+        validate();
+        repaint();
+        pnlShowAccessToken.setAccessToken(getAccessToken());
+    }
+
+    /**
+     * This is the panel displayed in the first step of the semi-automatic authorisation
+     * process.
+     */
+    private class RetrieveRequestTokenPanel extends JPanel {
+        private JCheckBox cbShowAdvancedParameters;
+
+        protected JPanel buildAdvancedParametersPanel() {
+            JPanel pnl = new JPanel(new GridBagLayout());
+            GridBagConstraints gc= new GridBagConstraints();
+
+            gc.anchor = GridBagConstraints.NORTHWEST;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 0.0;
+            gc.insets = new Insets(0,0,0,3);
+            pnl.add(cbShowAdvancedParameters = new JCheckBox(), gc);
+            cbShowAdvancedParameters.setSelected(false);
+            cbShowAdvancedParameters.addItemListener(
+                    new ItemListener() {
+                        public void itemStateChanged(ItemEvent evt) {
+                            getAdvancedPropertiesPanel().setVisible(evt.getStateChange() == ItemEvent.SELECTED);
+                        }
+                    }
+            );
+
+            gc.gridx = 1;
+            gc.weightx = 1.0;
+            JMultilineLabel lbl = new JMultilineLabel(tr("Display Advanced OAuth Parameters"));
+            lbl.setFont(lbl.getFont().deriveFont(Font.PLAIN));
+            pnl.add(lbl, gc);
+
+            gc.gridy = 1;
+            gc.gridx = 1;
+            gc.insets = new Insets(3,0,3,0);
+            gc.fill = GridBagConstraints.BOTH;
+            gc.weightx = 1.0;
+            gc.weighty = 1.0;
+            pnl.add(getAdvancedPropertiesPanel(), gc);
+            getAdvancedPropertiesPanel().setBorder(
+                    BorderFactory.createCompoundBorder(
+                            BorderFactory.createLineBorder(Color.GRAY, 1),
+                            BorderFactory.createEmptyBorder(3,3,3,3)
+                    )
+            );
+            getAdvancedPropertiesPanel().setVisible(false);
+            return pnl;
+        }
+
+        protected JPanel buildCommandPanel() {
+            JPanel pnl = new JPanel(new GridBagLayout());
+            GridBagConstraints gc= new GridBagConstraints();
+
+            gc.anchor = GridBagConstraints.NORTHWEST;
+            gc.fill = GridBagConstraints.BOTH;
+            gc.weightx = 1.0;
+            gc.weighty = 1.0;
+            gc.insets = new Insets(0,0,0,3);
+
+
+            HtmlPanel h = new HtmlPanel();
+            h.setText(tr("<html>"
+                    + "Please click on <strong>{0}</strong> to retrieve an OAuth Request Token from "
+                    + "''{1}''.</html>",
+                    tr("Retrieve Request Token"),
+                    getAdvancedPropertiesPanel().getAdvancedParameters().getRequestTokenUrl()
+            ));
+            pnl.add(h, gc);
+
+            JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
+            pnl1.add(new SideButton(new RetrieveRequestTokenAction()));
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 1.0;
+            gc.gridy = 1;
+            pnl.add(pnl1, gc);
+            return pnl;
+
+        }
+        protected void build() {
+            setLayout(new BorderLayout(0,5));
+            JLabel lbl = new JLabel(tr("<html>Step 1/3: Retrieve an OAuth Request Token</html>"));
+            lbl.setFont(lbl.getFont().deriveFont(16f));
+            add(lbl, BorderLayout.NORTH);
+            add(buildAdvancedParametersPanel(), BorderLayout.CENTER);
+            add(buildCommandPanel(), BorderLayout.SOUTH);
+        }
+
+        public RetrieveRequestTokenPanel() {
+            build();
+        }
+    }
+
+
+    /**
+     * This is the panel displayed in the second step of the semi-automatic authorization
+     * process.
+     */
+    private class RetrieveAccessTokenPanel extends JPanel {
+
+        private JTextField tfAuthoriseUrl;
+
+        protected JPanel buildTitlePanel() {
+            JPanel pnl = new JPanel(new BorderLayout());
+            JLabel lbl = new JLabel(tr("<html>Step 2/3: Authorise and retrieve an Access Token</html>"));
+            lbl.setFont(lbl.getFont().deriveFont(16f));
+            pnl.add(lbl, BorderLayout.CENTER);
+            return pnl;
+        }
+
+        protected JPanel buildContentPanel() {
+            JPanel pnl = new JPanel(new GridBagLayout());
+            GridBagConstraints gc = new GridBagConstraints();
+
+            gc.anchor= GridBagConstraints.NORTHWEST;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 1.0;
+            gc.gridwidth = 2;
+            HtmlPanel html = new HtmlPanel();
+            html.setText(tr("<html>"
+                    + "JOSM successfully retrieved a Request Token. "
+                    + "JOSM is now launching an authorisation page in an external browser. "
+                    + "Please login with your OSM username and password and follow the instructions "
+                    + "to authorise the Request Token. Then switch back to this dialog and click on "
+                    + "<strong>{0}</strong><br><br>"
+                    + "If launching the external browser fails you can copy the following authorise URL "
+                    + "and paste it into the address field of your browser.</html>",
+                    tr("Request Access Token")
+            ));
+            pnl.add(html, gc);
+
+            gc.gridx = 0;
+            gc.gridy = 1;
+            gc.weightx = 0.0;
+            gc.gridwidth = 1;
+            pnl.add(new JLabel(tr("Authorise URL:")), gc);
+
+            gc.gridx = 1;
+            gc.weightx = 1.0;
+            pnl.add(tfAuthoriseUrl = new JTextField(), gc);
+            tfAuthoriseUrl.setEditable(false);
+
+            return pnl;
+        }
+
+        protected JPanel buildActionPanel() {
+            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
+
+            pnl.add(new SideButton(new BackAction()));
+            pnl.add(new SideButton(new RetrieveAccessTokenAction()));
+            return pnl;
+        }
+
+        protected void build() {
+            setLayout(new BorderLayout());
+            add(buildTitlePanel(), BorderLayout.NORTH);
+            add(buildContentPanel(), BorderLayout.CENTER);
+            add(buildActionPanel(), BorderLayout.SOUTH);
+        }
+
+        public RetrieveAccessTokenPanel() {
+            build();
+        }
+
+        public void setAuthoriseUrl(String url) {
+            tfAuthoriseUrl.setText(url);
+        }
+
+        /**
+         * Action to go back to step 1 in the process
+         */
+        class BackAction extends AbstractAction {
+            public BackAction() {
+                putValue(NAME, tr("Back"));
+                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
+                putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
+            }
+
+            public void actionPerformed(ActionEvent arg0) {
+                transitionToRetrieveRequestToken();
+            }
+        }
+    }
+
+    /**
+     * Displays the retrieved Access Token in step 3.
+     */
+    class ShowAccessTokenPanel extends JPanel {
+
+        protected JPanel buildTitlePanel() {
+            JPanel pnl = new JPanel(new BorderLayout());
+            JLabel lbl = new JLabel(tr("<html>Step 3/3: Successfully retrieved an Access Token</html>"));
+            lbl.setFont(lbl.getFont().deriveFont(16f));
+            pnl.add(lbl, BorderLayout.CENTER);
+            return pnl;
+        }
+
+        protected JPanel buildContentPanel() {
+            JPanel pnl = new JPanel(new GridBagLayout());
+            GridBagConstraints gc = new GridBagConstraints();
+
+            gc.anchor= GridBagConstraints.NORTHWEST;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 1.0;
+            HtmlPanel html = new HtmlPanel();
+            html.setText(tr("<html>"
+                    + "JOSM has successfully retrieved an Access Token. "
+                    + "You can now accept this token. JOSM will use it in the future for authentication "
+                    + "and authorisation to the OSM server.<br><br>"
+                    + "The access token is: </html>"
+            ));
+            pnl.add(html, gc);
+
+            gc.gridx = 0;
+            gc.gridy = 1;
+            gc.weightx = 1.0;
+            gc.gridwidth = 1;
+            pnl.add(pnlAccessTokenInfo = new AccessTokenInfoPanel(), gc);
+            pnlAccessTokenInfo.setSaveToPreferences(
+                    OAuthAccessTokenHolder.getInstance().isSaveToPreferences()
+            );
+            return pnl;
+        }
+
+        protected JPanel buildActionPanel() {
+            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
+            pnl.add(new SideButton(new RestartAction()));
+            pnl.add(new SideButton(new TestAccessTokenAction()));
+            return pnl;
+        }
+
+        protected void build() {
+            setLayout(new BorderLayout());
+            add(buildTitlePanel(), BorderLayout.NORTH);
+            add(buildContentPanel(), BorderLayout.CENTER);
+            add(buildActionPanel(), BorderLayout.SOUTH);
+        }
+
+        public ShowAccessTokenPanel() {
+            build();
+        }
+
+        /**
+         * Action to go back to step 1 in the process
+         */
+        class RestartAction extends AbstractAction {
+            public RestartAction() {
+                putValue(NAME, tr("Restart"));
+                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
+                putValue(SMALL_ICON, ImageProvider.get("dialogs", "previous"));
+            }
+
+            public void actionPerformed(ActionEvent arg0) {
+                transitionToRetrieveRequestToken();
+            }
+        }
+
+        public void setAccessToken(OAuthToken accessToken) {
+            pnlAccessTokenInfo.setAccessToken(accessToken);
+        }
+    }
+
+    /**
+     * Action for retrieving a request token
+     */
+    class RetrieveRequestTokenAction extends AbstractAction{
+
+        public RetrieveRequestTokenAction() {
+            putValue(NAME, tr("Retrieve Request Token"));
+            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
+            putValue(SHORT_DESCRIPTION, tr("Click to retrieve a Request Token"));
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            final RetrieveRequestTokenTask task = new RetrieveRequestTokenTask(
+                    SemiAutomaticAuthorizationUI.this,
+                    getAdvancedPropertiesPanel().getAdvancedParameters()
+            );
+            Main.worker.submit(task);
+            Runnable r  = new Runnable() {
+                public void run() {
+                    if (task.isCanceled()) return;
+                    if (task.getRequestToken() == null) return;
+                    requestToken = task.getRequestToken();
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            transitionToRetrieveAccessToken();
+                        }
+                    });
+                }
+            };
+            Main.worker.submit(r);
+        }
+    }
+
+    /**
+     * Action for retrieving an Access Token
+     */
+    class RetrieveAccessTokenAction extends AbstractAction {
+
+        public RetrieveAccessTokenAction() {
+            putValue(NAME, tr("Retrieve Access Token"));
+            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
+            putValue(SHORT_DESCRIPTION, tr("Click to retrieve an Access Token"));
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            final RetrieveAccessTokenTask task = new RetrieveAccessTokenTask(
+                    SemiAutomaticAuthorizationUI.this,
+                    getAdvancedPropertiesPanel().getAdvancedParameters(),
+                    requestToken
+            );
+            Main.worker.submit(task);
+            Runnable r  = new Runnable() {
+                public void run() {
+                    if (task.isCanceled()) return;
+                    if (task.getAccessToken() == null) return;
+                    setAccessToken(task.getAccessToken());
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            transitionToShowAccessToken();
+                        }
+                    });
+                }
+            };
+            Main.worker.submit(r);
+        }
+    }
+
+    /**
+     * Action for testing an Access Token
+     */
+    class TestAccessTokenAction extends AbstractAction {
+
+        public TestAccessTokenAction() {
+            putValue(NAME, tr("Test Access Token"));
+            putValue(SMALL_ICON, ImageProvider.get("oauth", "oauth"));
+            putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
+        }
+
+        public void actionPerformed(ActionEvent evt) {
+            TestAccessTokenTask task = new TestAccessTokenTask(
+                    SemiAutomaticAuthorizationUI.this,
+                    getApiUrl(),
+                    getAdvancedPropertiesPanel().getAdvancedParameters(),
+                    getAccessToken()
+            );
+            Main.worker.submit(task);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 2860)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 2861)
@@ -97,5 +97,5 @@
     }
 
-    protected UserInfo getUserDetails() throws OsmOAuthAuthorisationException, OsmDataParsingException,OsmTransferException {
+    protected UserInfo getUserDetails() throws OsmOAuthAuthorizationException, OsmDataParsingException,OsmTransferException {
         boolean authenticatorEnabled = true;
         try {
@@ -133,5 +133,5 @@
             throw new OsmTransferException(e);
         } catch(OAuthException e) {
-            throw new OsmOAuthAuthorisationException(e);
+            throw new OsmOAuthAuthorizationException(e);
         } finally {
             DefaultAuthenticator.getInstance().setEnabled(authenticatorEnabled);
@@ -253,5 +253,5 @@
             if (canceled) return;
             notifySuccess(userInfo);
-        }catch(OsmOAuthAuthorisationException e) {
+        }catch(OsmOAuthAuthorizationException e) {
             if (canceled) return;
             e.printStackTrace();
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 2860)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 2861)
@@ -31,5 +31,5 @@
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.oauth.AdvancedOAuthPropertiesPanel;
-import org.openstreetmap.josm.gui.oauth.OAuthAuthorisationWizard;
+import org.openstreetmap.josm.gui.oauth.OAuthAuthorizationWizard;
 import org.openstreetmap.josm.gui.oauth.TestAccessTokenTask;
 import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
@@ -309,5 +309,5 @@
         }
         public void actionPerformed(ActionEvent arg0) {
-            OAuthAuthorisationWizard wizard = new OAuthAuthorisationWizard(
+            OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard(
                     OAuthAuthenticationPreferencesPanel.this,
                     apiUrl
@@ -334,5 +334,5 @@
         }
         public void actionPerformed(ActionEvent arg0) {
-            OAuthAuthorisationWizard wizard = new OAuthAuthorisationWizard(
+            OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard(
                     OAuthAuthenticationPreferencesPanel.this,
                     apiUrl
