Show login error in CredentialsDialog
diff --git a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/FixedCredentialsProvider.java b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/FixedCredentialsProvider.java
index 938f1ca..1d76cfa 100644
--- a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/FixedCredentialsProvider.java
+++ b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/FixedCredentialsProvider.java
@@ -28,7 +28,7 @@
   }
 
   @Override
-  public Credentials provideCredentials(IStorageService service)
+  public Credentials provideCredentials(IStorageService service, boolean reauthentication)
   {
     return credentials;
   }
diff --git a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/TestCredentialsProvider.java b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/TestCredentialsProvider.java
index 9bf6b36..ca94a2a 100644
--- a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/TestCredentialsProvider.java
+++ b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/util/TestCredentialsProvider.java
@@ -44,7 +44,7 @@
   }
 
   @Override
-  public Credentials provideCredentials(IStorageService service)
+  public Credentials provideCredentials(IStorageService service, boolean reauthentication)
   {
     if (CREDENTIALS_FILE.exists())
     {
diff --git a/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/CredentialsDialog.java b/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/CredentialsDialog.java
index 745ed95..7127edf 100644
--- a/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/CredentialsDialog.java
+++ b/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/CredentialsDialog.java
@@ -32,16 +32,19 @@
 {
   private final IStorageService service;
 
+  private final boolean reauthentication;
+
   private Credentials credentials;
 
   private CredentialsComposite credentialsComposite;
 
   private Button okButton;
 
-  public CredentialsDialog(Shell parentShell, IStorageService service)
+  public CredentialsDialog(Shell parentShell, IStorageService service, boolean reauthentication)
   {
     super(parentShell);
     this.service = service;
+    this.reauthentication = reauthentication;
   }
 
   public final IStorageService getService()
@@ -73,9 +76,16 @@
   protected Control createDialogArea(Composite parent)
   {
     setTitle("Log-In");
-    setMessage("Enter the log-in information for your " + service.getServiceLabel() + " account.");
-    initializeDialogUnits(parent);
+    if (reauthentication)
+    {
+      setErrorMessage("You could not be logged in to your " + service.getServiceLabel() + " account. Please try again.");
+    }
+    else
+    {
+      setMessage("Enter the log-in information for your " + service.getServiceLabel() + " account.");
+    }
 
+    initializeDialogUnits(parent);
     Composite area = (Composite)super.createDialogArea(parent);
 
     credentialsComposite = new CredentialsComposite(area, SWT.NONE, 10, 10, true)
diff --git a/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/internal/DialogCredentialsProvider.java b/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/internal/DialogCredentialsProvider.java
index 08266f7..a8b6740 100644
--- a/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/internal/DialogCredentialsProvider.java
+++ b/org.eclipse.userstorage.ui/src/org/eclipse/userstorage/ui/internal/DialogCredentialsProvider.java
@@ -25,7 +25,7 @@
   public static final DialogCredentialsProvider INSTANCE = new DialogCredentialsProvider();
 
   @Override
-  public Credentials provideCredentials(final IStorageService service)
+  public Credentials provideCredentials(final IStorageService service, final boolean reauthentication)
   {
     final Credentials[] credentials = { null };
 
@@ -37,7 +37,7 @@
         @Override
         public void run()
         {
-          CredentialsDialog dialog = new CredentialsDialog(shell, service);
+          CredentialsDialog dialog = new CredentialsDialog(shell, service, reauthentication);
           if (dialog.open() == CredentialsDialog.OK)
           {
             credentials[0] = dialog.getCredentials();
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Activator.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Activator.java
index f2f28fc..c942b3b 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Activator.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Activator.java
@@ -231,7 +231,7 @@
   private static final class CancelCredentialsProvider implements ICredentialsProvider
   {
     @Override
-    public Credentials provideCredentials(IStorageService service)
+    public Credentials provideCredentials(IStorageService service, boolean reauthentication)
     {
       return null;
     }
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
index cb04a55..bd37922 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
@@ -57,7 +57,7 @@
 
   public static final String NOT_FOUND_ETAG = "not_found";
 
-  private static final int AUTHORIZATION_ATTEMPTS = 3;
+  private static final int AUTHENTICATION_ATTEMPTS = 3;
 
   private static final boolean DEBUG = Boolean.getBoolean("org.eclipse.userstorage.session.debug");
 
@@ -359,7 +359,8 @@
 
     public final synchronized T send(ICredentialsProvider credentialsProvider) throws IOException
     {
-      int authorizationAttempts = AUTHORIZATION_ATTEMPTS;
+      int authenticationAttempts = AUTHENTICATION_ATTEMPTS;
+      boolean reauthentication = false;
 
       Credentials credentials = service.getCredentials();
       if (credentials != null)
@@ -370,7 +371,8 @@
         }
         else
         {
-          ++authorizationAttempts;
+          // The first attempt will be made with the stored credentials, so increase authenticationAttempts to 4 to prompt 3 times.
+          ++authenticationAttempts;
         }
       }
 
@@ -381,7 +383,7 @@
 
         try
         {
-          authenticate(credentials, credentialsProvider);
+          authenticate(credentials, credentialsProvider, reauthentication);
 
           Request request = prepareRequest();
           HttpResponse response = sendRequest(request, uri);
@@ -399,8 +401,9 @@
           if (ex instanceof ProtocolException)
           {
             ProtocolException protocolException = (ProtocolException)ex;
-            if (protocolException.getStatusCode() == AUTHORIZATION_REQUIRED && --authorizationAttempts > 0)
+            if (protocolException.getStatusCode() == AUTHORIZATION_REQUIRED && --authenticationAttempts > 0)
             {
+              reauthentication = true;
               continue;
             }
           }
@@ -417,7 +420,7 @@
       }
     }
 
-    protected final void authenticate(Credentials credentials, ICredentialsProvider credentialsProvider) throws IOException
+    protected final void authenticate(Credentials credentials, ICredentialsProvider credentialsProvider, boolean reauthentication) throws IOException
     {
       if (sessionID == null)
       {
@@ -428,7 +431,7 @@
 
         try
         {
-          credentials = getCredentials(credentials, credentialsProvider);
+          credentials = getCredentials(credentials, credentialsProvider, reauthentication);
 
           Map<String, Object> arguments = new LinkedHashMap<String, Object>();
           arguments.put("username", credentials.getUsername());
@@ -645,7 +648,8 @@
       return "HTTP";
     }
 
-    protected final Credentials getCredentials(Credentials credentials, ICredentialsProvider credentialsProvider) throws OperationCanceledException
+    protected final Credentials getCredentials(Credentials credentials, ICredentialsProvider credentialsProvider, boolean reauthentication)
+        throws OperationCanceledException
     {
       if (credentials == null)
       {
@@ -657,7 +661,7 @@
           {
             semaphore.acquire();
 
-            credentials = credentialsProvider.provideCredentials(service);
+            credentials = credentialsProvider.provideCredentials(service, reauthentication);
           }
           catch (InterruptedException ex)
           {
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/spi/ICredentialsProvider.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/spi/ICredentialsProvider.java
index 006b8de..f37380e 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/spi/ICredentialsProvider.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/spi/ICredentialsProvider.java
@@ -30,8 +30,9 @@
    * <p>
    *
    * @param service the storage service for which to provide the user's credentials, must not be <code>null</code>.<p>
+   * @param reauthentication <code>true</code> if this method has been called before (and returned wrong credentials), <code>false</code> if this call is the first.
    * @return the user's credentials for the given storage service,
    *         or <code>null</code> as an indication to cancel the authentication process.<p>
    */
-  public Credentials provideCredentials(IStorageService service);
+  public Credentials provideCredentials(IStorageService service, boolean reauthentication);
 }