Keep up with various spec/service changes
diff --git a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/StorageTests.java b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/StorageTests.java
index bfb7324..ca6bf68 100644
--- a/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/StorageTests.java
+++ b/org.eclipse.userstorage.tests/src/org/eclipse/userstorage/tests/StorageTests.java
@@ -40,9 +40,7 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
-import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -777,38 +775,7 @@
     IStorage storage = factory.create(APPLICATION_TOKEN);
     assertThat(storage.getBlob(makeKey()).setContentsUTF("A short UTF-8 string value"), is(true));
 
-    int xxx;
-    // for (IBlob blob : storage.getBlobs())
-    // {
-    // System.out.println(blob);
-    // blob.delete();
-    // }
-
-    boolean deleted = false;
-
-    for (;;)
-    {
-      try
-      {
-        int page = 0;
-        List<IBlob> blobs = Collections.emptyList();
-        while (blobs.isEmpty())
-        {
-          blobs = storage.getBlobs(100, ++page);
-        }
-
-        for (IBlob blob : blobs)
-        {
-          blob.delete();
-          deleted = true;
-        }
-      }
-      catch (NotFoundException ex)
-      {
-        break;
-      }
-    }
-
+    boolean deleted = storage.deleteAllBlobs();
     assertThat(deleted, is(true));
     assertThat(storage.getBlobs().iterator().hasNext(), is(false));
   }
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/IStorage.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/IStorage.java
index ff3ef5e..fba3799 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/IStorage.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/IStorage.java
@@ -171,6 +171,18 @@
   public IBlob getBlob(String key) throws BadKeyException;
 
   /**
+   * Deletes <b>all</b> blobs that this storage maintains for the logged-in user.
+   * <p>
+   * The blobs of other storages/applications are not affected by this call.
+   * <p>
+   *
+   * @return <code>true</code> if at least one blob was successfully deleted from the server, <code>false</code> if no blob existed.<p>
+   * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
+   * @throws NoServiceException if this storage has no {@link IStorageService service} assigned.<p>
+   */
+  public boolean deleteAllBlobs() throws IOException, NoServiceException;
+
+  /**
    * Adds the given listener to the list of listeners that are notified about {@link IStorageService service} changes.
    *
    * @param listener the listener to add to the list of listeners that are notified about service changes.
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 a03e024..4991592 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
@@ -32,7 +32,6 @@
 import org.apache.http.client.fluent.Executor;
 import org.apache.http.client.fluent.Request;
 import org.apache.http.client.fluent.Response;
-import org.apache.http.conn.HttpClientConnectionManager;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -44,7 +43,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author Eike Stepper
@@ -125,29 +123,28 @@
       @Override
       protected Map<String, Map<String, Object>> handleResponse(HttpResponse response, HttpEntity responseEntity) throws IOException
       {
-        int statusCode = getStatusCode("GET", uri, response, OK, REQUESTED_RANGE_NOT_SATISFIABLE);
-        if (statusCode == REQUESTED_RANGE_NOT_SATISFIABLE)
-        {
-          StatusLine statusLine = response.getStatusLine();
-          throw new NotFoundException("GET", uri, getProtocolVersion(statusLine), statusLine.getReasonPhrase());
-        }
+        getStatusCode("GET", uri, response, OK);
+        List<Object> array = JSONUtil.parse(responseEntity.getContent(), null);
 
         Map<String, Map<String, Object>> result = new HashMap<String, Map<String, Object>>();
 
-        List<Object> array = JSONUtil.parse(responseEntity.getContent(), null);
         for (Object element : array)
         {
           @SuppressWarnings("unchecked")
           Map<String, Object> map = (Map<String, Object>)element;
 
           Object appToken = map.remove("application_token");
-          if (applicationToken.equals(appToken))
+          if (!applicationToken.equals(appToken))
           {
-            map.remove("url");
-
-            String key = (String)map.remove("key");
-            result.put(key, map);
+            StatusLine statusLine = response.getStatusLine();
+            String protocolVersion = statusLine == null ? "HTTP" : getProtocolVersion(statusLine);
+            throw new ProtocolException("GET", uri, protocolVersion, BAD_RESPONSE, "Bad Response : Wrong application token: " + appToken);
           }
+
+          map.remove("url");
+
+          String key = (String)map.remove("key");
+          result.put(key, map);
         }
 
         return result;
@@ -307,28 +304,6 @@
       }
     }.send(credentialsProvider);
 
-    int xxx; // Work around bug 483709.
-    if (uri.toString().contains(".eclipse.org/"))
-    {
-      try
-      {
-        Field connmgrField = Executor.class.getDeclaredField("CONNMGR");
-        connmgrField.setAccessible(true);
-
-        HttpClientConnectionManager connectionManager = (HttpClientConnectionManager)connmgrField.get(null);
-        connectionManager.closeIdleConnections(0, TimeUnit.MILLISECONDS);
-        connectionManager.closeExpiredConnections();
-      }
-      catch (Throwable ex)
-      {
-        ex.printStackTrace();
-        //$FALL-THROUGH$
-      }
-
-      sessionID = null;
-      csrfToken = null;
-    }
-
     return deleted;
   }
 
@@ -749,7 +724,5 @@
 
   public static final int CONFLICT = 409;
 
-  public static final int REQUESTED_RANGE_NOT_SATISFIABLE = 422; // TODO This should become 416!!!
-
   public static final int BAD_RESPONSE = 444;
 }
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java
index 34289b3..f4bffcf 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java
@@ -34,7 +34,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.WeakHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -45,6 +44,8 @@
 {
   private static final String DEFAULT_APPLICATION_TOKEN = "<default>";
 
+  private static final int CHUNK_SIZE = 100;
+
   private final List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
 
   private final String applicationToken;
@@ -169,6 +170,8 @@
         {
           private int page;
 
+          private boolean lastChunk;
+
           private boolean endReached;
 
           private Iterator<IBlob> chunk;
@@ -190,14 +193,29 @@
                 throw exception;
               }
 
-              if (chunk != null && chunk.hasNext())
+              if (chunk != null)
               {
-                return true;
+                if (chunk.hasNext())
+                {
+                  return true;
+                }
+
+                if (lastChunk)
+                {
+                  endReached = true;
+                  return false;
+                }
               }
 
               try
               {
-                chunk = getBlobs(100, ++page).iterator();
+                List<IBlob> blobs = getBlobs(CHUNK_SIZE, ++page);
+                if (blobs.size() < CHUNK_SIZE)
+                {
+                  lastChunk = true;
+                }
+
+                chunk = blobs.iterator();
               }
               catch (NotFoundException ex)
               {
@@ -215,16 +233,7 @@
           @Override
           public IBlob next()
           {
-            if (exception != null)
-            {
-              throw exception;
-            }
-
-            if (chunk == null)
-            {
-              throw new NoSuchElementException();
-            }
-
+            hasNext();
             return chunk.next();
           }
 
@@ -420,6 +429,29 @@
   }
 
   @Override
+  public boolean deleteAllBlobs() throws IOException, NoServiceException
+  {
+    boolean deleted = false;
+
+    for (;;)
+    {
+      List<IBlob> blobs = getBlobs(100, 1);
+      if (blobs.isEmpty())
+      {
+        break;
+      }
+
+      for (IBlob blob : blobs)
+      {
+        blob.delete();
+        deleted = true;
+      }
+    }
+
+    return deleted;
+  }
+
+  @Override
   public String toString()
   {
     return service + " (" + applicationToken + ")";