Index: /trunk/ivy.xml
===================================================================
--- /trunk/ivy.xml	(revision 18990)
+++ /trunk/ivy.xml	(revision 18991)
@@ -38,5 +38,4 @@
         <dependency conf="api->default" org="com.formdev" name="svgSalamander" rev="1.1.4"/>
         <dependency conf="api->default" org="ch.poole" name="OpeningHoursParser" rev="0.28.1"/>
-        <dependency conf="api->default" org="oauth.signpost" name="signpost-core" rev="2.1.1"/>
         <!-- Don't forget to update org.openstreetmap.josm.tools.Tag2Link#PREF_SOURCE -->
         <dependency conf="api->default" org="org.webjars.npm" name="tag2link" rev="2024.2.8"/>
@@ -57,5 +56,4 @@
         <dependency conf="sources->sources" org="com.formdev" name="svgSalamander" rev="1.1.4"/>
         <dependency conf="sources->sources" org="ch.poole" name="OpeningHoursParser" rev="0.28.1"/>
-        <dependency conf="sources->sources" org="oauth.signpost" name="signpost-core" rev="2.1.1"/>
         <dependency conf="sources->default" org="org.webjars.npm" name="tag2link" rev="2024.2.8"/><!-- sources->default sic! (tag2link-sources.jar is empty, see #19335) -->
         <!-- commonslang->default -->
Index: /trunk/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/data/oauth/OAuth20Parameters.java	(revision 18991)
@@ -148,3 +148,22 @@
         return builder.build().toString();
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.apiUrl, this.authorizeUrl, this.tokenUrl, this.clientId, this.clientSecret, this.redirectUri);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj != null && this.getClass() == obj.getClass()) {
+            OAuth20Parameters other = (OAuth20Parameters) obj;
+            return Objects.equals(this.clientSecret, other.clientSecret) &&
+                    Objects.equals(this.clientId, other.clientId) &&
+                    Objects.equals(this.redirectUri, other.redirectUri) &&
+                    Objects.equals(this.tokenUrl, other.tokenUrl) &&
+                    Objects.equals(this.authorizeUrl, other.authorizeUrl) &&
+                    Objects.equals(this.apiUrl, other.apiUrl);
+        }
+        return false;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/data/oauth/OAuthAccessTokenHolder.java	(revision 18991)
@@ -37,6 +37,4 @@
 
     private boolean saveToPreferences;
-    private String accessTokenKey;
-    private String accessTokenSecret;
 
     private final Map<String, Map<OAuthVersion, IOAuthToken>> tokenMap = new HashMap<>();
@@ -53,8 +51,8 @@
     /**
      * Sets whether the current access token should be saved to the preferences file.
-     *
+     * <p>
      * If true, the access token is saved in clear text to the preferences file. The same
      * access token can therefore be used in multiple JOSM sessions.
-     *
+     * <p>
      * If false, the access token isn't saved to the preferences file. If JOSM is closed,
      * the access token is lost and new token has to be generated by the OSM server the
@@ -65,50 +63,4 @@
     public void setSaveToPreferences(boolean saveToPreferences) {
         this.saveToPreferences = saveToPreferences;
-    }
-
-    /**
-     * Replies the access token key. null, if no access token key is currently set.
-     *
-     * @return the access token key
-     */
-    public String getAccessTokenKey() {
-        return accessTokenKey;
-    }
-
-    /**
-     * Sets the access token key. Pass in null to remove the current access token key.
-     *
-     * @param accessTokenKey the access token key
-     */
-    public void setAccessTokenKey(String accessTokenKey) {
-        this.accessTokenKey = accessTokenKey;
-    }
-
-    /**
-     * Replies the access token secret. null, if no access token secret is currently set.
-     *
-     * @return the access token secret
-     */
-    public String getAccessTokenSecret() {
-        return accessTokenSecret;
-    }
-
-    /**
-     * Sets the access token secret. Pass in null to remove the current access token secret.
-     *
-     * @param accessTokenSecret access token secret, or null
-     */
-    public void setAccessTokenSecret(String accessTokenSecret) {
-        this.accessTokenSecret = accessTokenSecret;
-    }
-
-    /**
-     * Replies the access token.
-     * @return the access token, can be {@code null}
-     */
-    public OAuthToken getAccessToken() {
-        if (!containsAccessToken())
-            return null;
-        return new OAuthToken(accessTokenKey, accessTokenSecret);
     }
 
@@ -143,30 +95,4 @@
      * Sets the access token hold by this holder.
      *
-     * @param accessTokenKey the access token key
-     * @param accessTokenSecret the access token secret
-     */
-    public void setAccessToken(String accessTokenKey, String accessTokenSecret) {
-        this.accessTokenKey = accessTokenKey;
-        this.accessTokenSecret = accessTokenSecret;
-    }
-
-    /**
-     * Sets the access token hold by this holder.
-     *
-     * @param token the access token. Can be null to clear the content in this holder.
-     */
-    public void setAccessToken(OAuthToken token) {
-        if (token == null) {
-            this.accessTokenKey = null;
-            this.accessTokenSecret = null;
-        } else {
-            this.accessTokenKey = token.getKey();
-            this.accessTokenSecret = token.getSecret();
-        }
-    }
-
-    /**
-     * Sets the access token hold by this holder.
-     *
      * @param api The api the token is for
      * @param token the access token. Can be null to clear the content in this holder.
@@ -187,14 +113,4 @@
 
     /**
-     * Replies true if this holder contains an complete access token, consisting of an
-     * Access Token Key and an Access Token Secret.
-     *
-     * @return true if this holder contains an complete access token
-     */
-    public boolean containsAccessToken() {
-        return accessTokenKey != null && accessTokenSecret != null;
-    }
-
-    /**
      * Initializes the content of this holder from the Access Token managed by the
      * credential manager.
@@ -205,17 +121,5 @@
     public void init(CredentialsAgent cm) {
         CheckParameterUtil.ensureParameterNotNull(cm, "cm");
-        OAuthToken token = null;
-        try {
-            token = cm.lookupOAuthAccessToken();
-        } catch (CredentialsAgentException e) {
-            Logging.error(e);
-            Logging.warn(tr("Failed to retrieve OAuth Access Token from credential manager"));
-            Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
-        }
         saveToPreferences = Config.getPref().getBoolean("oauth.access-token.save-to-preferences", true);
-        if (token != null) {
-            accessTokenKey = token.getKey();
-            accessTokenSecret = token.getSecret();
-        }
     }
 
@@ -232,14 +136,8 @@
         try {
             if (!saveToPreferences) {
-                cm.storeOAuthAccessToken(null);
                 for (String host : this.tokenMap.keySet()) {
                     cm.storeOAuthAccessToken(host, null);
                 }
             } else {
-                if (this.accessTokenKey != null && this.accessTokenSecret != null) {
-                    cm.storeOAuthAccessToken(new OAuthToken(accessTokenKey, accessTokenSecret));
-                } else {
-                    cm.storeOAuthAccessToken(null);
-                }
                 for (Map.Entry<String, Map<OAuthVersion, IOAuthToken>> entry : this.tokenMap.entrySet()) {
                     if (entry.getValue().isEmpty()) {
@@ -265,6 +163,5 @@
      */
     public void clear() {
-        accessTokenKey = null;
-        accessTokenSecret = null;
+        this.tokenMap.clear();
     }
 }
Index: /trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java	(revision 18991)
@@ -4,6 +4,20 @@
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.Objects;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openstreetmap.josm.io.NetworkManager;
+import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.io.auth.CredentialsAgentException;
+import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.spi.preferences.IUrls;
+import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
+import org.openstreetmap.josm.tools.Utils;
 
 import jakarta.json.Json;
@@ -13,40 +27,27 @@
 import jakarta.json.JsonValue;
 
-import org.openstreetmap.josm.io.OsmApi;
-import org.openstreetmap.josm.io.auth.CredentialsAgentException;
-import org.openstreetmap.josm.io.auth.CredentialsManager;
-import org.openstreetmap.josm.spi.preferences.Config;
-import org.openstreetmap.josm.spi.preferences.IUrls;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.HttpClient;
-import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.Utils;
-
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.OAuthProvider;
-
 /**
  * This class manages an immutable set of OAuth parameters.
- * @since 2747
+ * @since 2747 (static factory class since 18991)
  */
-public class OAuthParameters implements IOAuthParameters {
-
-    /**
-     * The default JOSM OAuth consumer key (created by user josmeditor).
-     */
-    public static final String DEFAULT_JOSM_CONSUMER_KEY = "F7zPYlVCqE2BUH9Hr4SsWZSOnrKjpug1EgqkbsSb";
-    /**
-     * The default JOSM OAuth consumer secret (created by user josmeditor).
-     */
-    public static final String DEFAULT_JOSM_CONSUMER_SECRET = "rIkjpPcBNkMQxrqzcOvOC4RRuYupYr7k8mfP13H5";
+public final class OAuthParameters {
+    private static final Map<String, JsonObject> RFC8414_RESPONSES = new HashMap<>(1);
+    private static final String OSM_API_DEFAULT = "https://api.openstreetmap.org/api";
+    private static final String OSM_API_DEV = "https://api06.dev.openstreetmap.org/api";
+    private static final String OSM_API_MASTER = "https://master.apis.dev.openstreetmap.org/api";
+
+    private OAuthParameters() {
+        // Hide constructor
+    }
 
     /**
      * Replies a set of default parameters for a consumer accessing the standard OSM server
      * at {@link IUrls#getDefaultOsmApiUrl}.
-     *
+     * <p>
+     * Note that this may make network requests for RFC 8414 compliant endpoints.
      * @return a set of default parameters
      */
-    public static OAuthParameters createDefault() {
-        return createDefault(null);
+    public static IOAuthParameters createDefault() {
+        return createDefault(Config.getUrls().getDefaultOsmApiUrl(), OAuthVersion.OAuth20);
     }
 
@@ -55,17 +56,6 @@
      * at the given API url. URL parameters are only set if the URL equals {@link IUrls#getDefaultOsmApiUrl}
      * or references the domain "dev.openstreetmap.org", otherwise they may be <code>null</code>.
-     *
-     * @param apiUrl The API URL for which the OAuth default parameters are created. If null or empty, the default OSM API url is used.
-     * @return a set of default parameters for the given {@code apiUrl}
-     * @since 5422
-     */
-    public static OAuthParameters createDefault(String apiUrl) {
-        return (OAuthParameters) createDefault(apiUrl, OAuthVersion.OAuth10a);
-    }
-
-    /**
-     * Replies a set of default parameters for a consumer accessing an OSM server
-     * at the given API url. URL parameters are only set if the URL equals {@link IUrls#getDefaultOsmApiUrl}
-     * or references the domain "dev.openstreetmap.org", otherwise they may be <code>null</code>.
+     * <p>
+     * Note that this may make network requests for RFC 8414 compliant endpoints.
      *
      * @param apiUrl The API URL for which the OAuth default parameters are created. If null or empty, the default OSM API url is used.
@@ -80,6 +70,4 @@
 
         switch (oAuthVersion) {
-            case OAuth10a:
-                return getDefaultOAuth10Parameters(apiUrl);
             case OAuth20:
             case OAuth21: // For now, OAuth 2.1 (draft) is just OAuth 2.0 with mandatory extensions, which we implement.
@@ -90,4 +78,31 @@
     }
 
+    private static JsonObject getRFC8414Parameters(String apiUrl) {
+        HttpClient client = null;
+        try {
+            final URI apiURI = new URI(apiUrl);
+            final URL rfc8414URL = new URI(apiURI.getScheme(), apiURI.getHost(),
+                    "/.well-known/oauth-authorization-server", null).toURL();
+            client = HttpClient.create(rfc8414URL);
+            HttpClient.Response response = client.connect();
+            if (response.getResponseCode() == 200) {
+                try (BufferedReader reader = response.getContentReader();
+                     JsonReader jsonReader = Json.createReader(reader)) {
+                    JsonStructure structure = jsonReader.read();
+                    if (structure.getValueType() == JsonValue.ValueType.OBJECT) {
+                        return structure.asJsonObject();
+                    }
+                }
+            }
+        } catch (URISyntaxException | IOException e) {
+            throw new JosmRuntimeException(e);
+        } finally {
+            if (client != null) {
+                client.disconnect();
+            }
+        }
+        return Json.createObjectBuilder().build();
+    }
+
     /**
      * Get the default OAuth 2.0 parameters
@@ -98,39 +113,58 @@
         final String clientId;
         final String clientSecret;
-        final String redirectUri;
+        final String redirectUri = "http://127.0.0.1:8111/oauth_authorization";
         final String baseUrl;
-        if (apiUrl != null && !Config.getUrls().getDefaultOsmApiUrl().equals(apiUrl) && !"http://invalid".equals(apiUrl)) {
-            clientId = "";
-            clientSecret = "";
-            baseUrl = apiUrl;
-            HttpClient client = null;
-            redirectUri = "";
-            // Check if the server is RFC 8414 compliant
-            try {
-                client = HttpClient.create(new URL(apiUrl + (apiUrl.endsWith("/") ? "" : "/") + ".well-known/oauth-authorization-server"));
-                HttpClient.Response response = client.connect();
-                if (response.getResponseCode() == 200) {
-                    try (BufferedReader reader = response.getContentReader();
-                         JsonReader jsonReader = Json.createReader(reader)) {
-                        JsonStructure structure = jsonReader.read();
-                        if (structure.getValueType() == JsonValue.ValueType.OBJECT) {
-                            return parseAuthorizationServerMetadataResponse(clientId, clientSecret, apiUrl,
-                                    redirectUri, structure.asJsonObject());
-                        }
-                    }
-                }
-            } catch (IOException | OAuthException e) {
+        apiUrl = apiUrl == null ? OsmApi.getOsmApi().getServerUrl() : apiUrl;
+        switch (apiUrl) {
+            case OSM_API_DEV:
+            case OSM_API_MASTER:
+                // This clientId/clientSecret are provided by taylor.smock. Feel free to change if needed, but
+                // do let one of the maintainers with server access know so that they can update the test OAuth
+                // token.
+                clientId = "-QZt6n1btDfqrfJNGUIMZjzcyqTgIV6sy79_W4kmQLM";
+                // Keep secret for dev apis, just in case we want to test something that needs it.
+                clientSecret = "SWnmRD4AdLO-2-ttHE5TR3eLF2McNf7dh0_Z2WNzJdI";
+                break;
+            case OSM_API_DEFAULT:
+                clientId = "edPII614Lm0_0zEpc_QzEltA9BUll93-Y-ugRQUoHMI";
+                // We don't actually use the client secret in our authorization flow.
+                clientSecret = null;
+                break;
+            case "https://www.openhistoricalmap.org/api":
+                // clientId provided by 1ec5 (Minh Nguyễn)
+                clientId = "Hl5yIhFS-Egj6aY7A35ouLOuZl0EHjj8JJQQ46IO96E";
+                clientSecret = null;
+                break;
+            default:
+                clientId = "";
+                clientSecret = null;
+        }
+        baseUrl = apiUrl;
+        // Check if the server is RFC 8414 compliant
+        try {
+            synchronized (RFC8414_RESPONSES) {
+                final JsonObject data;
+                if (NetworkManager.isOffline(apiUrl)) {
+                    data = null;
+                } else {
+                    data = RFC8414_RESPONSES.computeIfAbsent(apiUrl, OAuthParameters::getRFC8414Parameters);
+                }
+                if (data == null || data.isEmpty()) {
+                    RFC8414_RESPONSES.remove(apiUrl);
+                } else {
+                    return parseAuthorizationServerMetadataResponse(clientId, clientSecret, apiUrl,
+                            redirectUri, data);
+                }
+            }
+        } catch (JosmRuntimeException e) {
+            if (e.getCause() instanceof URISyntaxException || e.getCause() instanceof IOException) {
                 Logging.trace(e);
-            } finally {
-                if (client != null) client.disconnect();
-            }
-        } else {
-            clientId = "edPII614Lm0_0zEpc_QzEltA9BUll93-Y-ugRQUoHMI";
-            // We don't actually use the client secret in our authorization flow.
-            clientSecret = null;
-            baseUrl = "https://www.openstreetmap.org/oauth2";
-            redirectUri = "http://127.0.0.1:8111/oauth_authorization";
-            apiUrl = OsmApi.getOsmApi().getBaseUrl();
-        }
+            } else {
+                throw e;
+            }
+        } catch (OAuthException e) {
+            Logging.trace(e);
+        }
+        // Fall back to guessing the parameters.
         return new OAuth20Parameters(clientId, clientSecret, baseUrl, apiUrl, redirectUri);
     }
@@ -155,44 +189,4 @@
 
     /**
-     * Get the default OAuth 1.0a parameters
-     * @param apiUrl The api url
-     * @return The default parameters
-     */
-    private static OAuthParameters getDefaultOAuth10Parameters(String apiUrl) {
-        final String consumerKey;
-        final String consumerSecret;
-        final String serverUrl;
-
-        if (apiUrl != null && !Config.getUrls().getDefaultOsmApiUrl().equals(apiUrl)) {
-            consumerKey = ""; // a custom consumer key is required
-            consumerSecret = ""; // a custom consumer secret is requireds
-            serverUrl = apiUrl.replaceAll("/api$", "");
-        } else {
-            consumerKey = DEFAULT_JOSM_CONSUMER_KEY;
-            consumerSecret = DEFAULT_JOSM_CONSUMER_SECRET;
-            serverUrl = Config.getUrls().getOSMWebsite();
-        }
-
-        return new OAuthParameters(
-                consumerKey,
-                consumerSecret,
-                serverUrl + "/oauth/request_token",
-                serverUrl + "/oauth/access_token",
-                serverUrl + "/oauth/authorize",
-                serverUrl + "/login",
-                serverUrl + "/logout");
-    }
-
-    /**
-     * Replies a set of parameters as defined in the preferences.
-     *
-     * @param apiUrl the API URL. Must not be null.
-     * @return the parameters
-     */
-    public static OAuthParameters createFromApiUrl(String apiUrl) {
-        return (OAuthParameters) createFromApiUrl(apiUrl, OAuthVersion.OAuth10a);
-    }
-
-    /**
      * Replies a set of parameters as defined in the preferences.
      *
@@ -205,14 +199,4 @@
         IOAuthParameters parameters = createDefault(apiUrl, oAuthVersion);
         switch (oAuthVersion) {
-            case OAuth10a:
-                OAuthParameters oauth10aParameters = (OAuthParameters) parameters;
-                return new OAuthParameters(
-                    Config.getPref().get("oauth.settings.consumer-key", oauth10aParameters.getConsumerKey()),
-                    Config.getPref().get("oauth.settings.consumer-secret", oauth10aParameters.getConsumerSecret()),
-                    Config.getPref().get("oauth.settings.request-token-url", oauth10aParameters.getRequestTokenUrl()),
-                    Config.getPref().get("oauth.settings.access-token-url", oauth10aParameters.getAccessTokenUrl()),
-                    Config.getPref().get("oauth.settings.authorise-url", oauth10aParameters.getAuthoriseUrl()),
-                    Config.getPref().get("oauth.settings.osm-login-url", oauth10aParameters.getOsmLoginUrl()),
-                    Config.getPref().get("oauth.settings.osm-logout-url", oauth10aParameters.getOsmLogoutUrl()));
             case OAuth20:
             case OAuth21: // Right now, OAuth 2.1 will work with our OAuth 2.0 implementation
@@ -229,187 +213,3 @@
         }
     }
-
-    /**
-     * Remembers the current values in the preferences.
-     */
-    @Override
-    public void rememberPreferences() {
-        Config.getPref().put("oauth.settings.consumer-key", getConsumerKey());
-        Config.getPref().put("oauth.settings.consumer-secret", getConsumerSecret());
-        Config.getPref().put("oauth.settings.request-token-url", getRequestTokenUrl());
-        Config.getPref().put("oauth.settings.access-token-url", getAccessTokenUrl());
-        Config.getPref().put("oauth.settings.authorise-url", getAuthoriseUrl());
-        Config.getPref().put("oauth.settings.osm-login-url", getOsmLoginUrl());
-        Config.getPref().put("oauth.settings.osm-logout-url", getOsmLogoutUrl());
-    }
-
-    private final String consumerKey;
-    private final String consumerSecret;
-    private final String requestTokenUrl;
-    private final String accessTokenUrl;
-    private final String authoriseUrl;
-    private final String osmLoginUrl;
-    private final String osmLogoutUrl;
-
-    /**
-     * Constructs a new {@code OAuthParameters}.
-     * @param consumerKey consumer key
-     * @param consumerSecret consumer secret
-     * @param requestTokenUrl request token URL
-     * @param accessTokenUrl access token URL
-     * @param authoriseUrl authorise URL
-     * @param osmLoginUrl the OSM login URL (for automatic mode)
-     * @param osmLogoutUrl the OSM logout URL (for automatic mode)
-     * @see #createDefault
-     * @see #createFromApiUrl
-     * @since 9220
-     */
-    public OAuthParameters(String consumerKey, String consumerSecret,
-                           String requestTokenUrl, String accessTokenUrl, String authoriseUrl, String osmLoginUrl, String osmLogoutUrl) {
-        this.consumerKey = consumerKey;
-        this.consumerSecret = consumerSecret;
-        this.requestTokenUrl = requestTokenUrl;
-        this.accessTokenUrl = accessTokenUrl;
-        this.authoriseUrl = authoriseUrl;
-        this.osmLoginUrl = osmLoginUrl;
-        this.osmLogoutUrl = osmLogoutUrl;
-    }
-
-    /**
-     * Creates a clone of the parameters in <code>other</code>.
-     *
-     * @param other the other parameters. Must not be null.
-     * @throws IllegalArgumentException if other is null
-     */
-    public OAuthParameters(OAuthParameters other) {
-        CheckParameterUtil.ensureParameterNotNull(other, "other");
-        this.consumerKey = other.consumerKey;
-        this.consumerSecret = other.consumerSecret;
-        this.accessTokenUrl = other.accessTokenUrl;
-        this.requestTokenUrl = other.requestTokenUrl;
-        this.authoriseUrl = other.authoriseUrl;
-        this.osmLoginUrl = other.osmLoginUrl;
-        this.osmLogoutUrl = other.osmLogoutUrl;
-    }
-
-    /**
-     * Gets the consumer key.
-     * @return The consumer key
-     */
-    public String getConsumerKey() {
-        return consumerKey;
-    }
-
-    /**
-     * Gets the consumer secret.
-     * @return The consumer secret
-     */
-    public String getConsumerSecret() {
-        return consumerSecret;
-    }
-
-    /**
-     * Gets the request token URL.
-     * @return The request token URL
-     */
-    public String getRequestTokenUrl() {
-        return requestTokenUrl;
-    }
-
-    /**
-     * Gets the access token URL.
-     * @return The access token URL
-     */
-    @Override
-    public String getAccessTokenUrl() {
-        return accessTokenUrl;
-    }
-
-    @Override
-    public String getAuthorizationUrl() {
-        return this.authoriseUrl;
-    }
-
-    @Override
-    public OAuthVersion getOAuthVersion() {
-        return OAuthVersion.OAuth10a;
-    }
-
-    @Override
-    public String getClientId() {
-        return this.consumerKey;
-    }
-
-    @Override
-    public String getClientSecret() {
-        return this.consumerSecret;
-    }
-
-    /**
-     * Gets the authorise URL.
-     * @return The authorise URL
-     */
-    public String getAuthoriseUrl() {
-        return this.getAuthorizationUrl();
-    }
-
-    /**
-     * Gets the URL used to login users on the website (for automatic mode).
-     * @return The URL used to login users
-     */
-    public String getOsmLoginUrl() {
-        return osmLoginUrl;
-    }
-
-    /**
-     * Gets the URL used to logout users on the website (for automatic mode).
-     * @return The URL used to logout users
-     */
-    public String getOsmLogoutUrl() {
-        return osmLogoutUrl;
-    }
-
-    /**
-     * Builds an {@link OAuthConsumer} based on these parameters.
-     *
-     * @return the consumer
-     */
-    public OAuthConsumer buildConsumer() {
-        return new SignpostAdapters.OAuthConsumer(consumerKey, consumerSecret);
-    }
-
-    /**
-     * Builds an {@link OAuthProvider} based on these parameters and a OAuth consumer <code>consumer</code>.
-     *
-     * @param consumer the consumer. Must not be null.
-     * @return the provider
-     * @throws IllegalArgumentException if consumer is null
-     */
-    public OAuthProvider buildProvider(OAuthConsumer consumer) {
-        CheckParameterUtil.ensureParameterNotNull(consumer, "consumer");
-        return new SignpostAdapters.OAuthProvider(
-                requestTokenUrl,
-                accessTokenUrl,
-                authoriseUrl
-        );
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        OAuthParameters that = (OAuthParameters) o;
-        return Objects.equals(consumerKey, that.consumerKey) &&
-                Objects.equals(consumerSecret, that.consumerSecret) &&
-                Objects.equals(requestTokenUrl, that.requestTokenUrl) &&
-                Objects.equals(accessTokenUrl, that.accessTokenUrl) &&
-                Objects.equals(authoriseUrl, that.authoriseUrl) &&
-                Objects.equals(osmLoginUrl, that.osmLoginUrl) &&
-                Objects.equals(osmLogoutUrl, that.osmLogoutUrl);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(consumerKey, consumerSecret, requestTokenUrl, accessTokenUrl, authoriseUrl, osmLoginUrl, osmLogoutUrl);
-    }
 }
Index: unk/src/org/openstreetmap/josm/data/oauth/OAuthToken.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/OAuthToken.java	(revision 18990)
+++ 	(revision )
@@ -1,82 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.oauth;
-
-import java.util.Objects;
-
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-
-import oauth.signpost.OAuthConsumer;
-
-/**
- * An oauth token that has been obtained by JOSM and can be used to authenticate the user on the server.
- */
-public class OAuthToken {
-
-    /**
-     * Creates an OAuthToken from the token currently managed by the {@link OAuthConsumer}.
-     *
-     * @param consumer the consumer
-     * @return the token
-     */
-    public static OAuthToken createToken(OAuthConsumer consumer) {
-        return new OAuthToken(consumer.getToken(), consumer.getTokenSecret());
-    }
-
-    private final String key;
-    private final String secret;
-
-    /**
-     * Creates a new token
-     *
-     * @param key the token key
-     * @param secret the token secret
-     */
-    public OAuthToken(String key, String secret) {
-        this.key = key;
-        this.secret = secret;
-    }
-
-    /**
-     * Creates a clone of another token
-     *
-     * @param other the other token. Must not be null.
-     * @throws IllegalArgumentException if other is null
-     */
-    public OAuthToken(OAuthToken other) {
-        CheckParameterUtil.ensureParameterNotNull(other, "other");
-        this.key = other.key;
-        this.secret = other.secret;
-    }
-
-    /**
-     * Replies the token key
-     *
-     * @return the token key
-     */
-    public String getKey() {
-        return key;
-    }
-
-    /**
-     * Replies the token secret
-     *
-     * @return the token secret
-     */
-    public String getSecret() {
-        return secret;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(key, secret);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null || getClass() != obj.getClass()) return false;
-        OAuthToken that = (OAuthToken) obj;
-        return Objects.equals(key, that.key) &&
-                Objects.equals(secret, that.secret);
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/data/oauth/OAuthVersion.java	(revision 18991)
@@ -8,5 +8,9 @@
  */
 public enum OAuthVersion {
-    /** <a href="https://oauth.net/core/1.0a/">OAuth 1.0a</a> */
+    /**
+     * <a href="https://oauth.net/core/1.0a/">OAuth 1.0a</a>
+     * @deprecated The OSM API server has deprecated and will remove OAuth 1.0a support in June 2024.
+     */
+    @Deprecated
     OAuth10a,
     /** <a href="https://datatracker.ietf.org/doc/html/rfc6749">OAuth 2.0</a> */
Index: unk/src/org/openstreetmap/josm/data/oauth/SignpostAdapters.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/oauth/SignpostAdapters.java	(revision 18990)
+++ 	(revision )
@@ -1,162 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.oauth;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Map;
-
-import org.openstreetmap.josm.tools.HttpClient;
-
-import oauth.signpost.AbstractOAuthConsumer;
-import oauth.signpost.AbstractOAuthProvider;
-
-/**
- * Adapters to make {@code oauth.signpost} work with {@link HttpClient}.
- */
-public final class SignpostAdapters {
-
-    private SignpostAdapters() {
-        // Hide constructor for utility classes
-    }
-
-    /**
-     * OAuth provider.
-     */
-    public static class OAuthProvider extends AbstractOAuthProvider {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Constructs a new {@code OAuthProvider}.
-         * @param requestTokenEndpointUrl request token endpoint URL
-         * @param accessTokenEndpointUrl access token endpoint URL
-         * @param authorizationWebsiteUrl authorization website URL
-         */
-        public OAuthProvider(String requestTokenEndpointUrl, String accessTokenEndpointUrl, String authorizationWebsiteUrl) {
-            super(requestTokenEndpointUrl, accessTokenEndpointUrl, authorizationWebsiteUrl);
-        }
-
-        @Override
-        protected HttpRequest createRequest(String endpointUrl) throws Exception {
-            return new HttpRequest(HttpClient.create(new URL(endpointUrl)));
-        }
-
-        @Override
-        protected HttpResponse sendRequest(oauth.signpost.http.HttpRequest request) throws Exception {
-            return new HttpResponse(((HttpRequest) request).request.connect());
-        }
-
-        @Override
-        protected void closeConnection(oauth.signpost.http.HttpRequest request, oauth.signpost.http.HttpResponse response) throws Exception {
-            if (response != null) {
-                ((HttpResponse) response).response.disconnect();
-            } else if (request != null) {
-                ((HttpRequest) request).request.disconnect();
-            }
-        }
-    }
-
-    /**
-     * OAuth consumer.
-     */
-    public static class OAuthConsumer extends AbstractOAuthConsumer {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * Constructs a new {@code OAuthConsumer}.
-         * @param consumerKey consumer key
-         * @param consumerSecret consumer secret
-         */
-        public OAuthConsumer(String consumerKey, String consumerSecret) {
-            super(consumerKey, consumerSecret);
-        }
-
-        @Override
-        protected HttpRequest wrap(Object request) {
-            return new HttpRequest((HttpClient) request);
-        }
-    }
-
-    static final class HttpRequest implements oauth.signpost.http.HttpRequest {
-        final HttpClient request;
-
-        HttpRequest(HttpClient request) {
-            this.request = request;
-        }
-
-        @Override
-        public void setHeader(String name, String value) {
-            request.setHeader(name, value);
-        }
-
-        @Override
-        public String getMethod() {
-            return request.getRequestMethod();
-        }
-
-        @Override
-        public String getRequestUrl() {
-            return request.getURL().toExternalForm();
-        }
-
-        @Override
-        public String getContentType() {
-            return request.getRequestHeader("Content-Type");
-        }
-
-        @Override
-        public String getHeader(String name) {
-            return request.getRequestHeader(name);
-        }
-
-        @Override
-        public InputStream getMessagePayload() {
-            return null;
-        }
-
-        @Override
-        public void setRequestUrl(String url) {
-            throw new IllegalStateException();
-        }
-
-        @Override
-        public Map<String, String> getAllHeaders() {
-            throw new IllegalStateException();
-        }
-
-        @Override
-        public Object unwrap() {
-            throw new IllegalStateException();
-        }
-    }
-
-    static final class HttpResponse implements oauth.signpost.http.HttpResponse {
-        final HttpClient.Response response;
-
-        HttpResponse(HttpClient.Response response) {
-            this.response = response;
-        }
-
-        @Override
-        public int getStatusCode() {
-            return response.getResponseCode();
-        }
-
-        @Override
-        public String getReasonPhrase() {
-            return response.getResponseMessage();
-        }
-
-        @Override
-        public InputStream getContent() throws IOException {
-            return response.getContent();
-        }
-
-        @Override
-        public Object unwrap() {
-            throw new IllegalStateException();
-        }
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/AbstractAuthorizationUI.java	(revision 18991)
@@ -5,6 +5,6 @@
 
 import org.openstreetmap.josm.data.oauth.IOAuthParameters;
+import org.openstreetmap.josm.data.oauth.IOAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
@@ -23,24 +23,21 @@
 
     private String apiUrl;
-    private final AdvancedOAuthPropertiesPanel pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(OAuthVersion.OAuth10a);
-    private transient OAuthToken accessToken;
-
-    /**
-     * Constructs a new {@code AbstractAuthorizationUI} without API URL.
-     * @since 10189
-     */
-    protected AbstractAuthorizationUI() {
-    }
+    private final AdvancedOAuthPropertiesPanel pnlAdvancedProperties;
+    private transient IOAuthToken accessToken;
 
     /**
      * Constructs a new {@code AbstractAuthorizationUI} for the given API URL.
-     * @param apiUrl The OSM API URL
-     * @since 5422
+     * @param apiUrl The OSM API URL (may be null)
+     * @param oAuthVersion The oauth version to use
+     * @since 18991
      */
-    protected AbstractAuthorizationUI(String apiUrl) {
-        setApiUrl(apiUrl);
+    protected AbstractAuthorizationUI(String apiUrl, OAuthVersion oAuthVersion) {
+        this.pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(oAuthVersion);
+        if (apiUrl != null) {
+            setApiUrl(apiUrl);
+        }
     }
 
-    protected void fireAccessTokenChanged(OAuthToken oldValue, OAuthToken newValue) {
+    protected void fireAccessTokenChanged(IOAuthToken oldValue, IOAuthToken newValue) {
         firePropertyChange(ACCESS_TOKEN_PROP, oldValue, newValue);
     }
@@ -91,5 +88,5 @@
      * @return the retrieved Access Token
      */
-    public OAuthToken getAccessToken() {
+    public IOAuthToken getAccessToken() {
         return accessToken;
     }
@@ -101,6 +98,6 @@
      * @param accessToken the new access token. null, to clear the current access token
      */
-    protected void setAccessToken(OAuthToken accessToken) {
-        OAuthToken oldValue = this.accessToken;
+    protected void setAccessToken(IOAuthToken accessToken) {
+        IOAuthToken oldValue = this.accessToken;
         this.accessToken = accessToken;
         if (oldValue == null ^ this.accessToken == null) {
@@ -111,4 +108,13 @@
             fireAccessTokenChanged(oldValue, this.accessToken);
         }
+    }
+
+    /**
+     * Get the OAuth version for this AuthorizationUI
+     * @return The OAuth version
+     * @since 18991
+     */
+    public OAuthVersion getOAuthVersion() {
+        return this.pnlAdvancedProperties.getAdvancedParameters().getOAuthVersion();
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/AccessTokenInfoPanel.java	(revision 18991)
@@ -12,16 +12,17 @@
 import javax.swing.JPanel;
 
+import org.openstreetmap.josm.data.oauth.IOAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuth20Token;
 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
+import org.openstreetmap.josm.tools.JosmRuntimeException;
 
 /**
- * Displays the key and the secret of an OAuth Access Token.
- * @since 2746
+ * Displays the key of an OAuth Access Token.
+ * @since 2746 (modified for OAuth 2 in 18991)
  */
 public class AccessTokenInfoPanel extends JPanel {
 
     private final JosmTextField tfAccessTokenKey = new JosmTextField(null, null, 0, false);
-    private final JosmTextField tfAccessTokenSecret = new JosmTextField(null, null, 0, false);
     private final JCheckBox cbSaveAccessTokenInPreferences = new JCheckBox(tr("Save Access Token in preferences"));
 
@@ -56,9 +57,5 @@
         add(new JLabel(tr("Access Token Secret:")), gc);
 
-        gc.gridx = 1;
         gc.weightx = 1.0;
-        add(tfAccessTokenSecret, gc);
-        tfAccessTokenSecret.setEditable(false);
-
         // the checkbox
         gc.gridx = 0;
@@ -87,12 +84,14 @@
      * @param token the access  token. If null, the content in the info panel is cleared
      */
-    public void setAccessToken(OAuthToken token) {
+    public void setAccessToken(IOAuthToken token) {
         if (token == null) {
             tfAccessTokenKey.setText("");
-            tfAccessTokenSecret.setText("");
             return;
         }
-        tfAccessTokenKey.setText(token.getKey());
-        tfAccessTokenSecret.setText(token.getSecret());
+        if (token instanceof OAuth20Token) {
+            tfAccessTokenKey.setText(((OAuth20Token) token).getBearerToken());
+        } else {
+            throw new JosmRuntimeException("Unknown token type: " + token.getClass());
+        }
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java	(revision 18991)
@@ -22,5 +22,7 @@
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
@@ -53,6 +55,4 @@
     private final JosmTextField tfAccessTokenURL = new JosmTextField();
     private final JosmTextField tfAuthoriseURL = new JosmTextField();
-    private final JosmTextField tfOsmLoginURL = new JosmTextField();
-    private final JosmTextField tfOsmLogoutURL = new JosmTextField();
     private final OAuthVersion oauthVersion;
     private transient UseDefaultItemListener ilUseDefault;
@@ -84,9 +84,5 @@
         gc.weightx = 0.0;
         gc.gridwidth = 1;
-        if (this.oauthVersion == OAuthVersion.OAuth10a) {
-            add(new JLabel(tr("Consumer Key:")), gc);
-        } else {
-            add(new JLabel(tr("Client ID:")), gc);
-        }
+        add(new JLabel(tr("Client ID:")), gc);
 
         gc.gridx = 1;
@@ -99,9 +95,5 @@
         gc.gridx = 0;
         gc.weightx = 0.0;
-        if (this.oauthVersion == OAuthVersion.OAuth10a) {
-            add(new JLabel(tr("Consumer Secret:")), gc);
-        } else {
-            add(new JLabel(tr("Client Secret:")), gc);
-        }
+        add(new JLabel(tr("Client Secret:")), gc);
 
         gc.gridx = 1;
@@ -114,9 +106,5 @@
         gc.gridx = 0;
         gc.weightx = 0.0;
-        if (this.oauthVersion == OAuthVersion.OAuth10a) {
-            add(new JLabel(tr("Request Token URL:")), gc);
-        } else {
-            add(new JLabel(tr("Redirect URL:")), gc);
-        }
+        add(new JLabel(tr("Redirect URL:")), gc);
 
         gc.gridx = 1;
@@ -147,34 +135,11 @@
         SelectAllOnFocusGainedDecorator.decorate(tfAuthoriseURL);
 
-        if (this.oauthVersion == OAuthVersion.OAuth10a) {
-            // -- OSM login URL
-            gc.gridy++;
-            gc.gridx = 0;
-            gc.weightx = 0.0;
-            add(new JLabel(tr("OSM login URL:")), gc);
-
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            add(tfOsmLoginURL, gc);
-            SelectAllOnFocusGainedDecorator.decorate(tfOsmLoginURL);
-
-            // -- OSM logout URL
-            gc.gridy++;
-            gc.gridx = 0;
-            gc.weightx = 0.0;
-            add(new JLabel(tr("OSM logout URL:")), gc);
-
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            add(tfOsmLogoutURL, gc);
-            SelectAllOnFocusGainedDecorator.decorate(tfOsmLogoutURL);
-        }
-
         ilUseDefault = new UseDefaultItemListener();
         cbUseDefaults.addItemListener(ilUseDefault);
+        cbUseDefaults.setSelected(Config.getPref().getBoolean("oauth.settings.use-default", true));
     }
 
     protected boolean hasCustomSettings() {
-        OAuthParameters params = OAuthParameters.createDefault(apiUrl);
+        IOAuthParameters params = OAuthParameters.createDefault(apiUrl, OAuthVersion.OAuth20);
         return !params.equals(getAdvancedParameters());
     }
@@ -211,28 +176,22 @@
 
     protected void resetToDefaultSettings() {
-        cbUseDefaults.setSelected(true);
         IOAuthParameters iParams = OAuthParameters.createDefault(apiUrl, this.oauthVersion);
-        switch (this.oauthVersion) {
-            case OAuth10a:
-                OAuthParameters params = (OAuthParameters) iParams;
-                tfConsumerKey.setText(params.getConsumerKey());
-                tfConsumerSecret.setText(params.getConsumerSecret());
-                tfRequestTokenURL.setText(params.getRequestTokenUrl());
-                tfAccessTokenURL.setText(params.getAccessTokenUrl());
-                tfAuthoriseURL.setText(params.getAuthoriseUrl());
-                tfOsmLoginURL.setText(params.getOsmLoginUrl());
-                tfOsmLogoutURL.setText(params.getOsmLogoutUrl());
-                break;
-            case OAuth20:
-            case OAuth21:
-                OAuth20Parameters params20 = (OAuth20Parameters) iParams;
-                tfConsumerKey.setText(params20.getClientId());
-                tfConsumerSecret.setText(params20.getClientSecret());
-                tfAccessTokenURL.setText(params20.getAccessTokenUrl());
-                tfAuthoriseURL.setText(params20.getAuthorizationUrl());
-                tfRequestTokenURL.setText(params20.getRedirectUri());
-        }
-
-        setChildComponentsEnabled(false);
+        GuiHelper.runInEDTAndWaitWithException(() -> {
+                    cbUseDefaults.setSelected(true);
+                    switch (this.oauthVersion) {
+                        case OAuth20:
+                        case OAuth21:
+                            OAuth20Parameters params20 = (OAuth20Parameters) iParams;
+                            tfConsumerKey.setText(params20.getClientId());
+                            tfConsumerSecret.setText(params20.getClientSecret());
+                            tfAccessTokenURL.setText(params20.getAccessTokenUrl());
+                            tfAuthoriseURL.setText(params20.getAuthorizationUrl());
+                            tfRequestTokenURL.setText(params20.getRedirectUri());
+                            break;
+                        default:
+                            throw new UnsupportedOperationException("Unsupported OAuth version: " + this.oauthVersion);
+                    }
+                    setChildComponentsEnabled(false);
+                });
     }
 
@@ -253,14 +212,4 @@
         if (cbUseDefaults.isSelected())
             return OAuthParameters.createDefault(apiUrl, this.oauthVersion);
-        if (this.oauthVersion == OAuthVersion.OAuth10a) {
-            return new OAuthParameters(
-                    tfConsumerKey.getText(),
-                    tfConsumerSecret.getText(),
-                    tfRequestTokenURL.getText(),
-                    tfAccessTokenURL.getText(),
-                    tfAuthoriseURL.getText(),
-                    tfOsmLoginURL.getText(),
-                    tfOsmLogoutURL.getText());
-        }
         return new OAuth20Parameters(
                 tfConsumerKey.getText(),
@@ -286,14 +235,5 @@
             cbUseDefaults.setSelected(false);
             setChildComponentsEnabled(true);
-            if (parameters instanceof OAuthParameters) {
-                OAuthParameters parameters10 = (OAuthParameters) parameters;
-                tfConsumerKey.setText(parameters10.getConsumerKey() == null ? "" : parameters10.getConsumerKey());
-                tfConsumerSecret.setText(parameters10.getConsumerSecret() == null ? "" : parameters10.getConsumerSecret());
-                tfRequestTokenURL.setText(parameters10.getRequestTokenUrl() == null ? "" : parameters10.getRequestTokenUrl());
-                tfAccessTokenURL.setText(parameters10.getAccessTokenUrl() == null ? "" : parameters10.getAccessTokenUrl());
-                tfAuthoriseURL.setText(parameters10.getAuthoriseUrl() == null ? "" : parameters10.getAuthoriseUrl());
-                tfOsmLoginURL.setText(parameters10.getOsmLoginUrl() == null ? "" : parameters10.getOsmLoginUrl());
-                tfOsmLogoutURL.setText(parameters10.getOsmLogoutUrl() == null ? "" : parameters10.getOsmLogoutUrl());
-            } else if (parameters instanceof OAuth20Parameters) {
+            if (parameters instanceof OAuth20Parameters) {
                 OAuth20Parameters parameters20 = (OAuth20Parameters) parameters;
                 tfConsumerKey.setText(parameters20.getClientId());
@@ -317,10 +257,12 @@
         boolean useDefault = Config.getPref().getBoolean("oauth.settings.use-default", true);
         ilUseDefault.setEnabled(false);
-        if (useDefault) {
-            resetToDefaultSettings();
-        } else {
-            setAdvancedParameters(OAuthParameters.createFromApiUrl(paramApiUrl));
-        }
-        ilUseDefault.setEnabled(true);
+        MainApplication.worker.execute(() -> {
+            if (useDefault) {
+                this.resetToDefaultSettings();
+            } else {
+                setAdvancedParameters(OAuthParameters.createFromApiUrl(paramApiUrl, OAuthVersion.OAuth20));
+            }
+            GuiHelper.runInEDT(() -> ilUseDefault.setEnabled(true));
+        });
     }
 
@@ -331,5 +273,5 @@
         Config.getPref().putBoolean("oauth.settings.use-default", cbUseDefaults.isSelected());
         if (cbUseDefaults.isSelected()) {
-            new OAuthParameters(null, null, null, null, null, null, null).rememberPreferences();
+            MainApplication.worker.execute(() -> OAuthParameters.createDefault().rememberPreferences());
         } else {
             getAdvancedParameters().rememberPreferences();
@@ -349,5 +291,5 @@
                     return;
                 }
-                resetToDefaultSettings();
+                MainApplication.worker.execute(AdvancedOAuthPropertiesPanel.this::resetToDefaultSettings);
                 break;
             case ItemEvent.DESELECTED:
@@ -372,5 +314,5 @@
         this.apiUrl = apiUrl;
         if (cbUseDefaults.isSelected()) {
-            resetToDefaultSettings();
+            MainApplication.worker.execute(this::resetToDefaultSettings);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 18991)
@@ -13,6 +13,4 @@
 import java.awt.event.ActionEvent;
 import java.io.IOException;
-import java.net.Authenticator.RequestorType;
-import java.net.PasswordAuthentication;
 import java.util.concurrent.Executor;
 
@@ -24,35 +22,22 @@
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
-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.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.data.oauth.IOAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.preferences.server.UserNameValidator;
 import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.gui.widgets.DefaultTextComponentValidator;
 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
-import org.openstreetmap.josm.gui.widgets.JosmPasswordField;
-import org.openstreetmap.josm.gui.widgets.JosmTextField;
-import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
-import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.io.auth.CredentialsAgent;
-import org.openstreetmap.josm.io.auth.CredentialsAgentException;
-import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
 
 /**
- * This is an UI which supports a JOSM user to get an OAuth Access Token in a fully
+ * This is a UI which supports a JOSM user to get an OAuth Access Token in a fully
  * automatic process.
  *
@@ -60,9 +45,4 @@
  */
 public class FullyAutomaticAuthorizationUI extends AbstractAuthorizationUI {
-
-    private final JosmTextField tfUserName = new JosmTextField();
-    private final JosmPasswordField tfPassword = new JosmPasswordField();
-    private transient UserNameValidator valUserName;
-    private transient PasswordValidator valPassword;
     private final AccessTokenInfoPanel pnlAccessTokenInfo = new AccessTokenInfoPanel();
     private OsmPrivilegesPanel pnlOsmPrivileges;
@@ -105,5 +85,5 @@
                 + tr("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.").replaceAll("\\. ", ".<br>")
+                        + "Subsequent data upload requests don''t use your password any more.").replace(". ", ".<br>")
                         + "</p>"
                         + "</body></html>");
@@ -119,11 +99,4 @@
         pnl.add(new JLabel(tr("Username: ")), gc);
 
-        gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfUserName, gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfUserName);
-        valUserName = new UserNameValidator(tfUserName);
-        valUserName.validate();
-
         // the password input field
         gc.anchor = GridBagConstraints.NORTHWEST;
@@ -134,12 +107,6 @@
         pnl.add(new JLabel(tr("Password:")), gc);
 
+        // filler - grab remaining space
         gc.gridx = 1;
-        gc.weightx = 1.0;
-        pnl.add(tfPassword, gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfPassword);
-        valPassword = new PasswordValidator(tfPassword);
-        valPassword.validate();
-
-        // filler - grab remaining space
         gc.gridy = 4;
         gc.gridwidth = 2;
@@ -168,28 +135,4 @@
 
     /**
-     * Initializes the panel with values from the preferences
-     * @param paramApiUrl the API URL
-     */
-    @Override
-    public void initialize(String paramApiUrl) {
-        super.initialize(paramApiUrl);
-        CredentialsAgent cm = CredentialsManager.getInstance();
-        try {
-            PasswordAuthentication pa = cm.lookup(RequestorType.SERVER, OsmApi.getOsmApi().getHost());
-            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 (CredentialsAgentException e) {
-            Logging.error(e);
-            tfUserName.setText("");
-            tfPassword.setText("");
-        }
-    }
-
-    /**
      * Builds the panel with the action button  for starting the authorisation
      *
@@ -200,6 +143,4 @@
 
         RunAuthorisationAction runAuthorisationAction = new RunAuthorisationAction();
-        tfPassword.getDocument().addDocumentListener(runAuthorisationAction);
-        tfUserName.getDocument().addDocumentListener(runAuthorisationAction);
         pnl.add(new JButton(runAuthorisationAction));
         return pnl;
@@ -289,12 +230,4 @@
     }
 
-    protected String getOsmUserName() {
-        return tfUserName.getText();
-    }
-
-    protected String getOsmPassword() {
-        return String.valueOf(tfPassword.getPassword());
-    }
-
     /**
      * Constructs a new {@code FullyAutomaticAuthorizationUI} for the given API URL.
@@ -302,7 +235,20 @@
      * @param executor the executor used for running the HTTP requests for the authorization
      * @since 5422
-     */
+     * @deprecated since 18991
+     */
+    @Deprecated
     public FullyAutomaticAuthorizationUI(String apiUrl, Executor executor) {
-        super(apiUrl);
+        this(apiUrl, executor, OAuthVersion.OAuth10a);
+    }
+
+    /**
+     * Constructs a new {@code FullyAutomaticAuthorizationUI} for the given API URL.
+     * @param apiUrl The OSM API URL
+     * @param executor the executor used for running the HTTP requests for the authorization
+     * @param oAuthVersion The OAuth version to use for this UI
+     * @since 18991
+     */
+    public FullyAutomaticAuthorizationUI(String apiUrl, Executor executor, OAuthVersion oAuthVersion) {
+        super(apiUrl, oAuthVersion);
         this.executor = executor;
         build();
@@ -315,5 +261,5 @@
 
     @Override
-    protected void setAccessToken(OAuthToken accessToken) {
+    protected void setAccessToken(IOAuthToken accessToken) {
         super.setAccessToken(accessToken);
         pnlAccessTokenInfo.setAccessToken(accessToken);
@@ -323,10 +269,9 @@
      * Starts the authorisation process
      */
-    class RunAuthorisationAction extends AbstractAction implements DocumentListener {
+    class RunAuthorisationAction extends AbstractAction {
         RunAuthorisationAction() {
             putValue(NAME, tr("Authorize now"));
             new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
             putValue(SHORT_DESCRIPTION, tr("Click to redirect you to the authorization form on the JOSM web site"));
-            updateEnabledState();
         }
 
@@ -334,23 +279,4 @@
         public void actionPerformed(ActionEvent evt) {
             executor.execute(new FullyAutomaticAuthorisationTask(FullyAutomaticAuthorizationUI.this));
-        }
-
-        protected final void updateEnabledState() {
-            setEnabled(valPassword.isValid() && valUserName.isValid());
-        }
-
-        @Override
-        public void changedUpdate(DocumentEvent e) {
-            updateEnabledState();
-        }
-
-        @Override
-        public void insertUpdate(DocumentEvent e) {
-            updateEnabledState();
-        }
-
-        @Override
-        public void removeUpdate(DocumentEvent e) {
-            updateEnabledState();
         }
     }
@@ -386,13 +312,6 @@
                     FullyAutomaticAuthorizationUI.this,
                     getApiUrl(),
-                    (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),
                     getAccessToken()
             ));
-        }
-    }
-
-    static class PasswordValidator extends DefaultTextComponentValidator {
-        PasswordValidator(JTextComponent tc) {
-            super(tc, tr("Please enter your OSM password"), tr("The password cannot be empty. Please enter your OSM password"));
         }
     }
@@ -439,5 +358,5 @@
                             + "Please check your advanced setting and try again."
                             + "</html>",
-                            ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getAuthoriseUrl()),
+                            getAdvancedPropertiesPanel().getAdvancedParameters().getAuthorizationUrl()),
                     tr("OAuth authorization failed"),
                     JOptionPane.ERROR_MESSAGE,
@@ -446,67 +365,22 @@
         }
 
-        protected void alertLoginFailed() {
-            final String loginUrl = ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getOsmLoginUrl();
-            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,
-                            Utils.escapeReservedCharactersHTML(getOsmUserName())),
-                    tr("OAuth authorization failed"),
-                    JOptionPane.ERROR_MESSAGE,
-                    HelpUtil.ht("/Dialog/OAuthAuthorisationWizard#FullyAutomaticProcessFailed")
-            );
-        }
-
         protected void handleException(final OsmOAuthAuthorizationException e) {
-            Runnable r = () -> {
-                if (e instanceof OsmLoginFailedException) {
-                    alertLoginFailed();
-                } else {
-                    alertAuthorisationFailed();
+            Logging.error(e);
+            GuiHelper.runInEDT(this::alertAuthorisationFailed);
+        }
+
+        @Override
+        protected void realRun() throws SAXException, IOException, OsmTransferException {
+            getProgressMonitor().setTicksCount(2);
+            OAuthAuthorizationWizard.authorize(true, token -> {
+                if (!canceled) {
+                    getProgressMonitor().worked(1);
+                    GuiHelper.runInEDT(() -> {
+                        prepareUIForResultDisplay();
+                        setAccessToken(token.orElse(null));
+                    });
                 }
-            };
-            Logging.error(e);
-            GuiHelper.runInEDT(r);
-        }
-
-        @Override
-        protected void realRun() throws SAXException, IOException, OsmTransferException {
-            try {
-                getProgressMonitor().setTicksCount(3);
-                OsmOAuthAuthorizationClient authClient = new OsmOAuthAuthorizationClient(
-                        (OAuthParameters) 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;
-                GuiHelper.runInEDT(() -> {
-                    prepareUIForResultDisplay();
-                    setAccessToken(accessToken);
-                });
-            } catch (final OsmOAuthAuthorizationException e) {
-                handleException(e);
-            }
+            }, getApiUrl(), getOAuthVersion());
+            getProgressMonitor().worked(1);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUI.java	(revision 18991)
@@ -25,7 +25,8 @@
 import javax.swing.text.JTextComponent;
 
+import org.openstreetmap.josm.data.oauth.OAuth20Exception;
+import org.openstreetmap.josm.data.oauth.OAuth20Token;
 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.widgets.DefaultTextComponentValidator;
 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
@@ -33,4 +34,5 @@
 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.JosmRuntimeException;
 
 /**
@@ -43,6 +45,4 @@
     private final JosmTextField tfAccessTokenKey = new JosmTextField();
     private transient AccessTokenKeyValidator valAccessTokenKey;
-    private final JosmTextField tfAccessTokenSecret = new JosmTextField();
-    private transient AccessTokenSecretValidator valAccessTokenSecret;
     private final JCheckBox cbSaveToPreferences = new JCheckBox(tr("Save Access Token in preferences"));
     private final HtmlPanel pnlMessage = new HtmlPanel();
@@ -54,7 +54,22 @@
      * @param executor the executor used for running the HTTP requests for the authorization
      * @since 5422
+     * @deprecated since 18991, use {@link ManualAuthorizationUI#ManualAuthorizationUI(String, Executor, OAuthVersion)}
+     * instead.
      */
+    @Deprecated
     public ManualAuthorizationUI(String apiUrl, Executor executor) {
-        super(/* dont pass apiURL because setApiUrl is overridden and references a local field */);
+        this(apiUrl, executor, OAuthVersion.OAuth10a);
+    }
+
+    /**
+     * Constructs a new {@code ManualAuthorizationUI} for the given API URL.
+     * @param apiUrl The OSM API URL
+     * @param executor the executor used for running the HTTP requests for the authorization
+     * @param oAuthVersion The OAuthVersion to use for this UI
+     * @since 18991
+     */
+    public ManualAuthorizationUI(String apiUrl, Executor executor, OAuthVersion oAuthVersion) {
+        super(null /* don't pass apiURL because setApiUrl is overridden and references a local field */,
+                oAuthVersion);
         setApiUrl(apiUrl);
         this.executor = executor;
@@ -95,18 +110,4 @@
         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, gc);
-        SelectAllOnFocusGainedDecorator.decorate(tfAccessTokenSecret);
-        valAccessTokenSecret = new AccessTokenSecretValidator(tfAccessTokenSecret);
-        valAccessTokenSecret.validate();
-        tfAccessTokenSecret.getDocument().addDocumentListener(accessTokenBuilder);
-
         // the checkbox for saving to preferences
         gc.gridy = 3;
@@ -185,18 +186,16 @@
     }
 
-    private static class AccessTokenSecretValidator extends DefaultTextComponentValidator {
-        AccessTokenSecretValidator(JTextComponent tc) {
-            super(tc, tr("Please enter an Access Token Secret"),
-                      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()) {
+            if (!valAccessTokenKey.isValid()) {
                 setAccessToken(null);
             } else {
-                setAccessToken(new OAuthToken(tfAccessTokenKey.getText().trim(), tfAccessTokenSecret.getText().trim()));
+                try {
+                    setAccessToken(new OAuth20Token(getOAuthParameters(), "{\"token_type\":\"bearer\", \"access_token\""
+                            + tfAccessTokenKey.getText().trim() + "\"}"));
+                } catch (OAuth20Exception e) {
+                    throw new JosmRuntimeException(e);
+                }
             }
         }
@@ -234,5 +233,4 @@
                     ManualAuthorizationUI.this,
                     getApiUrl(),
-                    (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),
                     getAccessToken()
             );
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/OAuthAuthorizationWizard.java	(revision 18991)
@@ -20,6 +20,8 @@
 import java.net.URL;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.Executor;
 import java.util.concurrent.FutureTask;
+import java.util.function.Consumer;
 
 import javax.swing.AbstractAction;
@@ -27,4 +29,5 @@
 import javax.swing.JButton;
 import javax.swing.JDialog;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
@@ -33,7 +36,11 @@
 import javax.swing.text.html.HTMLEditorKit;
 
+import org.openstreetmap.josm.data.oauth.IOAuthParameters;
+import org.openstreetmap.josm.data.oauth.IOAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuth20Authorization;
 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuthVersion;
+import org.openstreetmap.josm.data.oauth.osm.OsmScopes;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
@@ -43,4 +50,6 @@
 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
+import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.GBC;
@@ -59,7 +68,7 @@
     private final AuthorizationProcedure procedure;
     private final String apiUrl;
+    private final OAuthVersion oAuthVersion;
 
     private FullyAutomaticAuthorizationUI pnlFullyAutomaticAuthorisationUI;
-    private SemiAutomaticAuthorizationUI pnlSemiAutomaticAuthorisationUI;
     private ManualAuthorizationUI pnlManualAuthorisationUI;
     private JScrollPane spAuthorisationProcedureUI;
@@ -67,16 +76,55 @@
 
     /**
-     * Launches the wizard, {@link OAuthAccessTokenHolder#setAccessToken(OAuthToken) sets the token}
+     * Launches the wizard, {@link OAuthAccessTokenHolder#setAccessToken(String, IOAuthToken)} sets the token
      * and {@link OAuthAccessTokenHolder#setSaveToPreferences(boolean) saves to preferences}.
+     * @param callback Callback to run when authorization is finished
      * @throws UserCancelException if user cancels the operation
      */
-    public void showDialog() throws UserCancelException {
-        setVisible(true);
-        if (isCanceled()) {
-            throw new UserCancelException();
+    public void showDialog(Consumer<Optional<IOAuthToken>> callback) throws UserCancelException {
+        if ((this.oAuthVersion == OAuthVersion.OAuth20 || this.oAuthVersion == OAuthVersion.OAuth21)
+        && this.procedure == AuthorizationProcedure.FULLY_AUTOMATIC) {
+            authorize(true, callback, this.apiUrl, this.oAuthVersion);
+        } else {
+            setVisible(true);
+            if (isCanceled()) {
+                throw new UserCancelException();
+            }
         }
         OAuthAccessTokenHolder holder = OAuthAccessTokenHolder.getInstance();
-        holder.setAccessToken(getAccessToken());
+        holder.setAccessToken(apiUrl, getAccessToken());
         holder.setSaveToPreferences(isSaveAccessTokenToPreferences());
+    }
+
+    /**
+     * Perform the oauth dance
+     * @param startRemoteControl {@code true} to start remote control if it is not already running
+     * @param callback The callback to use to notify that the OAuth dance succeeded
+     * @param apiUrl The API URL to get the token for
+     * @param oAuthVersion The OAuth version that the authorization dance is force
+     */
+    static void authorize(boolean startRemoteControl, Consumer<Optional<IOAuthToken>> callback, String apiUrl, OAuthVersion oAuthVersion) {
+        final boolean remoteControlIsRunning = Boolean.TRUE.equals(RemoteControl.PROP_REMOTECONTROL_ENABLED.get());
+        // TODO: Ask user if they want to start remote control?
+        if (!remoteControlIsRunning && startRemoteControl) {
+            RemoteControl.start();
+        }
+        new OAuth20Authorization().authorize(OAuthParameters.createDefault(apiUrl, oAuthVersion), token -> {
+                    if (!remoteControlIsRunning) {
+                        RemoteControl.stop();
+                    }
+                    OAuthAccessTokenHolder.getInstance().setAccessToken(apiUrl, token.orElse(null));
+                    OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
+                    if (!token.isPresent()) {
+                        GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(MainApplication.getMainPanel(),
+                                tr("Authentication failed, please check browser for details."),
+                                tr("OAuth Authentication Failed"),
+                                JOptionPane.ERROR_MESSAGE));
+                    }
+                    if (callback != null) {
+                        callback.accept(token);
+                    }
+                }, OsmScopes.read_gpx, OsmScopes.write_gpx,
+                OsmScopes.read_prefs, OsmScopes.write_prefs,
+                OsmScopes.write_api, OsmScopes.write_notes);
     }
 
@@ -91,5 +139,4 @@
         AcceptAccessTokenAction actAcceptAccessToken = new AcceptAccessTokenAction();
         pnlFullyAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
-        pnlSemiAutomaticAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
         pnlManualAuthorisationUI.addPropertyChangeListener(actAcceptAccessToken);
 
@@ -154,12 +201,10 @@
             pnlFullyAutomaticAuthorisationUI.revalidate();
             break;
-        case SEMI_AUTOMATIC:
-            spAuthorisationProcedureUI.getViewport().setView(pnlSemiAutomaticAuthorisationUI);
-            pnlSemiAutomaticAuthorisationUI.revalidate();
-            break;
         case MANUALLY:
             spAuthorisationProcedureUI.getViewport().setView(pnlManualAuthorisationUI);
             pnlManualAuthorisationUI.revalidate();
             break;
+        default:
+            throw new UnsupportedOperationException("Unsupported auth type: " + procedure);
         }
         validate();
@@ -177,7 +222,6 @@
         this.setMinimumSize(new Dimension(500, 300));
 
-        pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI(apiUrl, executor);
-        pnlSemiAutomaticAuthorisationUI = new SemiAutomaticAuthorizationUI(apiUrl, executor);
-        pnlManualAuthorisationUI = new ManualAuthorizationUI(apiUrl, executor);
+        pnlFullyAutomaticAuthorisationUI = new FullyAutomaticAuthorizationUI(apiUrl, executor, oAuthVersion);
+        pnlManualAuthorisationUI = new ManualAuthorizationUI(apiUrl, executor, oAuthVersion);
 
         spAuthorisationProcedureUI = GuiHelper.embedInVerticalScrollPane(new JPanel());
@@ -213,11 +257,14 @@
      * @param apiUrl the API URL. Must not be null.
      * @param executor the executor used for running the HTTP requests for the authorization
+     * @param oAuthVersion The OAuth version this wizard is for
      * @throws IllegalArgumentException if apiUrl is null
      */
-    public OAuthAuthorizationWizard(Component parent, AuthorizationProcedure procedure, String apiUrl, Executor executor) {
+    public OAuthAuthorizationWizard(Component parent, AuthorizationProcedure procedure, String apiUrl,
+                                    Executor executor, OAuthVersion oAuthVersion) {
         super(GuiHelper.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
         this.procedure = Objects.requireNonNull(procedure, "procedure");
         this.apiUrl = Objects.requireNonNull(apiUrl, "apiUrl");
         this.executor = executor;
+        this.oAuthVersion = oAuthVersion;
         build();
     }
@@ -236,5 +283,4 @@
         case FULLY_AUTOMATIC: return pnlFullyAutomaticAuthorisationUI;
         case MANUALLY: return pnlManualAuthorisationUI;
-        case SEMI_AUTOMATIC: return pnlSemiAutomaticAuthorisationUI;
         default: return null;
         }
@@ -246,5 +292,5 @@
      * @return the access token. May be null if the wizard was canceled.
      */
-    public OAuthToken getAccessToken() {
+    public IOAuthToken getAccessToken() {
         return getCurrentAuthorisationUI().getAccessToken();
     }
@@ -255,6 +301,6 @@
      * @return the current OAuth parameters.
      */
-    public OAuthParameters getOAuthParameters() {
-        return (OAuthParameters) getCurrentAuthorisationUI().getOAuthParameters();
+    public IOAuthParameters getOAuthParameters() {
+        return getCurrentAuthorisationUI().getOAuthParameters();
     }
 
@@ -276,5 +322,4 @@
     public void initFromPreferences() {
         pnlFullyAutomaticAuthorisationUI.initialize(apiUrl);
-        pnlSemiAutomaticAuthorisationUI.initialize(apiUrl);
         pnlManualAuthorisationUI.initialize(apiUrl);
     }
@@ -316,6 +361,7 @@
                     MainApplication.getMainFrame(),
                     AuthorizationProcedure.FULLY_AUTOMATIC,
-                    serverUrl.toExternalForm(), Utils.newDirectExecutor());
-            wizard.showDialog();
+                    serverUrl.toString(), Utils.newDirectExecutor(),
+                    OAuthVersion.OAuth20);
+            wizard.showDialog(null);
             return wizard;
         });
@@ -368,5 +414,10 @@
         }
 
-        public final void updateEnabledState(OAuthToken token) {
+        /**
+         * Update the enabled state
+         * @param token The token to use
+         * @since 18991
+         */
+        public final void updateEnabledState(IOAuthToken token) {
             setEnabled(token != null);
         }
@@ -376,5 +427,5 @@
             if (!evt.getPropertyName().equals(AbstractAuthorizationUI.ACCESS_TOKEN_PROP))
                 return;
-            updateEnabledState((OAuthToken) evt.getNewValue());
+            updateEnabledState((IOAuthToken) evt.getNewValue());
         }
     }
Index: unk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java	(revision 18990)
+++ 	(revision )
@@ -1,17 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-/**
- * OSM login failure exception.
- * @since 2746
- */
-public class OsmLoginFailedException extends OsmOAuthAuthorizationException {
-
-    /**
-     * Constructs a new {@code OsmLoginFailedException} with the specified cause.
-     * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method).
-     */
-    public OsmLoginFailedException(Throwable cause) {
-        super(cause);
-    }
-}
Index: unk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 18990)
+++ 	(revision )
@@ -1,457 +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.BufferedReader;
-import java.io.IOException;
-import java.net.CookieHandler;
-import java.net.HttpURLConnection;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-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.OsmTransferCanceledException;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.HttpClient;
-import org.openstreetmap.josm.tools.Logging;
-import org.openstreetmap.josm.tools.Utils;
-
-import oauth.signpost.OAuth;
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.OAuthProvider;
-import oauth.signpost.exception.OAuthException;
-
-/**
- * An OAuth 1.0 authorization client.
- * @since 2746
- */
-public class OsmOAuthAuthorizationClient {
-    private final OAuthParameters oauthProviderParameters;
-    private final OAuthConsumer consumer;
-    private final OAuthProvider provider;
-    private boolean canceled;
-    private HttpClient connection;
-
-    protected static class SessionId {
-        protected String id;
-        protected String token;
-        protected String userName;
-    }
-
-    /**
-     * Creates a new authorisation client with the parameters <code>parameters</code>.
-     *
-     * @param parameters the OAuth parameters. Must not be null.
-     * @throws IllegalArgumentException if parameters is null
-     */
-    public OsmOAuthAuthorizationClient(OAuthParameters parameters) {
-        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 if parameters is null
-     * @throws IllegalArgumentException if requestToken is null
-     */
-    public OsmOAuthAuthorizationClient(OAuthParameters parameters, OAuthToken requestToken) {
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        oauthProviderParameters = new OAuthParameters(parameters);
-        consumer = oauthProviderParameters.buildConsumer();
-        provider = oauthProviderParameters.buildProvider(consumer);
-        consumer.setTokenWithSecret(requestToken.getKey(), requestToken.getSecret());
-    }
-
-    /**
-     * Cancels the current OAuth operation.
-     */
-    public void cancel() {
-        canceled = true;
-        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 {@link NullProgressMonitor#INSTANCE} if null
-     * @return the OAuth Request Token
-     * @throws OsmOAuthAuthorizationException if something goes wrong when retrieving the request token
-     * @throws OsmTransferCanceledException if the user canceled the request
-     */
-    public OAuthToken getRequestToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCanceledException {
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask("");
-            monitor.indeterminateSubTask(tr("Retrieving OAuth Request Token from ''{0}''", oauthProviderParameters.getRequestTokenUrl()));
-            provider.retrieveRequestToken(consumer, "");
-            return OAuthToken.createToken(consumer);
-        } catch (OAuthException e) {
-            if (canceled)
-                throw new OsmTransferCanceledException(e);
-            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 {@link #getRequestToken(ProgressMonitor)} first.
-     *
-     * @param monitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null
-     * @return the OAuth Access Token
-     * @throws OsmOAuthAuthorizationException if something goes wrong when retrieving the request token
-     * @throws OsmTransferCanceledException if the user canceled the request
-     * @see #getRequestToken(ProgressMonitor)
-     */
-    public OAuthToken getAccessToken(ProgressMonitor monitor) throws OsmOAuthAuthorizationException, OsmTransferCanceledException {
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask("");
-            monitor.indeterminateSubTask(tr("Retrieving OAuth Access Token from ''{0}''", oauthProviderParameters.getAccessTokenUrl()));
-            provider.retrieveAccessToken(consumer, null);
-            return OAuthToken.createToken(consumer);
-        } catch (OAuthException e) {
-            if (canceled)
-                throw new OsmTransferCanceledException(e);
-            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(32);
-
-        // 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('?'+OAuth.OAUTH_TOKEN+'=').append(requestToken.getKey());
-        return sb.toString();
-    }
-
-    protected String extractToken() {
-        try (BufferedReader r = connection.getResponse().getContentReader()) {
-            String c;
-            Pattern p = Pattern.compile(".*authenticity_token.*value=\"([^\"]+)\".*");
-            while ((c = r.readLine()) != null) {
-                Matcher m = p.matcher(c);
-                if (m.find()) {
-                    return m.group(1);
-                }
-            }
-        } catch (IOException e) {
-            Logging.error(e);
-            return null;
-        }
-        Logging.warn("No authenticity_token found in response!");
-        return null;
-    }
-
-    protected SessionId extractOsmSession() throws IOException, URISyntaxException {
-        // response headers might not contain the cookie, see #12584
-        final List<String> setCookies = CookieHandler.getDefault()
-                .get(connection.getURL().toURI(), Collections.<String, List<String>>emptyMap())
-                .get("Cookie");
-        if (setCookies == null) {
-            Logging.warn("No 'Set-Cookie' in response header!");
-            return null;
-        }
-
-        for (String setCookie: setCookies) {
-            String[] kvPairs = setCookie.split(";", -1);
-            for (String kvPair : kvPairs) {
-                kvPair = kvPair.trim();
-                String[] kv = kvPair.split("=", -1);
-                if (kv.length != 2) {
-                    continue;
-                }
-                if ("_osm_session".equals(kv[0])) {
-                    // osm session cookie found
-                    String token = extractToken();
-                    if (token == null)
-                        return null;
-                    SessionId si = new SessionId();
-                    si.id = kv[1];
-                    si.token = token;
-                    return si;
-                }
-            }
-        }
-        Logging.warn("No suitable 'Set-Cookie' in response header found! {0}", setCookies);
-        return null;
-    }
-
-    protected static String buildPostRequest(Map<String, String> parameters) {
-        StringBuilder sb = new StringBuilder(32);
-
-        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(Utils.encodeUrl(value));
-            if (it.hasNext()) {
-                sb.append('&');
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * 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 structure
-     * @throws OsmOAuthAuthorizationException if something went wrong
-     */
-    protected SessionId fetchOsmWebsiteSessionId() throws OsmOAuthAuthorizationException {
-        try {
-            final URL url = new URL(oauthProviderParameters.getOsmLoginUrl() + "?cookie_test=true");
-            synchronized (this) {
-                connection = HttpClient.create(url).useCache(false);
-                connection.connect();
-            }
-            SessionId sessionId = extractOsmSession();
-            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 | URISyntaxException e) {
-            throw new OsmOAuthAuthorizationException(e);
-        } finally {
-            synchronized (this) {
-                connection = null;
-            }
-        }
-    }
-
-    /**
-     * Submits a request to the OSM website for a OAuth form. The OSM website replies a session token in
-     * a hidden parameter.
-     * @param sessionId session id
-     * @param requestToken request token
-     *
-     * @throws OsmOAuthAuthorizationException if something went wrong
-     */
-    protected void fetchOAuthToken(SessionId sessionId, OAuthToken requestToken) throws OsmOAuthAuthorizationException {
-        try {
-            URL url = new URL(getAuthoriseUrl(requestToken));
-            synchronized (this) {
-                connection = HttpClient.create(url)
-                        .useCache(false)
-                        .setHeader("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);
-                connection.connect();
-            }
-            sessionId.token = extractToken();
-            if (sessionId.token == null)
-                throw new OsmOAuthAuthorizationException(tr("OSM website did not return a session cookie in response to ''{0}'',",
-                        url.toString()));
-        } catch (IOException e) {
-            throw new OsmOAuthAuthorizationException(e);
-        } finally {
-            synchronized (this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void authenticateOsmSession(SessionId sessionId, String userName, String password) throws OsmLoginFailedException {
-        try {
-            final URL url = new URL(oauthProviderParameters.getOsmLoginUrl());
-            final HttpClient client = HttpClient.create(url, "POST").useCache(false);
-
-            Map<String, String> parameters = new HashMap<>();
-            parameters.put("username", userName);
-            parameters.put("password", password);
-            parameters.put("referer", "/");
-            parameters.put("commit", "Login");
-            parameters.put("authenticity_token", sessionId.token);
-            client.setRequestBody(buildPostRequest(parameters).getBytes(StandardCharsets.UTF_8));
-
-            client.setHeader("Content-Type", "application/x-www-form-urlencoded");
-            client.setHeader("Cookie", "_osm_session=" + sessionId.id);
-            // make sure we can catch 302 Moved Temporarily below
-            client.setMaxRedirects(-1);
-
-            synchronized (this) {
-                connection = client;
-                connection.connect();
-            }
-
-            // 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.getResponse().getResponseCode();
-            if (retCode != HttpURLConnection.HTTP_MOVED_TEMP)
-                throw new OsmOAuthAuthorizationException(tr("Failed to authenticate user ''{0}'' with password ''***'' as OAuth user",
-                        userName));
-        } catch (OsmOAuthAuthorizationException | IOException e) {
-            throw new OsmLoginFailedException(e);
-        } finally {
-            synchronized (this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void logoutOsmSession(SessionId sessionId) throws OsmOAuthAuthorizationException {
-        try {
-            URL url = new URL(oauthProviderParameters.getOsmLogoutUrl());
-            synchronized (this) {
-                connection = HttpClient.create(url).setMaxRedirects(-1);
-                connection.connect();
-            }
-        } catch (IOException e) {
-            throw new OsmOAuthAuthorizationException(e);
-        } finally {
-            synchronized (this) {
-                connection = null;
-            }
-        }
-    }
-
-    protected void sendAuthorisationRequest(SessionId sessionId, OAuthToken requestToken, OsmPrivileges privileges)
-            throws OsmOAuthAuthorizationException {
-        Map<String, String> parameters = new HashMap<>();
-        fetchOAuthToken(sessionId, requestToken);
-        parameters.put("oauth_token", requestToken.getKey());
-        parameters.put("oauth_callback", "");
-        parameters.put("authenticity_token", sessionId.token);
-        parameters.put("allow_write_api", booleanParam(privileges.isAllowWriteApi()));
-        parameters.put("allow_write_gpx", booleanParam(privileges.isAllowWriteGpx()));
-        parameters.put("allow_read_gpx", booleanParam(privileges.isAllowReadGpx()));
-        parameters.put("allow_write_prefs", booleanParam(privileges.isAllowWritePrefs()));
-        parameters.put("allow_read_prefs", booleanParam(privileges.isAllowReadPrefs()));
-        parameters.put("allow_write_notes", booleanParam(privileges.isAllowModifyNotes()));
-        parameters.put("allow_write_diary", booleanParam(privileges.isAllowWriteDiary()));
-
-        String request = buildPostRequest(parameters);
-        try {
-            URL url = new URL(oauthProviderParameters.getAuthoriseUrl());
-            final HttpClient client = HttpClient.create(url, "POST").useCache(false);
-            client.setHeader("Content-Type", "application/x-www-form-urlencoded");
-            client.setHeader("Cookie", "_osm_session=" + sessionId.id + "; _osm_username=" + sessionId.userName);
-            client.setMaxRedirects(-1);
-            client.setRequestBody(request.getBytes(StandardCharsets.UTF_8));
-
-            synchronized (this) {
-                connection = client;
-                connection.connect();
-            }
-
-            int retCode = connection.getResponse().getResponseCode();
-            if (retCode != HttpURLConnection.HTTP_OK)
-                throw new OsmOAuthAuthorizationException(tr("Failed to authorize OAuth request  ''{0}''", requestToken.getKey()));
-        } catch (IOException e) {
-            throw new OsmOAuthAuthorizationException(e);
-        } finally {
-            synchronized (this) {
-                connection = null;
-            }
-        }
-    }
-
-    private static String booleanParam(boolean param) {
-        return param ? "1" : "0";
-    }
-
-    /**
-     * Automatically authorises a request token for a set of privileges.
-     *
-     * @param requestToken the request token. Must not be null.
-     * @param userName the OSM user name. Must not be null.
-     * @param password the OSM password. Must not be null.
-     * @param privileges the set of privileges. Must not be null.
-     * @param monitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null
-     * @throws IllegalArgumentException if requestToken is null
-     * @throws IllegalArgumentException if osmUserName is null
-     * @throws IllegalArgumentException if osmPassword is null
-     * @throws IllegalArgumentException if privileges is null
-     * @throws OsmOAuthAuthorizationException if the authorisation fails
-     * @throws OsmTransferCanceledException if the task is canceled by the user
-     */
-    public void authorise(OAuthToken requestToken, String userName, String password, OsmPrivileges privileges, ProgressMonitor monitor)
-            throws OsmOAuthAuthorizationException, OsmTransferCanceledException {
-        CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");
-        CheckParameterUtil.ensureParameterNotNull(userName, "userName");
-        CheckParameterUtil.ensureParameterNotNull(password, "password");
-        CheckParameterUtil.ensureParameterNotNull(privileges, "privileges");
-
-        if (monitor == null) {
-            monitor = NullProgressMonitor.INSTANCE;
-        }
-        try {
-            monitor.beginTask(tr("Authorizing OAuth Request token ''{0}'' at the OSM website ...", requestToken.getKey()));
-            monitor.setTicksCount(4);
-            monitor.indeterminateSubTask(tr("Initializing a session at the OSM website..."));
-            SessionId sessionId = fetchOsmWebsiteSessionId();
-            sessionId.userName = userName;
-            if (canceled)
-                throw new OsmTransferCanceledException("Authorization canceled");
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Authenticating the session for user ''{0}''...", userName));
-            authenticateOsmSession(sessionId, userName, password);
-            if (canceled)
-                throw new OsmTransferCanceledException("Authorization canceled");
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Authorizing request token ''{0}''...", requestToken.getKey()));
-            sendAuthorisationRequest(sessionId, requestToken, privileges);
-            if (canceled)
-                throw new OsmTransferCanceledException("Authorization canceled");
-            monitor.worked(1);
-
-            monitor.indeterminateSubTask(tr("Logging out session ''{0}''...", sessionId));
-            logoutOsmSession(sessionId);
-            if (canceled)
-                throw new OsmTransferCanceledException("Authorization canceled");
-            monitor.worked(1);
-        } catch (OsmOAuthAuthorizationException e) {
-            if (canceled)
-                throw new OsmTransferCanceledException(e);
-            throw e;
-        } finally {
-            monitor.finishTask();
-        }
-    }
-}
Index: unk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java	(revision 18990)
+++ 	(revision )
@@ -1,118 +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 java.io.IOException;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.io.OsmTransferCanceledException;
-import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.Logging;
-import org.xml.sax.SAXException;
-
-/**
- * Asynchronous task for retrieving an Access Token.
- *
- */
-public class RetrieveAccessTokenTask extends PleaseWaitRunnable {
-
-    private boolean canceled;
-    private OAuthToken accessToken;
-    private final OAuthParameters parameters;
-    private OsmOAuthAuthorizationClient client;
-    private final OAuthToken requestToken;
-    private final Component parent;
-
-    /**
-     * Creates the task
-     *
-     * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog
-     * is displayed
-     * @param parameters the OAuth parameters. Must not be null.
-     * @param requestToken the request token for which an Access Token is retrieved. Must not be null.
-     * @throws IllegalArgumentException if parameters is null.
-     * @throws IllegalArgumentException if requestToken is null.
-     */
-    public RetrieveAccessTokenTask(Component parent, OAuthParameters parameters, OAuthToken requestToken) {
-        super(parent, tr("Retrieving OAuth Access Token..."), false /* don't ignore exceptions */);
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        CheckParameterUtil.ensureParameterNotNull(requestToken, "requestToken");
-        this.parameters = parameters;
-        this.requestToken = requestToken;
-        this.parent = parent;
-    }
-
-    @Override
-    protected void cancel() {
-        canceled = true;
-        synchronized (this) {
-            if (client != null) {
-                client.cancel();
-            }
-        }
-    }
-
-    @Override
-    protected void finish() { /* not used in this task */}
-
-    protected void alertRetrievingAccessTokenFailed() {
-        HelpAwareOptionPane.showOptionDialog(
-                parent,
-                tr(
-                        "<html>Retrieving an OAuth Access Token from ''{0}'' failed.</html>",
-                        parameters.getAccessTokenUrl()
-                ),
-                tr("Request Failed"),
-                JOptionPane.ERROR_MESSAGE,
-                HelpUtil.ht("/OAuth#NotAuthorizedException")
-        );
-    }
-
-    @Override
-    protected void realRun() throws SAXException, IOException, OsmTransferException {
-        try {
-            synchronized (this) {
-                client = new OsmOAuthAuthorizationClient(parameters, requestToken);
-            }
-            accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false));
-        } catch (OsmTransferCanceledException e) {
-            Logging.trace(e);
-        } catch (final OsmOAuthAuthorizationException e) {
-            Logging.error(e);
-            GuiHelper.runInEDT(this::alertRetrievingAccessTokenFailed);
-            accessToken = null;
-        } finally {
-            synchronized (this) {
-                client = null;
-            }
-        }
-    }
-
-    /**
-     * Replies true if the task was canceled.
-     *
-     * @return {@code true} if user aborted operation
-     */
-    public boolean isCanceled() {
-        return canceled;
-    }
-
-    /**
-     * Replies the retrieved Access Token. null, if something went wrong.
-     *
-     * @return the retrieved Access Token
-     */
-    public OAuthToken getAccessToken() {
-        return accessToken;
-    }
-}
Index: unk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java	(revision 18990)
+++ 	(revision )
@@ -1,112 +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 java.io.IOException;
-
-import javax.swing.JOptionPane;
-
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.HelpAwareOptionPane;
-import org.openstreetmap.josm.gui.PleaseWaitRunnable;
-import org.openstreetmap.josm.gui.help.HelpUtil;
-import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.io.OsmTransferCanceledException;
-import org.openstreetmap.josm.io.OsmTransferException;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
-import org.openstreetmap.josm.tools.Logging;
-import org.xml.sax.SAXException;
-
-/**
- * Asynchronous task for retrieving a request token
- */
-public class RetrieveRequestTokenTask extends PleaseWaitRunnable {
-
-    private boolean canceled;
-    private OAuthToken requestToken;
-    private final OAuthParameters parameters;
-    private OsmOAuthAuthorizationClient client;
-    private final Component parent;
-
-    /**
-     * Creates the task
-     *
-     * @param parent the parent component relative to which the {@link PleaseWaitRunnable}-Dialog
-     * is displayed
-     * @param parameters the OAuth parameters. Must not be null.
-     * @throws IllegalArgumentException if parameters is null.
-     */
-    public RetrieveRequestTokenTask(Component parent, OAuthParameters parameters) {
-        super(parent, tr("Retrieving OAuth Request Token..."), false /* don't ignore exceptions */);
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        this.parameters = parameters;
-        this.parent = parent;
-    }
-
-    @Override
-    protected void cancel() {
-        canceled = true;
-        synchronized (this) {
-            if (client != null) {
-                client.cancel();
-            }
-        }
-    }
-
-    @Override
-    protected void finish() { /* not used in this task */}
-
-    protected void alertRetrievingRequestTokenFailed() {
-        HelpAwareOptionPane.showOptionDialog(
-                parent,
-                tr(
-                        "<html>Retrieving an OAuth Request Token from ''{0}'' failed.</html>",
-                        parameters.getRequestTokenUrl()
-                ),
-                tr("Request Failed"),
-                JOptionPane.ERROR_MESSAGE,
-                HelpUtil.ht("/OAuth#NotAuthorizedException")
-        );
-    }
-
-    @Override
-    protected void realRun() throws SAXException, IOException, OsmTransferException {
-        try {
-            synchronized (this) {
-                client = new OsmOAuthAuthorizationClient(parameters);
-            }
-            requestToken = client.getRequestToken(getProgressMonitor().createSubTaskMonitor(0, false));
-        } catch (OsmTransferCanceledException e) {
-            Logging.trace(e);
-        } catch (final OsmOAuthAuthorizationException e) {
-            Logging.error(e);
-            GuiHelper.runInEDT(this::alertRetrievingRequestTokenFailed);
-            requestToken = null;
-        } finally {
-            synchronized (this) {
-                client = null;
-            }
-        }
-    }
-
-    /**
-     * Replies true if the task was canceled
-     *
-     * @return true if the task was canceled
-     */
-    public boolean isCanceled() {
-        return canceled;
-    }
-
-    /**
-     * Replies the request token. null, if something went wrong.
-     *
-     * @return the request token
-     */
-    public OAuthToken getRequestToken() {
-        return requestToken;
-    }
-}
Index: unk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUI.java	(revision 18990)
+++ 	(revision )
@@ -1,460 +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.util.concurrent.Executor;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.gui.util.GuiHelper;
-import org.openstreetmap.josm.gui.widgets.HtmlPanel;
-import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
-import org.openstreetmap.josm.gui.widgets.JosmTextField;
-import org.openstreetmap.josm.tools.ImageProvider;
-import org.openstreetmap.josm.tools.OpenBrowser;
-
-/**
- * This is the UI for running a semi-automatic authorisation procedure.
- *
- * In contrast to the fully-automatic procedure the user is dispatched to an
- * external browser for login and authorisation.
- *
- * @since 2746
- */
-public class SemiAutomaticAuthorizationUI extends AbstractAuthorizationUI {
-    private final AccessTokenInfoPanel pnlAccessTokenInfo = new AccessTokenInfoPanel();
-    private transient OAuthToken requestToken;
-
-    private RetrieveRequestTokenPanel pnlRetrieveRequestToken;
-    private RetrieveAccessTokenPanel pnlRetrieveAccessToken;
-    private ShowAccessTokenPanel pnlShowAccessToken;
-    private final transient Executor executor;
-
-    /**
-     * build the UI
-     */
-    protected final 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);
-    }
-
-    /**
-     * Constructs a new {@code SemiAutomaticAuthorizationUI} for the given API URL.
-     * @param apiUrl The OSM API URL
-     * @param executor the executor used for running the HTTP requests for the authorization
-     * @since 5422
-     */
-    public SemiAutomaticAuthorizationUI(String apiUrl, Executor executor) {
-        super(apiUrl);
-        this.executor = executor;
-        build();
-    }
-
-    @Override
-    public boolean isSaveAccessTokenToPreferences() {
-        return pnlAccessTokenInfo.isSaveToPreferences();
-    }
-
-    protected void transitionToRetrieveAccessToken() {
-        OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(
-                (OAuthParameters) 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());
-    }
-
-    static class StepLabel extends JLabel {
-        StepLabel(String text) {
-            super(text);
-            setFont(getFont().deriveFont(16f));
-        }
-    }
-
-    /**
-     * This is the panel displayed in the first step of the semi-automatic authorisation process.
-     */
-    private class RetrieveRequestTokenPanel extends JPanel {
-
-        /**
-         * Constructs a new {@code RetrieveRequestTokenPanel}.
-         */
-        RetrieveRequestTokenPanel() {
-            build();
-        }
-
-        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);
-            JCheckBox cbShowAdvancedParameters = new JCheckBox();
-            pnl.add(cbShowAdvancedParameters, gc);
-            cbShowAdvancedParameters.setSelected(false);
-            cbShowAdvancedParameters.addItemListener(
-                    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"),
-                    ((OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()).getRequestTokenUrl()
-            ));
-            pnl.add(h, gc);
-
-            JPanel pnl1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            pnl1.add(new JButton(new RetrieveRequestTokenAction()));
-            gc.fill = GridBagConstraints.HORIZONTAL;
-            gc.weightx = 1.0;
-            gc.gridy = 1;
-            pnl.add(pnl1, gc);
-            return pnl;
-
-        }
-
-        protected final void build() {
-            setLayout(new BorderLayout(0, 5));
-            add(new StepLabel(tr("<html>Step 1/3: Retrieve an OAuth Request Token</html>")), BorderLayout.NORTH);
-            add(buildAdvancedParametersPanel(), BorderLayout.CENTER);
-            add(buildCommandPanel(), BorderLayout.SOUTH);
-        }
-    }
-
-    /**
-     * This is the panel displayed in the second step of the semi-automatic authorization process.
-     */
-    private class RetrieveAccessTokenPanel extends JPanel {
-
-        private final JosmTextField tfAuthoriseUrl = new JosmTextField(null, null, 0, false);
-
-        /**
-         * Constructs a new {@code RetrieveAccessTokenPanel}.
-         */
-        RetrieveAccessTokenPanel() {
-            build();
-        }
-
-        protected JPanel buildTitlePanel() {
-            JPanel pnl = new JPanel(new BorderLayout());
-            pnl.add(new StepLabel(tr("<html>Step 2/3: Authorize and retrieve an Access Token</html>")), 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 authorization page in an external browser. "
-                    + "Please login with your OSM username and password and follow the instructions "
-                    + "to authorize 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 authorize 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("Authorize URL:")), gc);
-
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            pnl.add(tfAuthoriseUrl, gc);
-            tfAuthoriseUrl.setEditable(false);
-
-            return pnl;
-        }
-
-        protected JPanel buildActionPanel() {
-            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            pnl.add(new JButton(new BackAction()));
-            pnl.add(new JButton(new RetrieveAccessTokenAction()));
-            return pnl;
-        }
-
-        protected final void build() {
-            setLayout(new BorderLayout());
-            add(buildTitlePanel(), BorderLayout.NORTH);
-            add(buildContentPanel(), BorderLayout.CENTER);
-            add(buildActionPanel(), BorderLayout.SOUTH);
-        }
-
-        public void setAuthoriseUrl(String url) {
-            tfAuthoriseUrl.setText(url);
-        }
-
-        /**
-         * Action to go back to step 1 in the process
-         */
-        class BackAction extends AbstractAction {
-            BackAction() {
-                putValue(NAME, tr("Back"));
-                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
-                new ImageProvider("dialogs", "previous").getResource().attachImageIcon(this);
-            }
-
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                transitionToRetrieveRequestToken();
-            }
-        }
-    }
-
-    /**
-     * Displays the retrieved Access Token in step 3.
-     */
-    class ShowAccessTokenPanel extends JPanel {
-
-        /**
-         * Constructs a new {@code ShowAccessTokenPanel}.
-         */
-        ShowAccessTokenPanel() {
-            build();
-        }
-
-        protected JPanel buildTitlePanel() {
-            JPanel pnl = new JPanel(new BorderLayout());
-            pnl.add(new StepLabel(tr("<html>Step 3/3: Successfully retrieved an Access Token</html>")), 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 authorization 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, gc);
-            pnlAccessTokenInfo.setSaveToPreferences(
-                    OAuthAccessTokenHolder.getInstance().isSaveToPreferences()
-            );
-            return pnl;
-        }
-
-        protected JPanel buildActionPanel() {
-            JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            pnl.add(new JButton(new RestartAction()));
-            pnl.add(new JButton(new TestAccessTokenAction()));
-            return pnl;
-        }
-
-        protected final void build() {
-            setLayout(new BorderLayout());
-            add(buildTitlePanel(), BorderLayout.NORTH);
-            add(buildContentPanel(), BorderLayout.CENTER);
-            add(buildActionPanel(), BorderLayout.SOUTH);
-        }
-
-        /**
-         * Action to go back to step 1 in the process
-         */
-        class RestartAction extends AbstractAction {
-            RestartAction() {
-                putValue(NAME, tr("Restart"));
-                putValue(SHORT_DESCRIPTION, tr("Go back to step 1/3"));
-                new ImageProvider("dialogs", "previous").getResource().attachImageIcon(this);
-            }
-
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                transitionToRetrieveRequestToken();
-            }
-        }
-
-        public void setAccessToken(OAuthToken accessToken) {
-            pnlAccessTokenInfo.setAccessToken(accessToken);
-        }
-    }
-
-    /**
-     * Action for retrieving a request token
-     */
-    class RetrieveRequestTokenAction extends AbstractAction {
-
-        RetrieveRequestTokenAction() {
-            putValue(NAME, tr("Retrieve Request Token"));
-            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
-            putValue(SHORT_DESCRIPTION, tr("Click to retrieve a Request Token"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent evt) {
-            final RetrieveRequestTokenTask task = new RetrieveRequestTokenTask(
-                    SemiAutomaticAuthorizationUI.this,
-                    (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters()
-            );
-            executor.execute(task);
-            Runnable r = () -> {
-                if (task.isCanceled()) return;
-                if (task.getRequestToken() == null) return;
-                requestToken = task.getRequestToken();
-                GuiHelper.runInEDT(SemiAutomaticAuthorizationUI.this::transitionToRetrieveAccessToken);
-            };
-            executor.execute(r);
-        }
-    }
-
-    /**
-     * Action for retrieving an Access Token
-     */
-    class RetrieveAccessTokenAction extends AbstractAction {
-
-        RetrieveAccessTokenAction() {
-            putValue(NAME, tr("Retrieve Access Token"));
-            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
-            putValue(SHORT_DESCRIPTION, tr("Click to retrieve an Access Token"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent evt) {
-            final RetrieveAccessTokenTask task = new RetrieveAccessTokenTask(
-                    SemiAutomaticAuthorizationUI.this,
-                    (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    requestToken
-            );
-            executor.execute(task);
-            Runnable r = () -> {
-                if (task.isCanceled()) return;
-                if (task.getAccessToken() == null) return;
-                GuiHelper.runInEDT(() -> {
-                    setAccessToken(task.getAccessToken());
-                    transitionToShowAccessToken();
-                });
-            };
-            executor.execute(r);
-        }
-    }
-
-    /**
-     * Action for testing an Access Token
-     */
-    class TestAccessTokenAction extends AbstractAction {
-
-        TestAccessTokenAction() {
-            putValue(NAME, tr("Test Access Token"));
-            new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
-            putValue(SHORT_DESCRIPTION, tr("Click to test the Access Token"));
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent evt) {
-            TestAccessTokenTask task = new TestAccessTokenTask(
-                    SemiAutomaticAuthorizationUI.this,
-                    getApiUrl(),
-                    (OAuthParameters) getAdvancedPropertiesPanel().getAdvancedParameters(),
-                    getAccessToken()
-            );
-            executor.execute(task);
-        }
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 18991)
@@ -12,9 +12,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.data.oauth.IOAuthParameters;
 import org.openstreetmap.josm.data.oauth.IOAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuth20Token;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
+import org.openstreetmap.josm.data.oauth.OAuthException;
 import org.openstreetmap.josm.data.osm.UserInfo;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
@@ -34,10 +32,7 @@
 import org.xml.sax.SAXException;
 
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.exception.OAuthException;
-
 /**
  * Checks whether an OSM API server can be accessed with a specific Access Token.
- *
+ * <p>
  * It retrieves the user details for the user which is authorized to access the server with
  * this token.
@@ -45,7 +40,5 @@
  */
 public class TestAccessTokenTask extends PleaseWaitRunnable {
-    private final OAuthToken tokenOAuth1;
     private final IOAuthToken tokenOAuth2;
-    private final IOAuthParameters oauthParameters;
     private boolean canceled;
     private final Component parent;
@@ -58,36 +51,12 @@
      * @param parent the parent component relative to which the  {@link PleaseWaitRunnable}-Dialog is displayed
      * @param apiUrl the API URL. Must not be null.
-     * @param parameters the OAuth parameters. Must not be null.
      * @param accessToken the Access Token. Must not be null.
+     * @since 18991
      */
-    public TestAccessTokenTask(Component parent, String apiUrl, OAuthParameters parameters, OAuthToken accessToken) {
+    public TestAccessTokenTask(Component parent, String apiUrl, IOAuthToken accessToken) {
         super(parent, tr("Testing OAuth Access Token"), false /* don't ignore exceptions */);
         CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
         CheckParameterUtil.ensureParameterNotNull(accessToken, "accessToken");
-        this.tokenOAuth1 = accessToken;
-        this.tokenOAuth2 = null;
-        this.oauthParameters = parameters;
-        this.parent = parent;
-        this.apiUrl = apiUrl;
-    }
-
-    /**
-     * Create the task
-     *
-     * @param parent the parent component relative to which the  {@link PleaseWaitRunnable}-Dialog is displayed
-     * @param apiUrl the API URL. Must not be null.
-     * @param parameters the OAuth parameters. Must not be null.
-     * @param accessToken the Access Token. Must not be null.
-     * @since 18764
-     */
-    public TestAccessTokenTask(Component parent, String apiUrl, IOAuthParameters parameters, IOAuthToken accessToken) {
-        super(parent, tr("Testing OAuth Access Token"), false /* don't ignore exceptions */);
-        CheckParameterUtil.ensureParameterNotNull(apiUrl, "apiUrl");
-        CheckParameterUtil.ensureParameterNotNull(parameters, "parameters");
-        CheckParameterUtil.ensureParameterNotNull(accessToken, "accessToken");
-        this.tokenOAuth1 = null;
         this.tokenOAuth2 = accessToken;
-        this.oauthParameters = parameters;
         this.parent = parent;
         this.apiUrl = apiUrl;
@@ -110,16 +79,5 @@
 
     protected void sign(HttpClient con) throws OAuthException {
-        if (oauthParameters instanceof OAuthParameters) {
-            OAuthConsumer consumer = ((OAuthParameters) oauthParameters).buildConsumer();
-            consumer.setTokenWithSecret(tokenOAuth1.getKey(), tokenOAuth1.getSecret());
-            consumer.sign(con);
-        } else {
-            try {
-                this.tokenOAuth2.sign(con);
-            } catch (org.openstreetmap.josm.data.oauth.OAuthException e) {
-                // Adapt our OAuthException to the SignPost OAuth exception
-                throw new OAuthException(e) {};
-            }
-        }
+        this.tokenOAuth2.sign(con);
     }
 
@@ -315,11 +273,8 @@
 
     private String getAuthKey() {
-        if (this.tokenOAuth1 != null) {
-            return this.tokenOAuth1.getKey();
-        }
         if (this.tokenOAuth2 instanceof OAuth20Token) {
             return ((OAuth20Token) this.tokenOAuth2).getBearerToken();
         }
-        throw new IllegalArgumentException("Only OAuth1 and OAuth2 tokens are understood: " + this.tokenOAuth2);
+        throw new IllegalArgumentException("Only OAuth2 tokens are understood: " + this.tokenOAuth2);
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java	(revision 18991)
@@ -39,6 +39,4 @@
     /** indicates whether we use basic authentication */
     private final JRadioButton rbBasicAuthentication = new JRadioButton();
-    /** indicates whether we use OAuth 1.0a as authentication scheme */
-    private final JRadioButton rbOAuth = new JRadioButton();
     /** indicates whether we use OAuth 2.0 as authentication scheme */
     private final JRadioButton rbOAuth20 = new JRadioButton();
@@ -47,6 +45,4 @@
     /** the panel for the basic authentication parameters */
     private BasicAuthenticationPreferencesPanel pnlBasicAuthPreferences;
-    /** the panel for the OAuth 1.0a authentication parameters */
-    private OAuthAuthenticationPreferencesPanel pnlOAuthPreferences;
     /** the panel for the OAuth 2.0 authentication parameters */
     private OAuthAuthenticationPreferencesPanel pnlOAuth20Preferences;
@@ -59,5 +55,4 @@
         final boolean defaultApi = JosmUrls.getInstance().getDefaultOsmApiUrl().equals(apiUrl);
         rbBasicAuthentication.setEnabled(rbBasicAuthentication.isSelected() || "basic".equals(authMethod) || isExpert || !defaultApi);
-        rbOAuth.setEnabled(rbOAuth.isSelected() || "oauth".equals(authMethod) || isExpert || !defaultApi);
     };
 
@@ -85,13 +80,7 @@
         rbBasicAuthentication.setToolTipText(tr("Select to use HTTP basic authentication with your OSM username and password"));
         rbBasicAuthentication.addItemListener(authChangeListener);
-
-        //-- radio button for OAuth 1.0a
-        buttonPanel.add(rbOAuth);
-        rbOAuth.setText(tr("Use OAuth {0}", "1.0a"));
-        rbOAuth.setToolTipText(tr("Select to use OAuth {0} as authentication mechanism", "1.0a"));
-        rbOAuth.addItemListener(authChangeListener);
-
         //-- radio button for OAuth 2.0
         buttonPanel.add(rbOAuth20);
+        rbOAuth20.setSelected(true); // This must before adding the listener; otherwise, saveToPreferences is called prior to initFromPreferences
         rbOAuth20.setText(tr("Use OAuth {0}", "2.0"));
         rbOAuth20.setToolTipText(tr("Select to use OAuth {0} as authentication mechanism", "2.0"));
@@ -102,5 +91,4 @@
         ButtonGroup bg = new ButtonGroup();
         bg.add(rbBasicAuthentication);
-        bg.add(rbOAuth);
         bg.add(rbOAuth20);
 
@@ -119,10 +107,8 @@
         //-- the two panels for authentication parameters
         pnlBasicAuthPreferences = new BasicAuthenticationPreferencesPanel();
-        pnlOAuthPreferences = new OAuthAuthenticationPreferencesPanel(OAuthVersion.OAuth10a);
         pnlOAuth20Preferences = new OAuthAuthenticationPreferencesPanel(OAuthVersion.OAuth20);
 
         ExpertToggleAction.addExpertModeChangeListener(expertModeChangeListener, true);
 
-        rbOAuth20.setSelected(true);
         pnlAuthenticationParameters.add(pnlOAuth20Preferences, BorderLayout.CENTER);
     }
@@ -133,21 +119,15 @@
     public final void initFromPreferences() {
         final String authMethod = OsmApi.getAuthMethod();
-        switch (authMethod) {
-            case "basic":
-                rbBasicAuthentication.setSelected(true);
-                break;
-            case "oauth":
-                rbOAuth.setSelected(true);
-                break;
-            case "oauth20":
-                rbOAuth20.setSelected(true);
-                break;
-            default:
-                Logging.warn(tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''Basic Authentication''.",
-                        "osm-server.auth-method", authMethod));
-                rbBasicAuthentication.setSelected(true);
+        if ("basic".equals(authMethod)) {
+            rbBasicAuthentication.setSelected(true);
+        } else if ("oauth20".equals(authMethod)) {
+            rbOAuth20.setSelected(true);
+        } else {
+            Logging.warn(
+                    tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''OAuth 2.0 Authentication''.",
+                            "osm-server.auth-method", authMethod));
+            rbOAuth20.setSelected(true);
         }
         pnlBasicAuthPreferences.initFromPreferences();
-        pnlOAuthPreferences.initFromPreferences();
         pnlOAuth20Preferences.initFromPreferences();
     }
@@ -161,6 +141,4 @@
         if (rbBasicAuthentication.isSelected()) {
             authMethod = "basic";
-        } else if (rbOAuth.isSelected()) {
-            authMethod = "oauth";
         } else if (rbOAuth20.isSelected()) {
             authMethod = "oauth20";
@@ -174,13 +152,8 @@
             OAuthAccessTokenHolder.getInstance().clear();
             OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
-        } else if ("oauth".equals(authMethod)) {
+        } else if ("oauth20".equals(authMethod)) {
+            // oauth20
             // clear the password in the preferences
             pnlBasicAuthPreferences.clearPassword();
-            pnlBasicAuthPreferences.saveToPreferences();
-            pnlOAuthPreferences.saveToPreferences();
-        } else { // oauth20
-            // clear the password in the preferences
-            pnlBasicAuthPreferences.clearPassword();
-            pnlBasicAuthPreferences.saveToPreferences();
             pnlOAuth20Preferences.saveToPreferences();
         }
@@ -188,6 +161,8 @@
             if ("basic".equals(authMethod)) {
                 UserIdentityManager.getInstance().initFromPreferences();
+            } else if (OsmApi.isUsingOAuthAndOAuthSetUp(OsmApi.getOsmApi())) {
+                UserIdentityManager.getInstance().initFromOAuth();
             } else {
-                UserIdentityManager.getInstance().initFromOAuth();
+                UserIdentityManager.getInstance().setAnonymous();
             }
         }
@@ -205,9 +180,4 @@
                 pnlAuthenticationParameters.add(pnlBasicAuthPreferences, BorderLayout.CENTER);
                 pnlBasicAuthPreferences.revalidate();
-            } else if (rbOAuth.isSelected()) {
-                pnlAuthenticationParameters.add(pnlOAuthPreferences, BorderLayout.CENTER);
-                pnlOAuthPreferences.saveToPreferences();
-                pnlOAuthPreferences.initFromPreferences();
-                pnlOAuthPreferences.revalidate();
             } else if (rbOAuth20.isSelected()) {
                 pnlAuthenticationParameters.add(pnlOAuth20Preferences, BorderLayout.CENTER);
@@ -222,7 +192,4 @@
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-        if (pnlOAuthPreferences != null) {
-            pnlOAuthPreferences.propertyChange(evt);
-        }
         if (pnlOAuth20Preferences != null) {
             pnlOAuth20Preferences.propertyChange(evt);
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 18991)
@@ -6,4 +6,5 @@
 import java.awt.BorderLayout;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.FlowLayout;
 import java.awt.Font;
@@ -15,4 +16,7 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Objects;
 
 import javax.swing.AbstractAction;
@@ -21,16 +25,13 @@
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 
 import org.openstreetmap.josm.actions.ExpertToggleAction;
 import org.openstreetmap.josm.data.oauth.IOAuthToken;
-import org.openstreetmap.josm.data.oauth.OAuth20Authorization;
 import org.openstreetmap.josm.data.oauth.OAuth20Token;
 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuthVersion;
-import org.openstreetmap.josm.data.oauth.osm.OsmScopes;
+import org.openstreetmap.josm.data.validation.routines.DomainValidator;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.oauth.AdvancedOAuthPropertiesPanel;
@@ -43,9 +44,9 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.auth.CredentialsManager;
-import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UserCancelException;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -69,11 +70,4 @@
 
     /**
-     * Create the panel. Uses {@link OAuthVersion#OAuth10a}.
-     */
-    public OAuthAuthenticationPreferencesPanel() {
-        this(OAuthVersion.OAuth10a);
-    }
-
-    /**
      * Create the panel.
      * @param oAuthVersion The OAuth version to use
@@ -82,6 +76,6 @@
         this.oAuthVersion = oAuthVersion;
         // These must come after we set the oauth version
+        this.pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(this.oAuthVersion);
         this.pnlNotYetAuthorised = new NotYetAuthorisedPanel();
-        this.pnlAdvancedProperties = new AdvancedOAuthPropertiesPanel(this.oAuthVersion);
         this.pnlAlreadyAuthorised = new AlreadyAuthorisedPanel();
         build();
@@ -124,22 +118,16 @@
         setLayout(new GridBagLayout());
         setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-        GridBagConstraints gc = new GridBagConstraints();
-
         // the panel for the OAuth parameters. pnlAuthorisationMessage is an
         // empty panel. It is going to be filled later, depending on the
         // current OAuth state in JOSM.
-        gc.fill = GridBagConstraints.BOTH;
-        gc.anchor = GridBagConstraints.NORTHWEST;
-        gc.weighty = 1.0;
-        gc.weightx = 1.0;
-        gc.insets = new Insets(10, 0, 0, 0);
-        add(pnlAuthorisationMessage, gc);
+        add(pnlAuthorisationMessage, GBC.eol().fill(GridBagConstraints.BOTH).anchor(GridBagConstraints.NORTHWEST)
+                .weight(1, 1).insets(0, 10, 0, 0));
+        // the panel with the advanced options
+        add(buildAdvancedPropertiesPanel(), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
     }
 
     protected void refreshView() {
         pnlAuthorisationMessage.removeAll();
-        if ((this.oAuthVersion == OAuthVersion.OAuth10a &&
-                OAuthAccessTokenHolder.getInstance().containsAccessToken())
-        || OAuthAccessTokenHolder.getInstance().getAccessToken(this.apiUrl, this.oAuthVersion) != null) {
+        if (OAuthAccessTokenHolder.getInstance().getAccessToken(this.apiUrl, this.oAuthVersion) != null) {
             pnlAuthorisationMessage.add(pnlAlreadyAuthorised, BorderLayout.CENTER);
             pnlAlreadyAuthorised.refreshView();
@@ -160,4 +148,11 @@
         this.apiUrl = apiUrl;
         pnlAdvancedProperties.setApiUrl(apiUrl);
+        for (JPanel panel : Arrays.asList(this.pnlNotYetAuthorised, (JPanel) this.pnlAlreadyAuthorised.getComponent(6))) {
+            for (Component component : panel.getComponents()) {
+                if (component instanceof JButton && ((JButton) component).getAction() instanceof AuthoriseNowAction) {
+                    ((AuthoriseNowAction) ((JButton) component).getAction()).updateEnabledState();
+                }
+            }
+        }
     }
 
@@ -204,13 +199,8 @@
 
             // Action for authorising now
-            if (oAuthVersion == OAuthVersion.OAuth10a) {
-                add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.FULLY_AUTOMATIC)), GBC.eol());
-            }
-            add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.SEMI_AUTOMATIC)), GBC.eol());
-            if (oAuthVersion == OAuthVersion.OAuth10a) {
-                JButton authManually = new JButton(new AuthoriseNowAction(AuthorizationProcedure.MANUALLY));
-                add(authManually, GBC.eol());
-                ExpertToggleAction.addVisibilitySwitcher(authManually);
-            }
+            add(new JButton(new AuthoriseNowAction(AuthorizationProcedure.FULLY_AUTOMATIC)), GBC.eol());
+            JButton authManually = new JButton(new AuthoriseNowAction(AuthorizationProcedure.MANUALLY));
+            add(authManually, GBC.eol());
+            ExpertToggleAction.addVisibilitySwitcher(authManually);
 
             // filler - grab remaining space
@@ -225,5 +215,4 @@
     private class AlreadyAuthorisedPanel extends JPanel {
         private final JosmTextField tfAccessTokenKey = new JosmTextField(null, null, 0, false);
-        private final JosmTextField tfAccessTokenSecret = new JosmTextField(null, null, 0, false);
 
         /**
@@ -266,9 +255,4 @@
             add(new JLabel(tr("Access Token Secret:")), gc);
 
-            gc.gridx = 1;
-            gc.weightx = 1.0;
-            add(tfAccessTokenSecret, gc);
-            tfAccessTokenSecret.setEditable(false);
-
             // -- access token secret
             gc.gridy = 3;
@@ -281,9 +265,6 @@
             // -- action buttons
             JPanel btns = new JPanel(new FlowLayout(FlowLayout.LEFT));
-            if (oAuthVersion == OAuthVersion.OAuth10a) {
-                // these want the OAuth 1.0 token information
-                btns.add(new JButton(new RenewAuthorisationAction(AuthorizationProcedure.FULLY_AUTOMATIC)));
-            }
-            btns.add(new JButton(new TestAuthorisationAction(oAuthVersion)));
+            btns.add(new JButton(new RenewAuthorisationAction(AuthorizationProcedure.FULLY_AUTOMATIC)));
+            btns.add(new JButton(new TestAuthorisationAction()));
             btns.add(new JButton(new RemoveAuthorisationAction()));
             gc.gridy = 4;
@@ -293,11 +274,4 @@
             add(btns, gc);
 
-            // the panel with the advanced options
-            gc.gridy = 5;
-            gc.gridx = 0;
-            gc.gridwidth = 2;
-            gc.weightx = 1.0;
-            add(buildAdvancedPropertiesPanel(), gc);
-
             // filler - grab the remaining space
             gc.gridy = 6;
@@ -310,11 +284,4 @@
         protected final void refreshView() {
             switch (oAuthVersion) {
-                case OAuth10a:
-                    String v = OAuthAccessTokenHolder.getInstance().getAccessTokenKey();
-                    tfAccessTokenKey.setText(v == null ? "" : v);
-                    v = OAuthAccessTokenHolder.getInstance().getAccessTokenSecret();
-                    tfAccessTokenSecret.setText(v == null ? "" : v);
-                    tfAccessTokenSecret.setVisible(true);
-                    break;
                 case OAuth20:
                 case OAuth21:
@@ -325,5 +292,6 @@
                     }
                     tfAccessTokenKey.setText(token == null ? "" : token);
-                    tfAccessTokenSecret.setVisible(false);
+                    break;
+                default:
             }
             cbSaveToPreferences.setSelected(OAuthAccessTokenHolder.getInstance().isSaveToPreferences());
@@ -341,49 +309,41 @@
             putValue(NAME, tr("{0} ({1})", tr("Authorize now"), procedure.getText()));
             putValue(SHORT_DESCRIPTION, procedure.getDescription());
-            if (procedure == AuthorizationProcedure.FULLY_AUTOMATIC
-            || OAuthAuthenticationPreferencesPanel.this.oAuthVersion != OAuthVersion.OAuth10a) {
+            if (procedure == AuthorizationProcedure.FULLY_AUTOMATIC) {
                 new ImageProvider("oauth", "oauth-small").getResource().attachImageIcon(this);
             }
+            updateEnabledState();
+        }
+
+        void updateEnabledState() {
+            if (procedure == AuthorizationProcedure.MANUALLY) {
+                this.setEnabled(true);
+            } else if (Utils.isValidUrl(apiUrl) && DomainValidator.getInstance().isValid(URI.create(apiUrl).getHost())) {
+                // We want to avoid trying to make connection with an invalid URL
+                final String currentApiUrl = apiUrl;
+                MainApplication.worker.execute(() -> {
+                    final String clientId = OAuthParameters.createDefault(apiUrl, oAuthVersion).getClientId();
+                    if (Objects.equals(apiUrl, currentApiUrl)) {
+                        GuiHelper.runInEDT(() -> this.setEnabled(!Utils.isEmpty(clientId)));
+                    }
+                });
+            }
         }
 
         @Override
         public void actionPerformed(ActionEvent arg0) {
-            if (OAuthAuthenticationPreferencesPanel.this.oAuthVersion == OAuthVersion.OAuth10a) {
-                OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard(
-                        OAuthAuthenticationPreferencesPanel.this,
-                        procedure,
-                        apiUrl,
-                        MainApplication.worker);
-                try {
-                    wizard.showDialog();
-                } catch (UserCancelException ignore) {
-                    Logging.trace(ignore);
-                    return;
-                }
-                pnlAdvancedProperties.setAdvancedParameters(wizard.getOAuthParameters());
-                refreshView();
-            } else {
-                final boolean remoteControlIsRunning = Boolean.TRUE.equals(RemoteControl.PROP_REMOTECONTROL_ENABLED.get());
-                // TODO: Ask user if they want to start remote control?
-                if (!remoteControlIsRunning) {
-                    RemoteControl.start();
-                }
-                new OAuth20Authorization().authorize(OAuthParameters.createDefault(OsmApi.getOsmApi().getServerUrl(), oAuthVersion), token -> {
-                    if (!remoteControlIsRunning) {
-                        RemoteControl.stop();
-                    }
-                    OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), token.orElse(null));
-                    OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
-                    GuiHelper.runInEDT(OAuthAuthenticationPreferencesPanel.this::refreshView);
-                    if (!token.isPresent()) {
-                        GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(MainApplication.getMainPanel(),
-                                tr("Authentication failed, please check browser for details."),
-                                tr("OAuth Authentication Failed"),
-                                JOptionPane.ERROR_MESSAGE));
-                    }
-                }, OsmScopes.read_gpx, OsmScopes.write_gpx,
-                        OsmScopes.read_prefs, OsmScopes.write_prefs,
-                        OsmScopes.write_api, OsmScopes.write_notes);
+            OAuthAuthorizationWizard wizard = new OAuthAuthorizationWizard(
+                    OAuthAuthenticationPreferencesPanel.this,
+                    procedure,
+                    apiUrl,
+                    MainApplication.worker,
+                    oAuthVersion);
+            try {
+                wizard.showDialog(token -> GuiHelper.runInEDT(OAuthAuthenticationPreferencesPanel.this::refreshView));
+            } catch (UserCancelException userCancelException) {
+                Logging.trace(userCancelException);
+                return;
             }
+            pnlAdvancedProperties.setAdvancedParameters(wizard.getOAuthParameters());
+            refreshView();
         }
     }
@@ -401,9 +361,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            if (oAuthVersion == OAuthVersion.OAuth10a) {
-                OAuthAccessTokenHolder.getInstance().setAccessToken(null);
-            } else {
-                OAuthAccessTokenHolder.getInstance().setAccessToken(apiUrl, (IOAuthToken) null);
-            }
+            OAuthAccessTokenHolder.getInstance().setAccessToken(apiUrl, null);
             OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
             refreshView();
@@ -430,11 +386,8 @@
      */
     private class TestAuthorisationAction extends AbstractAction {
-        private final OAuthVersion oAuthVersion;
-
         /**
          * Constructs a new {@code TestAuthorisationAction}.
          */
-        TestAuthorisationAction(OAuthVersion oAuthVersion) {
-            this.oAuthVersion = oAuthVersion;
+        TestAuthorisationAction() {
             putValue(NAME, tr("Test Access Token"));
             putValue(SHORT_DESCRIPTION, tr("Click test access to the OSM server with the current access token"));
@@ -444,24 +397,11 @@
         @Override
         public void actionPerformed(ActionEvent evt) {
-            if (this.oAuthVersion == OAuthVersion.OAuth10a) {
-                OAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken();
-                OAuthParameters parameters = OAuthParameters.createFromApiUrl(OsmApi.getOsmApi().getServerUrl());
-                TestAccessTokenTask task = new TestAccessTokenTask(
-                        OAuthAuthenticationPreferencesPanel.this,
-                        apiUrl,
-                        parameters,
-                        token
-                );
-                MainApplication.worker.submit(task);
-            } else {
-                IOAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20);
-                TestAccessTokenTask task = new TestAccessTokenTask(
-                        OAuthAuthenticationPreferencesPanel.this,
-                        apiUrl,
-                        token.getParameters(),
-                        token
-                );
-                MainApplication.worker.submit(task);
-            }
+            IOAuthToken token = OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20);
+            TestAccessTokenTask task = new TestAccessTokenTask(
+                    OAuthAuthenticationPreferencesPanel.this,
+                    apiUrl,
+                    token
+            );
+            MainApplication.worker.submit(task);
         }
     }
Index: /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 18991)
@@ -145,7 +145,5 @@
             try {
                 if (JosmPreferencesCredentialAgent.class.equals(credManager.getCredentialsAgentClass())) {
-                    if (OsmApi.isUsingOAuth(OAuthVersion.OAuth10a)) {
-                        return credManager.lookupOAuthAccessToken() != null;
-                    } else if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20) || OsmApi.isUsingOAuth(OAuthVersion.OAuth21)) {
+                    if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20) || OsmApi.isUsingOAuth(OAuthVersion.OAuth21)) {
                         return credManager.lookupOAuthAccessToken(OsmApi.getOsmApi().getHost()) != null;
                     } else if (OsmApi.isUsingOAuth()) {
Index: /trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 18991)
@@ -52,4 +52,6 @@
 import org.xml.sax.SAXParseException;
 
+import jakarta.annotation.Nullable;
+
 /**
  * Class that encapsulates the communications with the <a href="http://wiki.openstreetmap.org/wiki/API_v0.6">OSM API</a>.<br><br>
@@ -85,6 +87,4 @@
 
     private static final ListenerList<OsmApiInitializationListener> listeners = ListenerList.create();
-    /** This is used to make certain we have set osm-server.auth-method to the "right" default */
-    private static boolean oauthCompatibilitySwitch;
 
     private URL url;
@@ -653,6 +653,5 @@
      */
     public static boolean isUsingOAuth() {
-        return isUsingOAuth(OAuthVersion.OAuth10a)
-                || isUsingOAuth(OAuthVersion.OAuth20)
+        return isUsingOAuth(OAuthVersion.OAuth20)
                 || isUsingOAuth(OAuthVersion.OAuth21);
     }
@@ -665,8 +664,6 @@
      */
     public static boolean isUsingOAuth(OAuthVersion version) {
-        if (version == OAuthVersion.OAuth10a) {
-            return "oauth".equalsIgnoreCase(getAuthMethod());
-        } else if (version == OAuthVersion.OAuth20 || version == OAuthVersion.OAuth21) {
-            return "oauth20".equalsIgnoreCase(getAuthMethod());
+        if (version == OAuthVersion.OAuth20 || version == OAuthVersion.OAuth21) {
+            return getAuthMethodVersion() == OAuthVersion.OAuth20 || getAuthMethodVersion() == OAuthVersion.OAuth21;
         }
         return false;
@@ -680,7 +677,4 @@
     public static boolean isUsingOAuthAndOAuthSetUp(OsmApi api) {
         if (OsmApi.isUsingOAuth()) {
-            if (OsmApi.isUsingOAuth(OAuthVersion.OAuth10a)) {
-                return OAuthAccessTokenHolder.getInstance().containsAccessToken();
-            }
             if (OsmApi.isUsingOAuth(OAuthVersion.OAuth20)) {
                 return OAuthAccessTokenHolder.getInstance().getAccessToken(api.getBaseUrl(), OAuthVersion.OAuth20) != null;
@@ -698,22 +692,21 @@
      */
     public static String getAuthMethod() {
-        setCurrentAuthMethod();
         return Config.getPref().get("osm-server.auth-method", "oauth20");
     }
 
     /**
-     * This is a compatibility method for users who currently use OAuth 1.0 -- we are changing the default from oauth to oauth20,
-     * but since oauth was the default, pre-existing users will suddenly be switched to oauth20.
-     * This should be removed whenever {@link OAuthVersion#OAuth10a} support is removed.
-     */
-    private static void setCurrentAuthMethod() {
-        if (!oauthCompatibilitySwitch) {
-            oauthCompatibilitySwitch = true;
-            final String prefKey = "osm-server.auth-method";
-            if ("oauth20".equals(Config.getPref().get(prefKey, "oauth20"))
-                && !isUsingOAuthAndOAuthSetUp(OsmApi.getOsmApi())
-                && OAuthAccessTokenHolder.getInstance().containsAccessToken()) {
-                Config.getPref().put(prefKey, "oauth");
-            }
+     * Returns the authentication method set in the preferences
+     * @return the authentication method
+     * @since 18991
+     */
+    @Nullable
+    public static OAuthVersion getAuthMethodVersion() {
+        switch (getAuthMethod()) {
+            case "oauth20": return OAuthVersion.OAuth20;
+            case "oauth21": return OAuthVersion.OAuth21;
+            case "basic": return null;
+            default:
+                Config.getPref().put("osm-server.auth-method", null);
+                return getAuthMethodVersion();
         }
     }
Index: /trunk/src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 18991)
@@ -6,5 +6,4 @@
 import java.lang.reflect.InvocationTargetException;
 import java.net.Authenticator.RequestorType;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
@@ -36,7 +35,4 @@
 import org.openstreetmap.josm.tools.Logging;
 
-import oauth.signpost.OAuthConsumer;
-import oauth.signpost.exception.OAuthException;
-
 /**
  * Base class that handles common things like authentication for the reader and writer
@@ -51,5 +47,4 @@
     protected boolean cancel;
     protected HttpClient activeConnection;
-    protected OAuthParameters oauthParameters;
     protected IOAuthParameters oAuth20Parameters;
 
@@ -146,55 +141,4 @@
 
     /**
-     * Signs the connection with an OAuth authentication header
-     *
-     * @param connection the connection
-     *
-     * @throws MissingOAuthAccessTokenException if there is currently no OAuth Access Token configured
-     * @throws OsmTransferException if signing fails
-     */
-    protected void addOAuthAuthorizationHeader(HttpClient connection) throws OsmTransferException {
-        if (oauthParameters == null) {
-            oauthParameters = OAuthParameters.createFromApiUrl(OsmApi.getOsmApi().getServerUrl());
-        }
-        OAuthConsumer consumer = oauthParameters.buildConsumer();
-        OAuthAccessTokenHolder holder = OAuthAccessTokenHolder.getInstance();
-        if (!holder.containsAccessToken()) {
-            obtainAccessToken(connection);
-        }
-        if (!holder.containsAccessToken()) { // check if wizard completed
-            throw new MissingOAuthAccessTokenException();
-        }
-        consumer.setTokenWithSecret(holder.getAccessTokenKey(), holder.getAccessTokenSecret());
-        try {
-            consumer.sign(connection);
-        } catch (OAuthException e) {
-            throw new OsmTransferException(tr("Failed to sign a HTTP connection with an OAuth Authentication header"), e);
-        }
-    }
-
-    /**
-     * Obtains an OAuth access token for the connection.
-     * Afterwards, the token is accessible via {@link OAuthAccessTokenHolder} / {@link CredentialsManager}.
-     * @param connection connection for which the access token should be obtained
-     * @throws MissingOAuthAccessTokenException if the process cannot be completed successfully
-     */
-    protected void obtainAccessToken(final HttpClient connection) throws MissingOAuthAccessTokenException {
-        try {
-            final URL apiUrl = new URL(OsmApi.getOsmApi().getServerUrl());
-            if (!Objects.equals(apiUrl.getHost(), connection.getURL().getHost())) {
-                throw new MissingOAuthAccessTokenException();
-            }
-            fetcher.obtainAccessToken(apiUrl);
-            OAuthAccessTokenHolder.getInstance().setSaveToPreferences(true);
-            OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
-        } catch (MalformedURLException | InvocationTargetException e) {
-            throw new MissingOAuthAccessTokenException(e);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new MissingOAuthAccessTokenException(e);
-        }
-    }
-
-    /**
      * Obtains an OAuth access token for the connection.
      * Afterwards, the token is accessible via {@link OAuthAccessTokenHolder} / {@link CredentialsManager}.
@@ -221,5 +165,4 @@
                     }
                     // Clean up old token/password
-                    OAuthAccessTokenHolder.getInstance().setAccessToken(null);
                     OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), authToken.orElse(null));
                     OAuthAccessTokenHolder.getInstance().save(CredentialsManager.getInstance());
@@ -281,7 +224,4 @@
                 addBasicAuthorizationHeader(connection);
                 return;
-            case "oauth":
-                addOAuthAuthorizationHeader(connection);
-                return;
             case "oauth20":
                 addOAuth20AuthorizationHeader(connection);
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsAgent.java	(revision 18991)
@@ -7,5 +7,4 @@
 
 import org.openstreetmap.josm.data.oauth.IOAuthToken;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 
 import jakarta.annotation.Nullable;
@@ -65,6 +64,10 @@
      * @return the current OAuth Access Token to access the OSM server.
      * @throws CredentialsAgentException if something goes wrong
+     * @deprecated since 18991 -- OAuth 1.0 is being removed from the OSM API
      */
-    OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException;
+    @Deprecated
+    default IOAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
+        throw new CredentialsAgentException("Call to deprecated method");
+    }
 
     /**
@@ -85,6 +88,10 @@
      * @param accessToken the access Token. null, to remove the Access Token.
      * @throws CredentialsAgentException if something goes wrong
+     * @deprecated since 18991 -- OAuth 1.0 is being removed from the OSM API
      */
-    void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException;
+    @Deprecated
+    default void storeOAuthAccessToken(IOAuthToken accessToken) throws CredentialsAgentException {
+        throw new CredentialsAgentException("Call to deprecated method");
+    }
 
     /**
@@ -93,5 +100,5 @@
      * @param host The host the access token is for
      * @param accessToken the access Token. null, to remove the Access Token. This will remove all IOAuthTokens <i>not</i> managed by
-     *                    {@link #storeOAuthAccessToken(OAuthToken)}.
+     *                    {@link #storeOAuthAccessToken(IOAuthToken)}.
      * @throws CredentialsAgentException if something goes wrong
      * @since 18650
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 18991)
@@ -9,5 +9,4 @@
 import org.openstreetmap.josm.data.UserIdentityManager;
 import org.openstreetmap.josm.data.oauth.IOAuthToken;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -17,5 +16,5 @@
 /**
  * CredentialManager is a factory for the single credential agent used.
- *
+ * <p>
  * Currently, it defaults to replying an instance of {@link JosmPreferencesCredentialAgent}.
  * @since 2641
@@ -158,16 +157,6 @@
 
     @Override
-    public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
-        return delegate.lookupOAuthAccessToken();
-    }
-
-    @Override
     public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException {
         return delegate.lookupOAuthAccessToken(host);
-    }
-
-    @Override
-    public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {
-        delegate.storeOAuthAccessToken(accessToken);
     }
 
Index: /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialAgent.java	(revision 18991)
@@ -18,5 +18,4 @@
 import org.openstreetmap.josm.data.oauth.OAuth20Parameters;
 import org.openstreetmap.josm.data.oauth.OAuth20Token;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.widgets.HtmlPanel;
@@ -103,20 +102,4 @@
     }
 
-    /**
-     * Lookup the current OAuth Access Token to access the OSM server. Replies null, if no
-     * Access Token is currently managed by this CredentialManager.
-     *
-     * @return the current OAuth Access Token to access the OSM server.
-     * @throws CredentialsAgentException if something goes wrong
-     */
-    @Override
-    public OAuthToken lookupOAuthAccessToken() throws CredentialsAgentException {
-        String accessTokenKey = Config.getPref().get("oauth.access-token.key", null);
-        String accessTokenSecret = Config.getPref().get("oauth.access-token.secret", null);
-        if (accessTokenKey == null && accessTokenSecret == null)
-            return null;
-        return new OAuthToken(accessTokenKey, accessTokenSecret);
-    }
-
     @Override
     public IOAuthToken lookupOAuthAccessToken(String host) throws CredentialsAgentException {
@@ -141,21 +124,4 @@
         }
         return null;
-    }
-
-    /**
-     * Stores the OAuth Access Token <code>accessToken</code>.
-     *
-     * @param accessToken the access Token. null, to remove the Access Token.
-     * @throws CredentialsAgentException if something goes wrong
-     */
-    @Override
-    public void storeOAuthAccessToken(OAuthToken accessToken) throws CredentialsAgentException {
-        if (accessToken == null) {
-            Config.getPref().put("oauth.access-token.key", null);
-            Config.getPref().put("oauth.access-token.secret", null);
-        } else {
-            Config.getPref().put("oauth.access-token.key", accessToken.getKey());
-            Config.getPref().put("oauth.access-token.secret", accessToken.getSecret());
-        }
     }
 
Index: /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 18990)
+++ /trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 18991)
@@ -298,5 +298,5 @@
                 + "Please launch the preferences dialog and retrieve another OAuth token."
                 + "</html>",
-                OAuthAccessTokenHolder.getInstance().getAccessTokenKey()
+                OAuthAccessTokenHolder.getInstance().getAccessToken(e.getUrl(), OsmApi.getAuthMethodVersion())
         );
     }
@@ -344,5 +344,5 @@
                 + "Please launch the preferences dialog and retrieve another OAuth token."
                 + "</html>",
-                OAuthAccessTokenHolder.getInstance().getAccessTokenKey(),
+                OAuthAccessTokenHolder.getInstance().getAccessToken(e.getUrl(), OsmApi.getAuthMethodVersion()),
                 e.getAccessedUrl() == null ? tr("unknown") : e.getAccessedUrl()
         );
Index: /trunk/test/unit/org/openstreetmap/josm/TestUtils.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/TestUtils.java	(revision 18991)
@@ -659,8 +659,8 @@
     /**
      * Determines if OSM DEV_API credential have been provided. Required for functional tests.
-     * @return {@code true} if {@code osm.username} and {@code osm.password} have been defined on the command line
+     * @return {@code true} if {@code osm.oauth2} have been defined on the command line
      */
     public static boolean areCredentialsProvided() {
-        return Utils.getSystemProperty("osm.username") != null && Utils.getSystemProperty("osm.password") != null;
+        return Utils.getSystemProperty("osm.oauth2") != null;
     }
 
Index: /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuth20AuthorizationTest.java	(revision 18991)
@@ -186,5 +186,5 @@
         OAuth20Parameters parameters = (OAuth20Parameters) OAuthParameters.createDefault(OsmApi.getOsmApi().getBaseUrl(), OAuthVersion.OAuth20);
         RemoteControl.start();
-        authorization.authorize(new OAuth20Parameters(parameters.getClientId(), parameters.getClientSecret(),
+        authorization.authorize(new OAuth20Parameters(CLIENT_ID_VALUE, parameters.getClientSecret(),
                 wireMockRuntimeInfo.getHttpBaseUrl() + "/oauth2", wireMockRuntimeInfo.getHttpBaseUrl() + "/api",
                 parameters.getRedirectUri()), consumer::set, OsmScopes.read_gpx);
Index: /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java	(revision 18991)
@@ -24,14 +24,12 @@
     @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
     void testCreateDefault() {
-        OAuthParameters def = OAuthParameters.createDefault();
+        IOAuthParameters def = OAuthParameters.createDefault();
         assertNotNull(def);
-        assertEquals(def, OAuthParameters.createDefault(Config.getUrls().getDefaultOsmApiUrl()));
-        OAuthParameters dev = OAuthParameters.createDefault("https://api06.dev.openstreetmap.org/api");
+        assertEquals(def, OAuthParameters.createDefault(Config.getUrls().getDefaultOsmApiUrl(), OAuthVersion.OAuth20));
+        IOAuthParameters dev = OAuthParameters.createDefault("https://api06.dev.openstreetmap.org/api", OAuthVersion.OAuth20);
         assertNotNull(dev);
         assertNotEquals(def, dev);
         Logging.setLogLevel(Logging.LEVEL_TRACE); // enable trace for line coverage
-        assertEquals(def, OAuthParameters.createDefault("wrong_url"));
-        OAuthParameters dev2 = new OAuthParameters(dev);
-        assertEquals(dev, dev2);
+        assertEquals(def, OAuthParameters.createDefault("wrong_url", OAuthVersion.OAuth20));
     }
 
@@ -42,5 +40,5 @@
     void testEqualsContract() {
         TestUtils.assumeWorkingEqualsVerifier();
-        EqualsVerifier.forClass(OAuthParameters.class).usingGetClass().verify();
+        EqualsVerifier.forClass(OAuth20Parameters.class).usingGetClass().verify();
     }
 }
Index: unk/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java	(revision 18990)
+++ 	(revision )
@@ -1,40 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.oauth;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.Test;
-import org.openstreetmap.josm.TestUtils;
-
-import nl.jqno.equalsverifier.EqualsVerifier;
-import oauth.signpost.OAuthConsumer;
-
-/**
- * Unit tests for class {@link OAuthToken}.
- */
-class OAuthTokenTest {
-
-    /**
-     * Unit test of method {@link OAuthToken#createToken}.
-     */
-    @Test
-    void testCreateToken() {
-        OAuthConsumer defCon = OAuthParameters.createDefault().buildConsumer();
-        assertNotNull(defCon);
-        OAuthToken defTok = OAuthToken.createToken(defCon);
-        assertNotNull(defTok);
-        assertEquals(defCon.getToken(), defTok.getKey());
-        assertEquals(defCon.getTokenSecret(), defTok.getSecret());
-        assertEquals(defTok, new OAuthToken(defTok));
-    }
-
-    /**
-     * Unit test of methods {@link OAuthToken#equals} and {@link OAuthToken#hashCode}.
-     */
-    @Test
-    void testEqualsContract() {
-        TestUtils.assumeWorkingEqualsVerifier();
-        EqualsVerifier.forClass(OAuthToken.class).usingGetClass().verify();
-    }
-}
Index: unk/test/unit/org/openstreetmap/josm/data/oauth/SignpostAdaptersTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/data/oauth/SignpostAdaptersTest.java	(revision 18990)
+++ 	(revision )
@@ -1,99 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data.oauth;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.junit.jupiter.api.Test;
-import org.openstreetmap.josm.data.oauth.SignpostAdapters.HttpRequest;
-import org.openstreetmap.josm.data.oauth.SignpostAdapters.HttpResponse;
-import org.openstreetmap.josm.data.oauth.SignpostAdapters.OAuthConsumer;
-import org.openstreetmap.josm.testutils.annotations.HTTPS;
-import org.openstreetmap.josm.tools.HttpClient;
-
-import net.trajano.commons.testing.UtilityClassTestUtil;
-
-/**
- * Unit tests for class {@link SignpostAdapters}.
- */
-@HTTPS
-class SignpostAdaptersTest {
-
-    private static HttpClient newClient() throws MalformedURLException {
-        return HttpClient.create(new URL("https://www.openstreetmap.org"));
-    }
-
-    /**
-     * Tests that {@code SignpostAdapters} satisfies utility class criteria.
-     * @throws ReflectiveOperationException if an error occurs
-     */
-    @Test
-    void testUtilityClass() throws ReflectiveOperationException {
-        UtilityClassTestUtil.assertUtilityClassWellDefined(SignpostAdapters.class);
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.OAuthConsumer#wrap}.
-     * @throws MalformedURLException never
-     */
-    @Test
-    void testOAuthConsumerWrap() throws MalformedURLException {
-        assertNotNull(new OAuthConsumer("", "").wrap(newClient()));
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpRequest#getMessagePayload}.
-     * @throws IOException never
-     */
-    @Test
-    void testHttpRequestGetMessagePayload() throws IOException {
-        assertNull(new HttpRequest(newClient()).getMessagePayload());
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpRequest#setRequestUrl}.
-     */
-    @Test
-    void testHttpRequestSetRequestUrl() {
-        assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).setRequestUrl(null));
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpRequest#getAllHeaders}.
-     */
-    @Test
-    void testHttpRequestGetAllHeaders() {
-        assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).getAllHeaders());
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpRequest#unwrap}.
-     */
-    @Test
-    void testHttpRequestUnwrap() {
-        assertThrows(IllegalStateException.class, () -> new HttpRequest(newClient()).unwrap());
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpResponse#getReasonPhrase()}.
-     * @throws Exception never
-     */
-    @Test
-    void testHttpResponseGetReasonPhrase() throws Exception {
-        assertEquals("OK", new HttpResponse(new HttpRequest(newClient()).request.connect()).getReasonPhrase());
-    }
-
-    /**
-     * Unit test of method {@link SignpostAdapters.HttpResponse#unwrap}.
-     */
-    @Test
-    void testHttpResponseUnwrap() {
-        assertThrows(IllegalStateException.class, () -> new HttpResponse(new HttpRequest(newClient()).request.connect()).unwrap());
-    }
-}
Index: /trunk/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTaskTest.java	(revision 18991)
@@ -9,15 +9,14 @@
 import java.awt.GraphicsEnvironment;
 import java.net.URL;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.UserIdentityManager;
 import org.openstreetmap.josm.gui.oauth.OAuthAuthorizationWizard;
-import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
 import org.openstreetmap.josm.testutils.annotations.OsmApi;
@@ -64,12 +63,4 @@
 
     /**
-     * These tests were written with {@link org.openstreetmap.josm.data.oauth.OAuthVersion#OAuth10a} as the default auth method.
-     */
-    @BeforeEach
-    void setup() {
-        Config.getPref().put("osm-server.auth-method", "oauth");
-    }
-
-    /**
      * Test of {@link DownloadOpenChangesetsTask} class when anonymous.
      */
@@ -80,12 +71,10 @@
             new WindowMocker();
         }
-        final OAuthWizardMocker oaWizardMocker = new OAuthWizardMocker();
-        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
-            Collections.singletonMap(
-                "<html>Could not retrieve the list of your open changesets because<br>JOSM does not know "
+        final Map<String, Object> optionPaneMock = new HashMap<>(2);
+        optionPaneMock.put("<html>Could not retrieve the list of your open changesets because<br>JOSM does not know "
                 + "your identity.<br>You have either chosen to work anonymously or you are not "
-                + "entitled<br>to know the identity of the user on whose behalf you are working.</html>", JOptionPane.OK_OPTION
-            )
-        );
+                + "entitled<br>to know the identity of the user on whose behalf you are working.</html>", JOptionPane.OK_OPTION);
+        optionPaneMock.put("Obtain OAuth 2.0 token for authentication?", JOptionPane.NO_OPTION);
+        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(optionPaneMock);
 
         DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(new JPanel());
@@ -96,10 +85,12 @@
         assertNull(task.getChangesets());
 
-        assertEquals(1, jopsMocker.getInvocationLog().size());
-        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(2, jopsMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(1);
         assertEquals(JOptionPane.OK_OPTION, (int) invocationLogEntry[0]);
         assertEquals("Missing user identity", invocationLogEntry[2]);
 
-        assertTrue(oaWizardMocker.called);
+        invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(JOptionPane.NO_OPTION, (int) invocationLogEntry[0]);
+        assertEquals("Obtain authentication to OSM servers", invocationLogEntry[2]);
     }
 
@@ -113,8 +104,8 @@
             new WindowMocker();
         }
-        final OAuthWizardMocker oaWizardMocker = new OAuthWizardMocker();
-        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
-            Collections.singletonMap("There are no open changesets", JOptionPane.OK_OPTION)
-        );
+        final Map<String, Object> optionPaneMock = new HashMap<>(2);
+        optionPaneMock.put("There are no open changesets", JOptionPane.OK_OPTION);
+        optionPaneMock.put("Obtain OAuth 2.0 token for authentication?", JOptionPane.NO_OPTION);
+        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(optionPaneMock);
 
         DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(new JPanel());
@@ -124,10 +115,12 @@
         assertNotNull(task.getChangesets());
 
-        assertEquals(1, jopsMocker.getInvocationLog().size());
-        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(2, jopsMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(1);
         assertEquals(JOptionPane.OK_OPTION, (int) invocationLogEntry[0]);
         assertEquals("No open changesets", invocationLogEntry[2]);
 
-        assertTrue(oaWizardMocker.called);
+        invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(JOptionPane.NO_OPTION, (int) invocationLogEntry[0]);
+        assertEquals("Obtain authentication to OSM servers", invocationLogEntry[2]);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java	(revision 18991)
@@ -2,10 +2,11 @@
 package org.openstreetmap.josm.gui.oauth;
 
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
-
-import org.junit.jupiter.api.Test;
 
 /**
@@ -17,7 +18,8 @@
      * Unit test of {@link FullyAutomaticAuthorizationUI#FullyAutomaticAuthorizationUI}.
      */
-    @Test
-    void testFullyAutomaticAuthorizationUI() {
-        assertNotNull(new FullyAutomaticAuthorizationUI("", MainApplication.worker));
+    @ParameterizedTest
+    @EnumSource(OAuthVersion.class)
+    void testFullyAutomaticAuthorizationUI(OAuthVersion version) {
+        assertDoesNotThrow(() -> new FullyAutomaticAuthorizationUI("", MainApplication.worker, version));
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java	(revision 18991)
@@ -2,7 +2,8 @@
 package org.openstreetmap.josm.gui.oauth;
 
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 
 import org.junit.jupiter.api.Test;
+import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
@@ -18,5 +19,5 @@
     @Test
     void testManualAuthorizationUI() {
-        assertNotNull(new ManualAuthorizationUI("", MainApplication.worker));
+        assertDoesNotThrow(() -> new ManualAuthorizationUI("", MainApplication.worker, OAuthVersion.OAuth20));
     }
 }
Index: unk/test/unit/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClientTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClientTest.java	(revision 18990)
+++ 	(revision )
@@ -1,116 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.URI;
-import java.util.Collections;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Timeout;
-import org.openstreetmap.josm.data.oauth.OAuthParameters;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
-import org.openstreetmap.josm.io.OsmTransferCanceledException;
-import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
-import org.openstreetmap.josm.testutils.annotations.BasicWiremock;
-import org.openstreetmap.josm.testutils.annotations.HTTP;
-
-import com.github.tomakehurst.wiremock.WireMockServer;
-
-/**
- * Unit tests of {@link OsmOAuthAuthorizationClient} class.
- */
-@Timeout(20)
-@BasicWiremock
-// Needed for OAuthParameters
-@BasicPreferences
-@HTTP
-class OsmOAuthAuthorizationClientTest {
-    /**
-     * HTTP mock.
-     */
-    @BasicWiremock
-    WireMockServer wireMockServer;
-
-    /**
-     * Unit test of {@link OsmOAuthAuthorizationClient}.
-     * @throws OsmOAuthAuthorizationException if OAuth authorization error occurs
-     * @throws OsmTransferCanceledException  if OSM transfer error occurs
-     */
-    @Test
-    void testOsmOAuthAuthorizationClient() throws OsmTransferCanceledException, OsmOAuthAuthorizationException {
-        // request token
-        wireMockServer.stubFor(get(urlEqualTo("/oauth/request_token"))
-                .willReturn(aResponse().withStatus(200).withBody(String.join("&",
-                        "oauth_token=entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR",
-                        "oauth_token_secret=nsBD2Hr5lLGDUeNoh3SnLaGsUV1TiPYM4qUr7tPB"))));
-        OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(OAuthParameters.createDefault(
-                wireMockServer.url("/api")));
-
-        OAuthToken requestToken = client.getRequestToken(null);
-        assertEquals("entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR", requestToken.getKey(), "requestToken.key");
-        assertEquals("nsBD2Hr5lLGDUeNoh3SnLaGsUV1TiPYM4qUr7tPB", requestToken.getSecret(), "requestToken.secret");
-        String url = client.getAuthoriseUrl(requestToken);
-        assertEquals(wireMockServer.url("/oauth/authorize?oauth_token=entxUGuwRKV6KyVDF0OWScdGhbqXGMGmosXuiChR"), url, "url");
-
-        // access token
-        wireMockServer.stubFor(get(urlEqualTo("/oauth/access_token"))
-                .willReturn(aResponse().withStatus(200).withBody(String.join("&",
-                        "oauth_token=eGMGmosXuiChRntxUGuwRKV6KyVDF0OWScdGhbqX",
-                        "oauth_token_secret=nsBUeNor7tPh3SHr5lLaGsGDUD2PYMV1TinL4qUB"))));
-
-        OAuthToken accessToken = client.getAccessToken(null);
-        assertEquals("eGMGmosXuiChRntxUGuwRKV6KyVDF0OWScdGhbqX", accessToken.getKey(), "accessToken.key");
-        assertEquals("nsBUeNor7tPh3SHr5lLaGsGDUD2PYMV1TinL4qUB", accessToken.getSecret(), "accessToken.secret");
-    }
-
-    /**
-     * Unit test for correct cookie handling when logging in to the OSM website.
-     *
-     * https://josm.openstreetmap.de/ticket/12584
-     * @throws Exception if any error occurs
-     */
-    @Test
-    void testCookieHandlingMock() throws Exception {
-        wireMockServer.stubFor(get(urlEqualTo("/login?cookie_test=true"))
-                .willReturn(aResponse()
-                        .withStatus(200)
-                        .withHeader("Set-Cookie", "_osm_session=7fe8e2ea36c6b803cb902301b28e0a; path=/; HttpOnly; SameSite=Lax")
-                .withBody("<input type=\"hidden\" " +
-                        "name=\"authenticity_token\" " +
-                        "value=\"fzp6CWJhp6Vns09re3s2Tw==\" />")));
-        final OAuthParameters parameters = OAuthParameters.createDefault(wireMockServer.url("/api"));
-        final OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(parameters);
-        final OsmOAuthAuthorizationClient.SessionId sessionId = client.fetchOsmWebsiteSessionId();
-        assertNotNull(sessionId);
-        assertEquals("7fe8e2ea36c6b803cb902301b28e0a", sessionId.id, "sessionId.id");
-        assertEquals("fzp6CWJhp6Vns09re3s2Tw==", sessionId.token, "sessionId.token");
-        assertNull(sessionId.userName, "sessionId.userName");
-    }
-
-    /**
-     * Unit test for correct cookie handling when logging in to the OSM website.
-     *
-     * https://josm.openstreetmap.de/ticket/12584
-     * @throws Exception if any error occurs
-     */
-    @Test
-    void testCookieHandlingCookieManager() throws Exception {
-        // emulate Java Web Start behaviour
-        // see https://docs.oracle.com/javase/tutorial/deployment/doingMoreWithRIA/accessingCookies.html
-        final OAuthParameters parameters = OAuthParameters.createDefault();
-        final OsmOAuthAuthorizationClient client = new OsmOAuthAuthorizationClient(parameters);
-        final CookieManager cm = new CookieManager();
-        cm.put(new URI(parameters.getOsmLoginUrl()),
-                Collections.singletonMap("Cookie", Collections.singletonList("_osm_session=" + String.valueOf(Math.PI).substring(2))));
-        CookieHandler.setDefault(cm);
-        assertNotNull(client.fetchOsmWebsiteSessionId());
-    }
-}
Index: unk/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java	(revision 18990)
+++ 	(revision )
@@ -1,22 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.oauth;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.Test;
-import org.openstreetmap.josm.gui.MainApplication;
-import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
-
-/**
- * Unit tests of {@link SemiAutomaticAuthorizationUI} class.
- */
-@BasicPreferences
-class SemiAutomaticAuthorizationUITest {
-    /**
-     * Unit test of {@link SemiAutomaticAuthorizationUI#SemiAutomaticAuthorizationUI}.
-     */
-    @Test
-    void testSemiAutomaticAuthorizationUI() {
-        assertNotNull(new SemiAutomaticAuthorizationUI("", MainApplication.worker));
-    }
-}
Index: /trunk/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanelTest.java	(revision 18991)
@@ -21,10 +21,8 @@
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
-import org.openstreetmap.josm.data.oauth.IOAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuth20Exception;
 import org.openstreetmap.josm.data.oauth.OAuth20Parameters;
 import org.openstreetmap.josm.data.oauth.OAuth20Token;
 import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.data.oauth.OAuthVersion;
 import org.openstreetmap.josm.io.OsmApi;
@@ -47,5 +45,5 @@
         List<Exception> exceptionList = new ArrayList<>();
         try {
-            CredentialsManager.getInstance().storeOAuthAccessToken(null);
+            CredentialsManager.getInstance().storeOAuthAccessToken(OsmApi.getOsmApi().getServerUrl(), null);
         } catch (CredentialsAgentException exception) {
             exceptionList.add(exception);
@@ -61,5 +59,5 @@
 
     @ParameterizedTest
-    @EnumSource(value = OAuthVersion.class, names = {"OAuth10a", "OAuth20"})
+    @EnumSource(value = OAuthVersion.class, names = "OAuth20")
     void testRemoveToken(OAuthVersion oAuthVersion) throws ReflectiveOperationException, CredentialsAgentException, OAuth20Exception {
         final OAuthAuthenticationPreferencesPanel panel = new OAuthAuthenticationPreferencesPanel(oAuthVersion);
@@ -76,6 +74,6 @@
         assertSame(pnlAlreadyAuthorised.get(panel), holder.getComponent(0), "Authentication should now be set");
         assertNotNull(getAuthorization(oAuthVersion));
-        final JPanel buttons = (JPanel) ((JPanel) pnlAlreadyAuthorised.get(panel)).getComponent(6);
-        final JButton action = (JButton) buttons.getComponent(oAuthVersion == OAuthVersion.OAuth10a ? 2 : 1);
+        final JPanel buttons = (JPanel) ((JPanel) pnlAlreadyAuthorised.get(panel)).getComponent(5);
+        final JButton action = (JButton) buttons.getComponent(2);
         assertEquals(tr("Remove token"), action.getText(), "The selected button should be for removing the token");
         action.getAction().actionPerformed(null);
@@ -97,7 +95,4 @@
     private static void addAuthorization(OAuthVersion oAuthVersion) throws CredentialsAgentException, OAuth20Exception {
         switch (oAuthVersion) {
-            case OAuth10a:
-                CredentialsManager.getInstance().storeOAuthAccessToken(new OAuthToken("fake_key", "fake_secret"));
-                break;
             case OAuth20:
             case OAuth21:
@@ -117,16 +112,8 @@
     private static Object getAuthorization(OAuthVersion oAuthVersion) {
         OAuthAccessTokenHolder.getInstance().clear();
-        OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getHost(), (IOAuthToken) null);
+        OAuthAccessTokenHolder.getInstance().setAccessToken(OsmApi.getOsmApi().getServerUrl(), null);
         OAuthAccessTokenHolder.getInstance().init(CredentialsManager.getInstance());
         // Ensure that we are not saving authorization data
-        switch (oAuthVersion) {
-            case OAuth10a:
-                return OAuthAccessTokenHolder.getInstance().getAccessToken();
-            case OAuth20:
-            case OAuth21:
-                return OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getHost(), oAuthVersion);
-            default:
-                throw new AssertionError("OAuth version not understood");
-        }
+        return OAuthAccessTokenHolder.getInstance().getAccessToken(OsmApi.getOsmApi().getServerUrl(), oAuthVersion);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/io/auth/CredentialsAgentTest.java	(revision 18991)
@@ -19,5 +19,4 @@
 import org.openstreetmap.josm.data.oauth.OAuth20Parameters;
 import org.openstreetmap.josm.data.oauth.OAuth20Token;
-import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
@@ -76,16 +75,4 @@
     }
 
-    @Test
-    default void testLookUpAndStoreOAuth10() throws CredentialsAgentException {
-        final T agent = createAgent();
-        assertNull(agent.lookupOAuthAccessToken());
-        final OAuthToken token = new OAuthToken("foo", "bar");
-        agent.storeOAuthAccessToken(token);
-        final OAuthToken actual = agent.lookupOAuthAccessToken();
-        assertEquals(token, actual);
-        agent.storeOAuthAccessToken(null);
-        assertNull(agent.lookupOAuthAccessToken());
-    }
-
     @ParameterizedTest
     @MethodSource("getHosts")
Index: /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/BasicPreferences.java	(revision 18991)
@@ -65,4 +65,7 @@
             if (AnnotationSupport.isAnnotated(context.getElement(), BasicPreferences.class)) {
                 this.afterAll(context);
+                if (AnnotationSupport.isAnnotated(context.getTestClass(), BasicPreferences.class)) {
+                    this.beforeAll(context);
+                }
             }
         }
Index: /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java	(revision 18990)
+++ /trunk/test/unit/org/openstreetmap/josm/testutils/annotations/TestUser.java	(revision 18991)
@@ -10,5 +10,4 @@
 import java.lang.annotation.Target;
 import java.net.Authenticator;
-import java.net.PasswordAuthentication;
 
 import org.junit.jupiter.api.extension.AfterEachCallback;
@@ -19,4 +18,7 @@
 import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.UserIdentityManager;
+import org.openstreetmap.josm.data.oauth.OAuth20Token;
+import org.openstreetmap.josm.data.oauth.OAuthAccessTokenHolder;
+import org.openstreetmap.josm.data.oauth.OAuthParameters;
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.spi.preferences.Config;
@@ -51,15 +53,18 @@
         public void beforeEach(ExtensionContext context) throws Exception {
             assumeTrue(TestUtils.areCredentialsProvided(),
-                    "OSM DEV API credentials not provided. Please define them with -Dosm.username and -Dosm.password");
-            final String username = Utils.getSystemProperty("osm.username");
-            final String password = Utils.getSystemProperty("osm.password");
-            assumeTrue(username != null && !username.isEmpty(), "Please add -Dosm.username for the OSM DEV API");
-            assumeTrue(password != null && !password.isEmpty(), "Please add -Dosm.password for the OSM DEV API");
-            Config.getPref().put("osm-server.auth-method", "basic");
+                    "OSM DEV API credentials not provided. Please define them with -Dosm.oauth2");
+            final String oauth2 = Utils.getSystemProperty("osm.oauth2");
+            Config.getPref().put("osm-server.auth-method", "oauth20");
 
             // don't use atomic upload, the test API server can't cope with large diff uploads
             Config.getPref().putBoolean("osm-server.atomic-upload", false);
-            CredentialsManager.getInstance().store(Authenticator.RequestorType.SERVER, org.openstreetmap.josm.io.OsmApi.getOsmApi().getHost(),
-                    new PasswordAuthentication(username, password.toCharArray()));
+            final String serverUrl = org.openstreetmap.josm.io.OsmApi.getOsmApi().getServerUrl();
+            final OAuth20Token token = new OAuth20Token(OAuthParameters.createDefault(),
+                    "{\"token_type\":\"bearer\", \"access_token\": \"" + oauth2 + "\"}");
+            OAuthAccessTokenHolder.getInstance().setAccessToken(serverUrl, token);
+            CredentialsManager.getInstance().storeOAuthAccessToken(serverUrl, token);
+            if (!UserIdentityManager.getInstance().isFullyIdentified()) {
+                UserIdentityManager.getInstance().initFromOAuth();
+            }
         }
     }
