IMAP: capability flag variable needs to be bigger than 32bit -- bug 558659 part 1, r=bienvenu
authorBen Bucksch <ben.bucksch@beonex.com>
Sat, 12 May 2012 00:58:59 +0200
changeset 11050 a3307f98beb6537854bc682ad0fe5914d5d8fb22
parent 11049 8f22d9d7d6921131edfb1ab4cae3090d8e54da45
child 11051 9d5996744bca63985c54647fdfc8ce4e11334642
push id577
push userbugzilla@standard8.plus.com
push dateMon, 04 Jun 2012 20:15:01 +0000
treeherdercomm-aurora@4d25d797db2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbienvenu
bugs558659
IMAP: capability flag variable needs to be bigger than 32bit -- bug 558659 part 1, r=bienvenu We're storing IMAP server capabilities in a variable. That used to be a 32bit integer used as bitflag. We also saved it in prefs as integer. Now, we need more than 32 flags, so we're enlarging it to a 64bit integer, and use a typedef. That means we can't store the varible in prefs anymore, but we only needed to remember 2 capabilities, and that only for some UI dialog, so we pick out what we actually needed to know and store it as 2 bool prefs. This breaks trySTARTTLS somewhat, so another patch will follow which fixes that.
mailnews/imap/public/nsIIMAPHostSessionList.h
mailnews/imap/public/nsIImapIncomingServer.idl
mailnews/imap/public/nsIImapServerSink.idl
mailnews/imap/src/nsIMAPHostSessionList.cpp
mailnews/imap/src/nsIMAPHostSessionList.h
mailnews/imap/src/nsImapCore.h
mailnews/imap/src/nsImapIncomingServer.cpp
mailnews/imap/src/nsImapIncomingServer.h
mailnews/imap/src/nsImapMailFolder.cpp
mailnews/imap/src/nsImapProtocol.cpp
mailnews/imap/src/nsImapProtocol.h
mailnews/imap/src/nsImapServerResponseParser.cpp
mailnews/imap/src/nsImapServerResponseParser.h
mailnews/imap/src/nsSyncRunnableHelpers.cpp
--- a/mailnews/imap/public/nsIIMAPHostSessionList.h
+++ b/mailnews/imap/public/nsIIMAPHostSessionList.h
@@ -40,34 +40,31 @@
 
 #include "nsISupports.h"
 #include "nsImapCore.h"
 
 class nsIMAPBodyShellCache;
 class nsIMAPBodyShell;
 class nsIImapIncomingServer;
 
-// 2a8e21fe-e3c4-11d2-a504-0060b0fc04b7
-
+// f4d89e3e-77da-492c-962b-7835f0742c22
 #define NS_IIMAPHOSTSESSIONLIST_IID \
-{ 0x2a8e21fe, 0xe3c4, 0x11d2, {0xa5, 0x04, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7 } }
+{ 0xf4d89e3e, 0x77da, 0x492c, {0x96, 0x2b, 0x78, 0x35, 0xf0, 0x74, 0x2c, 0x22 } }
 
 // this is an interface to a linked list of host info's    
 class nsIImapHostSessionList : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIMAPHOSTSESSIONLIST_IID)
 
   // Host List
   NS_IMETHOD  AddHostToList(const char *serverKey, nsIImapIncomingServer *server) = 0;
   NS_IMETHOD ResetAll() = 0;
 
   // Capabilities
-  NS_IMETHOD  GetCapabilityForHost(const char *serverKey, PRUint32 &result) = 0;
-  NS_IMETHOD  SetCapabilityForHost(const char *serverKey, PRUint32 capability) = 0;
   NS_IMETHOD  GetHostHasAdminURL(const char *serverKey, bool &result) = 0;
   NS_IMETHOD  SetHostHasAdminURL(const char *serverKey, bool hasAdminUrl) = 0;
   // Subscription
   NS_IMETHOD  GetHostIsUsingSubscription(const char *serverKey, bool &result) = 0;
   NS_IMETHOD  SetHostIsUsingSubscription(const char *serverKey, bool usingSubscription) = 0;
 
   // Passwords
   NS_IMETHOD  GetPasswordForHost(const char *serverKey, nsString &result) = 0;
--- a/mailnews/imap/public/nsIImapIncomingServer.idl
+++ b/mailnews/imap/public/nsIImapIncomingServer.idl
@@ -49,24 +49,23 @@ typedef long nsMsgImapDeleteModel;
 [scriptable, uuid(bbfc33de-fe89-11d3-a564-0060b0fc04b7)]
 interface nsMsgImapDeleteModels
 {
   const long IMAPDelete = 0;    /* delete with a big red x */
   const long MoveToTrash = 1;   /* delete moves message to the trash */
   const long DeleteNoTrash = 2; /* delete is shift delete - don't create or use trash */
 };
 
-[scriptable, uuid(3f02221b-d556-48ef-8b4f-7e50bfe9813d)]
+[scriptable, uuid(ea6a0765-07b8-40df-924c-9004ed707251)]
 interface nsIImapIncomingServer : nsISupports {
 
   attribute long maximumConnectionsNumber;
   attribute long timeOutLimits;
   attribute ACString adminUrl;
   attribute ACString serverDirectory;
-  attribute long capabilityPref;
   /// RFC 2971 ID response stored as a pref
   attribute ACString serverIDPref;
   attribute boolean cleanupInboxOnExit;
   attribute nsMsgImapDeleteModel deleteModel;
   attribute boolean dualUseFolders;
   attribute long emptyTrashThreshhold;
   attribute ACString personalNamespace;
   attribute ACString publicNamespace;
@@ -74,16 +73,18 @@ interface nsIImapIncomingServer : nsISup
   attribute boolean offlineDownload;
   attribute boolean overrideNamespaces;
   attribute boolean usingSubscription;
   attribute ACString manageMailAccountUrl;
   attribute boolean fetchByChunks;
   attribute boolean mimePartsOnDemand;
   attribute boolean sendID;
   attribute boolean isAOLServer;
+  attribute boolean capabilityACL;
+  attribute boolean capabilityQuota;
   attribute boolean useIdle;
   attribute boolean checkAllFoldersForNew;
 
   /// Is this a GMail Server?
   attribute boolean isGMailServer;
 
   /**
    * See IMAP RFC 4551
--- a/mailnews/imap/public/nsIImapServerSink.idl
+++ b/mailnews/imap/public/nsIImapServerSink.idl
@@ -67,17 +67,17 @@ interface nsIImapServerSink : nsISupport
   void discoveryDone();
   void onlineFolderDelete(in ACString folderName);
   void onlineFolderCreateFailed(in ACString aFolderName);
   void onlineFolderRename(in nsIMsgWindow msgWindow, in ACString oldName, in ACString newName);
   boolean folderIsNoSelect(in ACString folderName);
   void setFolderAdminURL(in ACString folderName, in ACString adminUrl);
   boolean folderVerifiedOnline(in ACString folderName);
 
-  void setCapability(in unsigned long capability);
+  void setCapability(in unsigned long long capability);
   /// RFC 2971 ID server response
   void setServerID(in ACString aServerID);
   boolean loadNextQueuedUrl(in nsIImapProtocol protocol);
 
   /**
    * Prepare to retry the given URL.
    * @param imapUrl the url we're going to retry
    * @return channel to associate with the url. We return this because access
--- a/mailnews/imap/src/nsIMAPHostSessionList.cpp
+++ b/mailnews/imap/src/nsIMAPHostSessionList.cpp
@@ -178,36 +178,16 @@ nsIMAPHostSessionList::AddHostToList(con
       newHost->fNextHost = fHostInfoList;
       fHostInfoList = newHost;
     }
   }
   PR_ExitMonitor(gCachedHostInfoMonitor);
   return (newHost == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
 }
 
-NS_IMETHODIMP nsIMAPHostSessionList::GetCapabilityForHost(const char *serverKey, PRUint32 &result)
-{
-  PR_EnterMonitor(gCachedHostInfoMonitor);
-
-  nsIMAPHostInfo *host = FindHost(serverKey);
-  result = (host) ? host->fCapabilityFlags : 0;
-  PR_ExitMonitor(gCachedHostInfoMonitor);
-  return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
-}
-
-NS_IMETHODIMP nsIMAPHostSessionList::SetCapabilityForHost(const char *serverKey, PRUint32 capability)
-{
-  PR_EnterMonitor(gCachedHostInfoMonitor);
-  nsIMAPHostInfo *host = FindHost(serverKey);
-  if (host)
-    host->fCapabilityFlags = capability;
-  PR_ExitMonitor(gCachedHostInfoMonitor);
-  return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
-}
-
 NS_IMETHODIMP nsIMAPHostSessionList::GetPasswordForHost(const char *serverKey, nsString &result)
 {
   PR_EnterMonitor(gCachedHostInfoMonitor);
   nsIMAPHostInfo *host = FindHost(serverKey);
   if (host)
     CopyASCIItoUTF16(nsDependentCString(host->fCachedPassword), result);
   PR_ExitMonitor(gCachedHostInfoMonitor);
   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
--- a/mailnews/imap/src/nsIMAPHostSessionList.h
+++ b/mailnews/imap/src/nsIMAPHostSessionList.h
@@ -54,17 +54,17 @@ public:
 
   nsIMAPHostInfo(const char *serverKey, nsIImapIncomingServer *server);
   ~nsIMAPHostInfo();
 protected:
   nsCString fServerKey;
   char *fCachedPassword;
   nsCString fOnlineDir;
   nsIMAPHostInfo *fNextHost;
-  PRUint32 fCapabilityFlags;
+  eIMAPCapabilityFlags fCapabilityFlags;
   char *fHierarchyDelimiters;// string of top-level hierarchy delimiters
   bool fHaveWeEverDiscoveredFolders;
   char *fCanonicalOnlineSubDir;
   nsIMAPNamespaceList *fNamespaceList, *fTempNamespaceList;
   bool fNamespacesOverridable;
   bool fUsingSubscription;
   bool fOnlineTrashFolderExists;
   bool fShouldAlwaysListInbox;
@@ -87,18 +87,16 @@ public:
   virtual ~nsIMAPHostSessionList();
   nsresult Init();
   // Host List
   NS_IMETHOD AddHostToList(const char *serverKey, 
                             nsIImapIncomingServer *server);
   NS_IMETHOD ResetAll();
 
   // Capabilities
-  NS_IMETHOD GetCapabilityForHost(const char *serverKey, PRUint32 &result);
-  NS_IMETHOD SetCapabilityForHost(const char *serverKey, PRUint32 capability);
   NS_IMETHOD GetHostHasAdminURL(const char *serverKey, bool &result);
   NS_IMETHOD SetHostHasAdminURL(const char *serverKey, bool hasAdminUrl);
   // Subscription
   NS_IMETHOD GetHostIsUsingSubscription(const char *serverKey, bool &result);
   NS_IMETHOD SetHostIsUsingSubscription(const char *serverKey, bool usingSubscription);
 
   // Passwords
   NS_IMETHOD GetPasswordForHost(const char *serverKey, nsString &result);
--- a/mailnews/imap/src/nsImapCore.h
+++ b/mailnews/imap/src/nsImapCore.h
@@ -115,51 +115,68 @@ typedef enum {
 typedef enum {
     kPersonalNamespace = 0,
     kOtherUsersNamespace,
     kPublicNamespace,
     kDefaultNamespace,
     kUnknownNamespace
 } EIMAPNamespaceType;
 
-typedef enum {
-    kCapabilityUndefined = 0x00000000,
-    kCapabilityDefined = 0x00000001,
-    kHasAuthLoginCapability = 0x00000002, /* AUTH LOGIN (not the same as kHasAuthOldLoginCapability) */
-    kHasAuthOldLoginCapability = 0x00000004, /* original IMAP login method */
-    kHasXSenderCapability = 0x00000008,
-    kIMAP4Capability = 0x00000010,          /* RFC1734 */
-    kIMAP4rev1Capability = 0x00000020,      /* RFC2060 */
-    kIMAP4other = 0x00000040,                       /* future rev?? */
-    kNoHierarchyRename = 0x00000080,                        /* no hierarchy rename */
-    kACLCapability = 0x00000100,          /* ACL extension */
-    kNamespaceCapability = 0x00000200,    /* IMAP4 Namespace Extension */
-    kHasIDCapability = 0x00000400,  /* client user agent id extension */
-    kXServerInfoCapability = 0x00000800,  /* XSERVERINFO extension for admin urls */
-    kHasAuthPlainCapability = 0x00001000, /* new form of auth plain base64 login */
-    kUidplusCapability = 0x00002000,   /* RFC 2359 UIDPLUS extension */
-    kLiteralPlusCapability = 0x00004000, /* RFC 2088 LITERAL+ extension */
-    kAOLImapCapability = 0x00008000,     /* aol imap extensions */
-    kHasLanguageCapability = 0x00010000, /* language extensions */
-    kHasCRAMCapability     = 0x00020000, /* CRAM auth extension */
-    kQuotaCapability       = 0x00040000, /* RFC 2087 quota extension */
-    kHasIdleCapability       = 0x00080000,  /* RFC 2177 idle extension */
-    kHasAuthNTLMCapability = 0x00100000,  /* AUTH NTLM extension */
-    kHasAuthMSNCapability = 0x00200000,   /* AUTH MSN extension */
-    kHasStartTLSCapability = 0x00400000,   /* STARTTLS support */
-    kHasAuthNoneCapability = 0x00800000, /* needs no login */
-    kHasAuthGssApiCapability = 0x01000000, /* GSSAPI AUTH */
-    kHasCondStoreCapability =  0x02000000, /* RFC 3551 CondStore extension */
-    kHasEnableCapability    =  0x04000000, /* RFC 5161 ENABLE extension */
-    kHasXListCapability    =  0x08000000,  /* XLIST extension */
-    kHasCompressDeflateCapability  = 0x10000000,  /* RFC 4978 COMPRESS extension */
-    kHasAuthExternalCapability  = 0x20000000,  /* RFC 2222 SASL AUTH EXTERNAL */
-    kHasMoveCapability  = 0x40000000,  /* Proposed MOVE RFC */
-    kHasHighestModSeqCapability  = 0x80000000  /* Subset of RFC 3551 */
-} eIMAPCapabilityFlag;
+
+/**
+ * IMAP server feature, mostly CAPABILITY responses
+ *
+ * one of the cap flags below
+ */
+typedef PRUint64 eIMAPCapabilityFlag;
+/**
+ * IMAP server features, mostly CAPABILITY responses
+ *
+ * any set of the cap flags below, i.e.
+ * i.e. 0, 1 or more |eIMAPCapabilityFlag|.
+ */
+typedef PRUint64 eIMAPCapabilityFlags;
+
+const eIMAPCapabilityFlag kCapabilityUndefined = 0x00000000;
+const eIMAPCapabilityFlag kCapabilityDefined = 0x00000001;
+const eIMAPCapabilityFlag kHasAuthLoginCapability = 0x00000002;  /* AUTH LOGIN (not the same as kHasAuthOldLoginCapability) */
+const eIMAPCapabilityFlag kHasAuthOldLoginCapability = 0x00000004;  /* original IMAP login method */
+const eIMAPCapabilityFlag kHasXSenderCapability = 0x00000008;
+const eIMAPCapabilityFlag kIMAP4Capability = 0x00000010;           /* RFC1734 */
+const eIMAPCapabilityFlag kIMAP4rev1Capability = 0x00000020;       /* RFC2060 */
+const eIMAPCapabilityFlag kIMAP4other = 0x00000040;                        /* future rev?? */
+const eIMAPCapabilityFlag kNoHierarchyRename = 0x00000080;                         /* no hierarchy rename */
+const eIMAPCapabilityFlag kACLCapability = 0x00000100;           /* ACL extension */
+const eIMAPCapabilityFlag kNamespaceCapability = 0x00000200;     /* IMAP4 Namespace Extension */
+const eIMAPCapabilityFlag kHasIDCapability = 0x00000400;  /* client user agent id extension */
+const eIMAPCapabilityFlag kXServerInfoCapability = 0x00000800;  /* XSERVERINFO extension for admin urls */
+const eIMAPCapabilityFlag kHasAuthPlainCapability = 0x00001000; /* new form of auth plain base64 login */
+const eIMAPCapabilityFlag kUidplusCapability = 0x00002000;   /* RFC 2359 UIDPLUS extension */
+const eIMAPCapabilityFlag kLiteralPlusCapability = 0x00004000; /* RFC 2088 LITERAL+ extension */
+const eIMAPCapabilityFlag kAOLImapCapability = 0x00008000;     /* aol imap extensions */
+const eIMAPCapabilityFlag kHasLanguageCapability = 0x00010000; /* language extensions */
+const eIMAPCapabilityFlag kHasCRAMCapability = 0x00020000; /* CRAM auth extension */
+const eIMAPCapabilityFlag kQuotaCapability = 0x00040000; /* RFC 2087 quota extension */
+const eIMAPCapabilityFlag kHasIdleCapability = 0x00080000;  /* RFC 2177 idle extension */
+const eIMAPCapabilityFlag kHasAuthNTLMCapability = 0x00100000;  /* AUTH NTLM extension */
+const eIMAPCapabilityFlag kHasAuthMSNCapability = 0x00200000;   /* AUTH MSN extension */
+const eIMAPCapabilityFlag kHasStartTLSCapability =0x00400000;   /* STARTTLS support */
+const eIMAPCapabilityFlag kHasAuthNoneCapability = 0x00800000; /* needs no login */
+const eIMAPCapabilityFlag kHasAuthGssApiCapability = 0x01000000; /* GSSAPI AUTH */
+const eIMAPCapabilityFlag kHasCondStoreCapability = 0x02000000; /* RFC 3551 CondStore extension */
+const eIMAPCapabilityFlag kHasEnableCapability = 0x04000000; /* RFC 5161 ENABLE extension */
+const eIMAPCapabilityFlag kHasXListCapability = 0x08000000;  /* XLIST extension */
+const eIMAPCapabilityFlag kHasCompressDeflateCapability = 0x10000000;  /* RFC 4978 COMPRESS extension */
+const eIMAPCapabilityFlag kHasAuthExternalCapability = 0x20000000;  /* RFC 2222 SASL AUTH EXTERNAL */
+const eIMAPCapabilityFlag kHasMoveCapability = 0x40000000;  /* Proposed MOVE RFC */
+const eIMAPCapabilityFlag kHasHighestModSeqCapability = 0x80000000;  /* Subset of RFC 3551 */
+// above are 32bit; below start the PRUint64 bits 33-64
+const eIMAPCapabilityFlag kHasExtendedListCapability = 0x100000000LL;  /* RFC 5258 */
+const eIMAPCapabilityFlag kHasSpecialUseCapability = 0x200000000LL;  /* RFC 6154: Sent, Draft etc. folders */
+
 
 // this used to be part of the connection object class - maybe we should move it into 
 // something similar
 typedef enum {
     kEveryThingRFC822,
     kEveryThingRFC822Peek,
     kHeadersRFC822andUid,
     kUid,
--- a/mailnews/imap/src/nsImapIncomingServer.cpp
+++ b/mailnews/imap/src/nsImapIncomingServer.cpp
@@ -170,20 +170,16 @@ NS_IMETHODIMP nsImapIncomingServer::SetK
 
   if (!publicNamespace.IsEmpty())
       hostSession->SetNamespaceFromPrefForHost(key.get(), publicNamespace.get(),
                                                kPublicNamespace);
 
   if (!otherUsersNamespace.IsEmpty())
       hostSession->SetNamespaceFromPrefForHost(key.get(), otherUsersNamespace.get(),
                                                kOtherUsersNamespace);
-  PRInt32 capability;
-  rv = GetCapabilityPref(&capability);
-  NS_ENSURE_SUCCESS(rv, rv);
-  hostSession->SetCapabilityForHost(key.get(), capability);
   return rv;
 }
 
 // construct the pretty name to show to the user if they haven't
 // specified one. This should be overridden for news and mail.
 NS_IMETHODIMP
 nsImapIncomingServer::GetConstructedPrettyName(nsAString& retval)
 {
@@ -394,19 +390,16 @@ nsImapIncomingServer::SetDeleteModel(PRI
     }
   }
   return rv;
 }
 
 NS_IMPL_SERVERPREF_INT(nsImapIncomingServer, TimeOutLimits,
                        "timeout")
 
-NS_IMPL_SERVERPREF_INT(nsImapIncomingServer, CapabilityPref,
-                       "capability")
-
 NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, ServerIDPref,
                        "serverIDResponse")
 
 NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, PersonalNamespace,
                        "namespace.personal")
 
 NS_IMPL_SERVERPREF_STR(nsImapIncomingServer, PublicNamespace,
                        "namespace.public")
@@ -418,16 +411,21 @@ NS_IMPL_SERVERPREF_BOOL(nsImapIncomingSe
                        "fetch_by_chunks")
 
 NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, MimePartsOnDemand,
                        "mime_parts_on_demand")
 
 NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, SendID,
                        "send_client_info")
 
+NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, CapabilityACL,
+                       "cacheCapa.acl")
+NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, CapabilityQuota,
+                       "cacheCapa.quota")
+
 NS_IMETHODIMP
 nsImapIncomingServer::GetIsAOLServer(bool *aBool)
 {
   NS_ENSURE_ARG_POINTER(aBool);
   *aBool = ((m_capability & kAOLImapCapability) != 0);
   return NS_OK;
 }
 
@@ -2204,20 +2202,21 @@ nsImapIncomingServer::PromptPassword(nsI
 
   rv = GetPasswordWithUI(passwordText, passwordTitle, aMsgWindow, aPassword);
   if (NS_SUCCEEDED(rv))
     m_password = aPassword;
   return rv;
 }
 
 // for the nsIImapServerSink interface
-NS_IMETHODIMP nsImapIncomingServer::SetCapability(PRUint32 capability)
+NS_IMETHODIMP nsImapIncomingServer::SetCapability(eIMAPCapabilityFlags capability)
 {
   m_capability = capability;
-  SetCapabilityPref(capability);
+  SetCapabilityACL(capability & kACLCapability);
+  SetCapabilityQuota(capability & kQuotaCapability);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsImapIncomingServer::SetServerID(const nsACString &aServerID)
 {
   return SetServerIDPref(aServerID);
 }
 
--- a/mailnews/imap/src/nsImapIncomingServer.h
+++ b/mailnews/imap/src/nsImapIncomingServer.h
@@ -132,17 +132,17 @@ private:
                             PRUint32 folderFlag, nsCString &existingUri);
 
   nsCOMArray<nsIImapProtocol> m_connectionCache;
   nsCOMArray<nsIImapUrl> m_urlQueue;
   nsCOMPtr<nsIStringBundle>	m_stringBundle;
   nsCOMArray<nsIMsgFolder> m_subscribeFolders; // used to keep folder resources around while subscribe UI is up.
   nsCOMArray<nsIMsgImapMailFolder> m_foldersToStat; // folders to check for new mail with Status
   nsVoidArray       m_urlConsumers;
-  PRUint32          m_capability;
+  eIMAPCapabilityFlags          m_capability;
   nsCString         m_manageMailAccountUrl;
   bool              m_userAuthenticated;
   bool              mDoingSubscribeDialog;
   bool              mDoingLsub;
   bool              m_shuttingDown;
 
   mozilla::Mutex mLock;
   // subscribe dialog stuff
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -5926,29 +5926,31 @@ nsImapMailFolder::FillInFolderProps(nsIM
   nsString folderType;
   nsString folderTypeDesc;
   nsString folderQuotaStatusDesc;
   nsCOMPtr<nsIStringBundle> bundle;
   nsresult rv = IMAPGetStringBundle(getter_AddRefs(bundle));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // get the host session list and get server capabilities.
-  PRUint32 capability = kCapabilityUndefined;
-
-  nsCOMPtr<nsIImapHostSessionList> hostSession = do_GetService(kCImapHostSessionList, &rv);
+  eIMAPCapabilityFlags capability = kCapabilityUndefined;
+
+  nsCOMPtr<nsIImapIncomingServer> imapServer;
+  rv = GetImapIncomingServer(getter_AddRefs(imapServer));
   // if for some bizarre reason this fails, we'll still fall through to the normal sharing code
-  if (NS_SUCCEEDED(rv) && hostSession)
-  {
-    nsCString serverKey;
-    GetServerKey(serverKey);
-    hostSession->GetCapabilityForHost(serverKey.get(), capability);
+  if (NS_SUCCEEDED(rv))
+  {
+    bool haveACL = false;
+    bool haveQuota = false;
+    imapServer->GetCapabilityACL(&haveACL);
+    imapServer->GetCapabilityQuota(&haveQuota);
 
     // Figure out what to display in the Quota tab of the folder properties.
     // Does the server support quotas?
-    if(capability & kQuotaCapability)
+    if (haveQuota)
     {
       // Have we asked the server for quota information?
       if(m_folderQuotaCommandIssued)
       {
         // Has the server replied with storage quota info?
         if(m_folderQuotaDataIsValid)
         {
           // If so, set quota data
@@ -5989,17 +5991,17 @@ nsImapMailFolder::FillInFolderProps(nsIM
       rv = IMAPGetStringByID(folderQuotaStatusStringID, getter_Copies(folderQuotaStatusDesc));
       if (NS_SUCCEEDED(rv))
         aFolderProps->SetQuotaStatus(folderQuotaStatusDesc);
     }
 
     // See if the server supports ACL.
     // If not, just set the folder description to a string that says
     // the server doesn't support sharing, and return.
-    if (! (capability & kACLCapability))
+    if (!haveACL)
     {
       rv = IMAPGetStringByID(IMAP_SERVER_DOESNT_SUPPORT_ACL, getter_Copies(folderTypeDesc));
       if (NS_SUCCEEDED(rv))
         aFolderProps->SetFolderTypeDescription(folderTypeDesc);
       aFolderProps->ServerDoesntSupportACL();
       return NS_OK;
     }
   }
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -747,20 +747,16 @@ nsresult nsImapProtocol::SetupWithUrl(ns
     // we need to turn it into a proxy object....we'll assume that the listener is on the same thread
     // as the event sink queue
     if (aRealStreamListener)
     {
       NS_ASSERTION(!m_channelListener, "shouldn't already have a channel listener");
       m_channelListener = new StreamListenerProxy(aRealStreamListener);
     }
 
-    PRUint32 capability = kCapabilityUndefined;
-
-    m_hostSessionList->GetCapabilityForHost(GetImapServerKey(), capability);
-
     server->GetRealHostName(m_realHostName);
     PRInt32 authMethod;
     (void) server->GetAuthMethod(&authMethod);
     InitPrefAuthMethods(authMethod);
     (void) server->GetSocketType(&m_socketType);
     bool shuttingDown;
     (void) imapServer->GetShuttingDown(&shuttingDown);
     if (!shuttingDown)
@@ -809,19 +805,17 @@ nsresult nsImapProtocol::SetupWithUrl(ns
         aURL->GetPort(&port);
 
         Log("SetupWithUrl", nsnull, "clearing IMAP_CONNECTION_IS_OPEN");
         ClearFlag(IMAP_CONNECTION_IS_OPEN);
         const char *connectionType = nsnull;
 
         if (m_socketType == nsMsgSocketType::SSL)
           connectionType = "ssl";
-        else if ((m_socketType == nsMsgSocketType::trySTARTTLS &&
-                 (capability & kHasStartTLSCapability))
-                 || m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+        else if (m_socketType == nsMsgSocketType::alwaysSTARTTLS)
           connectionType = "starttls";
 
         nsCOMPtr<nsIProxyInfo> proxyInfo;
         rv = MsgExamineForProxy("imap", m_realHostName.get(), port, getter_AddRefs(proxyInfo));
         if (NS_FAILED(rv))
           proxyInfo = nsnull;
 
         const nsACString *socketHost;
@@ -1654,29 +1648,36 @@ bool nsImapProtocol::ProcessCurrentURL()
             {
               nsCOMPtr<nsISSLSocketControl> sslControl = do_QueryInterface(secInfo, &rv);
 
               if (NS_SUCCEEDED(rv) && sslControl)
               {
                 rv = sslControl->StartTLS();
                 if (NS_SUCCEEDED(rv))
                 {
+                  // Upgrade "trySTARTTLS" accounts to "alwaysSTARTTLS" in prefs
+                  if (m_socketType == nsMsgSocketType::trySTARTTLS)
+                  {
+                    nsCOMPtr<nsIMsgIncomingServer> imapServer =
+                        do_QueryReferent(m_server);
+                    imapServer->SetSocketType(nsMsgSocketType::alwaysSTARTTLS);
+                  }
+
                   // force re-issue of "capability", because servers may
                   // enable other auth features (e.g. remove LOGINDISABLED
                   // and add AUTH=PLAIN) after we upgraded to SSL.
                   Capability();
-                  PRInt32 capabilityFlag = GetServerStateParser().GetCapabilityFlag();
+                  eIMAPCapabilityFlags capabilityFlag = GetServerStateParser().GetCapabilityFlag();
                   // Courier imap doesn't return STARTTLS capability if we've done
                   // a STARTTLS! But we need to remember this capability so we'll
                   // try to use STARTTLS next time.
                   if (!(capabilityFlag & kHasStartTLSCapability))
                   {
                     capabilityFlag |= kHasStartTLSCapability;
                     GetServerStateParser().SetCapabilityFlag(capabilityFlag);
-                    m_hostSessionList->SetCapabilityForHost(GetImapServerKey(), capabilityFlag);
                     CommitCapability();
                   }
                 }
               }
             }
             if (NS_FAILED(rv))
             {
               nsCAutoString logLine("STARTTLS negotiation failed. Error 0x");
@@ -3364,17 +3365,17 @@ nsImapProtocol::FetchMessage(const nsCSt
     }
     commandString.Append(")");
 
     break;
 
   case kEveryThingRFC822Peek:
     {
       const char *formatString = "";
-      PRUint32 server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
+      eIMAPCapabilityFlags server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
 
       GetServerStateParser().SetFetchingEverythingRFC822(true);
       if (server_capabilityFlags & kIMAP4rev1Capability)
       {
         // use body[].peek since rfc822.peek is not in IMAP4rev1
         if (server_capabilityFlags & kHasXSenderCapability)
           formatString = " %s (XSENDER UID RFC822.SIZE BODY.PEEK[]";
         else
@@ -3400,17 +3401,17 @@ nsImapProtocol::FetchMessage(const nsCSt
         }
       }
       commandString.Append(")");
     }
     break;
   case kHeadersRFC822andUid:
     if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
     {
-      PRUint32 server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
+      eIMAPCapabilityFlags server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
       bool aolImapServer = ((server_capabilityFlags & kAOLImapCapability) != 0);
       bool downloadAllHeaders = false;
       // checks if we're filtering on "any header" or running a spam filter requiring all headers
       GetShouldDownloadAllHeaders(&downloadAllHeaders);
 
       if (!downloadAllHeaders)  // if it's ok -- no filters on any header, etc.
       {
         char *headersToDL = nsnull;
@@ -5337,21 +5338,20 @@ void nsImapProtocol::Capability()
 
     command.Append(" capability" CRLF);
 
     nsresult rv = SendData(command.get());
     if (NS_SUCCEEDED(rv))
         ParseIMAPandCheckForNewMail();
     if (!gUseLiteralPlus)
     {
-      PRUint32 capabilityFlag = GetServerStateParser().GetCapabilityFlag();
+      eIMAPCapabilityFlags capabilityFlag = GetServerStateParser().GetCapabilityFlag();
       if (capabilityFlag & kLiteralPlusCapability)
       {
         GetServerStateParser().SetCapabilityFlag(capabilityFlag & ~kLiteralPlusCapability);
-        m_hostSessionList->SetCapabilityForHost(GetImapServerKey(), capabilityFlag & ~kLiteralPlusCapability);
       }
     }
 }
 
 void nsImapProtocol::ID()
 {
   if (!gAppName[0])
     return;
@@ -5542,18 +5542,18 @@ void nsImapProtocol::InitPrefAuthMethods
 
 /**
  * Changes m_currentAuthMethod to pick the best remaining one
  * which is allowed by server and prefs and not marked failed.
  * The order of preference and trying of auth methods is encoded here.
  */
 nsresult nsImapProtocol::ChooseAuthMethod()
 {
-  PRInt32 serverCaps = GetServerStateParser().GetCapabilityFlag();
-  PRInt32 availCaps = serverCaps & m_prefAuthMethods & ~m_failedAuthMethods;
+  eIMAPCapabilityFlags serverCaps = GetServerStateParser().GetCapabilityFlag();
+  eIMAPCapabilityFlags availCaps = serverCaps & m_prefAuthMethods & ~m_failedAuthMethods;
 
   PR_LOG(IMAP, PR_LOG_DEBUG, ("IMAP auth: server caps 0x%X, pref 0x%X, failed 0x%X, avail caps 0x%X",
         serverCaps, m_prefAuthMethods, m_failedAuthMethods, availCaps));
   PR_LOG(IMAP, PR_LOG_DEBUG, ("(GSSAPI = 0x%X, CRAM = 0x%X, NTLM = 0x%X, "
         "MSN =  0x%X, PLAIN = 0x%X, LOGIN = 0x%X, old-style IMAP login = 0x%X)"
         "auth external IMAP login = 0x%X",
         kHasAuthGssApiCapability, kHasCRAMCapability, kHasAuthNTLMCapability,
         kHasAuthMSNCapability, kHasAuthPlainCapability, kHasAuthLoginCapability,
@@ -5580,17 +5580,17 @@ nsresult nsImapProtocol::ChooseAuthMetho
     PR_LOG(IMAP, PR_LOG_DEBUG, ("no remaining auth method"));
     m_currentAuthMethod = kCapabilityUndefined;
     return NS_ERROR_FAILURE;
   }
   PR_LOG(IMAP, PR_LOG_DEBUG, ("trying auth method 0x%X", m_currentAuthMethod));
   return NS_OK;
 }
 
-void nsImapProtocol::MarkAuthMethodAsFailed(PRInt32 failedAuthMethod)
+void nsImapProtocol::MarkAuthMethodAsFailed(eIMAPCapabilityFlags failedAuthMethod)
 {
   PR_LOG(IMAP, PR_LOG_DEBUG, ("marking auth method 0x%X failed", failedAuthMethod));
   m_failedAuthMethods |= failedAuthMethod;
 }
 
 /**
  * Start over, trying all auth methods again
  */
--- a/mailnews/imap/src/nsImapProtocol.h
+++ b/mailnews/imap/src/nsImapProtocol.h
@@ -492,17 +492,17 @@ private:
   const char *GetServerCommandTag();
 
   void StartTLS();
 
   // login related methods.
   nsresult GetPassword(nsCString &password, bool aNewPasswordRequested);
   void InitPrefAuthMethods(PRInt32 authMethodPrefValue);
   nsresult ChooseAuthMethod();
-  void MarkAuthMethodAsFailed(PRInt32 failedAuthMethod);
+  void MarkAuthMethodAsFailed(eIMAPCapabilityFlags failedAuthMethod);
   void ResetAuthMethods();
 
   // All of these methods actually issue protocol
   void Capability(); // query host for capabilities.
   void ID(); // send RFC 2971 app info to server
   void EnableCondStore(); 
   void StartCompressDeflate();
   nsresult BeginCompressing();
@@ -618,18 +618,18 @@ private:
   PRInt32 m_tooFastTime;
   PRInt32 m_idealTime;
   PRInt32 m_chunkAddSize;
   PRInt32 m_chunkStartSize;
   bool    m_fetchByChunks;
   bool    m_sendID;
   PRInt32 m_curFetchSize;
   bool    m_ignoreExpunges;
-  PRInt32 m_prefAuthMethods; // set of capability flags (in nsImapCore.h) for auth methods
-  PRInt32 m_failedAuthMethods; // ditto
+  eIMAPCapabilityFlags m_prefAuthMethods; // set of capability flags (in nsImapCore.h) for auth methods
+  eIMAPCapabilityFlags m_failedAuthMethods; // ditto
   eIMAPCapabilityFlag m_currentAuthMethod; // exactly one capability flag, or 0
   PRInt32 m_socketType;
   PRInt32 m_chunkSize;
   PRInt32 m_chunkThreshold;
   nsRefPtr <nsMsgImapLineDownloadCache> m_downloadLineCache;
   nsRefPtr <nsMsgImapHdrXferInfo> m_hdrDownloadCache;
   nsCOMPtr <nsIImapHeaderInfo> m_curHdrInfo;
   // mapping between special xlist mailboxes and the corresponding folder flag
--- a/mailnews/imap/src/nsImapServerResponseParser.cpp
+++ b/mailnews/imap/src/nsImapServerResponseParser.cpp
@@ -2247,31 +2247,31 @@ void nsImapServerResponseParser::capabil
       else if (token.Equals("LANGUAGE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasLanguageCapability;
       else if (token.Equals("IDLE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasIdleCapability;
       else if (token.Equals("CONDSTORE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasCondStoreCapability;
       else if (token.Equals("ENABLE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasEnableCapability;
+      else if (token.Equals("EXTENDED-LIST", nsCaseInsensitiveCStringComparator()))
+        fCapabilityFlag |= kHasExtendedListCapability;
       else if (token.Equals("XLIST", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasXListCapability;
+      else if (token.Equals("SPECIAL-USE", nsCaseInsensitiveCStringComparator()))
+        fCapabilityFlag |= kHasSpecialUseCapability;
       else if (token.Equals("COMPRESS=DEFLATE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasCompressDeflateCapability;
       else if (token.Equals("MOVE", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasMoveCapability;
       else if (token.Equals("HIGHESTMODSEQ", nsCaseInsensitiveCStringComparator()))
         fCapabilityFlag |= kHasHighestModSeqCapability;
     }
   } while (fNextToken && endToken < 0 && !fAtEndOfLine && ContinueParse());
 
-  if (fHostSessionList)
-    fHostSessionList->SetCapabilityForHost(
-    fServerConnection.GetImapServerKey(), 
-    fCapabilityFlag);
   nsImapProtocol *navCon = &fServerConnection;
   NS_ASSERTION(navCon, "null imap protocol connection while parsing capability response");	// we should always have this
   if (navCon)
     navCon->CommitCapability();
   skip_to_CRLF();
 }
 
 void nsImapServerResponseParser::xmailboxinfo_data()
@@ -3037,21 +3037,16 @@ void	nsImapServerResponseParser::UseCach
 		NS_ASSERTION(false, "shell collision");
 	}
 	m_shell = cachedShell;
 }
 
 
 void nsImapServerResponseParser::ResetCapabilityFlag() 
 {
-    if (fHostSessionList)
-    {
-        fHostSessionList->SetCapabilityForHost(
-            fServerConnection.GetImapServerKey(), kCapabilityUndefined);
-    }
 }
 
 /*
  literal         ::= "{" number "}" CRLF *CHAR8
                               ;; Number represents the number of CHAR8 octets
 */
 // returns true if this is the last chunk and we should close the stream
 bool nsImapServerResponseParser::msg_fetch_literal(bool chunk, PRInt32 origin)
--- a/mailnews/imap/src/nsImapServerResponseParser.h
+++ b/mailnews/imap/src/nsImapServerResponseParser.h
@@ -116,18 +116,18 @@ public:
   // Resets the flags state.
   void ResetFlagInfo();
 
   // set this to false if you don't want to alert the user to server
   // error messages
   void SetReportingErrors(bool reportThem) { fReportingErrors=reportThem;}
   bool GetReportingErrors() { return fReportingErrors; }
 
-  PRUint32 GetCapabilityFlag() { return fCapabilityFlag; }
-  void   SetCapabilityFlag(PRUint32 capability) {fCapabilityFlag = capability;}
+  eIMAPCapabilityFlags GetCapabilityFlag() { return fCapabilityFlag; }
+  void   SetCapabilityFlag(eIMAPCapabilityFlags capability) {fCapabilityFlag = capability;}
   bool ServerHasIMAP4Rev1Capability() { return ((fCapabilityFlag & kIMAP4rev1Capability) != 0); }
   bool ServerHasACLCapability() { return ((fCapabilityFlag & kACLCapability) != 0); }
   bool ServerHasNamespaceCapability() { return ((fCapabilityFlag & kNamespaceCapability) != 0); }
   bool ServerIsNetscape3xServer() { return fServerIsNetscape3xServer; }
   bool ServerHasServerInfo() {return ((fCapabilityFlag & kXServerInfoCapability) != 0); }
   bool ServerIsAOLServer() {return ((fCapabilityFlag & kAOLImapCapability) != 0); }
   void SetFetchingFlags(bool aFetchFlags) { fFetchingAllFlags = aFetchFlags;}
   void ResetCapabilityFlag() ;
@@ -267,17 +267,17 @@ private:
   char              *fSelectedMailboxName;
 
   nsImapSearchResultSequence    *fSearchResults;
 
   nsCOMPtr <nsIImapFlagAndUidState> fFlagState;		// NOT owned by us, it's a copy, do not destroy
 
   eIMAPstate               fIMAPstate;
 
-  PRUint32      fCapabilityFlag;
+  eIMAPCapabilityFlags      fCapabilityFlag;
   nsCString     fMailAccountUrl;
   char          *fNetscapeServerVersionString;
   char          *fXSenderInfo; /* changed per message download */
   char          *fLastAlert; /* used to avoid displaying the same alert over and over */
   nsCString     fManageListsUrl;
   nsCString    fManageFiltersUrl;
   char          *fFolderAdminUrl;
   nsCString    fServerIdResponse; // RFC 
--- a/mailnews/imap/src/nsSyncRunnableHelpers.cpp
+++ b/mailnews/imap/src/nsSyncRunnableHelpers.cpp
@@ -453,17 +453,17 @@ NS_SYNCRUNNABLEMETHOD3(ImapServerSink, A
 NS_SYNCRUNNABLEMETHOD1(ImapServerSink, RefreshFolderRights, const nsACString &)
 NS_SYNCRUNNABLEMETHOD0(ImapServerSink, DiscoveryDone)
 NS_SYNCRUNNABLEMETHOD1(ImapServerSink, OnlineFolderDelete, const nsACString &)
 NS_SYNCRUNNABLEMETHOD1(ImapServerSink, OnlineFolderCreateFailed, const nsACString &)
 NS_SYNCRUNNABLEMETHOD3(ImapServerSink, OnlineFolderRename, nsIMsgWindow *, const nsACString &, const nsACString &)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, FolderIsNoSelect, const nsACString &, bool *)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, SetFolderAdminURL, const nsACString &, const nsACString &)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, FolderVerifiedOnline, const nsACString &, bool *)
-NS_SYNCRUNNABLEMETHOD1(ImapServerSink, SetCapability, PRUint32)
+NS_SYNCRUNNABLEMETHOD1(ImapServerSink, SetCapability, eIMAPCapabilityFlags)
 NS_SYNCRUNNABLEMETHOD1(ImapServerSink, SetServerID, const nsACString &)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, LoadNextQueuedUrl, nsIImapProtocol *, bool *)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, PrepareToRetryUrl, nsIImapUrl *, nsIImapMockChannel **)
 NS_SYNCRUNNABLEMETHOD1(ImapServerSink, SuspendUrl, nsIImapUrl *)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, RetryUrl, nsIImapUrl *, nsIImapMockChannel *)
 NS_SYNCRUNNABLEMETHOD0(ImapServerSink, AbortQueuedUrls)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, GetImapStringByID, PRInt32, nsAString &)
 NS_SYNCRUNNABLEMETHOD2(ImapServerSink, PromptLoginFailed, nsIMsgWindow *, PRInt32 *)