Index: trunk/.classpath
===================================================================
--- trunk/.classpath	(revision 9219)
+++ trunk/.classpath	(revision 9220)
@@ -18,4 +18,5 @@
 	<classpathentry kind="lib" path="test/lib/fest/MRJToolkitStubs-1.0.jar"/>
 	<classpathentry kind="lib" path="test/lib/jfcunit.jar"/>
+	<classpathentry kind="lib" path="test/lib/equalsverifier-1.7.6.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.7.0_80"/>
 	<classpathentry exported="true" kind="con" path="GROOVY_SUPPORT"/>
@@ -24,5 +25,5 @@
 	<classpathentry kind="lib" path="test/lib/unitils-core/commons-logging-1.1.jar"/>
 	<classpathentry kind="lib" path="test/lib/unitils-core/ognl-2.6.9.jar"/>
-	<classpathentry kind="lib" path="test/lib/unitils-core/unitils-core-3.3.jar"/>
+	<classpathentry kind="lib" path="test/lib/unitils-core/unitils-core-3.4.2.jar"/>
 	<classpathentry kind="lib" path="test/lib/fest/debug-1.0.jar"/>
 	<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
Index: trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java	(revision 9219)
+++ trunk/src/org/openstreetmap/josm/data/oauth/OAuthParameters.java	(revision 9220)
@@ -14,5 +14,5 @@
 
 /**
- * This class manages a set of OAuth parameters.
+ * This class manages an immutable set of OAuth parameters.
  * @since 2747
  */
@@ -40,5 +40,4 @@
     public static final String DEFAULT_AUTHORISE_URL = Main.getOSMWebsite() + "/oauth/authorize";
 
-
     /**
      * Replies a set of default parameters for a consumer accessing the standard OSM server
@@ -61,18 +60,8 @@
      */
     public static OAuthParameters createDefault(String apiUrl) {
-        OAuthParameters parameters = new OAuthParameters();
-        parameters.setConsumerKey(DEFAULT_JOSM_CONSUMER_KEY);
-        parameters.setConsumerSecret(DEFAULT_JOSM_CONSUMER_SECRET);
-        parameters.setRequestTokenUrl(DEFAULT_REQUEST_TOKEN_URL);
-        parameters.setAccessTokenUrl(DEFAULT_ACCESS_TOKEN_URL);
-        parameters.setAuthoriseUrl(DEFAULT_AUTHORISE_URL);
+        String host = "";
         if (!OsmApi.DEFAULT_API_URL.equals(apiUrl)) {
             try {
-                String host = new URL(apiUrl).getHost();
-                if (host.endsWith("dev.openstreetmap.org")) {
-                    parameters.setRequestTokenUrl(DEFAULT_REQUEST_TOKEN_URL.replace("www.openstreetmap.org", host));
-                    parameters.setAccessTokenUrl(DEFAULT_ACCESS_TOKEN_URL.replace("www.openstreetmap.org", host));
-                    parameters.setAuthoriseUrl(DEFAULT_AUTHORISE_URL.replace("www.openstreetmap.org", host));
-                }
+                host = new URL(apiUrl).getHost();
             } catch (MalformedURLException e) {
                 // Ignored
@@ -82,5 +71,11 @@
             }
         }
-        return parameters;
+        boolean osmDevServer = host.endsWith("dev.openstreetmap.org");
+        return new OAuthParameters(
+            DEFAULT_JOSM_CONSUMER_KEY,
+            DEFAULT_JOSM_CONSUMER_SECRET,
+            osmDevServer ? DEFAULT_REQUEST_TOKEN_URL.replace("www.openstreetmap.org", host) : DEFAULT_REQUEST_TOKEN_URL,
+            osmDevServer ? DEFAULT_ACCESS_TOKEN_URL.replace("www.openstreetmap.org", host) : DEFAULT_ACCESS_TOKEN_URL,
+            osmDevServer ? DEFAULT_AUTHORISE_URL.replace("www.openstreetmap.org", host) : DEFAULT_AUTHORISE_URL);
     }
 
@@ -93,26 +88,38 @@
     public static OAuthParameters createFromPreferences(Preferences pref) {
         OAuthParameters parameters = createDefault(pref.get("osm-server.url"));
-        parameters.setConsumerKey(pref.get("oauth.settings.consumer-key", parameters.getConsumerKey()));
-        parameters.setConsumerSecret(pref.get("oauth.settings.consumer-secret", parameters.getConsumerSecret()));
-        parameters.setRequestTokenUrl(pref.get("oauth.settings.request-token-url", parameters.getRequestTokenUrl()));
-        parameters.setAccessTokenUrl(pref.get("oauth.settings.access-token-url", parameters.getAccessTokenUrl()));
-        parameters.setAuthoriseUrl(pref.get("oauth.settings.authorise-url", parameters.getAuthoriseUrl()));
-        return parameters;
-    }
-
-    private String consumerKey;
-    private String consumerSecret;
-    private String requestTokenUrl;
-    private String accessTokenUrl;
-    private String authoriseUrl;
-
-    /**
-     * Constructs a new, unitialized, {@code OAuthParameters}.
+        return new OAuthParameters(
+                pref.get("oauth.settings.consumer-key", parameters.getConsumerKey()),
+                pref.get("oauth.settings.consumer-secret", parameters.getConsumerSecret()),
+                pref.get("oauth.settings.request-token-url", parameters.getRequestTokenUrl()),
+                pref.get("oauth.settings.access-token-url", parameters.getAccessTokenUrl()),
+                pref.get("oauth.settings.authorise-url", parameters.getAuthoriseUrl())
+                );
+    }
+
+    private final String consumerKey;
+    private final String consumerSecret;
+    private final String requestTokenUrl;
+    private final String accessTokenUrl;
+    private final String authoriseUrl;
+
+    /**
+     * 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
      *
      * @see #createDefault
      * @see #createFromPreferences
-     */
-    public OAuthParameters() {
-        // contents can be set later with setters
+     * @since 9220
+     */
+    public OAuthParameters(String consumerKey, String consumerSecret,
+            String requestTokenUrl, String accessTokenUrl, String authoriseUrl) {
+        this.consumerKey = consumerKey;
+        this.consumerSecret = consumerSecret;
+        this.requestTokenUrl = requestTokenUrl;
+        this.accessTokenUrl = accessTokenUrl;
+        this.authoriseUrl = authoriseUrl;
     }
 
@@ -141,12 +148,4 @@
 
     /**
-     * Sets the consumer key.
-     * @param consumerKey The consumer key
-     */
-    public void setConsumerKey(String consumerKey) {
-        this.consumerKey = consumerKey;
-    }
-
-    /**
      * Gets the consumer secret.
      * @return The consumer secret
@@ -157,12 +156,4 @@
 
     /**
-     * Sets the consumer secret.
-     * @param consumerSecret The consumer secret
-     */
-    public void setConsumerSecret(String consumerSecret) {
-        this.consumerSecret = consumerSecret;
-    }
-
-    /**
      * Gets the request token URL.
      * @return The request token URL
@@ -173,12 +164,4 @@
 
     /**
-     * Sets the request token URL.
-     * @param requestTokenUrl the request token URL
-     */
-    public void setRequestTokenUrl(String requestTokenUrl) {
-        this.requestTokenUrl = requestTokenUrl;
-    }
-
-    /**
      * Gets the access token URL.
      * @return The access token URL
@@ -189,12 +172,4 @@
 
     /**
-     * Sets the access token URL.
-     * @param accessTokenUrl The access token URL
-     */
-    public void setAccessTokenUrl(String accessTokenUrl) {
-        this.accessTokenUrl = accessTokenUrl;
-    }
-
-    /**
      * Gets the authorise URL.
      * @return The authorise URL
@@ -202,12 +177,4 @@
     public String getAuthoriseUrl() {
         return authoriseUrl;
-    }
-
-    /**
-     * Sets the authorise URL.
-     * @param authoriseUrl The authorise URL
-     */
-    public void setAuthoriseUrl(String authoriseUrl) {
-        this.authoriseUrl = authoriseUrl;
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java	(revision 9219)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/AdvancedOAuthPropertiesPanel.java	(revision 9220)
@@ -193,11 +193,10 @@
         if (cbUseDefaults.isSelected())
             return OAuthParameters.createDefault(apiUrl);
-        OAuthParameters parameters = new OAuthParameters();
-        parameters.setConsumerKey(tfConsumerKey.getText());
-        parameters.setConsumerSecret(tfConsumerSecret.getText());
-        parameters.setRequestTokenUrl(tfRequestTokenURL.getText());
-        parameters.setAccessTokenUrl(tfAccessTokenURL.getText());
-        parameters.setAuthoriseUrl(tfAuthoriseURL.getText());
-        return parameters;
+        return new OAuthParameters(
+            tfConsumerKey.getText(),
+            tfConsumerSecret.getText(),
+            tfRequestTokenURL.getText(),
+            tfAccessTokenURL.getText(),
+            tfAuthoriseURL.getText());
     }
 
Index: trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java	(revision 9219)
+++ trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthParametersTest.java	(revision 9220)
@@ -5,6 +5,8 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import nl.jqno.equalsverifier.EqualsVerifier;
 
 import org.junit.Test;
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.OsmApi;
 
@@ -25,15 +27,14 @@
         assertNotNull(dev);
         assertNotEquals(def, dev);
+        Main.logLevel = 5; // enable trace for line coverage
         assertEquals(def, OAuthParameters.createDefault("wrong_url"));
     }
 
     /**
-     * Unit test of method {@link OAuthParameters#equals}.
+     * Unit test of methods {@link OAuthParameters#equals} and {@link OAuthParameters#hashCode}.
      */
     @Test
-    public void testEquals() {
-        OAuthParameters dev = OAuthParameters.createDefault("http://master.apis.dev.openstreetmap.org/api");
-        OAuthParameters dev2 = new OAuthParameters(dev);
-        assertEquals(dev, dev2);
+    public void equalsContract() {
+        EqualsVerifier.forClass(OAuthParameters.class).usingGetClass().verify();
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java	(revision 9219)
+++ trunk/test/unit/org/openstreetmap/josm/data/oauth/OAuthTokenTest.java	(revision 9220)
@@ -4,4 +4,5 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import nl.jqno.equalsverifier.EqualsVerifier;
 import oauth.signpost.OAuthConsumer;
 
@@ -27,13 +28,9 @@
 
     /**
-     * Unit test of method {@link OAuthToken#equals}.
+     * Unit test of methods {@link OAuthToken#equals} and {@link OAuthToken#hashCode}.
      */
     @Test
-    public void testEquals() {
-        OAuthToken tok = new OAuthToken(
-                OAuthParameters.DEFAULT_JOSM_CONSUMER_KEY,
-                OAuthParameters.DEFAULT_JOSM_CONSUMER_SECRET);
-        OAuthToken tok2 = new OAuthToken(tok);
-        assertEquals(tok, tok2);
+    public void equalsContract() {
+        EqualsVerifier.forClass(OAuthToken.class).usingGetClass().verify();
     }
 }
