Delete cache file after NotFoundException
diff --git a/org.eclipse.userstorage/src/org/eclipse/userstorage/IBlob.java b/org.eclipse.userstorage/src/org/eclipse/userstorage/IBlob.java
index baa5df0..e26e209 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/IBlob.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/IBlob.java
@@ -152,13 +152,13 @@
    * @return an {@link InputStream} that represents the current contents of this blob, never <code>null</code>.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
-   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    * @throws NotFoundException if this blob does not exist on the server.<p>
+   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #setContents(InputStream)
    * @see #getETag()
    */
-  public InputStream getContents() throws IOException, NoServiceException, IllegalStateException, NotFoundException;
+  public InputStream getContents() throws IOException, NoServiceException, NotFoundException, IllegalStateException;
 
   /**
    * Sets an {@link InputStream} that represents the new contents of this blob.
@@ -178,14 +178,14 @@
    * @param in an {@link InputStream} that represents the new contents of this blob.<p>
    * @return <code>true</code> if a new blob was created, <code>false</code> if an existing blob was updated.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
-   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
+   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #getContents()
    * @see #setETag(String)
    */
-  public boolean setContents(InputStream in) throws IOException, ConflictException, NoServiceException, IllegalStateException;
+  public boolean setContents(InputStream in) throws IOException, NoServiceException, ConflictException, IllegalStateException;
 
   /**
    * Returns a {@link String} that represents the current contents of this blob.
@@ -199,8 +199,8 @@
    * @return a {@link String} that represents the current contents of this blob, never <code>null</code>.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
-   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    * @throws NotFoundException if this blob does not exist on the server.<p>
+   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #getContents()
    */
@@ -216,13 +216,13 @@
    * @param value a {@link String} that represents the new contents of this blob.<p>
    * @return <code>true</code> if a new blob was created, <code>false</code> if an existing blob was updated.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
-   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
+   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #setContents(InputStream)
    */
-  public boolean setContentsUTF(String value) throws IOException, ConflictException, NoServiceException, IllegalStateException;
+  public boolean setContentsUTF(String value) throws IOException, NoServiceException, ConflictException, IllegalStateException;
 
   /**
    * Returns a primitive int value that represents the current contents of this blob.
@@ -236,12 +236,12 @@
    * @return a primitive int value that represents the current contents of this blob.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
-   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    * @throws NotFoundException if this blob does not exist on the server.<p>
+   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #getContents()
    */
-  public int getContentsInt() throws IOException, NumberFormatException, NoServiceException, IllegalStateException, NotFoundException;
+  public int getContentsInt() throws IOException, NoServiceException, NotFoundException, IllegalStateException, NumberFormatException;
 
   /**
    * Sets a a primitive int value that represents the new contents of this blob.
@@ -253,13 +253,13 @@
    * @param value a a primitive int value that represents the new contents of this blob.<p>
    * @return <code>true</code> if a new blob was created, <code>false</code> if an existing blob was updated.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
-   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
+   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #setContents(InputStream)
    */
-  public boolean setContentsInt(int value) throws IOException, ConflictException, NoServiceException, IllegalStateException;
+  public boolean setContentsInt(int value) throws IOException, NoServiceException, ConflictException, IllegalStateException;
 
   /**
    * Returns a primitive boolean value that represents the current contents of this blob.
@@ -273,12 +273,12 @@
    * @return a primitive boolean value that represents the current contents of this blob.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
-   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    * @throws NotFoundException if this blob does not exist on the server.<p>
+   * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #getContents()
    */
-  public boolean getContentsBoolean() throws IOException, NoServiceException, IllegalStateException, NotFoundException;
+  public boolean getContentsBoolean() throws IOException, NoServiceException, NotFoundException, IllegalStateException;
 
   /**
    * Sets a a primitive boolean value that represents the new contents of this blob.
@@ -290,13 +290,13 @@
    * @param value a a primitive boolean value that represents the new contents of this blob.<p>
    * @return <code>true</code> if a new blob was created, <code>false</code> if an existing blob was updated.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
-   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
+   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #setContents(InputStream)
    */
-  public boolean setContentsBoolean(boolean value) throws IOException, ConflictException, NoServiceException, IllegalStateException;
+  public boolean setContentsBoolean(boolean value) throws IOException, NoServiceException, ConflictException, IllegalStateException;
 
   /**
    * Deletes this blob.
@@ -315,13 +315,13 @@
    *
    * @return <code>true</code> if this blob was successfully deleted from the server, <code>false</code> if it did not exist.<p>
    * @throws IOException if remote I/O was unsuccessful. A {@link ProtocolException} may contain more information about protocol-specific problems.<p>
-   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws NoServiceException if the {@link #getStorage() storage} of this blob has no {@link IStorageService service} assigned.<p>
+   * @throws ConflictException if the server detected a conflict and did not update the blob.<p>
    * @throws IllegalStateException if this blob is {@link #isDisposed() disposed}.<p>
    *
    * @see #setETag(String)
    */
-  public boolean delete() throws IOException, ConflictException, NoServiceException, IllegalStateException;
+  public boolean delete() throws IOException, NoServiceException, ConflictException, IllegalStateException;
 
   /**
    * Returns <code>true</code> if this blob is disposed, <code>false</code> otherwise.
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 eed0bf7..3d9d831 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Session.java
@@ -207,7 +207,7 @@
         }
 
         // Blob wasn't found.
-        properties.remove(Blob.ETAG);
+        properties.clear();
 
         StatusLine statusLine = response.getStatusLine();
         throw new NotFoundException("GET", uri, getProtocolVersion(statusLine), statusLine.getReasonPhrase());
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 dd41863..81a736b 100644
--- a/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java
+++ b/org.eclipse.userstorage/src/org/eclipse/userstorage/internal/Storage.java
@@ -377,25 +377,28 @@
           return cacheStreamResult;
         }
 
-        if (contents == null)
-        {
-          cache.internalDelete(applicationToken, key);
-          return null;
-        }
-
         OutputStream output = cache.internalGetOutputStream(applicationToken, key, properties);
         return new TeeInputStream(contents, output);
       }
 
       return contents;
     }
+    catch (NotFoundException ex)
+    {
+      if (cache != null)
+      {
+        cache.internalDelete(applicationToken, key);
+      }
+
+      throw ex;
+    }
     finally
     {
       IOUtil.closeSilent(cacheStream);
     }
   }
 
-  public boolean updateBlob(String key, Map<String, String> properties, InputStream in) throws IOException, ConflictException, NoServiceException
+  public boolean updateBlob(String key, Map<String, String> properties, InputStream in) throws IOException, NoServiceException, ConflictException
   {
     StorageService service = getServiceSafe();
 
@@ -431,7 +434,7 @@
     return created;
   }
 
-  public boolean deleteBlob(String key, Map<String, String> properties) throws IOException, ConflictException, NoServiceException
+  public boolean deleteBlob(String key, Map<String, String> properties) throws IOException, NoServiceException, ConflictException
   {
     StorageService service = getServiceSafe();
     boolean deleted = service.deleteBlob(credentialsProvider, applicationToken, key, properties);
@@ -481,7 +484,7 @@
     }
   }
 
-  private StorageService getServiceSafe()
+  private StorageService getServiceSafe() throws NoServiceException
   {
     StorageService service = getService();
     if (service != null)