Bug 1021843 - Migrate NNTP and IMAP to cache2. r=mkmelin
authorJorg K <jorgk@jorgk.com>
Tue, 30 Aug 2016 23:05:21 +0200
changeset 19958 c679c89e86ba8617f840c9defa89a304a17f86ce
parent 19957 8c7ddccf95c4168995fa6e57182133f22d21be03
child 19959 e5fd1b18853f50d5340a585cc86364d602eb9499
push id12239
push usermozilla@jorgk.com
push dateTue, 30 Aug 2016 21:22:19 +0000
treeherdercomm-central@c679c89e86ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1021843
Bug 1021843 - Migrate NNTP and IMAP to cache2. r=mkmelin
mail/app/profile/all-thunderbird.js
mailnews/base/public/nsIMsgMailNewsUrl.idl
mailnews/base/public/nsIMsgMessageService.idl
mailnews/base/src/MailnewsLoadContextInfo.cpp
mailnews/base/src/MailnewsLoadContextInfo.h
mailnews/base/src/moz.build
mailnews/base/util/nsMsgMailNewsUrl.cpp
mailnews/base/util/nsMsgMailNewsUrl.h
mailnews/imap/public/nsIImapService.idl
mailnews/imap/src/nsImapIncomingServer.cpp
mailnews/imap/src/nsImapMailFolder.cpp
mailnews/imap/src/nsImapProtocol.cpp
mailnews/imap/src/nsImapProtocol.h
mailnews/imap/src/nsImapService.cpp
mailnews/imap/src/nsImapService.h
mailnews/imap/src/nsImapUrl.cpp
mailnews/local/src/nsMailboxService.cpp
mailnews/news/public/nsINntpService.idl
mailnews/news/src/nsNNTPProtocol.cpp
mailnews/news/src/nsNNTPProtocol.h
mailnews/news/src/nsNntpService.cpp
mailnews/news/src/nsNntpService.h
mailnews/news/test/unit/test_bug540288.js
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -854,14 +854,10 @@ pref("mail.pgpmime.addon_url", "https://
 // If set to true, Thunderbird will collapse the main menu for new profiles
 // (or, more precisely, profiles that start with no accounts created).
 pref("mail.main_menu.collapse_by_default", true);
 
 // If set to true, when saving a message to a file, use underscore
 // instead of space in the file name.
 pref("mail.save_msg_filename_underscores_for_space", false);
 
-// Disable cache v2 since migration has not been done, it is pending in bug 1021843.
-pref("browser.cache.use_new_backend",       0);
-pref("browser.cache.use_new_backend_temp",  false);
-
 // calendar promotion status
 pref("mail.calendar-integration.opt-out", false);
--- a/mailnews/base/public/nsIMsgMailNewsUrl.idl
+++ b/mailnews/base/public/nsIMsgMailNewsUrl.idl
@@ -8,17 +8,17 @@
 
 interface nsIFile;
 interface nsIUrlListener;
 interface nsIMsgStatusFeedback;
 interface nsIMsgIncomingServer;
 interface nsIMsgWindow;
 interface nsILoadGroup;
 interface nsIMsgSearchSession;
-interface nsICacheEntryDescriptor;
+interface nsICacheEntry;
 interface nsIMimeHeaders;
 interface nsIStreamListener;
 interface nsIMsgFolder;
 interface nsIMsgHeaderSink;
 interface nsIMsgDBHdr;
 interface nsIDocShellLoadInfo;
 interface nsIDocShell; 
 
@@ -94,17 +94,17 @@ interface nsIMsgMailNewsUrl : nsIURL {
   readonly attribute nsILoadGroup loadGroup;
 
   // search session, if we're running a search.
   attribute nsIMsgSearchSession searchSession;
   attribute boolean updatingFolder;
   attribute boolean msgIsInLocalCache;
   attribute boolean suppressErrorMsgs; // used to avoid displaying biff error messages
 
-  attribute nsICacheEntryDescriptor memCacheEntry;
+  attribute nsICacheEntry memCacheEntry;
 
   const unsigned long eCopy     = 0;
   const unsigned long eMove     = 1;
   const unsigned long eDisplay  = 2;
   boolean IsUrlType(in unsigned long type);
   nsIStreamListener getSaveAsListener(in boolean addDummyEnvelope, in nsIFile aFile);
 
   // typically the header sink is tied to the nsIMsgWindow, but in certain circumstances, a consumer
--- a/mailnews/base/public/nsIMsgMessageService.idl
+++ b/mailnews/base/public/nsIMsgMessageService.idl
@@ -9,17 +9,17 @@ interface nsIURI;
 interface nsIUrlListener;
 interface nsIStreamListener;
 interface nsIMsgWindow;
 interface nsIFile;
 interface nsIMsgFolder;
 interface nsIMsgSearchSession;
 interface nsIMsgDBHdr;
 interface nsIStreamConverter;
-interface nsICacheEntryDescriptor;
+interface nsICacheEntry;
 
 %{C++
 #include "MailNewsTypes.h"
 %}
 
 [scriptable, uuid(3aa7080a-73ac-4394-9636-fc00e182319b)]
 interface nsIMsgMessageService : nsISupports {
      
@@ -210,23 +210,21 @@ interface nsIMsgMessageService : nsISupp
                        [optional] in boolean aLocalOnly);
 
   /**
    * Determines whether a message is in the memory cache. Local folders
    * don't implement this.
    *
    * @param aUrl The URL of the message, possibly with an appropriate command in it
    * @param aFolder The folder this message is in
-   * @param aCacheEntry If a cache entry is found, then a pointer to it
    * 
    * @return TRUE if the message is in mem cache; FALSE if it is not.
    */
   boolean isMsgInMemCache(in nsIURI aUrl,
-                          in nsIMsgFolder aFolder,
-                          out nsICacheEntryDescriptor aCacheEntry);
+                          in nsIMsgFolder aFolder);
 
   /**
    * now the the message datasource is going away
    * we need away to go from message uri to go nsIMsgDBHdr
    *
    * @param uri A message uri to get nsIMsgDBHdr for.
    *
    * @return nsIMsgDBHdr for specified uri or null if failed. 
new file mode 100644
--- /dev/null
+++ b/mailnews/base/src/MailnewsLoadContextInfo.cpp
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This was copied from netwerk/base/LoadContextInfo.cpp
+
+#include "MailnewsLoadContextInfo.h"
+
+#include "mozilla/dom/ToJSValue.h"
+#include "nsIChannel.h"
+#include "nsILoadContext.h"
+#include "nsIWebNavigation.h"
+#include "nsNetUtil.h"
+
+// MailnewsLoadContextInfo
+
+NS_IMPL_ISUPPORTS(MailnewsLoadContextInfo, nsILoadContextInfo)
+
+MailnewsLoadContextInfo::MailnewsLoadContextInfo(bool aIsPrivate, bool aIsAnonymous, mozilla::NeckoOriginAttributes aOriginAttributes)
+  : mIsPrivate(aIsPrivate)
+  , mIsAnonymous(aIsAnonymous)
+  , mOriginAttributes(aOriginAttributes)
+{
+  mOriginAttributes.SyncAttributesWithPrivateBrowsing(mIsPrivate);
+}
+
+MailnewsLoadContextInfo::~MailnewsLoadContextInfo()
+{
+}
+
+NS_IMETHODIMP MailnewsLoadContextInfo::GetIsPrivate(bool *aIsPrivate)
+{
+  *aIsPrivate = mIsPrivate;
+  return NS_OK;
+}
+
+NS_IMETHODIMP MailnewsLoadContextInfo::GetIsAnonymous(bool *aIsAnonymous)
+{
+  *aIsAnonymous = mIsAnonymous;
+  return NS_OK;
+}
+
+mozilla::NeckoOriginAttributes const* MailnewsLoadContextInfo::OriginAttributesPtr()
+{
+  return &mOriginAttributes;
+}
+
+NS_IMETHODIMP MailnewsLoadContextInfo::GetOriginAttributes(JSContext *aCx,
+                                                   JS::MutableHandle<JS::Value> aVal)
+{
+  if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/base/src/MailnewsLoadContextInfo.h
@@ -0,0 +1,32 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This was copied from netwerk/base/LoadContextInfo.h
+
+#ifndef MailnewsLoadContextInfo_h__
+#define MailnewsLoadContextInfo_h__
+
+#include "nsILoadContextInfo.h"
+
+class nsIChannel;
+class nsILoadContext;
+
+class MailnewsLoadContextInfo : public nsILoadContextInfo
+{
+public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_NSILOADCONTEXTINFO
+
+  MailnewsLoadContextInfo(bool aIsPrivate, bool aIsAnonymous, mozilla::NeckoOriginAttributes aOriginAttributes);
+
+private:
+  virtual ~MailnewsLoadContextInfo();
+
+protected:
+  bool mIsPrivate : 1;
+  bool mIsAnonymous : 1;
+  mozilla::NeckoOriginAttributes mOriginAttributes;
+};
+
+#endif
--- a/mailnews/base/src/moz.build
+++ b/mailnews/base/src/moz.build
@@ -6,16 +6,17 @@
 EXPORTS += [
     'nsMailDirServiceDefs.h',
     'nsMsgRDFDataSource.h',
     'nsMsgRDFUtils.h',
 ]
 
 SOURCES += [
     'MailNewsDLF.cpp',
+    'MailnewsLoadContextInfo.cpp',
     'nsCidProtocolHandler.cpp',
     'nsCopyMessageStreamListener.cpp',
     'nsMailDirProvider.cpp',
     'nsMessenger.cpp',
     'nsMessengerBootstrap.cpp',
     'nsMessengerContentHandler.cpp',
     'nsMsgAccount.cpp',
     'nsMsgAccountManager.cpp',
--- a/mailnews/base/util/nsMsgMailNewsUrl.cpp
+++ b/mailnews/base/util/nsMsgMailNewsUrl.cpp
@@ -681,23 +681,23 @@ NS_IMETHODIMP nsMsgMailNewsUrl::GetCommo
   return m_baseURL->GetCommonBaseSpec(uri2, result);
 }
 
 NS_IMETHODIMP nsMsgMailNewsUrl::GetRelativeSpec(nsIURI *uri2, nsACString &result)
 {
   return m_baseURL->GetRelativeSpec(uri2, result);
 }
 
-NS_IMETHODIMP nsMsgMailNewsUrl::SetMemCacheEntry(nsICacheEntryDescriptor *memCacheEntry)
+NS_IMETHODIMP nsMsgMailNewsUrl::SetMemCacheEntry(nsICacheEntry *memCacheEntry)
 {
   m_memCacheEntry = memCacheEntry;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsMsgMailNewsUrl:: GetMemCacheEntry(nsICacheEntryDescriptor **memCacheEntry)
+NS_IMETHODIMP nsMsgMailNewsUrl::GetMemCacheEntry(nsICacheEntry **memCacheEntry)
 {
   NS_ENSURE_ARG(memCacheEntry);
   nsresult rv = NS_OK;
 
   if (m_memCacheEntry)
   {
     *memCacheEntry = m_memCacheEntry;
     NS_ADDREF(*memCacheEntry);
--- a/mailnews/base/util/nsMsgMailNewsUrl.h
+++ b/mailnews/base/util/nsMsgMailNewsUrl.h
@@ -14,17 +14,17 @@
 #include "nsIMsgStatusFeedback.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
 #include "nsIMimeHeaders.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsIURL.h"
 #include "nsILoadGroup.h"
 #include "nsIMsgSearchSession.h"
-#include "nsICacheEntryDescriptor.h"
+#include "nsICacheEntry.h"
 #include "nsICacheSession.h"
 #include "nsIMimeMiscStatus.h"
 #include "nsWeakReference.h"
 #include "nsStringGlue.h"
 
 ///////////////////////////////////////////////////////////////////////////////////
 // Okay, I found that all of the mail and news url interfaces needed to support
 // several common interfaces (in addition to those provided through nsIURI). 
@@ -50,17 +50,17 @@ protected:
   virtual ~nsMsgMailNewsUrl();
 
   nsCOMPtr<nsIURL> m_baseURL;
   nsWeakPtr m_statusFeedbackWeak;
   nsWeakPtr m_msgWindowWeak;
   nsWeakPtr m_loadGroupWeak;
   nsCOMPtr<nsIMimeHeaders> mMimeHeaders;
   nsCOMPtr<nsIMsgSearchSession> m_searchSession;
-  nsCOMPtr<nsICacheEntryDescriptor> m_memCacheEntry;
+  nsCOMPtr<nsICacheEntry> m_memCacheEntry;
   nsCOMPtr<nsIMsgHeaderSink> mMsgHeaderSink;
   char *m_errorMessage;
   int64_t mMaxProgress;
   bool m_runningUrl;
   bool m_updatingFolder;
   bool m_msgIsInLocalCache;
   bool m_suppressErrorMsgs;
 
--- a/mailnews/imap/public/nsIImapService.idl
+++ b/mailnews/imap/public/nsIImapService.idl
@@ -17,17 +17,17 @@
 
 interface nsIImapMessageSink;
 interface nsIUrlListener;
 interface nsIURI;
 interface nsIFile;
 interface nsIMsgFolder;
 interface nsIMsgWindow;
 interface nsIImapIncomingServer;
-interface nsICacheSession;
+interface nsICacheStorage;
 
 [scriptable, uuid(aba44b3d-7a0f-4987-8794-96d2de66d966)]
 interface nsIImapService : nsISupports
 {
   // You can pass in null for the url listener and the url if you don't require either.....
   void selectFolder(in nsIMsgFolder aImapMailFolder,
                     in nsIUrlListener aUrlListener,
                     in nsIMsgWindow   aMsgWindow,
@@ -249,10 +249,10 @@ interface nsIImapService : nsISupports
                              in ACString aMessageIdentifierList);
 
   void getListOfFoldersOnServer(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow);
   void getListOfFoldersWithPath(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow, in ACString folderPath);
 
   nsISupports playbackAllOfflineOperations(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
   void downloadAllOffineImapFolders(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
 
-  readonly attribute nsICacheSession cacheSession;
+  readonly attribute nsICacheStorage cacheStorage;
 };
--- a/mailnews/imap/src/nsImapIncomingServer.cpp
+++ b/mailnews/imap/src/nsImapIncomingServer.cpp
@@ -27,17 +27,17 @@
 #include "nsImapUtils.h"
 #include "nsIRDFService.h"
 #include "nsRDFCID.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsIImapService.h"
 #include "nsMsgI18N.h"
 #include "nsIImapMockChannel.h"
 // for the memory cache...
-#include "nsICacheEntryDescriptor.h"
+#include "nsICacheEntry.h"
 #include "nsImapUrl.h"
 #include "nsIMsgProtocolInfo.h"
 #include "nsIMsgMailSession.h"
 #include "nsIMAPNamespace.h"
 #include "nsArrayUtils.h"
 #include "nsITimer.h"
 #include "nsMsgUtils.h"
 #include "nsServiceManagerUtils.h"
@@ -643,20 +643,20 @@ nsresult nsImapIncomingServer::DoomUrlIf
         nsresult res;
         *urlDoomed = true;
         nsImapProtocol::LogImapUrl("dooming url", aImapUrl);
 
         mockChannel->Close(); // try closing it to get channel listener nulled out.
 
         if (aMailNewsUrl)
         {
-          nsCOMPtr<nsICacheEntryDescriptor>  cacheEntry;
+          nsCOMPtr<nsICacheEntry> cacheEntry;
           res = aMailNewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
           if (NS_SUCCEEDED(res) && cacheEntry)
-            cacheEntry->Doom();
+            cacheEntry->AsyncDoom(nullptr);
           // we're aborting this url - tell listeners
           aMailNewsUrl->SetUrlState(false, NS_MSG_ERROR_URL_ABORTED);
         }
       }
     }
   }
   return rv;
 }
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -69,17 +69,17 @@
 #include "nsIMimeHeaders.h"
 #include "nsIMsgMdnGenerator.h"
 #include "nsISpamSettings.h"
 #include <time.h>
 #include "nsIMsgMailNewsUrl.h"
 #include "nsEmbedCID.h"
 #include "nsIMsgComposeService.h"
 #include "nsMsgCompCID.h"
-#include "nsICacheEntryDescriptor.h"
+#include "nsICacheEntry.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIMsgIdentity.h"
 #include "nsIMsgFolderNotificationService.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsIExternalProtocolService.h"
 #include "nsCExternalHandlerService.h"
 #include "prprf.h"
 #include "nsIMutableArray.h"
@@ -9345,49 +9345,31 @@ NS_IMETHODIMP nsImapMailFolder::FetchMsg
     nsCOMPtr <nsIURI> url;
     nsCOMPtr<nsIInputStream> inputStream;
     nsCString messageUri;
     rv = GetUriForMsg(msgHdr, messageUri);
     NS_ENSURE_SUCCESS(rv,rv);
     rv = msgService->GetUrlForUri(messageUri.get(), getter_AddRefs(url), nullptr);
     NS_ENSURE_SUCCESS(rv,rv);
 
-    nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
-    bool msgInMemCache = false;
-    rv = msgService->IsMsgInMemCache(url, this, getter_AddRefs(cacheEntry), &msgInMemCache);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (msgInMemCache)
-    {
-      rv = cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-      if (NS_SUCCEEDED(rv))
-      {
-        uint64_t bytesAvailable = 0;
-        rv = inputStream->Available(&bytesAvailable);
-        if (!bytesAvailable)
-          continue;
+    // Lets look in the offline store.
+    uint32_t msgFlags;
+    msgHdr->GetFlags(&msgFlags);
+    nsMsgKey msgKey;
+    msgHdr->GetMessageKey(&msgKey);
+    if (msgFlags & nsMsgMessageFlags::Offline)
+    {
+      int64_t messageOffset;
+      uint32_t messageSize;
+      GetOfflineFileStream(msgKey, &messageOffset, &messageSize, getter_AddRefs(inputStream));
+      if (inputStream)
         rv = GetMsgPreviewTextFromStream(msgHdr, inputStream);
-      }
-    }
-    else // lets look in the offline store
-    {
-      uint32_t msgFlags;
-      msgHdr->GetFlags(&msgFlags);
-      nsMsgKey msgKey;
-      msgHdr->GetMessageKey(&msgKey);
-      if (msgFlags & nsMsgMessageFlags::Offline)
-      {
-        int64_t messageOffset;
-        uint32_t messageSize;
-        GetOfflineFileStream(msgKey, &messageOffset, &messageSize, getter_AddRefs(inputStream));
-        if (inputStream)
-          rv = GetMsgPreviewTextFromStream(msgHdr, inputStream);
-      }
-      else if (!aLocalOnly)
-        keysToFetchFromServer.AppendElement(msgKey);
+    }
+    else if (!aLocalOnly) {
+      keysToFetchFromServer.AppendElement(msgKey);
     }
   }
   if (!keysToFetchFromServer.IsEmpty())
   {
     uint32_t msgCount = keysToFetchFromServer.Length();
     nsAutoCString messageIds;
     AllocateImapUidString(keysToFetchFromServer.Elements(), msgCount,
                          nullptr, messageIds);
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -35,18 +35,20 @@
 #include "nsMsgMessageFlags.h"
 #include "nsImapStringBundle.h"
 #include "nsICopyMsgStreamListener.h"
 #include "nsTextFormatter.h"
 #include "nsIMsgHdr.h"
 #include "nsMsgI18N.h"
 #include <algorithm>
 // for the memory cache...
-#include "nsICacheEntryDescriptor.h"
-#include "nsICacheSession.h"
+#include "nsICacheEntry.h"
+#include "nsICacheStorage.h"
+#include "nsICacheEntryOpenCallback.h"
+
 #include "nsIPrompt.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellLoadInfo.h"
 #include "nsILoadInfo.h"
 #include "nsIMessengerWindowService.h"
 #include "nsIWindowMediator.h"
 #include "nsIWindowWatcher.h"
 #include "nsCOMPtr.h"
@@ -933,17 +935,17 @@ nsresult nsImapProtocol::SetupWithUrl(ns
         m_transport->SetEventSink(sink, thread);
       }
 
       // and if we have a cache entry that we are saving the message to, set the security info on it too.
       // since imap only uses the memory cache, passing this on is the right thing to do.
       nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
       if (mailnewsUrl)
       {
-        nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
+        nsCOMPtr<nsICacheEntry> cacheEntry;
         mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
         if (cacheEntry)
           cacheEntry->SetSecurityInfo(securityInfo);
       }
     }
   } // if aUR
 
   return rv;
@@ -1527,20 +1529,20 @@ void nsImapProtocol::EstablishServerConn
 // the memory cache.
 static void DoomCacheEntry(nsIMsgMailNewsUrl *url)
 {
   bool readingFromMemCache = false;
   nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(url);
   imapUrl->GetMsgLoadingFromCache(&readingFromMemCache);
   if (!readingFromMemCache)
   {
-    nsCOMPtr<nsICacheEntryDescriptor>  cacheEntry;
+    nsCOMPtr<nsICacheEntry> cacheEntry;
     url->GetMemCacheEntry(getter_AddRefs(cacheEntry));
     if (cacheEntry)
-      cacheEntry->Doom();
+      cacheEntry->AsyncDoom(nullptr);
   }
 }
 
 // returns true if another url was run, false otherwise.
 bool nsImapProtocol::ProcessCurrentURL()
 {
   nsresult rv = NS_OK;
   if (m_idle)
@@ -8730,17 +8732,17 @@ nsImapCacheStreamListener::OnStopRequest
 
 NS_IMETHODIMP
 nsImapCacheStreamListener::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt, nsIInputStream * aInStream, uint64_t aSourceOffset, uint32_t aCount)
 {
   return mListener->OnDataAvailable(mChannelToUse, aCtxt, aInStream, aSourceOffset, aCount);
 }
 
 NS_IMPL_ISUPPORTS(nsImapMockChannel, nsIImapMockChannel, nsIChannel,
-  nsIRequest, nsICacheListener, nsITransportEventSink, nsISupportsWeakReference)
+  nsIRequest, nsICacheEntryOpenCallback, nsITransportEventSink, nsISupportsWeakReference)
 
 
 nsImapMockChannel::nsImapMockChannel()
 {
   m_channelContext = nullptr;
   m_cancelStatus = NS_OK;
   mLoadFlags = 0;
   mChannelClosed = false;
@@ -8786,17 +8788,17 @@ NS_IMETHODIMP nsImapMockChannel::Close()
 {
   if (mReadingFromCache)
     NotifyStartEndReadFromCache(false);
   else
   {
     nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
     if (mailnewsUrl)
     {
-      nsCOMPtr<nsICacheEntryDescriptor>  cacheEntry;
+      nsCOMPtr<nsICacheEntry> cacheEntry;
       mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
       if (cacheEntry)
         cacheEntry->MarkValid();
       // remove the channel from the load group
       nsCOMPtr <nsILoadGroup> loadGroup;
       GetLoadGroup(getter_AddRefs(loadGroup));
       // if the mock channel wasn't initialized with a load group then
       // use our load group (they may differ)
@@ -8963,53 +8965,48 @@ NS_IMETHODIMP nsImapMockChannel::Open2(n
 {
   nsCOMPtr<nsIStreamListener> listener;
   nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
   NS_ENSURE_SUCCESS(rv, rv);
   return Open(_retval);
 }
 
 NS_IMETHODIMP
-nsImapMockChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAccessMode access, nsresult status)
+nsImapMockChannel::OnCacheEntryAvailable(nsICacheEntry *entry, bool aNew, nsIApplicationCache* aAppCache, nsresult status)
 {
   nsresult rv = NS_OK;
 
   // make sure we didn't close the channel before the async call back came in...
   // hmmm....if we had write access and we canceled this mock channel then I wonder if we should
   // be invalidating the cache entry before kicking out...
   if (mChannelClosed)
   {
-    entry->Doom();
+    entry->AsyncDoom(nullptr);
     return NS_OK;
   }
 
   NS_ENSURE_ARG(m_url); // kick out if m_url is null for some reason.
 
-#ifdef DEBUG_bienvenu
-      nsAutoCString entryKey("null");
-      if (entry)
-        entry->GetKey(entryKey);
-      printf("*** OnCacheEntryAvailable %s with access %d status %u\n", entryKey.get(), access, status);
-#endif
   if (NS_SUCCEEDED(status))
   {
     nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
     mailnewsUrl->SetMemCacheEntry(entry);
 
-    if (mTryingToReadPart && access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
-    {
-      entry->Doom();
+    if (mTryingToReadPart && aNew)
+    {
+      entry->AsyncDoom(nullptr);
       // whoops, we're looking for a part, but didn't find it. Fall back to fetching the whole msg.
       nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
       SetupPartExtractorListener(imapUrl, m_channelListener);
       return OpenCacheEntry();
     }
+
     // if we have write access then insert a "stream T" into the flow so data
     // gets written to both
-    if (access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
+    if (aNew)
     {
       // use a stream listener Tee to force data into the cache and to our current channel listener...
       nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID, &rv);
       if (NS_SUCCEEDED(rv))
       {
         nsCOMPtr<nsIOutputStream> out;
         // this will fail with the mem cache turned off, so we need to fall through
         // to ReadFromImapConnection instead of aborting with NS_ENSURE_SUCCESS(rv,rv)
@@ -9024,110 +9021,116 @@ nsImapMockChannel::OnCacheEntryAvailable
       }
     }
     else
     {
       rv = ReadFromMemCache(entry);
       if (NS_SUCCEEDED(rv))
       {
         NotifyStartEndReadFromCache(true);
-        if (access & nsICache::ACCESS_WRITE)
-          entry->MarkValid();
+        entry->MarkValid();
         return NS_OK; // kick out if reading from the cache succeeded...
       }
-      entry->Doom(); // doom entry if we failed to read from mem cache
+      entry->AsyncDoom(nullptr); // doom entry if we failed to read from mem cache
       mailnewsUrl->SetMemCacheEntry(nullptr); // we aren't going to be reading from the cache
     }
   } // if we got a valid entry back from the cache...
 
   // if reading from the cache failed or if we are writing into the cache, default to ReadFromImapConnection.
   return ReadFromImapConnection();
 }
 
 NS_IMETHODIMP
-nsImapMockChannel::OnCacheEntryDoomed(nsresult status)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
+nsImapMockChannel::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appCache,
+                                     uint32_t* aResult)
+{
+  *aResult = nsICacheEntryOpenCallback::ENTRY_WANTED;
+  return NS_OK;
 }
 
 nsresult nsImapMockChannel::OpenCacheEntry()
 {
   nsresult rv;
   // get the cache session from our imap service...
   nsCOMPtr<nsIImapService> imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsICacheSession> cacheSession;
-  rv = imapService->GetCacheSession(getter_AddRefs(cacheSession));
+  nsCOMPtr<nsICacheStorage> cacheStorage;
+  rv = imapService->GetCacheStorage(getter_AddRefs(cacheStorage));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // we're going to need to extend this logic for the case where we're looking
   // for a part. If we're looking for a part, we need to first ask for the part.
   // if that comes back with a writeable cache entry, we need to doom it right
   // away and not use it, and turn around and ask for a cache entry for the whole
   // message, if that's available. But it seems like we shouldn't write into that
   // cache entry if we just fetch that part - though we're doing that now. Maybe
   // we never try to download just a single part from imap because our mime parser
   // can't handle that, though I would think saving a single part as a file wouldn't
   // need to go through mime...
 
   // Open a cache entry with key = url
-  nsAutoCString urlSpec;
-  m_url->GetAsciiSpec(urlSpec);
-
-  // for now, truncate of the query part so we don't duplicate urls in the cache...
-  int32_t anchorIndex = urlSpec.RFindChar('?');
+  nsCOMPtr <nsIURI> newUri;
+  m_url->Clone(getter_AddRefs(newUri));
+  nsAutoCString path;
+  newUri->GetPath(path);
+
+  // Truncate of the query part so we don't duplicate urls in the cache for
+  // various message parts.
+  int32_t anchorIndex = path.RFindChar('?');
   if (anchorIndex > 0)
   {
     // if we were trying to read a part, we failed - fall back and look for whole msg
     if (mTryingToReadPart)
     {
       mTryingToReadPart = false;
-      urlSpec.SetLength(anchorIndex);
+      path.SetLength(anchorIndex);
+      newUri->SetPath(path);
     }
     else
     {
       // check if this is a filter plugin requesting the message. In that case,we're not
       // fetching a part, and we want the cache key to be just the uri.
-      nsAutoCString anchor(Substring(urlSpec, anchorIndex));
+      nsAutoCString anchor(Substring(path, anchorIndex));
 
       if (!anchor.EqualsLiteral("?header=filter")
-        && !anchor.EqualsLiteral("?header=attach") && !anchor.EqualsLiteral("?header=src"))
+        && !anchor.EqualsLiteral("?header=attach") && !anchor.EqualsLiteral("?header=src")) {
         mTryingToReadPart = true;
-      else
-        urlSpec.SetLength(anchorIndex);
+      } else {
+        path.SetLength(anchorIndex);
+        newUri->SetPath(path);
+      }
     }
   }
   int32_t uidValidity = -1;
-  nsCacheAccessMode cacheAccess = nsICache::ACCESS_READ_WRITE;
+  nsCacheAccessMode cacheAccess = nsICacheStorage::OPEN_NORMALLY;
 
   nsCOMPtr <nsIImapUrl> imapUrl = do_QueryInterface(m_url, &rv);
   if (imapUrl)
   {
     bool storeResultsOffline;
     nsCOMPtr <nsIImapMailFolderSink> folderSink;
 
     rv = imapUrl->GetImapMailFolderSink(getter_AddRefs(folderSink));
     if (folderSink)
       folderSink->GetUidValidity(&uidValidity);
     imapUrl->GetStoreResultsOffline(&storeResultsOffline);
     // If we're storing the message in the offline store, don't
     // write to the disk cache.
     if (storeResultsOffline)
-      cacheAccess = nsICache::ACCESS_READ;
+      cacheAccess = nsICacheStorage::OPEN_READONLY;
   }
   // stick the uid validity in front of the url, so that if the uid validity
   // changes, we won't re-use the wrong cache entries.
-  nsAutoCString cacheKey;
-  cacheKey.AppendInt(uidValidity, 16);
-  cacheKey.Append(urlSpec);
-  return cacheSession->AsyncOpenCacheEntry(cacheKey, cacheAccess, this, false);
-}
-
-nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry)
+  nsAutoCString extension;
+  extension.AppendInt(uidValidity, 16);
+  return cacheStorage->AsyncOpenURI(newUri, extension, cacheAccess, this);
+}
+
+nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntry *entry)
 {
   NS_ENSURE_ARG(entry);
 
   nsCString annotation;
   nsAutoCString entryKey;
   nsAutoCString contentType;
   nsresult rv = NS_OK;
   bool shouldUseCacheEntry = false;
@@ -9142,35 +9145,36 @@ nsresult nsImapMockChannel::ReadFromMemC
     shouldUseCacheEntry = true;
   }
   else
   {
     // otherwise, we have the whole msg, and we should make sure the content isn't modified.
     rv = entry->GetMetaDataElement("ContentModified", getter_Copies(annotation));
     if (NS_SUCCEEDED(rv) && !annotation.IsEmpty())
       shouldUseCacheEntry = annotation.EqualsLiteral("Not Modified");
+    // XXX When reading a part, should we compare its length to the full message length?
     if (shouldUseCacheEntry)
     {
-      uint32_t entrySize;
+      int64_t entrySize;
 
       rv = entry->GetDataSize(&entrySize);
       nsCOMPtr<nsIMsgMessageUrl> msgUrl(do_QueryInterface(m_url));
       if (msgUrl)
       {
         nsCOMPtr<nsIMsgDBHdr> msgHdr;
         // A failure to get a message header isn't an error
         msgUrl->GetMessageHeader(getter_AddRefs(msgHdr));
         if (msgHdr)
         {
           uint32_t messageSize;
           if (NS_SUCCEEDED(msgHdr->GetMessageSize(&messageSize)) &&
               messageSize != entrySize)
           {
             MOZ_LOG(IMAP, LogLevel::Warning,
-                ("ReadFromMemCache size mismatch for %s: message %d, cache %d\n",
+                ("ReadFromMemCache size mismatch for %s: message %d, cache %ld\n",
                  entryKey.get(), messageSize, entrySize));
             shouldUseCacheEntry = false;
           }
         }
       }
     }
   }
   if (shouldUseCacheEntry)
--- a/mailnews/imap/src/nsImapProtocol.h
+++ b/mailnews/imap/src/nsImapProtocol.h
@@ -41,26 +41,26 @@
 #include "nsCOMArray.h"
 #include "nsIThread.h"
 #include "nsIRunnable.h"
 #include "nsIImapMockChannel.h"
 #include "nsILoadGroup.h"
 #include "nsCOMPtr.h"
 #include "nsIImapIncomingServer.h"
 #include "nsIMsgWindow.h"
-#include "nsICacheListener.h"
 #include "nsIImapHeaderXferInfo.h"
 #include "nsMsgLineBuffer.h"
 #include "nsIAsyncInputStream.h"
 #include "nsITimer.h"
 #include "nsAutoPtr.h"
 #include "nsIMsgFolder.h"
 #include "nsIMsgAsyncPrompter.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsSyncRunnableHelpers.h"
+#include "nsICacheEntryOpenCallback.h"
 
 class nsIMAPMessagePartIDArray;
 class nsIMsgIncomingServer;
 class nsIPrefBranch;
 class nsIMAPMailboxInfo;
 
 #define kDownLoadCacheSize 16000 // was 1536 - try making it bigger
 
@@ -677,31 +677,31 @@ private:
 
 // This small class is a "mock" channel because it is a mockery of the imap channel's implementation...
 // it's a light weight channel that we can return to necko when they ask for a channel on a url before
 // we actually have an imap protocol instance around which can run the url. Please see my comments in
 // nsIImapMockChannel.idl for more details..
 //
 // Threading concern: This class lives entirely in the UI thread.
 
-class nsICacheEntryDescriptor;
+class nsICacheEntry;
 
 class nsImapMockChannel : public nsIImapMockChannel
-                        , public nsICacheListener
+                        , public nsICacheEntryOpenCallback
                         , public nsITransportEventSink
                         , public nsSupportsWeakReference
 {
 public:
   friend class nsImapProtocol;
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIIMAPMOCKCHANNEL
   NS_DECL_NSICHANNEL
   NS_DECL_NSIREQUEST
-  NS_DECL_NSICACHELISTENER
+  NS_DECL_NSICACHEENTRYOPENCALLBACK
   NS_DECL_NSITRANSPORTEVENTSINK
 
   nsImapMockChannel();
   static nsresult Create (const nsIID& iid, void **result);
 
 protected:
   virtual ~nsImapMockChannel();
   nsCOMPtr <nsIURI> m_url;
@@ -725,17 +725,17 @@ protected:
   bool mReadingFromCache;
   bool mTryingToReadPart;
   int64_t mContentLength;
 
   // cache related helper methods
   nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
   bool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
   nsresult ReadFromImapConnection(); // creates a new imap connection to read the url
-  nsresult ReadFromMemCache(nsICacheEntryDescriptor *entry); // attempts to read the url out of our memory cache
+  nsresult ReadFromMemCache(nsICacheEntry *entry); // attempts to read the url out of our memory cache
   nsresult NotifyStartEndReadFromCache(bool start);
 
   // we end up daisy chaining multiple nsIStreamListeners into the load process.
   nsresult SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer);
 };
 
 // This class contains the name of a mailbox and whether or not
 // its children have been listed.
--- a/mailnews/imap/src/nsImapService.cpp
+++ b/mailnews/imap/src/nsImapService.cpp
@@ -37,17 +37,19 @@
 #include "nsIDirectoryService.h"
 #include "nsMailDirServiceDefs.h"
 #include "nsIWebNavigation.h"
 #include "nsImapStringBundle.h"
 #include "plbase64.h"
 #include "nsImapOfflineSync.h"
 #include "nsIMsgHdr.h"
 #include "nsMsgUtils.h"
-#include "nsICacheService.h"
+#include "nsICacheStorage.h"
+#include "nsICacheStorageService.h"
+#include "nsILoadContextInfo.h"
 #include "nsIStreamListenerTee.h"
 #include "nsNetCID.h"
 #include "nsMsgI18N.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsICopyMsgStreamListener.h"
 #include "nsIMsgParseMailMsgState.h"
@@ -62,24 +64,23 @@
 #include "nsImapProtocol.h"
 #include "nsIMsgMailSession.h"
 #include "nsIStreamConverterService.h"
 #include "nsIAutoSyncManager.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsMsgMessageFlags.h"
 #include "nsIMsgPluggableStore.h"
+#include "../../base/src/MailnewsLoadContextInfo.h"
 
 #define PREF_MAIL_ROOT_IMAP "mail.root.imap"            // old - for backward compatibility only
 #define PREF_MAIL_ROOT_IMAP_REL "mail.root.imap-rel"
 
 static NS_DEFINE_CID(kImapUrlCID, NS_IMAPURL_CID);
 static NS_DEFINE_CID(kCImapMockChannel, NS_IMAPMOCKCHANNEL_CID);
-static NS_DEFINE_CID(kCacheServiceCID, NS_CACHESERVICE_CID);
-
 
 static const char sequenceString[] = "SEQUENCE";
 static const char uidString[] = "UID";
 
 static bool gInitialized = false;
 static int32_t gMIMEOnDemandThreshold = 15000;
 static bool gMIMEOnDemand = false;
 
@@ -987,17 +988,17 @@ NS_IMETHODIMP nsImapService::FetchMessag
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (WeAreOffline())
   {
     bool msgIsInCache = false;
     nsCOMPtr<nsIMsgMailNewsUrl> msgUrl(do_QueryInterface(aImapUrl));
     msgUrl->GetMsgIsInLocalCache(&msgIsInCache);
     if (!msgIsInCache)
-      IsMsgInMemCache(url, aImapMailFolder, nullptr, &msgIsInCache);
+      IsMsgInMemCache(url, aImapMailFolder, &msgIsInCache);
 
     // Display the "offline" message if we didn't find it in the memory cache either
     if (!msgIsInCache)
     {
       nsCOMPtr<nsIMsgIncomingServer> server;
       rv = aImapMailFolder->GetServer(getter_AddRefs(server));
       if (server && aDisplayConsumer)
         rv = server->DisplayOfflineMsg(aMsgWindow);
@@ -1178,17 +1179,17 @@ NS_IMETHODIMP nsImapService::StreamMessa
 
       // If we don't have the message available locally, and we can't get it over
       // the network, return with an error
       if (aLocalOnly || WeAreOffline())
       {
         bool isMsgInMemCache = false;
         if (!hasMsgOffline)
         {
-          rv = IsMsgInMemCache(url, folder, nullptr, &isMsgInMemCache);
+          rv = IsMsgInMemCache(url, folder, &isMsgInMemCache);
           NS_ENSURE_SUCCESS(rv, rv);
 
           if (!isMsgInMemCache)
             return NS_ERROR_FAILURE;
         }
       }
 
       bool shouldStoreMsgOffline = false;
@@ -1231,74 +1232,55 @@ NS_IMETHODIMP nsImapService::StreamHeade
     if (hasMsgOffline)
     {
       int64_t messageOffset;
       uint32_t messageSize;
       folder->GetOfflineFileStream(key, &messageOffset, &messageSize, getter_AddRefs(inputStream));
       if (inputStream)
         return MsgStreamMsgHeaders(inputStream, aConsumer);
     }
-    nsCOMPtr<nsIImapUrl> imapUrl;
-    nsAutoCString urlSpec;
-    char hierarchyDelimiter = GetHierarchyDelimiter(folder);
-    rv = CreateStartOfImapUrl(nsDependentCString(aMessageURI), getter_AddRefs(imapUrl), 
-                              folder, aUrlListener, urlSpec, hierarchyDelimiter);
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIURI> url(do_QueryInterface(imapUrl));
-    nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
-    bool msgInMemCache = false;
-    rv = IsMsgInMemCache(url, folder, getter_AddRefs(cacheEntry), &msgInMemCache);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (msgInMemCache)
-    {
-      rv = cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-      if (NS_SUCCEEDED(rv))
-        return MsgStreamMsgHeaders(inputStream, aConsumer);
-    }
   }
+
   if (aLocalOnly)
     return NS_ERROR_FAILURE;
   return rv;
 }
 
 NS_IMETHODIMP nsImapService::IsMsgInMemCache(nsIURI *aUrl,
                                              nsIMsgFolder *aImapMailFolder,
-                                             nsICacheEntryDescriptor **aCacheEntry,
                                              bool *aResult)
 {
   NS_ENSURE_ARG_POINTER(aUrl);
   NS_ENSURE_ARG_POINTER(aImapMailFolder);
   *aResult = false;
 
   // Poke around in the memory cache
-  if (mCacheSession)
+  if (mCacheStorage)
   {
+    // XXX: No truncation after a possible '?' done here?
+    nsAutoCString urlSpec;
+    aUrl->GetAsciiSpec(urlSpec);
+    if (urlSpec.RFindChar('?') != kNotFound)
+      NS_WARNING ("nsImapService::IsMsgInMemCache found ? in URL");
+
     nsresult rv;
     nsCOMPtr<nsIImapMailFolderSink> folderSink(do_QueryInterface(aImapMailFolder, &rv));
     NS_ENSURE_SUCCESS(rv, rv);
 
     int32_t uidValidity = -1;
     folderSink->GetUidValidity(&uidValidity);
     // stick the uid validity in front of the url, so that if the uid validity
     // changes, we won't re-use the wrong cache entries.
-    nsAutoCString cacheKey;
-    nsAutoCString escapedSpec;
-
-    cacheKey.AppendInt(uidValidity, 16);
-    aUrl->GetAsciiSpec(escapedSpec);
-    cacheKey.Append(escapedSpec);
-    nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
-    rv = mCacheSession->OpenCacheEntry(cacheKey, nsICache::ACCESS_READ, false,
-                                       getter_AddRefs(cacheEntry));
-    if (NS_SUCCEEDED(rv))
-    {
+    nsAutoCString extension;
+    extension.AppendInt(uidValidity, 16);
+
+    bool exists;
+    rv = mCacheStorage->Exists(aUrl, extension, &exists);
+    if (NS_SUCCEEDED(rv) && exists) {
       *aResult = true;
-      if (aCacheEntry)
-        NS_IF_ADDREF(*aCacheEntry = cacheEntry);
     }
   }
 
   return NS_OK;
 }
 
 nsresult nsImapService::CreateStartOfImapUrl(const nsACString &aImapURI, 
                                              nsIImapUrl **imapUrl,
@@ -3311,31 +3293,33 @@ NS_IMETHODIMP nsImapService::DownloadAll
     NS_ADDREF(downloadForOffline); 
     nsresult rv = downloadForOffline->ProcessNextOperation();
     NS_RELEASE(downloadForOffline);
     return rv;
   }
   return NS_ERROR_OUT_OF_MEMORY;
 }
 
-
-NS_IMETHODIMP nsImapService::GetCacheSession(nsICacheSession **result)
+NS_IMETHODIMP nsImapService::GetCacheStorage(nsICacheStorage **result)
 {
   nsresult rv = NS_OK;
-  if (!mCacheSession)
+  if (!mCacheStorage)
   {
-    nsCOMPtr<nsICacheService> serv = do_GetService(kCacheServiceCID, &rv);
+    nsCOMPtr<nsICacheStorageService> cacheStorageService =
+      do_GetService("@mozilla.org/netwerk/cache-storage-service;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
-    
-    rv = serv->CreateSession("IMAP-anywhere", nsICache::STORE_ANYWHERE, nsICache::STREAM_BASED, getter_AddRefs(mCacheSession));
+
+    RefPtr<MailnewsLoadContextInfo> lci =
+      new MailnewsLoadContextInfo(false, false, mozilla::NeckoOriginAttributes());
+
+    rv = cacheStorageService->MemoryCacheStorage(lci, getter_AddRefs(mCacheStorage));
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mCacheSession->SetDoomEntriesIfExpired(false);
   }
 
-  NS_IF_ADDREF(*result = mCacheSession);
+  NS_IF_ADDREF(*result = mCacheStorage);
   return rv;
 }
 
 NS_IMETHODIMP nsImapService::HandleContent(const char *aContentType, 
                                            nsIInterfaceRequestor *aWindowContext, 
                                            nsIRequest *request)
 {
   NS_ENSURE_ARG_POINTER(request);
--- a/mailnews/imap/src/nsImapService.h
+++ b/mailnews/imap/src/nsImapService.h
@@ -8,17 +8,17 @@
 
 #include "nsIImapService.h"
 #include "nsIMsgMessageService.h"
 #include "nsCOMPtr.h"
 #include "nsIFile.h"
 #include "nsIProtocolHandler.h"
 #include "nsIMsgProtocolInfo.h"
 #include "nsIContentHandler.h"
-#include "nsICacheSession.h"
+#include "nsICacheStorage.h"
 
 class nsIImapHostSessionList; 
 class nsCString;
 class nsIImapUrl;
 class nsIMsgFolder;
 class nsIMsgStatusFeedback;
 class nsIMsgIncomingServer;
 
@@ -111,13 +111,13 @@ protected:
   nsresult GetServerFromUrl(nsIImapUrl *aImapUrl, nsIMsgIncomingServer **aServer);
 
   // just a little helper method...maybe it should be a macro? which helps break down a imap message uri
   // into the folder and message key equivalents
   nsresult DecomposeImapURI(const nsACString &aMessageURI, nsIMsgFolder **aFolder, nsACString &msgKey);
   nsresult DecomposeImapURI(const nsACString &aMessageURI, nsIMsgFolder **aFolder, nsMsgKey *msgKey);
 
 
-  nsCOMPtr<nsICacheSession> mCacheSession;  // handle to the cache session for imap.....
+  nsCOMPtr<nsICacheStorage> mCacheStorage;
   bool mPrintingOperation;                // Flag for printing operations
 };
 
 #endif /* nsImapService_h___ */
--- a/mailnews/imap/src/nsImapUrl.cpp
+++ b/mailnews/imap/src/nsImapUrl.cpp
@@ -15,17 +15,17 @@
 #include "plstr.h"
 #include "prprf.h"
 #include "nsMemory.h"
 #include "nsCOMPtr.h"
 #include "nsIImapIncomingServer.h"
 #include "nsMsgBaseCID.h"
 #include "nsImapUtils.h"
 #include "nsIMAPNamespace.h"
-#include "nsICacheEntryDescriptor.h"
+#include "nsICacheEntry.h"
 #include "nsIMsgFolder.h"
 #include "nsIDocShell.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsMsgUtils.h"
 #include "nsIMsgHdr.h"
 #include "nsIProgressEventSink.h"
 #include "nsAlgorithm.h"
@@ -1038,17 +1038,17 @@ NS_IMETHODIMP nsImapUrl::SetAllowContent
 {
   m_allowContentChange = allowContentChange;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsImapUrl::SetContentModified(nsImapContentModifiedType contentModified)
 {
   m_contentModified = contentModified;
-  nsCOMPtr<nsICacheEntryDescriptor>  cacheEntry;
+  nsCOMPtr<nsICacheEntry> cacheEntry;
   nsresult res = GetMemCacheEntry(getter_AddRefs(cacheEntry));
   if (NS_SUCCEEDED(res) && cacheEntry)
   {
     const char *contentModifiedAnnotation = "";
     switch (m_contentModified)
     {
     case IMAP_CONTENT_NOT_MODIFIED:
       contentModifiedAnnotation = "Not Modified";
--- a/mailnews/local/src/nsMailboxService.cpp
+++ b/mailnews/local/src/nsMailboxService.cpp
@@ -326,17 +326,16 @@ NS_IMETHODIMP nsMailboxService::StreamHe
   if (!inputStream)
     return NS_ERROR_FAILURE;
   return MsgStreamMsgHeaders(inputStream, aConsumer);
 }
 
 
 NS_IMETHODIMP nsMailboxService::IsMsgInMemCache(nsIURI *aUrl,
                                                 nsIMsgFolder *aFolder,
-                                                nsICacheEntryDescriptor **aCacheEntry,
                                                 bool *aResult)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsMailboxService::OpenAttachment(const char *aContentType,
                                                const char *aFileName,
                                                const char *aUrl,
--- a/mailnews/news/public/nsINntpService.idl
+++ b/mailnews/news/public/nsINntpService.idl
@@ -7,17 +7,17 @@
 #include "nsIUrlListener.idl"
 #include "nsINntpIncomingServer.idl"
 #include "MailNewsTypes2.idl"
 
 interface nsIURI;
 interface nsIFile;
 interface nsIMsgWindow;
 interface nsIMsgFolder;
-interface nsICacheSession;
+interface nsICacheStorage;
 
 [scriptable, uuid(dc5cadb0-966c-4ef1-a4c8-cc1e48d1ac61)]
 interface nsINntpService : nsISupports {
   
   /* newsgroupsList is a comma separated list of newsgroups, which may be
    * in news://host/group or group form
    * "news://host/group1,news://host/group2" or "group1,group2"
    *
@@ -41,10 +41,10 @@ interface nsINntpService : nsISupports {
 
   void downloadNewsgroupsForOffline(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
   /** 
    * can handle news-message:// and news:// 
    */
   void decomposeNewsURI(in string uri, out nsIMsgFolder folder, out nsMsgKey key);
 
   // handle to the cache session used by news....
-  readonly attribute nsICacheSession cacheSession;
+  readonly attribute nsICacheStorage cacheStorage;
 };
--- a/mailnews/news/src/nsNNTPProtocol.cpp
+++ b/mailnews/news/src/nsNNTPProtocol.cpp
@@ -52,18 +52,19 @@
 
 #include "nsIMsgFolder.h"
 #include "nsIMsgNewsFolder.h"
 #include "nsIDocShell.h"
 
 #include "nsIMsgFilterList.h"
 
 // for the memory cache...
-#include "nsICacheEntryDescriptor.h"
-#include "nsICacheSession.h"
+#include "nsICacheEntry.h"
+#include "nsICacheStorage.h"
+#include "nsIApplicationCache.h"
 #include "nsIStreamListener.h"
 #include "nsNetCID.h"
 
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 
 #include "nsIMsgWindow.h"
 #include "nsIWindowWatcher.h"
@@ -254,17 +255,17 @@ char *MSG_UnEscapeSearchUrl (const char 
   return ToNewCString(result);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////
 // END OF TEMPORARY HARD CODED FUNCTIONS
 ///////////////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED(nsNNTPProtocol, nsMsgProtocol, nsINNTPProtocol,
-  nsITimerCallback, nsICacheListener, nsIMsgAsyncPromptListener)
+  nsITimerCallback, nsICacheEntryOpenCallback, nsIMsgAsyncPromptListener)
 
 nsNNTPProtocol::nsNNTPProtocol(nsINntpIncomingServer *aServer, nsIURI *aURL,
                                nsIMsgWindow *aMsgWindow)
 : nsMsgProtocol(aURL),
   m_connectionBusy(false),
   m_nntpServer(aServer)
 {
   if (!NNTP)
@@ -684,17 +685,17 @@ nsresult nsNNTPProtocol::SetupPartExtrac
       if (newConsumer)
         m_channelListener = newConsumer;
     }
   }
 
   return rv;
 }
 
-nsresult nsNNTPProtocol::ReadFromMemCache(nsICacheEntryDescriptor *entry)
+nsresult nsNNTPProtocol::ReadFromMemCache(nsICacheEntry *entry)
 {
   NS_ENSURE_ARG(entry);
 
   nsCOMPtr<nsIInputStream> cacheStream;
   nsresult rv = entry->OpenInputStream(0, getter_AddRefs(cacheStream));
 
   if (NS_SUCCEEDED(rv))
   {
@@ -806,94 +807,92 @@ bool nsNNTPProtocol::ReadFromLocalCache(
         mailnewsUrl->SetMsgIsInLocalCache(false);
     }
   }
 
   return false;
 }
 
 NS_IMETHODIMP
-nsNNTPProtocol::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAccessMode access, nsresult status)
+nsNNTPProtocol::OnCacheEntryAvailable(nsICacheEntry *entry, bool aNew, nsIApplicationCache* aAppCache, nsresult status)
 {
   nsresult rv = NS_OK;
 
   if (NS_SUCCEEDED(status))
   {
     nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL, &rv);
     mailnewsUrl->SetMemCacheEntry(entry);
 
-    // If we have an empty cache entry with read access, we probably failed to
-    // clear it out from an error ealier. In this case, we'll simply try to
-    // write in the cache entry this time and hope we get luckier.
-    bool canRead = access & nsICache::ACCESS_READ;
-    if (canRead)
-    {
-      uint32_t size;
-      entry->GetDataSize(&size);
-      if (size == 0)
-        canRead = false;
-    }
-
-    // if we have write access then insert a "stream T" into the flow so data
-    // gets written to both
-    if (access & nsICache::ACCESS_WRITE && !canRead)
+    // Insert a "stream T" into the flow so data gets written to both.
+    if (aNew)
     {
       // use a stream listener Tee to force data into the cache and to our current channel listener...
       nsCOMPtr<nsIStreamListener> newListener;
       nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIOutputStream> outStream;
       rv = entry->OpenOutputStream(0, getter_AddRefs(outStream));
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = tee->Init(m_channelListener, outStream, nullptr);
       m_channelListener = do_QueryInterface(tee);
       NS_ENSURE_SUCCESS(rv, rv);
     }
-    else if (canRead)
+    else
     {
       rv = ReadFromMemCache(entry);
-      if (access & nsICache::ACCESS_WRITE)
+      if (NS_SUCCEEDED(rv)) {
         entry->MarkValid();
-      if (NS_SUCCEEDED(rv))
         return NS_OK; // kick out if reading from the cache succeeded...
+      }
     }
   } // if we got a valid entry back from the cache...
 
-  // if reading from the cache failed or if we are writing into the cache, default to ReadFromImapConnection.
+  // if reading from the cache failed or if we are writing into the cache, default to ReadFromNewsConnection.
   return ReadFromNewsConnection();
 }
 
 NS_IMETHODIMP
-nsNNTPProtocol::OnCacheEntryDoomed(nsresult status)
+nsNNTPProtocol::OnCacheEntryCheck(nsICacheEntry* entry, nsIApplicationCache* appCache,
+                                  uint32_t* aResult)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  *aResult = nsICacheEntryOpenCallback::ENTRY_WANTED;
+  return NS_OK;
 }
 
 nsresult nsNNTPProtocol::OpenCacheEntry()
 {
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL, &rv);
   // get the cache session from our nntp service...
   nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsICacheSession> cacheSession;
-  rv = nntpService->GetCacheSession(getter_AddRefs(cacheSession));
+  nsCOMPtr<nsICacheStorage> cacheStorage;
+  rv = nntpService->GetCacheStorage(getter_AddRefs(cacheStorage));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Open a cache entry with key = url, no extension.
+  nsCOMPtr<nsIURI> uri;
+  rv = mailnewsUrl->GetBaseURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Open a cache entry with key = url
-  nsAutoCString urlSpec;
-  mailnewsUrl->GetAsciiSpec(urlSpec);
-  // for now, truncate of the query part so we don't duplicate urls in the cache...
-  int32_t pos = urlSpec.FindChar('?');
-  if (pos != -1)
-    urlSpec.SetLength(pos);
-  return cacheSession->AsyncOpenCacheEntry(urlSpec, nsICache::ACCESS_READ_WRITE, this, false);
+  // Truncate of the query part so we don't duplicate urls in the cache for
+  // various message parts.
+  nsCOMPtr<nsIURI> newUri;
+  uri->Clone(getter_AddRefs(newUri));
+  nsAutoCString path;
+  newUri->GetPath(path);
+  int32_t pos = path.FindChar('?');
+  if (pos != kNotFound) {
+    path.SetLength(pos);
+    newUri->SetPath(path);
+  }
+  return cacheStorage->AsyncOpenURI(newUri, EmptyCString(), nsICacheStorage::OPEN_NORMALLY, this);
 }
 
 NS_IMETHODIMP nsNNTPProtocol::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
 {
   nsresult rv;
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningURL, &rv);
   NS_ENSURE_SUCCESS(rv,rv);
 
@@ -1145,26 +1144,26 @@ FAIL:
     else if (m_typeWanted == IDS_WANTED)
       NS_ASSERTION(m_newsFolder, "IDS_WANTED needs m_newsFolder");
 
     return rv;
 }
 
 void nsNNTPProtocol::FinishMemCacheEntry(bool valid)
 {
-  nsCOMPtr <nsICacheEntryDescriptor> memCacheEntry;
+  nsCOMPtr <nsICacheEntry> memCacheEntry;
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_runningURL);
   if (mailnewsurl)
     mailnewsurl->GetMemCacheEntry(getter_AddRefs(memCacheEntry));
   if (memCacheEntry)
   {
     if (valid)
       memCacheEntry->MarkValid();
     else
-      memCacheEntry->Doom();
+      memCacheEntry->AsyncDoom(nullptr);
   }
 }
 
 // stop binding is a "notification" informing us that the stream associated with aURL is going away.
 NS_IMETHODIMP nsNNTPProtocol::OnStopRequest(nsIRequest *request, nsISupports * aContext, nsresult aStatus)
 {
     // either remove mem cache entry, or mark it valid if url successful and
     // command succeeded
--- a/mailnews/news/src/nsNNTPProtocol.h
+++ b/mailnews/news/src/nsNNTPProtocol.h
@@ -19,17 +19,17 @@
 #include "nsINNTPArticleList.h"
 #include "nsIMsgAsyncPrompter.h"
 #include "nsIMsgNewsFolder.h"
 #include "nsIMsgWindow.h"
 
 #include "nsMsgLineBuffer.h"
 #include "nsIStringBundle.h"
 #include "nsITimer.h"
-#include "nsICacheListener.h"
+#include "nsICacheEntryOpenCallback.h"
 
 // this is only needed as long as our libmime hack is in place
 #include "prio.h"
 
 // State Flags (Note, I use the word state in terms of storing
 // state information about the connection (authentication, have we sent
 // commands, etc. I do not intend it to refer to protocol state)
 
@@ -113,28 +113,28 @@ NNTP_LIST_GROUP_RESPONSE,
 NEWS_DONE,
 NEWS_POST_DONE,
 NEWS_ERROR,
 NNTP_ERROR,
 NEWS_FREE,
 NNTP_SUSPENDED
 } StatesEnum;
 
-class nsICacheEntryDescriptor;
+class nsICacheEntry;
 
 class nsNNTPProtocol : public nsMsgProtocol,
                        public nsINNTPProtocol,
                        public nsITimerCallback,
-                       public nsICacheListener,
+                       public nsICacheEntryOpenCallback,
                        public nsIMsgAsyncPromptListener
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSINNTPPROTOCOL
-  NS_DECL_NSICACHELISTENER
+  NS_DECL_NSICACHEENTRYOPENCALLBACK
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIMSGASYNCPROMPTLISTENER
 
   // Creating a protocol instance requires the URL
   // need to call Initialize after we do a new of nsNNTPProtocol
   nsNNTPProtocol(nsINntpIncomingServer *aServer, nsIURI *aURL,
                  nsIMsgWindow *aMsgWindow);
 
@@ -497,14 +497,14 @@ private:
   nsresult SetCurrentGroup(); /* sets m_currentGroup.  should be called after doing a successful GROUP command */
   nsresult CleanupNewsgroupList(); /* cleans up m_newsgroupList, and set it to null */
 
   // cache related helper methods
   void FinishMemCacheEntry(bool valid); // either mark it valid, or doom it
   nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
   bool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
   nsresult ReadFromNewsConnection(); // creates a new news connection to read the url
-  nsresult ReadFromMemCache(nsICacheEntryDescriptor *entry); // attempts to read the url out of our memory cache
+  nsresult ReadFromMemCache(nsICacheEntry *entry); // attempts to read the url out of our memory cache
   nsresult SetupPartExtractorListener(nsIStreamListener * aConsumer);
 };
 
 
 #endif  // nsNNTPProtocol_h___
--- a/mailnews/news/src/nsNntpService.cpp
+++ b/mailnews/news/src/nsNntpService.cpp
@@ -34,28 +34,31 @@
 #include "nsIMsgSearchSession.h"
 #include "nsMailDirServiceDefs.h"
 #include "nsIWebNavigation.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 #include "nsIPrompt.h"
 #include "nsNewsDownloader.h"
 #include "prprf.h"
-#include "nsICacheService.h"
-#include "nsICacheEntryDescriptor.h"
+#include "nsICacheStorage.h"
+#include "nsICacheStorageService.h"
+#include "nsILoadContextInfo.h"
+#include "nsICacheEntry.h"
 #include "nsMsgUtils.h"
 #include "nsNetUtil.h"
 #include "nsIWindowWatcher.h"
 #include "nsICommandLine.h"
 #include "nsIMsgMailNewsUrl.h"
 #include "nsIMsgMailSession.h"
 #include "nsISupportsPrimitives.h"
 #include "nsArrayUtils.h"
 #include "nsIStreamListener.h"
 #include "nsIInputStream.h"
+#include "../../base/src/MailnewsLoadContextInfo.h"
 
 #undef GetPort  // XXX Windows!
 #undef SetPort  // XXX Windows!
 
 #define PREF_MAIL_ROOT_NNTP   "mail.root.nntp"        // old - for backward compatibility only
 #define PREF_MAIL_ROOT_NNTP_REL   "mail.root.nntp-rel"
 
 nsNntpService::nsNntpService()
@@ -272,17 +275,17 @@ nsNntpService::DisplayMessage(const char
 
     // Look for the message in the offline cache
     bool hasMsgOffline = false;
     folder->HasMsgOffline(key, &hasMsgOffline);
 
     // Now look in the memory cache
     if (!hasMsgOffline)
     {
-      rv = IsMsgInMemCache(url, folder, nullptr, &hasMsgOffline);
+      rv = IsMsgInMemCache(url, folder, &hasMsgOffline);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // If the message is not found in either, then we might need to return
     if (!hasMsgOffline && WeAreOffline())
       return server->DisplayOfflineMsg(aMsgWindow);
 
     msgUrl->SetMsgIsInLocalCache(hasMsgOffline);
@@ -1439,17 +1442,17 @@ nsNntpService::StreamMessage(const char 
 
         int32_t socketType;
         rv = server->GetSocketType(&socketType);
         NS_ENSURE_SUCCESS(rv, rv);
 
         url->SetPort((socketType == nsMsgSocketType::SSL) ?
                      nsINntpUrl::DEFAULT_NNTPS_PORT : nsINntpUrl::DEFAULT_NNTP_PORT);
 
-        rv = IsMsgInMemCache(url, folder, nullptr, &hasMsgOffline);
+        rv = IsMsgInMemCache(url, folder, &hasMsgOffline);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       // Return with an error if we didn't find it in the memory cache either
       if (!hasMsgOffline)
         return NS_ERROR_FAILURE;
 
       msgUrl->SetMsgIsInLocalCache(true);
@@ -1488,65 +1491,45 @@ NS_IMETHODIMP nsNntpService::StreamHeade
     folder->GetOfflineFileStream(key, &messageOffset, &messageSize, getter_AddRefs(inputStream));
     if (inputStream)
       return MsgStreamMsgHeaders(inputStream, aConsumer);
   }
   nsAutoCString urlStr;
   rv = CreateMessageIDURL(folder, key, getter_Copies(urlStr));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsNewsAction action = nsINntpUrl::ActionFetchArticle;
-
-  nsCOMPtr<nsIURI> url;
-  rv = ConstructNntpUrl(urlStr.get(), aUrlListener, nullptr, aMessageURI,
-                        action, getter_AddRefs(url));
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
-  bool msgInMemCache = false;
-  rv = IsMsgInMemCache(url, folder, getter_AddRefs(cacheEntry), &msgInMemCache);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (msgInMemCache)
-  {
-    rv = cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
-    if (NS_SUCCEEDED(rv))
-      return MsgStreamMsgHeaders(inputStream, aConsumer);
-  }
   if (aLocalOnly)
     return NS_ERROR_FAILURE;
   return rv;
 }
 
 NS_IMETHODIMP nsNntpService::IsMsgInMemCache(nsIURI *aUrl,
                                              nsIMsgFolder *aFolder,
-                                             nsICacheEntryDescriptor **aCacheEntry,
                                              bool *aResult)
 {
   NS_ENSURE_ARG_POINTER(aUrl);
-  NS_ENSURE_ARG_POINTER(aFolder);
   *aResult = false;
+  nsresult rv;
 
-  if (mCacheSession)
+  if (mCacheStorage)
   {
-    // check if message is in memory cache
-    nsAutoCString cacheKey;
-    aUrl->GetAsciiSpec(cacheKey);
-    // nntp urls are truncated at the query part when used as cache keys
-    int32_t pos = cacheKey.FindChar('?');
-    if (pos != -1)
-      cacheKey.SetLength(pos);
-
-    nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
-    if (NS_SUCCEEDED(mCacheSession->OpenCacheEntry(cacheKey,
-                     nsICache::ACCESS_READ, false,
-                     getter_AddRefs(cacheEntry))))
-    {
+    // NNTP urls are truncated at the query part when used as cache keys.
+    nsCOMPtr <nsIURI> newUri;
+    aUrl->Clone(getter_AddRefs(newUri));
+    nsAutoCString path;
+    newUri->GetPath(path);
+    int32_t pos = path.FindChar('?');
+    if (pos != kNotFound) {
+      path.SetLength(pos);
+      newUri->SetPath(path);
+    }
+    bool exists;
+    rv = mCacheStorage->Exists(newUri, EmptyCString(), &exists);
+    if (NS_SUCCEEDED(rv) && exists) {
       *aResult = true;
-      if (aCacheEntry)
-        NS_IF_ADDREF(*aCacheEntry = cacheEntry);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsNntpService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgWindow *aMsgWindow, nsIMsgFolder *aMsgFolder, const char *aSearchUri)
 {
@@ -1745,25 +1728,27 @@ nsNntpService::DownloadNewsgroupsForOffl
   nsMsgDownloadAllNewsgroups *newsgroupDownloader = new nsMsgDownloadAllNewsgroups(aMsgWindow, aListener);
   if (newsgroupDownloader)
     rv = newsgroupDownloader->ProcessNextGroup();
   else
     rv = NS_ERROR_OUT_OF_MEMORY;
   return rv;
 }
 
-NS_IMETHODIMP nsNntpService::GetCacheSession(nsICacheSession **result)
+NS_IMETHODIMP nsNntpService::GetCacheStorage(nsICacheStorage **result)
 {
   nsresult rv = NS_OK;
-  if (!mCacheSession)
+  if (!mCacheStorage)
   {
-    nsCOMPtr<nsICacheService> serv = do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
+    nsCOMPtr<nsICacheStorageService> cacheStorageService =
+      do_GetService("@mozilla.org/netwerk/cache-storage-service;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = serv->CreateSession("NNTP-memory-only", nsICache::STORE_IN_MEMORY, nsICache::STREAM_BASED, getter_AddRefs(mCacheSession));
+    RefPtr<MailnewsLoadContextInfo> lci =
+      new MailnewsLoadContextInfo(false, false, mozilla::NeckoOriginAttributes());
+
+    rv = cacheStorageService->MemoryCacheStorage(lci, getter_AddRefs(mCacheStorage));
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mCacheSession->SetDoomEntriesIfExpired(false);
   }
 
-  *result = mCacheSession;
-  NS_IF_ADDREF(*result);
+  NS_IF_ADDREF(*result = mCacheStorage);
   return rv;
 }
--- a/mailnews/news/src/nsNntpService.h
+++ b/mailnews/news/src/nsNntpService.h
@@ -13,17 +13,17 @@
 #include "nsIMsgIncomingServer.h"
 #include "nsIFile.h"
 #include "MailNewsTypes.h"
 #include "nsIMsgProtocolInfo.h"
 #include "nsIMsgWindow.h"
 #include "nsINntpUrl.h"
 #include "nsCOMPtr.h"
 #include "nsIContentHandler.h"
-#include "nsICacheSession.h"
+#include "nsICacheStorage.h"
 
 #include "nsICommandLineHandler.h"
 
 class nsIURI;
 class nsIUrlListener;
 
 class nsNntpService : public nsINntpService,
                       public nsIMsgMessageService,
@@ -65,12 +65,12 @@ protected:
   nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer);
   // a convience routine to go from folder uri to msg folder
   nsresult GetFolderFromUri(const char *uri, nsIMsgFolder **folder);
   nsresult DecomposeNewsMessageURI(const char * aMessageURI, nsIMsgFolder ** aFolder, nsMsgKey *aMsgKey);
 
   bool              mPrintingOperation; // Flag for printing operations
   bool        mOpenAttachmentOperation; // Flag for opening attachments
 
-  nsCOMPtr<nsICacheSession> mCacheSession; // the cache session used by news
+  nsCOMPtr<nsICacheStorage> mCacheStorage; // the cache storage used by news
 };
 
 #endif /* nsNntpService_h___ */
--- a/mailnews/news/test/unit/test_bug540288.js
+++ b/mailnews/news/test/unit/test_bug540288.js
@@ -55,29 +55,29 @@ function doTestFinished() {
     do_test_finished();
 }
 
 
 function run_test() {
   server = makeServer(NNTP_RFC977_handler, daemon);
   server.start();
   localserver = setupLocalServer(server.port);
-  const kCacheKey = "news://localhost:" + server.port + "/TSS1%40nntp.test";
+  var uri = Cc["@mozilla.org/network/standard-url;1"]
+              .createInstance(Ci.nsIURI);
+  uri.spec = "news://localhost:" + server.port + "/TSS1%40nntp.test";
 
   try {
     // Add an empty message to the cache
     MailServices.nntp
-                .cacheSession
-                .asyncOpenCacheEntry(kCacheKey, Ci.nsICache.ACCESS_WRITE, {
-      onCacheEntryAvailable: function(cacheEntry, access, status) {
+                .cacheStorage
+                .asyncOpenURI(uri, "", Ci.nsICacheStorage.OPEN_NORMALLY, {
+      onCacheEntryAvailable: function(cacheEntry, isNew, appCache, status) {
         do_check_eq(status, Components.results.NS_OK);
 
         cacheEntry.markValid();
-        var firstAccess = cacheEntry.fetchCount;
-        cacheEntry.close();
 
         // Get the folder and new mail
         var folder = localserver.rootFolder.getChildNamed("test.subscribe.simple");
         folder.clearFlag(Ci.nsMsgFolderFlags.Offline);
         folder.getNewMessages(null, {
           OnStopRunningUrl: function () { localserver.closeCachedConnections(); }});
         server.performTest();