Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sun, 22 Jul 2012 22:01:57 -0400
changeset 100124 82b6c58853454e56d0876dc2f58d66dfc2b64e13
parent 100123 57499abe647938d0350eb641bd13e39036360d14 (current diff)
parent 100081 c6a54c7607ca879c1e72da094ec0cc9cdd31a661 (diff)
child 100125 91b0607471cca891bcf27f2446c885c3d72e636d
child 100243 d78729026fb9db89f3040e70a2837cc3e221a901
child 100295 20c801d85f36ff273e357bd55c781f32aaac5d79
push id12341
push useremorley@mozilla.com
push dateMon, 23 Jul 2012 13:33:45 +0000
treeherdermozilla-inbound@91b0607471cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
82b6c5885345 / 17.0a1 / 20120723030606 / files
nightly linux64
82b6c5885345 / 17.0a1 / 20120723030606 / files
nightly mac
82b6c5885345 / 17.0a1 / 20120723030606 / files
nightly win32
82b6c5885345 / 17.0a1 / 20120723030606 / files
nightly win64
82b6c5885345 / 17.0a1 / 20120723030606 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
netwerk/base/public/nsIPrivateBrowsingConsumer.idl
netwerk/base/src/PrivateBrowsingConsumer.h
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -198,18 +198,17 @@ nsCoreUtils::GetDOMElementFor(nsIContent
   return nsnull;
 }
 
 nsINode *
 nsCoreUtils::GetDOMNodeFromDOMPoint(nsINode *aNode, PRUint32 aOffset)
 {
   if (aNode && aNode->IsElement()) {
     PRUint32 childCount = aNode->GetChildCount();
-    NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
-                 "Wrong offset of the DOM point!");
+    NS_ASSERTION(aOffset <= childCount, "Wrong offset of the DOM point!");
 
     // The offset can be after last child of container node that means DOM point
     // is placed immediately after the last child. In this case use the DOM node
     // from the given DOM point is used as result node.
     if (aOffset != childCount)
       return aNode->GetChildAt(aOffset);
   }
 
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -260,17 +260,17 @@ ARIAGridAccessible::SelectedCells(nsTArr
         aCells->AppendElement(cell);
     }
   }
 }
 
 void
 ARIAGridAccessible::SelectedCellIndices(nsTArray<PRUint32>* aCells)
 {
-  PRUint32 rowCount = RowCount(), colCount = ColCount();
+  PRUint32 colCount = ColCount();
 
   AccIterator rowIter(this, filters::GetRow);
   Accessible* row = nsnull;
   for (PRUint32 rowIdx = 0; (row = rowIter.Next()); rowIdx++) {
     if (nsAccUtils::IsARIASelected(row)) {
       for (PRUint32 colIdx = 0; colIdx < colCount; colIdx++)
         aCells->AppendElement(rowIdx * colCount + colIdx);
 
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1803,18 +1803,16 @@ HyperTextAccessible::SetSelectionBounds(
   Selection* domSel =
     frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
   NS_ENSURE_STATE(domSel);
 
   PRUint32 rangeCount = domSel->GetRangeCount();
   if (rangeCount < static_cast<PRUint32>(aSelectionNum))
     return NS_ERROR_INVALID_ARG;
 
-  // Caret is a collapsed selection
-  bool isOnlyCaret = (aStartOffset == aEndOffset);
   nsRefPtr<nsRange> range;
   if (aSelectionNum == rangeCount)
     range = new nsRange();
   else
     range = domSel->GetRangeAt(aSelectionNum);
 
   nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset, range);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -31,16 +31,17 @@
 #include "nsIPresShell.h"
 #include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
 #include "nsFrameSelection.h"
 #include "nsLayoutErrors.h"
 #include "nsArrayUtils.h"
 #include "nsComponentManagerUtils.h"
 
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLTableCellAccessible::
   HTMLTableCellAccessible(nsIContent* aContent, DocAccessible* aDoc) :
@@ -761,40 +762,42 @@ HTMLTableAccessible::ColExtentAt(PRUint3
   if (!tableLayout)
     return 0;
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan;
   bool isSelected;
   PRInt32 columnExtent = 0;
 
-  tableLayout->
+  DebugOnly<nsresult> rv = tableLayout->
     GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
                   startRowIndex, startColIndex, rowSpan, colSpan,
                   actualRowSpan, columnExtent, isSelected);
+  NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get cell data");
 
   return columnExtent;
 }
 
 PRUint32
 HTMLTableAccessible::RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
   nsITableLayout* tableLayout = GetTableLayout();
   if (!tableLayout)
     return 0;
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualColSpan;
   bool isSelected;
   PRInt32 rowExtent = 0;
 
-  tableLayout->
+  DebugOnly<nsresult> rv = tableLayout->
     GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
                   startRowIndex, startColIndex, rowSpan, colSpan,
                   rowExtent, actualColSpan, isSelected);
+  NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get cell data");
 
   return rowExtent;
 }
 
 bool
 HTMLTableAccessible::IsColSelected(PRUint32 aColIdx)
 {
   bool isSelected = false;
--- a/accessible/src/xpcom/nsAccessibleRelation.h
+++ b/accessible/src/xpcom/nsAccessibleRelation.h
@@ -5,26 +5,27 @@
 
 #ifndef _nsAccessibleRelation_H_
 #define _nsAccessibleRelation_H_
 
 #include "nsIAccessibleRelation.h"
 
 #include "nsCOMPtr.h"
 #include "nsIMutableArray.h"
+#include "mozilla/Attributes.h"
 
 namespace mozilla {
 namespace a11y {
 
 class Relation;
 
 /**
  * Class represents an accessible relation.
  */
-class nsAccessibleRelation : public nsIAccessibleRelation
+class nsAccessibleRelation MOZ_FINAL : public nsIAccessibleRelation
 {
 public:
   nsAccessibleRelation(PRUint32 aType, Relation* aRel);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIACCESSIBLERELATION
 
 private:
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3866,16 +3866,22 @@ NS_DOMStructuredCloneError(JSContext* cx
   xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
 }
 
 static nsresult
 ReadSourceFromFilename(JSContext *cx, const char *filename, jschar **src, PRUint32 *len)
 {
   nsresult rv;
 
+  // mozJSSubScriptLoader prefixes the filenames of the scripts it loads with
+  // the filename of its caller. Axe that if present.
+  const char *arrow = strstr(filename, " -> ");
+  if (arrow)
+    filename = arrow + strlen(" -> ");
+
   // Get the URI.
   nsCOMPtr<nsIURI> uri;
   rv = NS_NewURI(getter_AddRefs(uri), filename);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIChannel> scriptChannel;
   rv = NS_NewChannel(getter_AddRefs(scriptChannel), uri);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -78,16 +78,17 @@
 #endif
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 
 #include "mozilla/dom/sms/SmsChild.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
+#include "mozilla/dom/indexedDB/PIndexedDBChild.h"
 
 using namespace mozilla::docshell;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::sms;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -16,14 +16,17 @@ class GeckoContentController {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
 
   /**
    * Requests a paint of the given FrameMetrics |aFrameMetrics| from Gecko.
    * Implementations per-platform are responsible for actually handling this.
    */
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) = 0;
+
+  GeckoContentController() {};
+  virtual ~GeckoContentController() {};
 };
 
 }
 }
 
 #endif // mozilla_layers_GeckoContentController_h
--- a/js/xpconnect/tests/chrome/test_chrometoSource.xul
+++ b/js/xpconnect/tests/chrome/test_chrometoSource.xul
@@ -12,24 +12,29 @@
   <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=761723" target="_blank">Mozilla Bug 761723</a>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript" src="outoflinexulscript.js"></script>
   <script type="application/javascript"><![CDATA[
 const Cu = Components.utils;
 Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
 function inlinefunction() {
          return 42;
 }
 
 var src;
 src = inlinefunction.toSource();
 isnot(src.indexOf("return 42"), -1, "inline XUL script should have source");
 is(src.charAt(src.length - 1), "}", "inline XUL source should end with '}'");
 src = outoflinefunction.toSource();
 isnot(src.indexOf("return 42"), -1, "out of line XUL script should have source")
 is(src.charAt(src.length - 1), "}", "out of line XUL source should end with '}'");
-src = NetUtil.asyncFetch.toSource()
+src = NetUtil.asyncFetch.toSource();
 isnot(src.indexOf("return"), -1, "JSM should have source");
+var ns = {};
+Services.scriptloader.loadSubScript("resource://gre/modules/NetUtil.jsm", ns);
+src = ns.NetUtil.asyncFetch.toSource();
+isnot(src.indexOf("return"), -1, "subscript should have source");
   ]]></script>
 </window>
--- a/netwerk/base/public/Makefile.in
+++ b/netwerk/base/public/Makefile.in
@@ -53,17 +53,16 @@ XPIDLSRCS	= \
 		nsIInputStreamChannel.idl \
                 nsIIOService2.idl \
                 nsIIPCSerializable.idl \
 		nsIMIMEInputStream.idl \
 		nsINetAddr.idl \
                 nsINetworkLinkService.idl \
 		nsIPermission.idl \
 		nsIPermissionManager.idl \
-		nsIPrivateBrowsingConsumer.idl \
 		nsIPrivateBrowsingService.idl \
 		nsIProgressEventSink.idl \
 		nsIPrompt.idl \
 		nsIProtocolProxyService.idl \
 		nsIProtocolProxyService2.idl \
 		nsIProtocolProxyFilter.idl \
 		nsIProtocolProxyCallback.idl \
 		nsIProxiedProtocolHandler.idl \
deleted file mode 100644
--- a/netwerk/base/public/nsIPrivateBrowsingConsumer.idl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* 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/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(5deb421c-592b-4375-b425-9ac11532aa30)]
-interface nsIPrivateBrowsingConsumer : nsISupports
-{
-  readonly attribute boolean usingPrivateBrowsing;
-
-%{C++
-  /**
-   * De-XPCOMed getter to make call-sites cleaner.
-   */
-  bool UsePrivateBrowsing() {
-    bool usingPB;
-    GetUsingPrivateBrowsing(&usingPB);
-    return usingPB;
-  }
-%}
-};
--- a/netwerk/base/public/nsNetUtil.h
+++ b/netwerk/base/public/nsNetUtil.h
@@ -69,16 +69,17 @@
 #include "nsIWritablePropertyBag2.h"
 #include "nsIIDNService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIChannelPolicy.h"
 #include "nsISocketProviderService.h"
 #include "nsISocketProvider.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "nsIMIMEHeaderParam.h"
+#include "nsILoadContext.h"
 #include "mozilla/Services.h"
 
 #ifdef MOZILLA_INTERNAL_API
 
 inline already_AddRefed<nsIIOService>
 do_GetIOService(nsresult* error = 0)
 {
     already_AddRefed<nsIIOService> ret = mozilla::services::GetIOService();
@@ -1292,16 +1293,31 @@ NS_QueryNotificationCallbacks(nsIInterfa
             loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
             if (cbs)
                 cbs->GetInterface(iid, result);
         }
     }
 }
 
 /**
+ * Returns true if channel is using Private Browsing, or false if not.
+ *
+ * Note: you may get a false negative if you call this before AsyncOpen has been
+ * called (technically, before the channel's notificationCallbacks are set: this
+ * is almost always done before AsyncOpen).
+ */
+inline bool
+NS_UsePrivateBrowsing(nsIChannel *channel)
+{
+  nsCOMPtr<nsILoadContext> loadContext;
+  NS_QueryNotificationCallbacks(channel, loadContext);
+  return loadContext && loadContext->UsePrivateBrowsing();
+}
+
+/**
  * Wraps an nsIAuthPrompt so that it can be used as an nsIAuthPrompt2. This
  * method is provided mainly for use by other methods in this file.
  *
  * *aAuthPrompt2 should be set to null before calling this function.
  */
 inline void
 NS_WrapAuthPrompt(nsIAuthPrompt *aAuthPrompt, nsIAuthPrompt2** aAuthPrompt2)
 {
deleted file mode 100644
--- a/netwerk/base/src/PrivateBrowsingConsumer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* 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/. */
-
-#ifndef mozilla_net_PrivateBrowsingConsumer_h
-#define mozilla_net_PrivateBrowsingConsumer_h
-
-#include "nsIPrivateBrowsingConsumer.h"
-#include "nsILoadContext.h"
-#include "nsNetUtil.h"
-#include "nsXULAppAPI.h"
-
-namespace mozilla {
-namespace net {
-
-class PrivateBrowsingConsumer : public nsIPrivateBrowsingConsumer
-{
- public:
-  PrivateBrowsingConsumer(nsIChannel* aSelf) : mSelf(aSelf), mUsingPB(false), mOverride(false) {}
-
-  NS_IMETHOD GetUsingPrivateBrowsing(bool *aUsingPB)
-  {
-    *aUsingPB = (mOverride ? mUsingPB : UsingPrivateBrowsingInternal());
-    return NS_OK;
-  }
-  
-  void OverridePrivateBrowsing(bool aUsingPrivateBrowsing)
-  {
-    MOZ_ASSERT(!mOverride);
-    MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
-    mOverride = true;
-    mUsingPB = aUsingPrivateBrowsing;
-  }
-
- protected:
-  bool UsingPrivateBrowsingInternal()
-  {
-    nsCOMPtr<nsILoadContext> loadContext;
-    NS_QueryNotificationCallbacks(mSelf, loadContext);
-    return loadContext && loadContext->UsePrivateBrowsing();
-  }
-
- private:
-   nsIChannel* mSelf;
-
-  // Private browsing capabilities can only be determined in content
-  // processes, so when networking occurs these values are used in
-  // lieu of UsingPrivateBrowsing().
-  bool mUsingPB;
-  bool mOverride;
-};
-
-}
-}
-
-#endif // mozilla_net_PrivateBrowsingConsumer_h
--- a/netwerk/base/src/nsBaseChannel.h
+++ b/netwerk/base/src/nsBaseChannel.h
@@ -240,17 +240,16 @@ private:
 
   private:
     nsRefPtr<nsBaseChannel> mChannel;
     nsCOMPtr<nsIChannel> mNewChannel;
   };
   friend class RedirectRunnable;
 
   nsRefPtr<nsInputStreamPump>         mPump;
-  nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
   nsCOMPtr<nsIProgressEventSink>      mProgressSink;
   nsCOMPtr<nsIURI>                    mOriginalURI;
   nsCOMPtr<nsIURI>                    mURI;
   nsCOMPtr<nsISupports>               mOwner;
   nsCOMPtr<nsISupports>               mSecurityInfo;
   nsCOMPtr<nsIChannel>                mRedirectChannel;
   nsCString                           mContentType;
   nsCString                           mContentCharset;
@@ -259,14 +258,15 @@ private:
   bool                                mSynthProgressEvents;
   bool                                mWasOpened;
   bool                                mWaitingOnAsyncRedirect;
   bool                                mOpenRedirectChannel;
   PRUint32                            mRedirectFlags;
 
 protected:
   nsCOMPtr<nsILoadGroup>              mLoadGroup;
+  nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
   nsCOMPtr<nsIStreamListener>         mListener;
   nsCOMPtr<nsISupports>               mListenerContext;
   nsresult                            mStatus;
 };
 
 #endif // !nsBaseChannel_h__
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -8,28 +8,28 @@
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/FTPChannelChild.h"
 #include "nsFtpProtocolHandler.h"
 
 #include "nsStringStream.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsIURIFixup.h"
+#include "nsILoadContext.h"
 #include "nsCDefaultURIFixup.h"
 #include "base/compiler_specific.h"
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelChild::FTPChannelChild(nsIURI* uri)
-: PrivateBrowsingConsumer(this)
-, mIPCOpen(false)
+: mIPCOpen(false)
 , ALLOW_THIS_IN_INITIALIZER_LIST(mEventQ(static_cast<nsIFTPChannel*>(this)))
 , mCanceled(false)
 , mSuspendCount(0)
 , mIsPending(false)
 , mWasOpened(false)
 , mLastModifiedTime(0)
 , mStartPos(0)
 {
@@ -155,18 +155,37 @@ FTPChannelChild::AsyncOpen(::nsIStreamLi
   gNeckoChild->SendPFTPChannelConstructor(this);
   mListener = listener;
   mListenerContext = aContext;
 
   // add ourselves to the load group. 
   if (mLoadGroup)
     mLoadGroup->AddRequest(this, nsnull);
 
+  // Get info from nsILoadContext, if any
+  bool haveLoadContext = false;
+  bool isContent = false;
+  bool usePrivateBrowsing = false;
+  bool isInBrowserElement = false;
+  PRUint32 appId = 0;
+  nsCOMPtr<nsILoadContext> loadContext;
+  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
+                                NS_GET_IID(nsILoadContext),
+                                getter_AddRefs(loadContext));
+  if (loadContext) {
+    haveLoadContext = true;
+    loadContext->GetIsContent(&isContent);
+    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
+    loadContext->GetIsInBrowserElement(&isInBrowserElement);
+    loadContext->GetAppId(&appId);
+  }
+
   SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID,
-                IPC::InputStream(mUploadStream), UsePrivateBrowsing());
+                IPC::InputStream(mUploadStream), haveLoadContext, isContent,
+                usePrivateBrowsing, isInBrowserElement, appId);
 
   // The socket transport layer in the chrome process now has a logical ref to
   // us until OnStopRequest is called.
   AddIPDLReference();
 
   mIsPending = true;
   mWasOpened = true;
 
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -11,17 +11,16 @@
 #include "mozilla/net/PFTPChannelChild.h"
 #include "mozilla/net/ChannelEventQueue.h"
 #include "nsBaseChannel.h"
 #include "nsIFTPChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsIProxiedChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsIChildChannel.h"
-#include "PrivateBrowsingConsumer.h"
 
 #include "nsIStreamListener.h"
 
 namespace mozilla {
 namespace net {
 
 // This class inherits logic from nsBaseChannel that is not needed for an
 // e10s child channel, but it works.  At some point we could slice up
@@ -30,17 +29,16 @@ namespace net {
 
 class FTPChannelChild : public PFTPChannelChild
                       , public nsBaseChannel
                       , public nsIFTPChannel
                       , public nsIUploadChannel
                       , public nsIResumableChannel
                       , public nsIProxiedChannel
                       , public nsIChildChannel
-                      , public PrivateBrowsingConsumer
 {
 public:
   typedef ::nsIStreamListener nsIStreamListener;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIFTPCHANNEL
   NS_DECL_NSIUPLOADCHANNEL
   NS_DECL_NSIRESUMABLECHANNEL
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -14,17 +14,22 @@
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelParent::FTPChannelParent()
-: mIPCClosed(false)
+  : mIPCClosed(false)
+  , mHaveLoadContext(false)
+  , mIsContent(false)
+  , mUsePrivateBrowsing(false)
+  , mIsInBrowserElement(false)
+  , mAppId(0)
 {
   nsIProtocolHandler* handler;
   CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler);
   NS_ASSERTION(handler, "no ftp handler");
 }
 
 FTPChannelParent::~FTPChannelParent()
 {
@@ -38,32 +43,37 @@ FTPChannelParent::ActorDestroy(ActorDest
   // yet, but we must not send any more msgs to child.
   mIPCClosed = true;
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS4(FTPChannelParent,
+NS_IMPL_ISUPPORTS5(FTPChannelParent,
                    nsIStreamListener,
                    nsIParentChannel,
                    nsIInterfaceRequestor,
+                   nsILoadContext,
                    nsIRequestObserver);
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::PFTPChannelParent
 //-----------------------------------------------------------------------------
 
 bool
 FTPChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
                                 const PRUint64& aStartPos,
                                 const nsCString& aEntityID,
                                 const IPC::InputStream& aUploadStream,
-                                const bool& aUsePrivateBrowsing)
+                                const bool& haveLoadContext,
+                                const bool& isContent,
+                                const bool& usePrivateBrowsing,
+                                const bool& isInBrowserElement,
+                                const PRUint32& appId)
 {
   nsCOMPtr<nsIURI> uri(aURI);
 
 #ifdef DEBUG
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
   LOG(("FTPChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
        this, uriSpec.get()));
@@ -88,17 +98,23 @@ FTPChannelParent::RecvAsyncOpen(const IP
     if (NS_FAILED(rv))
       return SendFailedAsyncOpen(rv);
   }
 
   rv = mChannel->ResumeAt(aStartPos, aEntityID);
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
-  mChannel->OverridePrivateBrowsing(aUsePrivateBrowsing);
+  // fields needed to impersonate nsILoadContext
+  mHaveLoadContext = haveLoadContext;
+  mIsContent = isContent;
+  mUsePrivateBrowsing = usePrivateBrowsing;
+  mIsInBrowserElement = isInBrowserElement;
+  mAppId = appId;
+  mChannel->SetNotificationCallbacks(this);
 
   rv = mChannel->AsyncOpen(this, nsnull);
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
   
   return true;
 }
 
@@ -224,14 +240,87 @@ FTPChannelParent::Delete()
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 FTPChannelParent::GetInterface(const nsIID& uuid, void** result)
 {
+  // Only support nsILoadContext if child channel's callbacks did too
+  if (uuid.Equals(NS_GET_IID(nsILoadContext)) && !mHaveLoadContext) {
+    return NS_NOINTERFACE;
+  }
+
   return QueryInterface(uuid, result);
 }
 
+//-----------------------------------------------------------------------------
+// FTPChannelParent::nsILoadContext
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+FTPChannelParent::GetAssociatedWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::GetTopWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::IsAppOfType(PRUint32, bool*)
+{
+  // don't expect we need this in parent (Thunderbird/SeaMonkey specific?)
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::GetIsContent(bool *aIsContent)
+{
+  NS_ENSURE_ARG_POINTER(aIsContent);
+
+  *aIsContent = mIsContent;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
+{
+  NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
+
+  *aUsePrivateBrowsing = mUsePrivateBrowsing;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
+{
+  // We shouldn't need this on parent...
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  NS_ENSURE_ARG_POINTER(aIsInBrowserElement);
+
+  *aIsInBrowserElement = mIsInBrowserElement;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+FTPChannelParent::GetAppId(PRUint32* aAppId)
+{
+  NS_ENSURE_ARG_POINTER(aAppId);
+
+  *aAppId = mAppId;
+  return NS_OK;
+}
+
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/ftp/FTPChannelParent.h
+++ b/netwerk/protocol/ftp/FTPChannelParent.h
@@ -7,50 +7,65 @@
 
 #ifndef mozilla_net_FTPChannelParent_h
 #define mozilla_net_FTPChannelParent_h
 
 #include "mozilla/net/PFTPChannelParent.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsIParentChannel.h"
 #include "nsIInterfaceRequestor.h"
+#include "nsILoadContext.h"
 
 class nsFtpChannel;
 
 namespace mozilla {
 namespace net {
 
 class FTPChannelParent : public PFTPChannelParent
                        , public nsIParentChannel
                        , public nsIInterfaceRequestor
+                       , public nsILoadContext
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIPARENTCHANNEL
   NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSILOADCONTEXT
 
   FTPChannelParent();
   virtual ~FTPChannelParent();
 
 protected:
   NS_OVERRIDE virtual bool RecvAsyncOpen(const IPC::URI& uri,
                                          const PRUint64& startPos,
                                          const nsCString& entityID,
                                          const IPC::InputStream& uploadStream,
-                                         const bool& aUsePrivateBrowsing);
+                                         const bool& haveLoadContext,
+                                         const bool& isContent,
+                                         const bool& usingPrivateBrowsing,
+                                         const bool& isInBrowserElement,
+                                         const PRUint32& appId);
   NS_OVERRIDE virtual bool RecvConnectChannel(const PRUint32& channelId);
   NS_OVERRIDE virtual bool RecvCancel(const nsresult& status);
   NS_OVERRIDE virtual bool RecvSuspend();
   NS_OVERRIDE virtual bool RecvResume();
 
   NS_OVERRIDE virtual void ActorDestroy(ActorDestroyReason why);
 
   nsRefPtr<nsFtpChannel> mChannel;
 
   bool mIPCClosed;
+
+  // fields for impersonating nsILoadContext
+  bool mHaveLoadContext       : 1;
+  bool mIsContent             : 1;
+  bool mUsePrivateBrowsing    : 1;
+  bool mIsInBrowserElement    : 1;
+
+  PRUint32 mAppId;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_FTPChannelParent_h
--- a/netwerk/protocol/ftp/PFTPChannel.ipdl
+++ b/netwerk/protocol/ftp/PFTPChannel.ipdl
@@ -18,18 +18,25 @@ namespace net {
 
 async protocol PFTPChannel
 {
   manager PNecko;
 
 parent:
   __delete__();
 
-  AsyncOpen(URI uri, PRUint64 startPos, nsCString entityID,
-            InputStream uploadStream, bool usePrivateBrowsing);
+  AsyncOpen(URI uri,
+            PRUint64 startPos,
+            nsCString entityID,
+            InputStream uploadStream,
+            bool haveLoadContext,
+            bool isContent,
+            bool usePrivateBrowsing,
+            bool isInBrowserElement,
+            PRUint32 appID);
   ConnectChannel(PRUint32 channelId);
   Cancel(nsresult status);
   Suspend();
   Resume();
 
 child:
   OnStartRequest(PRInt32 aContentLength, nsCString aContentType,
                  PRTime aLastModified, nsCString aEntityID, URI aURI);
--- a/netwerk/protocol/ftp/nsFTPChannel.h
+++ b/netwerk/protocol/ftp/nsFTPChannel.h
@@ -23,34 +23,32 @@
 #include "nsIStreamListener.h"
 #include "nsIFTPChannel.h"
 #include "nsIUploadChannel.h"
 #include "nsIProxyInfo.h"
 #include "nsIProxiedChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsHashPropertyBag.h"
 #include "nsFtpProtocolHandler.h"
-#include "PrivateBrowsingConsumer.h"
+#include "nsNetUtil.h"
 
 class nsFtpChannel : public nsBaseChannel,
                      public nsIFTPChannel,
                      public nsIUploadChannel,
                      public nsIResumableChannel,
-                     public nsIProxiedChannel,
-                     public mozilla::net::PrivateBrowsingConsumer
+                     public nsIProxiedChannel
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIUPLOADCHANNEL
     NS_DECL_NSIRESUMABLECHANNEL
     NS_DECL_NSIPROXIEDCHANNEL
     
     nsFtpChannel(nsIURI *uri, nsIProxyInfo *pi)
-        : mozilla::net::PrivateBrowsingConsumer(this)
-        , mProxyInfo(pi)
+        : mProxyInfo(pi)
         , mStartPos(0)
         , mResumeRequested(false)
         , mLastModifiedTime(0)
     {
         SetURI(uri);
     }
 
     nsIProxyInfo *ProxyInfo() {
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -2212,17 +2212,17 @@ nsFtpState::CheckCache()
     // In some cases, we don't want to use the cache:
     if (mChannel->UploadStream() || mChannel->ResumeRequested())
         return false;
 
     nsCOMPtr<nsICacheService> cache = do_GetService(NS_CACHESERVICE_CONTRACTID);
     if (!cache)
         return false;
 
-    bool isPrivate = mChannel->UsePrivateBrowsing();
+    bool isPrivate = NS_UsePrivateBrowsing(mChannel);
     const char* sessionName = isPrivate ? "FTP-private" : "FTP";
     nsCacheStoragePolicy policy =
         isPrivate ? nsICache::STORE_IN_MEMORY : nsICache::STORE_ANYWHERE;
     nsCOMPtr<nsICacheSession> session;
     cache->CreateSession(sessionName,
                          policy,
                          nsICache::STREAM_BASED,
                          getter_AddRefs(session));
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -22,18 +22,17 @@
 #include "nsStreamListenerWrapper.h"
 
 #include "prnetdb.h"
 
 namespace mozilla {
 namespace net {
 
 HttpBaseChannel::HttpBaseChannel()
-  : PrivateBrowsingConsumer(this)
-  , mStartPos(LL_MAXUINT)
+  : mStartPos(LL_MAXUINT)
   , mStatus(NS_OK)
   , mLoadFlags(LOAD_NORMAL)
   , mPriority(PRIORITY_NORMAL)
   , mCaps(0)
   , mRedirectionLimit(gHttpHandler->RedirectionLimit())
   , mApplyConversion(true)
   , mCanceled(false)
   , mIsPending(false)
@@ -44,16 +43,17 @@ HttpBaseChannel::HttpBaseChannel()
   , mUploadStreamHasHeaders(false)
   , mInheritApplicationCache(true)
   , mChooseApplicationCache(false)
   , mLoadedFromApplicationCache(false)
   , mChannelIsForDownload(false)
   , mTracingEnabled(true)
   , mTimingEnabled(false)
   , mAllowSpdy(true)
+  , mPrivateBrowsing(false)
   , mSuspendCount(0)
 {
   LOG(("Creating HttpBaseChannel @%x\n", this));
 
   // grab a reference to the handler to ensure that it doesn't go away.
   NS_ADDREF(gHttpHandler);
 
   // Subfields of unions cannot be targeted in an initializer list
@@ -135,28 +135,27 @@ HttpBaseChannel::Init(nsIURI *aURI,
 
   return rv;
 }
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS_INHERITED10(HttpBaseChannel,
-                              nsHashPropertyBag, 
+NS_IMPL_ISUPPORTS_INHERITED9( HttpBaseChannel,
+                              nsHashPropertyBag,
                               nsIRequest,
                               nsIChannel,
                               nsIEncodedChannel,
                               nsIHttpChannel,
                               nsIHttpChannelInternal,
                               nsIUploadChannel,
                               nsIUploadChannel2,
                               nsISupportsPriority,
-                              nsITraceableChannel,
-                              nsIPrivateBrowsingConsumer)
+                              nsITraceableChannel)
 
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpBaseChannel::GetName(nsACString& aName)
 {
@@ -268,16 +267,19 @@ HttpBaseChannel::GetNotificationCallback
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
 {
   mCallbacks = aCallbacks;
   mProgressSink = nsnull;
+
+  // Will never change unless SetNotificationCallbacks called again, so cache
+  mPrivateBrowsing = NS_UsePrivateBrowsing(this);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetContentType(nsACString& aContentType)
 {
   if (!mResponseHead) {
     aContentType.Truncate();
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -22,18 +22,18 @@
 #include "nsIUploadChannel2.h"
 #include "nsIProgressEventSink.h"
 #include "nsIURI.h"
 #include "nsIStringEnumerator.h"
 #include "nsISupportsPriority.h"
 #include "nsIApplicationCache.h"
 #include "nsIResumableChannel.h"
 #include "nsITraceableChannel.h"
+#include "nsILoadContext.h"
 #include "mozilla/net/NeckoCommon.h"
-#include "PrivateBrowsingConsumer.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace net {
 
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild. 
@@ -45,17 +45,16 @@ class HttpBaseChannel : public nsHashPro
                       , public nsIEncodedChannel
                       , public nsIHttpChannel
                       , public nsIHttpChannelInternal
                       , public nsIUploadChannel
                       , public nsIUploadChannel2
                       , public nsISupportsPriority
                       , public nsIResumableChannel
                       , public nsITraceableChannel
-                      , public PrivateBrowsingConsumer
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIUPLOADCHANNEL
   NS_DECL_NSIUPLOADCHANNEL2
   NS_DECL_NSITRACEABLECHANNEL
 
   HttpBaseChannel();
@@ -181,17 +180,17 @@ public:
 
     const PRNetAddr& GetSelfAddr() { return mSelfAddr; }
     const PRNetAddr& GetPeerAddr() { return mPeerAddr; }
 
 public: /* Necko internal use only... */
 
   bool ShouldRewriteRedirectToGET(PRUint32 httpStatus, nsHttpAtom method);
   bool IsSafeMethod(nsHttpAtom method);
-  
+
 protected:
 
   // Handle notifying listener, removing from loadgroup if request failed.
   void     DoNotifyListener();
   virtual void DoNotifyListenerCleanup() = 0;
 
   nsresult ApplyContentConversions();
 
@@ -260,16 +259,17 @@ protected:
   PRUint32                          mInheritApplicationCache    : 1;
   PRUint32                          mChooseApplicationCache     : 1;
   PRUint32                          mLoadedFromApplicationCache : 1;
   PRUint32                          mChannelIsForDownload       : 1;
   PRUint32                          mTracingEnabled             : 1;
   // True if timing collection is enabled
   PRUint32                          mTimingEnabled              : 1;
   PRUint32                          mAllowSpdy                  : 1;
+  PRUint32                          mPrivateBrowsing            : 1;
 
   // Current suspension depth for this channel object
   PRUint32                          mSuspendCount;
 
   nsAutoPtr<nsTArray<nsCString> >   mRedirectedCachekeys;
 };
 
 // Share some code while working around C++'s absurd inability to handle casting
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1010,16 +1010,32 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
       nsCOMPtr<nsIApplicationCache> appCache;
       rv = appCacheContainer->GetApplicationCache(getter_AddRefs(appCache));
       if (NS_SUCCEEDED(rv) && appCache) {
         appCache->GetClientID(appCacheClientId);
       }
     }
   }
 
+  // Get info from nsILoadContext, if any
+  bool haveLoadContext = false;
+  bool isContent = false;
+  bool usePrivateBrowsing = false;
+  bool isInBrowserElement = false;
+  PRUint32 appId = 0;
+  nsCOMPtr<nsILoadContext> loadContext;
+  GetCallback(loadContext);
+  if (loadContext) {
+    haveLoadContext = true;
+    loadContext->GetIsContent(&isContent);
+    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
+    loadContext->GetIsInBrowserElement(&isInBrowserElement);
+    loadContext->GetAppId(&appId);
+  }
+
   //
   // Send request to the chrome process...
   //
 
   // FIXME: bug 558623: Combine constructor and SendAsyncOpen into one IPC msg
 
   mozilla::dom::TabChild* tabChild = nsnull;
   nsCOMPtr<nsITabChild> iTabChild;
@@ -1035,18 +1051,19 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
 
   SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
                 IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
                 mClientSetRequestHeaders, mRequestHead.Method(),
                 IPC::InputStream(mUploadStream), mUploadStreamHasHeaders,
                 mPriority, mRedirectionLimit, mAllowPipelining,
                 mForceAllowThirdPartyCookie, mSendResumeAt,
-                mStartPos, mEntityID, mChooseApplicationCache, 
-                appCacheClientId, mAllowSpdy, UsePrivateBrowsing());
+                mStartPos, mEntityID, mChooseApplicationCache,
+                appCacheClientId, mAllowSpdy, haveLoadContext, isContent,
+                usePrivateBrowsing, isInBrowserElement, appId);
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIHttpChannel
 //-----------------------------------------------------------------------------
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -30,16 +30,21 @@ namespace net {
 HttpChannelParent::HttpChannelParent(PBrowserParent* iframeEmbedding)
   : mIPCClosed(false)
   , mStoredStatus(0)
   , mStoredProgress(0)
   , mStoredProgressMax(0)
   , mSentRedirect1Begin(false)
   , mSentRedirect1BeginFailed(false)
   , mReceivedRedirect2Verify(false)
+  , mHaveLoadContext(false)
+  , mIsContent(false)
+  , mUsePrivateBrowsing(false)
+  , mIsInBrowserElement(false)
+  , mAppId(0)
 {
   // Ensure gHttpHandler is initialized: we need the atom table up and running.
   nsIHttpProtocolHandler* handler;
   CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &handler);
   NS_ASSERTION(handler, "no http handler");
 
   mTabParent = do_QueryObject(static_cast<TabParent*>(iframeEmbedding));
 }
@@ -57,17 +62,18 @@ HttpChannelParent::ActorDestroy(ActorDes
   // to child, or IPDL will kill chrome process, too.
   mIPCClosed = true;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS6(HttpChannelParent,
+NS_IMPL_ISUPPORTS7(HttpChannelParent,
+                   nsILoadContext,
                    nsIInterfaceRequestor,
                    nsIProgressEventSink,
                    nsIRequestObserver,
                    nsIStreamListener,
                    nsIParentChannel,
                    nsIParentRedirectingChannel)
 
 //-----------------------------------------------------------------------------
@@ -80,16 +86,21 @@ HttpChannelParent::GetInterface(const ns
   if (aIID.Equals(NS_GET_IID(nsIAuthPromptProvider)) ||
       aIID.Equals(NS_GET_IID(nsISecureBrowserUI))) {
     if (!mTabParent)
       return NS_NOINTERFACE;
 
     return mTabParent->QueryInterface(aIID, result);
   }
 
+  // Only support nsILoadContext if child channel's callbacks did too
+  if (aIID.Equals(NS_GET_IID(nsILoadContext)) && !mHaveLoadContext) {
+    return NS_NOINTERFACE;
+  }
+
   return QueryInterface(aIID, result);
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::PHttpChannelParent
 //-----------------------------------------------------------------------------
 
 bool 
@@ -107,17 +118,21 @@ HttpChannelParent::RecvAsyncOpen(const I
                                  const bool&              allowPipelining,
                                  const bool&              forceAllowThirdPartyCookie,
                                  const bool&                doResumeAt,
                                  const PRUint64&            startPos,
                                  const nsCString&           entityID,
                                  const bool&                chooseApplicationCache,
                                  const nsCString&           appCacheClientID,
                                  const bool&                allowSpdy,
-                                 const bool&                usingPrivateBrowsing)
+                                 const bool&                haveLoadContext,
+                                 const bool&                isContent,
+                                 const bool&                usePrivateBrowsing,
+                                 const bool&                isInBrowserElement,
+                                 const PRUint32&            appId)
 {
   nsCOMPtr<nsIURI> uri(aURI);
   nsCOMPtr<nsIURI> originalUri(aOriginalURI);
   nsCOMPtr<nsIURI> docUri(aDocURI);
   nsCOMPtr<nsIURI> referrerUri(aReferrerURI);
 
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
@@ -129,16 +144,23 @@ HttpChannelParent::RecvAsyncOpen(const I
   nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   rv = NS_NewChannel(getter_AddRefs(mChannel), uri, ios, nsnull, nsnull, loadFlags);
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
+  // fields needed to impersonate nsILoadContext
+  mHaveLoadContext = haveLoadContext;
+  mIsContent = isContent;
+  mUsePrivateBrowsing = usePrivateBrowsing;
+  mIsInBrowserElement = isInBrowserElement;
+  mAppId = appId;
+
   nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
 
   if (doResumeAt)
     httpChan->ResumeAt(startPos, entityID);
 
   if (originalUri)
     httpChan->SetOriginalURI(originalUri);
   if (docUri)
@@ -204,18 +226,16 @@ HttpChannelParent::RecvAsyncOpen(const I
                                                            &setChooseApplicationCache);
 
         if (setChooseApplicationCache && NS_SUCCEEDED(rv))
           appCacheChan->SetChooseApplicationCache(true);
       }
     }
   }
 
-  httpChan->OverridePrivateBrowsing(usingPrivateBrowsing);
-
   rv = httpChan->AsyncOpen(channelListener, nsnull);
   if (NS_FAILED(rv))
     return SendFailedAsyncOpen(rv);
 
   return true;
 }
 
 bool
@@ -581,9 +601,77 @@ HttpChannelParent::CompleteRedirect(bool
     // TODO: check return value: assume child dead if failed
     unused << SendRedirect3Complete();
   }
 
   mRedirectChannel = nsnull;
   return NS_OK;
 }
 
+//-----------------------------------------------------------------------------
+// HttpChannelParent::nsILoadContext
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+HttpChannelParent::GetAssociatedWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::GetTopWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::IsAppOfType(PRUint32, bool*)
+{
+  // don't expect we need this in parent (Thunderbird/SeaMonkey specific?)
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::GetIsContent(bool *aIsContent)
+{
+  NS_ENSURE_ARG_POINTER(aIsContent);
+
+  *aIsContent = mIsContent;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
+{
+  NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
+
+  *aUsePrivateBrowsing = mUsePrivateBrowsing;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
+{
+  // We shouldn't need this on parent...
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  NS_ENSURE_ARG_POINTER(aIsInBrowserElement);
+
+  *aIsInBrowserElement = mIsInBrowserElement;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+HttpChannelParent::GetAppId(PRUint32* aAppId)
+{
+  NS_ENSURE_ARG_POINTER(aAppId);
+
+  *aAppId = mAppId;
+  return NS_OK;
+}
+
 }} // mozilla::net
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -26,25 +26,27 @@ namespace mozilla {
 namespace net {
 
 class HttpChannelParentListener;
 
 class HttpChannelParent : public PHttpChannelParent
                         , public nsIParentRedirectingChannel
                         , public nsIProgressEventSink
                         , public nsIInterfaceRequestor
+                        , public nsILoadContext
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIPARENTCHANNEL
   NS_DECL_NSIPARENTREDIRECTINGCHANNEL
   NS_DECL_NSIPROGRESSEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSILOADCONTEXT
 
   HttpChannelParent(PBrowserParent* iframeEmbedding);
   virtual ~HttpChannelParent();
 
 protected:
   virtual bool RecvAsyncOpen(const IPC::URI&            uri,
                              const IPC::URI&            originalUri,
                              const IPC::URI&            docUri,
@@ -59,17 +61,21 @@ protected:
                              const bool&              allowPipelining,
                              const bool&              forceAllowThirdPartyCookie,
                              const bool&                doResumeAt,
                              const PRUint64&            startPos,
                              const nsCString&           entityID,
                              const bool&                chooseApplicationCache,
                              const nsCString&           appCacheClientID,
                              const bool&                allowSpdy,
-                             const bool&                usingPrivateBrowsing);
+                             const bool &               haveLoadContext,
+                             const bool &               isContent,
+                             const bool&                usingPrivateBrowsing,
+                             const bool&                isInBrowserElement,
+                             const PRUint32&            appId);
 
   virtual bool RecvConnectChannel(const PRUint32& channelId);
   virtual bool RecvSetPriority(const PRUint16& priority);
   virtual bool RecvSetCacheTokenCachedCharset(const nsCString& charset);
   virtual bool RecvSuspend();
   virtual bool RecvResume();
   virtual bool RecvCancel(const nsresult& status);
   virtual bool RecvRedirect2Verify(const nsresult& result,
@@ -99,17 +105,25 @@ private:
   nsAutoPtr<class nsHttpChannel::OfflineCacheEntryAsForeignMarker> mOfflineForeignMarker;
 
   // state for combining OnStatus/OnProgress with OnDataAvailable
   // into one IPDL call to child.
   nsresult mStoredStatus;
   PRUint64 mStoredProgress;
   PRUint64 mStoredProgressMax;
 
-  bool mSentRedirect1Begin : 1;
-  bool mSentRedirect1BeginFailed : 1;
-  bool mReceivedRedirect2Verify : 1;
+  bool mSentRedirect1Begin          : 1;
+  bool mSentRedirect1BeginFailed    : 1;
+  bool mReceivedRedirect2Verify     : 1;
+
+  // fields for impersonating nsILoadContext
+  bool mHaveLoadContext             : 1;
+  bool mIsContent                   : 1;
+  bool mUsePrivateBrowsing          : 1;
+  bool mIsInBrowserElement          : 1;
+
+  PRUint32 mAppId;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_HttpChannelParent_h
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -45,17 +45,23 @@ parent:
             bool                allowPipelining,
             bool                forceAllowThirdPartyCookie,
             bool                resumeAt,
             PRUint64            startPos,
             nsCString           entityID,
             bool                chooseApplicationCache,
             nsCString           appCacheClientID,
             bool                allowSpdy,
-            bool                usePrivateBrowsing);
+            // If child channel callbacks implement nsILoadContext, we implement
+            // it in HttpChannelParent too
+            bool                haveLoadContext,
+            bool                isContent,
+            bool                usePrivateBrowsing,
+            bool                isInBrowserElement,
+            PRUint32            appID);
 
   // Used to connect redirected-to channel on the parent with redirected-to
   // channel on the child.
   ConnectChannel(PRUint32 channelId);
 
   SetPriority(PRUint16 priority);
 
   SetCacheTokenCachedCharset(nsCString charset);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -539,17 +539,17 @@ nsHttpChannel::SpeculativeConnect()
     
     nsCOMPtr<nsIInterfaceRequestor> callbacks;
     NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
                                            getter_AddRefs(callbacks));
     if (!callbacks)
         return;
 
     mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
-    mConnectionInfo->SetPrivate(UsingPrivateBrowsing());
+    mConnectionInfo->SetPrivate(mPrivateBrowsing);
     gHttpHandler->SpeculativeConnect(mConnectionInfo,
                                      callbacks, NS_GetCurrentThread());
 }
 
 void
 nsHttpChannel::DoNotifyListenerCleanup()
 {
     // We don't need this info anymore
@@ -834,17 +834,17 @@ nsHttpChannel::SetupTransaction()
     // See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
     if (mLoadFlags & LOAD_ANONYMOUS)
         mCaps |= NS_HTTP_LOAD_ANONYMOUS;
 
     if (mTimingEnabled)
         mCaps |= NS_HTTP_TIMING_ENABLED;
 
     mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
-    mConnectionInfo->SetPrivate(UsingPrivateBrowsing());
+    mConnectionInfo->SetPrivate(mPrivateBrowsing);
 
     if (mUpgradeProtocolCallback) {
         mRequestHead.SetHeader(nsHttp::Upgrade, mUpgradeProtocol, false);
         mRequestHead.SetHeader(nsHttp::Connection,
                                nsDependentCString(nsHttp::Upgrade.get()),
                                true);
         mCaps |=  NS_HTTP_STICKY_CONNECTION;
         mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
@@ -2442,17 +2442,17 @@ nsHttpChannel::OpenCacheEntry(bool using
         nsCAutoString appCacheClientID;
         rv = mApplicationCache->GetClientID(appCacheClientID);
         if (NS_SUCCEEDED(rv)) {
             // We open with ACCESS_READ only, because we don't want to overwrite
             // the offline cache entry non-atomically. ACCESS_READ will prevent
             // us from writing to the offline cache as a normal cache entry.
             mCacheQuery = new HttpCacheQuery(
                                 this, appCacheClientID,
-                                nsICache::STORE_OFFLINE, UsingPrivateBrowsing(),
+                                nsICache::STORE_OFFLINE, mPrivateBrowsing,
                                 cacheKey, nsICache::ACCESS_READ,
                                 mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
                                 usingSSL, true);
 
             mOnCacheEntryAvailableCallback =
                 &nsHttpChannel::OnOfflineCacheEntryAvailable;
 
             rv = mCacheQuery->Dispatch();
@@ -2543,33 +2543,31 @@ nsHttpChannel::OnOfflineCacheEntryAvaila
 
 nsresult
 nsHttpChannel::OpenNormalCacheEntry(bool usingSSL)
 {
     NS_ASSERTION(!mCacheEntry, "We have already mCacheEntry");
 
     nsresult rv;
 
-    bool isPrivate = UsingPrivateBrowsing();
-    nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy(isPrivate);
+    nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
     nsDependentCString clientID(
-        GetCacheSessionNameForStoragePolicy(storagePolicy, isPrivate));
+        GetCacheSessionNameForStoragePolicy(storagePolicy, mPrivateBrowsing));
 
     nsCAutoString cacheKey;
     GenerateCacheKey(mPostID, cacheKey);
 
     nsCacheAccessMode accessRequested;
     rv = DetermineCacheAccess(&accessRequested);
     if (NS_FAILED(rv))
         return rv;
  
     mCacheQuery = new HttpCacheQuery(
                                 this, clientID, storagePolicy,
-                                UsingPrivateBrowsing(), cacheKey,
-                                accessRequested,
+                                mPrivateBrowsing, cacheKey, accessRequested,
                                 mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
                                 usingSSL, false);
 
     mOnCacheEntryAvailableCallback =
         &nsHttpChannel::OnNormalCacheEntryAvailable;
 
     rv = mCacheQuery->Dispatch();
     if (NS_SUCCEEDED(rv))
@@ -5868,49 +5866,48 @@ nsHttpChannel::DoInvalidateCacheEntry(co
 {
     // NOTE:
     // Following comments 24,32 and 33 in bug #327765, we only care about
     // the cache in the protocol-handler, not the application cache.
     // The logic below deviates from the original logic in OpenCacheEntry on
     // one point by using only READ_ONLY access-policy. I think this is safe.
 
     // First, find session holding the cache-entry - use current storage-policy
-    bool isPrivate = UsingPrivateBrowsing();
-    nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy(isPrivate);
-    const char * clientID = GetCacheSessionNameForStoragePolicy(storagePolicy,
-                                                                isPrivate);
+    nsCacheStoragePolicy storagePolicy = DetermineStoragePolicy();
+    const char * clientID =
+        GetCacheSessionNameForStoragePolicy(storagePolicy, mPrivateBrowsing);
 
     LOG(("DoInvalidateCacheEntry [channel=%p session=%s policy=%d key=%s]",
          this, clientID, PRIntn(storagePolicy), key.get()));
 
     nsresult rv;
     nsCOMPtr<nsICacheService> serv =
         do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
     nsCOMPtr<nsICacheSession> session;
     if (NS_SUCCEEDED(rv)) {
         rv = serv->CreateSession(clientID, storagePolicy,  
                                  nsICache::STREAM_BASED,
                                  getter_AddRefs(session));
     }
     if (NS_SUCCEEDED(rv)) {
-        rv = session->SetIsPrivate(UsingPrivateBrowsing());
+        rv = session->SetIsPrivate(mPrivateBrowsing);
     }
     if (NS_SUCCEEDED(rv)) {
         rv = session->DoomEntry(key, nsnull);
     }
 
     LOG(("DoInvalidateCacheEntry [channel=%p session=%s policy=%d key=%s rv=%d]",
          this, clientID, PRIntn(storagePolicy), key.get(), PRIntn(rv)));
 }
 
 nsCacheStoragePolicy
-nsHttpChannel::DetermineStoragePolicy(bool isPrivate)
+nsHttpChannel::DetermineStoragePolicy()
 {
     nsCacheStoragePolicy policy = nsICache::STORE_ANYWHERE;
-    if (isPrivate)
+    if (mPrivateBrowsing)
         policy = nsICache::STORE_IN_MEMORY;
     else if (mLoadFlags & INHIBIT_PERSISTENT_CACHING)
         policy = nsICache::STORE_IN_MEMORY;
 
     return policy;
 }
 
 nsresult
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -140,26 +140,16 @@ public: /* internal necko use only */
              , mCacheKey(key)
         {}
 
         nsresult MarkAsForeign();
     };
 
     OfflineCacheEntryAsForeignMarker* GetOfflineCacheEntryAsForeignMarker();
 
-    /**
-     * Returns true if this channel is operating in private browsing mode,
-     * false otherwise.
-     */
-    bool UsingPrivateBrowsing() {
-        bool usingPB;
-        GetUsingPrivateBrowsing(&usingPB);
-        return usingPB;
-    }
-
 private:
     typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result);
 
     bool     RequestIsConditional();
     nsresult Connect();
     nsresult ContinueConnect();
     void     SpeculativeConnect();
     nsresult SetupTransaction();
@@ -230,17 +220,17 @@ private:
     void     UpdateInhibitPersistentCachingFlag();
     nsresult InitOfflineCacheEntry();
     nsresult AddCacheEntryHeaders(nsICacheEntryDescriptor *entry);
     nsresult StoreAuthorizationMetaData(nsICacheEntryDescriptor *entry);
     nsresult FinalizeCacheEntry();
     nsresult InstallCacheListener(PRUint32 offset = 0);
     nsresult InstallOfflineCacheListener();
     void     MaybeInvalidateCacheEntryForSubsequentGet();
-    nsCacheStoragePolicy DetermineStoragePolicy(bool isPrivate);
+    nsCacheStoragePolicy DetermineStoragePolicy();
     nsresult DetermineCacheAccess(nsCacheAccessMode *_retval);
     void     AsyncOnExamineCachedResponse();
 
     // Handle the bogus Content-Encoding Apache sometimes sends
     void ClearBogusContentEncodingIfNeeded();
 
     // byte range request specific methods
     nsresult ProcessPartialContent();
--- a/netwerk/protocol/websocket/PWebSocket.ipdl
+++ b/netwerk/protocol/websocket/PWebSocket.ipdl
@@ -17,17 +17,25 @@ namespace mozilla {
 namespace net {
 
 async protocol PWebSocket
 {
   manager PNecko;
 
 parent:
   // Forwarded methods corresponding to methods on nsIWebSocketChannel
-  AsyncOpen(URI aURI, nsCString aOrigin, nsCString aProtocol, bool aSecure);
+  AsyncOpen(URI aURI,
+            nsCString aOrigin,
+            nsCString aProtocol,
+            bool aSecure,
+            bool haveLoadContext,
+            bool isContent,
+            bool usePrivateBrowsing,
+            bool isInBrowserElement,
+            PRUint32 appID);
   Close(PRUint16 code, nsCString reason);
   SendMsg(nsCString aMsg);
   SendBinaryMsg(nsCString aMsg);
   SendBinaryStream(InputStream aStream, PRUint32 aLength);
 
   DeleteSelf();
 
 child:
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -4,16 +4,18 @@
  * 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/. */
 
 #include "WebSocketLog.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "WebSocketChannelChild.h"
 #include "nsITabChild.h"
+#include "nsILoadContext.h"
+#include "nsNetUtil.h"
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ADDREF(WebSocketChannelChild)
 
 NS_IMETHODIMP_(nsrefcnt) WebSocketChannelChild::Release()
 {
@@ -321,21 +323,41 @@ WebSocketChannelChild::AsyncOpen(nsIURI 
   nsCOMPtr<nsITabChild> iTabChild;
   NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                 NS_GET_IID(nsITabChild),
                                 getter_AddRefs(iTabChild));
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
 
+  // Get info from nsILoadContext, if any
+  bool haveLoadContext = false;
+  bool isContent = false;
+  bool usePrivateBrowsing = false;
+  bool isInBrowserElement = false;
+  PRUint32 appId = 0;
+  nsCOMPtr<nsILoadContext> loadContext;
+  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
+                                NS_GET_IID(nsILoadContext),
+                                getter_AddRefs(loadContext));
+  if (loadContext) {
+    haveLoadContext = true;
+    loadContext->GetIsContent(&isContent);
+    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
+    loadContext->GetIsInBrowserElement(&isInBrowserElement);
+    loadContext->GetAppId(&appId);
+  }
+
   // Corresponding release in DeallocPWebSocket
   AddIPDLReference();
 
   gNeckoChild->SendPWebSocketConstructor(this, tabChild);
-  if (!SendAsyncOpen(aURI, nsCString(aOrigin), mProtocol, mEncrypted))
+  if (!SendAsyncOpen(aURI, nsCString(aOrigin), mProtocol, mEncrypted,
+                     haveLoadContext, isContent, usePrivateBrowsing,
+                     isInBrowserElement, appId))
     return NS_ERROR_UNEXPECTED;
 
   mOriginalURI = aURI;
   mURI = mOriginalURI;
   mListener = aListener;
   mContext = aContext;
   mOrigin = aOrigin;
 
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -6,57 +6,78 @@
 
 #include "WebSocketLog.h"
 #include "WebSocketChannelParent.h"
 #include "nsIAuthPromptProvider.h"
 
 namespace mozilla {
 namespace net {
 
-NS_IMPL_THREADSAFE_ISUPPORTS2(WebSocketChannelParent,
+NS_IMPL_THREADSAFE_ISUPPORTS3(WebSocketChannelParent,
                               nsIWebSocketListener,
+                              nsILoadContext,
                               nsIInterfaceRequestor)
 
 WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider)
   : mAuthProvider(aAuthProvider)
   , mIPCOpen(true)
+  , mHaveLoadContext(false)
+  , mIsContent(false)
+  , mUsePrivateBrowsing(false)
+  , mIsInBrowserElement(false)
+  , mAppId(0)
 {
 #if defined(PR_LOGGING)
   if (!webSocketLog)
     webSocketLog = PR_NewLogModule("nsWebSocket");
 #endif
 }
 
+//-----------------------------------------------------------------------------
+// WebSocketChannelParent::PWebSocketChannelParent
+//-----------------------------------------------------------------------------
+
 bool
 WebSocketChannelParent::RecvDeleteSelf()
 {
   LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
   mChannel = nsnull;
   mAuthProvider = nsnull;
   return mIPCOpen ? Send__delete__(this) : true;
 }
 
 bool
 WebSocketChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
                                       const nsCString& aOrigin,
                                       const nsCString& aProtocol,
-                                      const bool& aSecure)
+                                      const bool& aSecure,
+                                      const bool& haveLoadContext,
+                                      const bool& isContent,
+                                      const bool& usePrivateBrowsing,
+                                      const bool& isInBrowserElement,
+                                      const PRUint32& appId)
 {
   LOG(("WebSocketChannelParent::RecvAsyncOpen() %p\n", this));
   nsresult rv;
   if (aSecure) {
     mChannel =
       do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
   } else {
     mChannel =
       do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
   }
   if (NS_FAILED(rv))
     goto fail;
 
+  // fields needed to impersonate nsILoadContext
+  mHaveLoadContext = haveLoadContext;
+  mIsContent = isContent;
+  mUsePrivateBrowsing = usePrivateBrowsing;
+  mIsInBrowserElement = isInBrowserElement;
+  mAppId = appId;
   rv = mChannel->SetNotificationCallbacks(this);
   if (NS_FAILED(rv))
     goto fail;
 
   rv = mChannel->SetProtocol(aProtocol);
   if (NS_FAILED(rv))
     goto fail;
 
@@ -111,26 +132,19 @@ WebSocketChannelParent::RecvSendBinarySt
   LOG(("WebSocketChannelParent::RecvSendBinaryStream() %p\n", this));
   if (mChannel) {
     nsresult rv = mChannel->SendBinaryStream(aStream, aLength);
     NS_ENSURE_SUCCESS(rv, true);
   }
   return true;
 }
 
-NS_IMETHODIMP
-WebSocketChannelParent::GetInterface(const nsIID & iid, void **result NS_OUTPARAM)
-{
-  LOG(("WebSocketChannelParent::GetInterface() %p\n", this));
-  if (mAuthProvider && iid.Equals(NS_GET_IID(nsIAuthPromptProvider)))
-    return mAuthProvider->GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
-                                        iid, result);
-
-  return NS_ERROR_FAILURE;
-}
+//-----------------------------------------------------------------------------
+// WebSocketChannelParent::nsIRequestObserver
+//-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnStart(nsISupports *aContext)
 {
   LOG(("WebSocketChannelParent::OnStart() %p\n", this));
   nsCAutoString protocol, extensions;
   if (mChannel) {
     mChannel->GetProtocol(protocol);
@@ -195,10 +209,99 @@ WebSocketChannelParent::OnServerClose(ns
 
 void
 WebSocketChannelParent::ActorDestroy(ActorDestroyReason why)
 {
   LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));
   mIPCOpen = false;
 }
 
+//-----------------------------------------------------------------------------
+// WebSocketChannelParent::nsIInterfaceRequestor
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetInterface(const nsIID & iid, void **result NS_OUTPARAM)
+{
+  LOG(("WebSocketChannelParent::GetInterface() %p\n", this));
+  if (mAuthProvider && iid.Equals(NS_GET_IID(nsIAuthPromptProvider)))
+    return mAuthProvider->GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
+                                        iid, result);
+
+  // Only support nsILoadContext if child channel's callbacks did too
+  if (iid.Equals(NS_GET_IID(nsILoadContext)) && !mHaveLoadContext) {
+    return NS_NOINTERFACE;
+  }
+
+  return QueryInterface(iid, result);
+}
+
+//-----------------------------------------------------------------------------
+// WebSocketChannelParent::nsILoadContext
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetAssociatedWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetTopWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::IsAppOfType(PRUint32, bool*)
+{
+  // don't expect we need this in parent (Thunderbird/SeaMonkey specific?)
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetIsContent(bool *aIsContent)
+{
+  NS_ENSURE_ARG_POINTER(aIsContent);
+
+  *aIsContent = mIsContent;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
+{
+  NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
+
+  *aUsePrivateBrowsing = mUsePrivateBrowsing;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
+{
+  // We shouldn't need this on parent...
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  NS_ENSURE_ARG_POINTER(aIsInBrowserElement);
+
+  *aIsInBrowserElement = mIsInBrowserElement;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WebSocketChannelParent::GetAppId(PRUint32* aAppId)
+{
+  NS_ENSURE_ARG_POINTER(aAppId);
+
+  *aAppId = mAppId;
+  return NS_OK;
+}
+
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/websocket/WebSocketChannelParent.h
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.h
@@ -5,50 +5,66 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_WebSocketChannelParent_h
 #define mozilla_net_WebSocketChannelParent_h
 
 #include "mozilla/net/PWebSocketParent.h"
 #include "nsIWebSocketListener.h"
 #include "nsIWebSocketChannel.h"
+#include "nsILoadContext.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 class nsIAuthPromptProvider;
 
 namespace mozilla {
 namespace net {
 
 class WebSocketChannelParent : public PWebSocketParent,
                                public nsIWebSocketListener,
-                               public nsIInterfaceRequestor
+                               public nsIInterfaceRequestor,
+                               public nsILoadContext
 {
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIWEBSOCKETLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSILOADCONTEXT
 
   WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider);
 
  private:
   bool RecvAsyncOpen(const IPC::URI& aURI,
                      const nsCString& aOrigin,
                      const nsCString& aProtocol,
-                     const bool& aSecure);
+                     const bool& aSecure,
+                     const bool& haveLoadContext,
+                     const bool& isContent,
+                     const bool& usingPrivateBrowsing,
+                     const bool& isInBrowserElement,
+                     const PRUint32& appId);
   bool RecvClose(const PRUint16 & code, const nsCString & reason);
   bool RecvSendMsg(const nsCString& aMsg);
   bool RecvSendBinaryMsg(const nsCString& aMsg);
   bool RecvSendBinaryStream(const InputStream& aStream,
                             const PRUint32& aLength);
   bool RecvDeleteSelf();
 
   void ActorDestroy(ActorDestroyReason why);
 
   nsCOMPtr<nsIAuthPromptProvider> mAuthProvider;
   nsCOMPtr<nsIWebSocketChannel> mChannel;
   bool mIPCOpen;
+
+  // fields for impersonating nsILoadContext
+  bool mHaveLoadContext             : 1;
+  bool mIsContent                   : 1;
+  bool mUsePrivateBrowsing          : 1;
+  bool mIsInBrowserElement          : 1;
+
+  PRUint32 mAppId;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_WebSocketChannelParent_h
--- a/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl
+++ b/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl
@@ -17,17 +17,21 @@ protocol PWyciwygChannel
   manager PNecko;
 
 parent:
   __delete__();
 
   Init(URI uri);
   AsyncOpen(URI      originalURI,
             PRUint32 loadFlags,
-            bool     usingPrivateBrowsing);
+            bool     haveLoadContext,
+            bool     isContent,
+            bool     usePrivateBrowsing,
+            bool     isInBrowserElement,
+            PRUint32 appID);
 
   // methods corresponding to those of nsIWyciwygChannel
   WriteToCacheEntry(nsString data);
   CloseCacheEntry(nsresult reason);
   SetCharsetAndSource(PRInt32 source, nsCString charset);
   SetSecurityInfo(nsCString securityInfo);
   Cancel(nsresult status);
 
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -8,29 +8,29 @@
 #include "WyciwygChannelChild.h"
 
 #include "nsCharsetSource.h"
 #include "nsStringStream.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsISerializable.h"
 #include "nsSerializationHelper.h"
+#include "nsILoadContext.h"
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS3(WyciwygChannelChild,
                    nsIRequest,
                    nsIChannel,
                    nsIWyciwygChannel);
 
 
 WyciwygChannelChild::WyciwygChannelChild()
-  : PrivateBrowsingConsumer(this)
-  , mStatus(NS_OK)
+  : mStatus(NS_OK)
   , mIsPending(false)
   , mCanceled(false)
   , mLoadFlags(LOAD_NORMAL)
   , mContentLength(-1)
   , mCharsetSource(kCharsetUninitialized)
   , mState(WCC_NEW)
   , mIPCOpen(false)
   , mEventQ(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this))
@@ -557,17 +557,36 @@ WyciwygChannelChild::AsyncOpen(nsIStream
 
   mListener = aListener;
   mListenerContext = aContext;
   mIsPending = true;
 
   if (mLoadGroup)
     mLoadGroup->AddRequest(this, nsnull);
 
-  SendAsyncOpen(IPC::URI(mOriginalURI), mLoadFlags, UsePrivateBrowsing());
+  // Get info from nsILoadContext, if any
+  bool haveLoadContext = false;
+  bool isContent = false;
+  bool usePrivateBrowsing = false;
+  bool isInBrowserElement = false;
+  PRUint32 appId = 0;
+  nsCOMPtr<nsILoadContext> loadContext;
+  NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
+                                NS_GET_IID(nsILoadContext),
+                                getter_AddRefs(loadContext));
+  if (loadContext) {
+    haveLoadContext = true;
+    loadContext->GetIsContent(&isContent);
+    loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
+    loadContext->GetIsInBrowserElement(&isInBrowserElement);
+    loadContext->GetAppId(&appId);
+  }
+
+  SendAsyncOpen(IPC::URI(mOriginalURI), mLoadFlags, haveLoadContext, isContent,
+                usePrivateBrowsing, isInBrowserElement, appId);
 
   mState = WCC_OPENED;
 
   return NS_OK;
 }
 
 
 //-----------------------------------------------------------------------------
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.h
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.h
@@ -5,17 +5,16 @@
 #ifndef mozilla_net_WyciwygChannelChild_h
 #define mozilla_net_WyciwygChannelChild_h
 
 #include "mozilla/net/PWyciwygChannelChild.h"
 #include "mozilla/net/ChannelEventQueue.h"
 #include "nsIWyciwygChannel.h"
 #include "nsIChannel.h"
 #include "nsIProgressEventSink.h"
-#include "PrivateBrowsingConsumer.h"
 
 namespace mozilla {
 namespace net {
 
 // TODO: replace with IPDL states
 enum WyciwygChannelChildState {
   WCC_NEW,
   WCC_INIT,
@@ -30,17 +29,16 @@ enum WyciwygChannelChildState {
   WCC_ONWRITE,
   WCC_ONCLOSED
 };
 
 
 // Header file contents
 class WyciwygChannelChild : public PWyciwygChannelChild
                           , public nsIWyciwygChannel
-                          , public PrivateBrowsingConsumer
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUEST
   NS_DECL_NSICHANNEL
   NS_DECL_NSIWYCIWYGCHANNEL
 
   WyciwygChannelChild();
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
@@ -12,16 +12,21 @@
 #include "nsISerializable.h"
 #include "nsSerializationHelper.h"
 
 namespace mozilla {
 namespace net {
 
 WyciwygChannelParent::WyciwygChannelParent()
  : mIPCClosed(false)
+ , mHaveLoadContext(false)
+ , mIsContent(false)
+ , mUsePrivateBrowsing(false)
+ , mIsInBrowserElement(false)
+ , mAppId(0)
 {
 #if defined(PR_LOGGING)
   if (!gWyciwygLog)
     gWyciwygLog = PR_NewLogModule("nsWyciwygChannel");
 #endif
 }
 
 WyciwygChannelParent::~WyciwygChannelParent()
@@ -35,18 +40,20 @@ WyciwygChannelParent::ActorDestroy(Actor
   // yet, but we must not send any more msgs to child.
   mIPCClosed = true;
 }
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelParent::nsISupports
 //-----------------------------------------------------------------------------
 
-NS_IMPL_ISUPPORTS2(WyciwygChannelParent,
+NS_IMPL_ISUPPORTS4(WyciwygChannelParent,
                    nsIStreamListener,
+                   nsIInterfaceRequestor,
+                   nsILoadContext,
                    nsIRequestObserver);
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelParent::PWyciwygChannelParent
 //-----------------------------------------------------------------------------
 
 bool
 WyciwygChannelParent::RecvInit(const IPC::URI& aURI)
@@ -74,17 +81,21 @@ WyciwygChannelParent::RecvInit(const IPC
     return SendCancelEarly(rv);
 
   return true;
 }
 
 bool
 WyciwygChannelParent::RecvAsyncOpen(const IPC::URI& aOriginal,
                                     const PRUint32& aLoadFlags,
-                                    const bool& aUsingPrivateBrowsing)
+                                    const bool& haveLoadContext,
+                                    const bool& isContent,
+                                    const bool& usePrivateBrowsing,
+                                    const bool& isInBrowserElement,
+                                    const PRUint32& appId)
 {
   nsCOMPtr<nsIURI> original(aOriginal);
 
   LOG(("WyciwygChannelParent RecvAsyncOpen [this=%x]\n", this));
 
   if (!mChannel)
     return true;
 
@@ -93,18 +104,23 @@ WyciwygChannelParent::RecvAsyncOpen(cons
   rv = mChannel->SetOriginalURI(original);
   if (NS_FAILED(rv))
     return SendCancelEarly(rv);
 
   rv = mChannel->SetLoadFlags(aLoadFlags);
   if (NS_FAILED(rv))
     return SendCancelEarly(rv);
 
-  static_cast<nsWyciwygChannel*>(mChannel.get())->
-    OverridePrivateBrowsing(aUsingPrivateBrowsing);
+  // fields needed to impersonate nsILoadContext
+  mHaveLoadContext = haveLoadContext;
+  mIsContent = isContent;
+  mUsePrivateBrowsing = usePrivateBrowsing;
+  mIsInBrowserElement = isInBrowserElement;
+  mAppId = appId;
+  mChannel->SetNotificationCallbacks(this);
 
   rv = mChannel->AsyncOpen(this, nsnull);
   if (NS_FAILED(rv))
     return SendCancelEarly(rv);
 
   return true;
 }
 
@@ -236,9 +252,92 @@ WyciwygChannelParent::OnDataAvailable(ns
 
   if (mIPCClosed || !SendOnDataAvailable(data, aOffset)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
+//-----------------------------------------------------------------------------
+// WyciwygChannelParent::nsIInterfaceRequestor
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetInterface(const nsIID& uuid, void** result)
+{
+  // Only support nsILoadContext if child channel's callbacks did too
+  if (uuid.Equals(NS_GET_IID(nsILoadContext)) && !mHaveLoadContext) {
+    return NS_NOINTERFACE;
+  }
+
+  return QueryInterface(uuid, result);
+}
+
+//-----------------------------------------------------------------------------
+// WyciwygChannelParent::nsILoadContext
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetAssociatedWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetTopWindow(nsIDOMWindow**)
+{
+  // can't support this in the parent process
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::IsAppOfType(PRUint32, bool*)
+{
+  // don't expect we need this in parent (Thunderbird/SeaMonkey specific?)
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetIsContent(bool *aIsContent)
+{
+  NS_ENSURE_ARG_POINTER(aIsContent);
+
+  *aIsContent = mIsContent;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
+{
+  NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
+
+  *aUsePrivateBrowsing = mUsePrivateBrowsing;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
+{
+  // We shouldn't need this on parent...
+  return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetIsInBrowserElement(bool* aIsInBrowserElement)
+{
+  NS_ENSURE_ARG_POINTER(aIsInBrowserElement);
+
+  *aIsInBrowserElement = mIsInBrowserElement;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+WyciwygChannelParent::GetAppId(PRUint32* aAppId)
+{
+  NS_ENSURE_ARG_POINTER(aAppId);
+
+  *aAppId = mAppId;
+  return NS_OK;
+}
+
 }} // mozilla::net
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.h
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.h
@@ -5,45 +5,63 @@
 #ifndef mozilla_net_WyciwygChannelParent_h
 #define mozilla_net_WyciwygChannelParent_h
 
 #include "mozilla/net/PWyciwygChannelParent.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsIStreamListener.h"
 
 #include "nsIWyciwygChannel.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsILoadContext.h"
 
 namespace mozilla {
 namespace net {
 
 class WyciwygChannelParent : public PWyciwygChannelParent
                            , public nsIStreamListener
+                           , public nsIInterfaceRequestor
+                           , public nsILoadContext
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
+  NS_DECL_NSIINTERFACEREQUESTOR
+  NS_DECL_NSILOADCONTEXT
 
   WyciwygChannelParent();
   virtual ~WyciwygChannelParent();
 
 protected:
   virtual bool RecvInit(const IPC::URI& uri);
   virtual bool RecvAsyncOpen(const IPC::URI& original,
                              const PRUint32& loadFlags,
-                             const bool& usingPrivateBrowsing);
+                             const bool& haveLoadContext,
+                             const bool& isContent,
+                             const bool& usingPrivateBrowsing,
+                             const bool& isInBrowserElement,
+                             const PRUint32& appId);
   virtual bool RecvWriteToCacheEntry(const nsString& data);
   virtual bool RecvCloseCacheEntry(const nsresult& reason);
   virtual bool RecvSetCharsetAndSource(const PRInt32& source,
                                        const nsCString& charset);
   virtual bool RecvSetSecurityInfo(const nsCString& securityInfo);
   virtual bool RecvCancel(const nsresult& statusCode);
 
   virtual void ActorDestroy(ActorDestroyReason why);
 
   nsCOMPtr<nsIWyciwygChannel> mChannel;
   bool mIPCClosed;
+
+  // fields for impersonating nsILoadContext
+  bool mHaveLoadContext             : 1;
+  bool mIsContent                   : 1;
+  bool mUsePrivateBrowsing          : 1;
+  bool mIsInBrowserElement          : 1;
+
+  PRUint32 mAppId;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_WyciwygChannelParent_h
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
@@ -74,22 +74,21 @@ public:
   }
 private:
   nsresult mReason;
 };
 
 
 // nsWyciwygChannel methods 
 nsWyciwygChannel::nsWyciwygChannel()
-  : PrivateBrowsingConsumer(this),
-    mStatus(NS_OK),
+  : mStatus(NS_OK),
     mIsPending(false),
     mCharsetAndSourceSet(false),
     mNeedToWriteCharset(false),
-    mPrivate(false),
+    mPrivateBrowsing(false),
     mCharsetSource(kCharsetUninitialized),
     mContentLength(-1),
     mLoadFlags(LOAD_NORMAL)
 {
 }
 
 nsWyciwygChannel::~nsWyciwygChannel() 
 {
@@ -267,16 +266,20 @@ nsWyciwygChannel::GetNotificationCallbac
 NS_IMETHODIMP
 nsWyciwygChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
 {
   mCallbacks = aNotificationCallbacks;
   NS_QueryNotificationCallbacks(mCallbacks,
                                 mLoadGroup,
                                 NS_GET_IID(nsIProgressEventSink),
                                 getter_AddRefs(mProgressSink));
+
+  // Will never change unless SetNotificationCallbacks called again, so cache
+  mPrivateBrowsing = NS_UsePrivateBrowsing(this);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsWyciwygChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
 {
   NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
 
@@ -391,19 +394,16 @@ NS_IMETHODIMP
 nsWyciwygChannel::WriteToCacheEntry(const nsAString &aData)
 {
   // URIs not thread-safe, so get spec now in case we need it
   nsCAutoString spec;
   nsresult rv = mURI->GetAsciiSpec(spec);
   if (NS_FAILED(rv)) 
     return rv;
 
-  // UsePrivateBrowsing deals with non-threadsafe objects
-  mPrivate = UsePrivateBrowsing();
-
   return mCacheIOTarget->Dispatch(new nsWyciwygWriteEvent(this, aData, spec),
                                   NS_DISPATCH_NORMAL);
 }
 
 nsresult
 nsWyciwygChannel::WriteToCacheEntryInternal(const nsAString &aData, const nsACString& spec)
 {
   NS_ASSERTION(IsOnCacheIOThread(), "wrong thread");
@@ -663,30 +663,30 @@ nsWyciwygChannel::OpenCacheEntry(const n
   nsresult rv = NS_ERROR_FAILURE;
   // Get cache service
   nsCOMPtr<nsICacheService> cacheService =
     do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // honor security settings
   nsCacheStoragePolicy storagePolicy;
-  if (mPrivate || mLoadFlags & INHIBIT_PERSISTENT_CACHING)
+  if (mPrivateBrowsing || mLoadFlags & INHIBIT_PERSISTENT_CACHING)
     storagePolicy = nsICache::STORE_IN_MEMORY;
   else
     storagePolicy = nsICache::STORE_ANYWHERE;
 
   nsCOMPtr<nsICacheSession> cacheSession;
   // Open a stream based cache session.
-  const char* sessionName = mPrivate ? "wyciwyg-private" : "wyciwyg";
+  const char* sessionName = mPrivateBrowsing ? "wyciwyg-private" : "wyciwyg";
   rv = cacheService->CreateSession(sessionName, storagePolicy, true,
                                    getter_AddRefs(cacheSession));
   if (!cacheSession) 
     return NS_ERROR_FAILURE;
 
-  cacheSession->SetIsPrivate(mPrivate);
+  cacheSession->SetIsPrivate(mPrivateBrowsing);
 
   if (aAccessMode == nsICache::ACCESS_WRITE)
     rv = cacheSession->OpenCacheEntry(aCacheKey, aAccessMode, false,
                                       getter_AddRefs(mCacheEntry));
   else
     rv = cacheSession->AsyncOpenCacheEntry(aCacheKey, aAccessMode, this, false);
 
   return rv;
--- a/netwerk/protocol/wyciwyg/nsWyciwygChannel.h
+++ b/netwerk/protocol/wyciwyg/nsWyciwygChannel.h
@@ -19,26 +19,26 @@
 #include "nsIInputStreamPump.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIProgressEventSink.h"
 #include "nsIStreamListener.h"
 #include "nsICacheListener.h"
 #include "nsICacheEntryDescriptor.h"
 #include "nsIURI.h"
 #include "nsIEventTarget.h"
-#include "PrivateBrowsingConsumer.h"
+#include "nsILoadContext.h"
+#include "nsNetUtil.h"
 
 extern PRLogModuleInfo * gWyciwygLog;
 
 //-----------------------------------------------------------------------------
 
 class nsWyciwygChannel: public nsIWyciwygChannel,
                         public nsIStreamListener,
-                        public nsICacheListener,
-                        public mozilla::net::PrivateBrowsingConsumer
+                        public nsICacheListener
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUEST
     NS_DECL_NSICHANNEL
     NS_DECL_NSIWYCIWYGCHANNEL
     NS_DECL_NSIREQUESTOBSERVER
     NS_DECL_NSISTREAMLISTENER
@@ -67,17 +67,17 @@ protected:
 
     void NotifyListener();
     bool IsOnCacheIOThread();
 
     nsresult                            mStatus;
     bool                                mIsPending;
     bool                                mCharsetAndSourceSet;
     bool                                mNeedToWriteCharset;
-    bool                                mPrivate;
+    bool                                mPrivateBrowsing;
     PRInt32                             mCharsetSource;
     nsCString                           mCharset;
     PRInt32                             mContentLength;
     PRUint32                            mLoadFlags;
     nsCOMPtr<nsIURI>                    mURI;
     nsCOMPtr<nsIURI>                    mOriginalURI;
     nsCOMPtr<nsISupports>               mOwner;
     nsCOMPtr<nsIInterfaceRequestor>     mCallbacks;
--- a/netwerk/test/unit/test_cacheflags.js
+++ b/netwerk/test/unit/test_cacheflags.js
@@ -6,50 +6,80 @@ var httpserver = null;
 var suffix = Math.random();
 var httpBase = "http://localhost:4444";
 var httpsBase = "http://localhost:4445";
 var shortexpPath = "/shortexp" + suffix;
 var longexpPath = "/longexp" + suffix;
 var nocachePath = "/nocache" + suffix;
 var nostorePath = "/nostore" + suffix;
 
-function make_channel(url, flags) {
+// We attach this to channel when we want to test Private Browsing mode
+function LoadContext(usePrivateBrowsing) {
+  this.usePrivateBrowsing = usePrivateBrowsing;
+}
+
+LoadContext.prototype = {
+  usePrivateBrowsing: false,
+  // don't bother defining rest of nsILoadContext fields: don't need 'em
+
+  QueryInterface: function(iid) {
+    if (iid.equals(Ci.nsILoadContext))
+      return this;
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  },
+
+  getInterface: function(iid) {
+    if (iid.equals(Ci.nsILoadContext))
+      return this;
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  }
+};
+
+PrivateBrowsingLoadContext = new LoadContext(true);
+
+function make_channel(url, flags, usePrivateBrowsing) {
   var ios = Cc["@mozilla.org/network/io-service;1"].
     getService(Ci.nsIIOService);
   var req = ios.newChannel(url, null, null);
   req.loadFlags = flags;
+  if (usePrivateBrowsing) {
+    req.notificationCallbacks = PrivateBrowsingLoadContext;    
+  }
   return req;
 }
 
-function Test(path, flags, expectSuccess, readFromCache, hitServer) {
+function Test(path, flags, expectSuccess, readFromCache, hitServer, 
+              usePrivateBrowsing /* defaults to false */) {
   this.path = path;
   this.flags = flags;
   this.expectSuccess = expectSuccess;
   this.readFromCache = readFromCache;
   this.hitServer = hitServer;
+  this.usePrivateBrowsing = usePrivateBrowsing;
 }
 
 Test.prototype = {
   flags: 0,
   expectSuccess: true,
   readFromCache: false,
   hitServer: true,
+  usePrivateBrowsing: false,
   _buffer: "",
   _isFromCache: false,
 
   QueryInterface: function(iid) {
     if (iid.equals(Components.interfaces.nsIStreamListener) ||
         iid.equals(Components.interfaces.nsIRequestObserver) ||
         iid.equals(Components.interfaces.nsISupports))
       return this;
     throw Components.results.NS_ERROR_NO_INTERFACE;
   },
 
   onStartRequest: function(request, context) {
-    var cachingChannel = request.QueryInterface(Ci.nsICachingChannel);
+    var cachingChannel = request.QueryInterface(Ci.nsICacheInfoChannel);
     this._isFromCache = request.isPending() && cachingChannel.isFromCache();
   },
 
   onDataAvailable: function(request, context, stream, offset, count) {
     this._buffer = this._buffer.concat(read_stream(stream, count));
   },
 
   onStopRequest: function(request, context, status) {
@@ -63,24 +93,30 @@ Test.prototype = {
   run: function() {
     dump("Running:" +
          "\n  " + this.path +
          "\n  " + this.flags +
          "\n  " + this.expectSuccess +
          "\n  " + this.readFromCache +
          "\n  " + this.hitServer + "\n");
     gHitServer = false;
-    var channel = make_channel(this.path, this.flags);
+    var channel = make_channel(this.path, this.flags, this.usePrivateBrowsing);
     channel.asyncOpen(this, null);
   }
 };
 
 var gHitServer = false;
 
 var gTests = [
+
+  new Test(httpBase + shortexpPath, 0,
+           true,   // expect success
+           false,  // read from cache
+           true,   // hit server
+           true),  // USE PRIVATE BROWSING, so not cached for later requests
   new Test(httpBase + shortexpPath, 0,
            true,   // expect success
            false,  // read from cache
            true),  // hit server
   new Test(httpBase + shortexpPath, 0,
            true,   // expect success
            true,   // read from cache
            true),  // hit server
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit_ipc/test_cacheflags_wrap.js
@@ -0,0 +1,7 @@
+//
+// Run test script in content process instead of chrome (xpcshell's default)
+//
+
+function run_test() {
+  run_test_in_child("../unit/test_cacheflags.js");
+}
--- a/netwerk/test/unit_ipc/xpcshell.ini
+++ b/netwerk/test/unit_ipc/xpcshell.ini
@@ -1,12 +1,13 @@
 [DEFAULT]
 head = head_channels_clone.js
 tail = 
 
+[test_cacheflags_wrap.js]
 [test_channel_close_wrap.js]
 [test_cookie_wrap.js]
 [test_duplicate_headers_wrap.js]
 [test_event_sink_wrap.js]
 [test_head_wrap.js]
 [test_headers_wrap.js]
 [test_httpcancel_wrap.js]
 [test_httpsuspend_wrap.js]
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -101,17 +101,16 @@
 #include "prmem.h"
 
 #include "ContentChild.h"
 #include "nsXULAppAPI.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellTreeItem.h"
 #include "ExternalHelperAppChild.h"
-#include "nsIPrivateBrowsingConsumer.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
@@ -2176,18 +2175,18 @@ nsresult nsExternalAppHandler::OpenWithA
 #if !defined(XP_MACOSX)
                            true);
 #else
                            false);
 #endif
 
     // See whether the channel has been opened in private browsing mode
     NS_ASSERTION(mRequest, "This should never be called with a null request");
-    nsCOMPtr<nsIPrivateBrowsingConsumer> pbConsumer = do_QueryInterface(mRequest);
-    bool inPrivateBrowsing = pbConsumer && pbConsumer->UsePrivateBrowsing();
+    nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
+    bool inPrivateBrowsing = channel && NS_UsePrivateBrowsing(channel);
 
     // make the tmp file readonly so users won't edit it and lose the changes
     // only if we're going to delete the file
     if (deleteTempFileOnExit || inPrivateBrowsing)
       mFinalFileDestination->SetPermissions(0400);
 
     rv = mMimeInfo->LaunchWithFile(mFinalFileDestination);
     if (NS_FAILED(rv))