Back out d3b8c0394c5e, 701372c96a92, f2c16b13cf65, 367ff8c94636 (bug 683290, bug 684919, bug 685516) for Android reftest failures
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 10 Oct 2011 13:45:13 -0700
changeset 78495 29c1738d7e27
parent 78494 3a8a23bd7708
child 78496 b0e79255fa97
push id21305
push usermbrubeck@mozilla.com
push date2011-10-10 20:46 +0000
treeherdermozilla-central@29c1738d7e27 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs683290, 684919, 685516
milestone10.0a1
Back out d3b8c0394c5e, 701372c96a92, f2c16b13cf65, 367ff8c94636 (bug 683290, bug 684919, bug 685516) for Android reftest failures
content/base/public/nsIImageLoadingContent.idl
content/base/src/nsGenConImageContent.cpp
content/base/src/nsImageLoadingContent.cpp
content/base/src/nsImageLoadingContent.h
content/base/src/nsNodeUtils.cpp
content/base/src/nsObjectLoadingContent.cpp
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLObjectElement.cpp
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGImageElement.cpp
content/svg/content/src/nsSVGImageElement.h
modules/libpr0n/src/RasterImage.cpp
modules/libpr0n/src/imgRequest.cpp
modules/libpref/src/init/all.js
xpcom/glue/COMPtrAndFlag.h
xpcom/glue/Makefile.in
xpcom/tests/TestCOMPtr.cpp
--- a/content/base/public/nsIImageLoadingContent.idl
+++ b/content/base/public/nsIImageLoadingContent.idl
@@ -60,17 +60,17 @@ interface nsIDocument;
  * observers to check which request they are getting notifications for.
  *
  * Observers added in mid-load will not get any notifications they
  * missed.  We should NOT freeze this interface without considering
  * this issue.  (It could be that the image status on imgIRequest is
  * sufficient, when combined with the imageBlockingStatus information.)
  */
 
-[scriptable, uuid(4bf1a7c5-6edb-4191-a257-e31a90f6aa85)]
+[scriptable, uuid(95c74255-df9a-4060-b5a0-0d111fcafe08)]
 interface nsIImageLoadingContent : imgIDecoderObserver
 {
   /**
    * Request types.  Image loading content nodes attempt to do atomic
    * image changes when the image url is changed.  This means that
    * when the url changes the new image load will start, but the old
    * image will remain the "current" request until the new image is
    * fully loaded.  At that point, the old "current" request will be
@@ -170,9 +170,14 @@ interface nsIImageLoadingContent : imgID
   void forceReload();
 
   /**
    * Enables/disables image state forcing. When |aForce| is PR_TRUE, we force
    * nsImageLoadingContent::ImageState() to return |aState|. Call again with |aForce|
    * as PR_FALSE to revert ImageState() to its original behaviour.
    */
   void forceImageState(in boolean aForce, in unsigned long long aState);
+
+  /**
+    * We need to be notified when our document changes.
+    */
+  [noscript, notxpcom] void NotifyOwnerDocumentChanged(in nsIDocument aOldDoc);
 };
--- a/content/base/src/nsGenConImageContent.cpp
+++ b/content/base/src/nsGenConImageContent.cpp
@@ -62,20 +62,16 @@ public:
 
   nsresult Init(imgIRequest* aImageRequest)
   {
     // No need to notify, since we have no frame.
     return UseAsPrimaryRequest(aImageRequest, PR_FALSE);
   }
 
   // nsIContent overrides
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
   virtual nsEventStates IntrinsicState() const;
   
 private:
   virtual ~nsGenConImageContent();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 };
@@ -98,38 +94,16 @@ NS_NewGenConImageContent(nsIContent** aR
   return rv;
 }
 
 nsGenConImageContent::~nsGenConImageContent()
 {
   DestroyImageLoadingContent();
 }
 
-nsresult
-nsGenConImageContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                                 nsIContent* aBindingParent,
-                                 bool aCompileEventHandlers)
-{
-  nsresult rv;
-  rv = nsXMLElement::BindToTree(aDocument, aParent, aBindingParent,
-                                aCompileEventHandlers);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-  return NS_OK;
-}
-
-void
-nsGenConImageContent::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
-  nsXMLElement::UnbindFromTree(aDeep, aNullParent);
-}
-
 nsEventStates
 nsGenConImageContent::IntrinsicState() const
 {
   nsEventStates state = nsXMLElement::IntrinsicState();
 
   nsEventStates imageState = nsImageLoadingContent::ImageState();
   if (imageState.HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED)) {
     // We should never be in an error state; if the image fails to load, we
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -127,17 +127,17 @@ nsImageLoadingContent::DestroyImageLoadi
 {
   // Cancel our requests so they won't hold stale refs to us
   ClearCurrentRequest(NS_BINDING_ABORTED);
   ClearPendingRequest(NS_BINDING_ABORTED);
 }
 
 nsImageLoadingContent::~nsImageLoadingContent()
 {
-  NS_ASSERTION(!mCurrentRequest.Ptr() && !mPendingRequest.Ptr(),
+  NS_ASSERTION(!mCurrentRequest && !mPendingRequest,
                "DestroyImageLoadingContent not called");
   NS_ASSERTION(!mObserverList.mObserver && !mObserverList.mNext,
                "Observers still registered?");
 }
 
 // Macro to call some func on each observer.  This handles observers
 // removing themselves.
 #define LOOP_OVER_OBSERVERS(func_)                                       \
@@ -176,17 +176,17 @@ nsImageLoadingContent::OnStartRequest(im
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::OnStartDecode(imgIRequest* aRequest)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   // Onload blocking. This only applies for the current request.
-  if (aRequest == mCurrentRequest.Ptr()) {
+  if (aRequest == mCurrentRequest) {
 
     // Determine whether this is a background request (this can be the case
     // with multipart/x-mixed-replace images, for example).
     PRUint32 loadFlags;
     nsresult rv = aRequest->GetLoadFlags(&loadFlags);
     bool background =
       (NS_SUCCEEDED(rv) && (loadFlags & nsIRequest::LOAD_BACKGROUND));
 
@@ -238,17 +238,17 @@ nsImageLoadingContent::OnDataAvailable(i
 
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
                                    PRUint32 aFrame)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   // If we're blocking a load, one frame is enough
-  if (aRequest == mCurrentRequest.Ptr())
+  if (aRequest == mCurrentRequest)
     SetBlockingOnload(PR_FALSE);
 
   LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::OnStopContainer(imgIRequest* aRequest,
@@ -257,17 +257,17 @@ nsImageLoadingContent::OnStopContainer(i
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   // This is really hacky. We need to handle the case where we start decoding,
   // block onload, but then hit an error before we get to our first frame. In
   // theory we would just hook in at OnStopDecode, but OnStopDecode is broken
   // until we fix bug 505385. OnStopContainer is actually going away at that
   // point. So for now we take advantage of the fact that OnStopContainer is
   // always fired in the decoders at the same time as OnStopDecode.
-  if (aRequest == mCurrentRequest.Ptr())
+  if (aRequest == mCurrentRequest)
     SetBlockingOnload(PR_FALSE);
 
   LOOP_OVER_OBSERVERS(OnStopContainer(aRequest, aContainer));
   return NS_OK;
 }
 
 // Warning - This isn't actually fired when decode is complete. Rather, it's
 // fired when load is complete. See bug 505385, and in the mean time use
@@ -277,41 +277,39 @@ nsImageLoadingContent::OnStopDecode(imgI
                                     nsresult aStatus,
                                     const PRUnichar* aStatusArg)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   // We should definitely have a request here
   NS_ABORT_IF_FALSE(aRequest, "no request?");
 
-  NS_PRECONDITION(aRequest == mCurrentRequest.Ptr() ||
-                  aRequest == mPendingRequest.Ptr(),
+  NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
                   "Unknown request");
   LOOP_OVER_OBSERVERS(OnStopDecode(aRequest, aStatus, aStatusArg));
 
   // XXXbholley - When we fix bug 505385,  everything here should go in
   // OnStopRequest.
 
   // Our state may change. Watch it.
   AutoStateChanger changer(this, PR_TRUE);
 
   // If the pending request is loaded, switch to it.
-  if (aRequest == mPendingRequest.Ptr()) {
-    PrepareCurrentRequest();
-    mCurrentRequest = mPendingRequest;
-    mPendingRequest.Clear();
+  if (aRequest == mPendingRequest) {
+    PrepareCurrentRequest() = mPendingRequest;
+    mPendingRequest = nsnull;
     mCurrentRequestNeedsResetAnimation = mPendingRequestNeedsResetAnimation;
     mPendingRequestNeedsResetAnimation = PR_FALSE;
   }
-  NS_ABORT_IF_FALSE(aRequest == mCurrentRequest.Ptr(),
+  NS_ABORT_IF_FALSE(aRequest == mCurrentRequest,
                     "One way or another, we should be current by now");
 
   if (mCurrentRequestNeedsResetAnimation) {
     nsCOMPtr<imgIContainer> container;
-    mCurrentRequest.Ptr()->GetImage(getter_AddRefs(container));
+    mCurrentRequest->GetImage(getter_AddRefs(container));
     if (container)
       container->ResetAnimation();
     mCurrentRequestNeedsResetAnimation = PR_FALSE;
   }
 
   // We just loaded all the data we're going to get. If we haven't done an
   // initial paint, we want to make sure the image starts decoding for 2
   // reasons:
@@ -322,19 +320,17 @@ nsImageLoadingContent::OnStopDecode(imgI
   // 2) We want to block onload until all visible images are decoded. We do this
   // by blocking onload until all in progress decodes get at least one frame
   // decoded. However, if all the data comes in while painting is suppressed
   // (ie, before the initial paint delay is finished), we fire onload without
   // doing a paint first. This means that decode-on-draw images don't start
   // decoding, so we can't wait for them to finish. See bug 512435.
 
   // We can only do this if we have a presshell
-  // XXXkhuey should this be GetOurCurrentDoc?  Decoding if we're not in
-  // the document seems silly.
-  nsIDocument* doc = GetOurOwnerDoc();
+  nsIDocument* doc = GetOurDocument();
   nsIPresShell* shell = doc ? doc->GetShell() : nsnull;
   if (shell) {
 
     // We need to figure out whether to kick off decoding
     bool doRequestDecode = false;
 
     // If we haven't got the initial reflow yet, IsPaintingSuppressed actually
     // returns false
@@ -345,17 +341,17 @@ nsImageLoadingContent::OnStopDecode(imgI
     // to be suppressed for reasons other than the initial paint delay (for
     // example - being in the bfcache), but we probably aren't loading images in
     // those situations.
     if (shell->IsPaintingSuppressed())
       doRequestDecode = PR_TRUE;
 
     // If we're requesting a decode, do it
     if (doRequestDecode)
-      mCurrentRequest.Ptr()->RequestDecode();
+      mCurrentRequest->RequestDecode();
   }
 
   // Fire the appropriate DOM event.
   if (NS_SUCCEEDED(aStatus)) {
     FireEvent(NS_LITERAL_STRING("load"));
   } else {
     FireEvent(NS_LITERAL_STRING("error"));
   }
@@ -485,20 +481,20 @@ nsImageLoadingContent::RemoveObserver(im
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::GetRequest(PRInt32 aRequestType,
                                   imgIRequest** aRequest)
 {
   switch(aRequestType) {
   case CURRENT_REQUEST:
-    *aRequest = mCurrentRequest.Ptr();
+    *aRequest = mCurrentRequest;
     break;
   case PENDING_REQUEST:
-    *aRequest = mPendingRequest.Ptr();
+    *aRequest = mPendingRequest;
     break;
   default:
     NS_ERROR("Unknown request type");
     *aRequest = nsnull;
     return NS_ERROR_UNEXPECTED;
   }
   
   NS_IF_ADDREF(*aRequest);
@@ -509,36 +505,36 @@ nsImageLoadingContent::GetRequest(PRInt3
 NS_IMETHODIMP
 nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
                                       PRInt32* aRequestType)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   NS_PRECONDITION(aRequestType, "Null out param");
   
-  if (aRequest == mCurrentRequest.Ptr()) {
+  if (aRequest == mCurrentRequest) {
     *aRequestType = CURRENT_REQUEST;
     return NS_OK;
   }
 
-  if (aRequest == mPendingRequest.Ptr()) {
+  if (aRequest == mPendingRequest) {
     *aRequestType = PENDING_REQUEST;
     return NS_OK;
   }
 
   *aRequestType = UNKNOWN_REQUEST;
   NS_ERROR("Unknown request");
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::GetCurrentURI(nsIURI** aURI)
 {
-  if (mCurrentRequest.Ptr()) {
-    return mCurrentRequest.Ptr()->GetURI(aURI);
+  if (mCurrentRequest) {
+    return mCurrentRequest->GetURI(aURI);
   }
 
   if (!mCurrentURI) {
     *aURI = nsnull;
     return NS_OK;
   }
   
   return NS_EnsureSafeToReturn(mCurrentURI, aURI);
@@ -549,40 +545,40 @@ nsImageLoadingContent::LoadImageWithChan
                                             nsIStreamListener** aListener)
 {
   NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
 
   if (!nsContentUtils::GetImgLoader()) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  nsCOMPtr<nsIDocument> doc = GetOurOwnerDoc();
+  nsCOMPtr<nsIDocument> doc = GetOurDocument();
   if (!doc) {
     // Don't bother
     return NS_OK;
   }
 
   // XXX what should we do with content policies here, if anything?
   // Shouldn't that be done before the start of the load?
   // XXX what about shouldProcess?
 
   // Our state might change. Watch it.
   AutoStateChanger changer(this, PR_TRUE);
 
   // Do the load.
-  RequestWithState& req = PrepareNextRequest();
+  nsCOMPtr<imgIRequest>& req = PrepareNextRequest();
   nsresult rv = nsContentUtils::GetImgLoader()->
     LoadImageWithChannel(aChannel, this, doc, aListener,
                          getter_AddRefs(req));
   if (NS_SUCCEEDED(rv)) {
     TrackImage(req);
   } else {
     // If we don't have a current URI, we might as well store this URI so people
     // know what we tried (and failed) to load.
-    if (!mCurrentRequest.Ptr())
+    if (!mCurrentRequest)
       aChannel->GetURI(getter_AddRefs(mCurrentURI));
     FireEvent(NS_LITERAL_STRING("error"));
     return rv;
   }
   return NS_OK;;
 }
 
 NS_IMETHODIMP nsImageLoadingContent::ForceReload()
@@ -597,23 +593,39 @@ NS_IMETHODIMP nsImageLoadingContent::For
 
   return LoadImage(currentURI, PR_TRUE, PR_TRUE, nsnull, nsIRequest::VALIDATE_ALWAYS);
 }
 
 /*
  * Non-interface methods
  */
 
+void
+nsImageLoadingContent::NotifyOwnerDocumentChanged(nsIDocument *aOldDoc)
+{
+  // If we had a document before, unregister ourselves with it.
+  if (aOldDoc) {
+    if (mCurrentRequest)
+      aOldDoc->RemoveImage(mCurrentRequest);
+    if (mPendingRequest)
+      aOldDoc->RemoveImage(mPendingRequest);
+  }
+
+  // Re-track the images
+  TrackImage(mCurrentRequest);
+  TrackImage(mPendingRequest);
+}
+
 nsresult
 nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
                                  bool aForce,
                                  bool aNotify)
 {
   // First, get a document (needed for security checks and the like)
-  nsIDocument* doc = GetOurOwnerDoc();
+  nsIDocument* doc = GetOurDocument();
   if (!doc) {
     // No reason to bother, I think...
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> imageURI;
   nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -651,21 +663,21 @@ nsImageLoadingContent::LoadImage(nsIURI*
 {
   if (!mLoadingEnabled) {
     // XXX Why fire an error here? seems like the callers to SetLoadingEnabled
     // don't want/need it.
     FireEvent(NS_LITERAL_STRING("error"));
     return NS_OK;
   }
 
-  NS_ASSERTION(!aDocument || aDocument == GetOurOwnerDoc(),
+  NS_ASSERTION(!aDocument || aDocument == GetOurDocument(),
                "Bogus document passed in");
   // First, get a document (needed for security checks and the like)
   if (!aDocument) {
-    aDocument = GetOurOwnerDoc();
+    aDocument = GetOurDocument();
     if (!aDocument) {
       // No reason to bother, I think...
       return NS_OK;
     }
   }
 
   // URI equality check.
   //
@@ -711,29 +723,29 @@ nsImageLoadingContent::LoadImage(nsIURI*
   PRInt32 corsmode = GetCORSMode();
   if (corsmode == nsImageLoadingContent::CORS_ANONYMOUS) {
     loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
   } else if (corsmode == nsImageLoadingContent::CORS_USE_CREDENTIALS) {
     loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
   }
 
   // Not blocked. Do the load.
-  RequestWithState& req = PrepareNextRequest();
+  nsCOMPtr<imgIRequest>& req = PrepareNextRequest();
   nsresult rv;
   rv = nsContentUtils::LoadImage(aNewURI, aDocument,
                                  aDocument->NodePrincipal(),
                                  aDocument->GetDocumentURI(),
                                  this, loadFlags,
                                  getter_AddRefs(req));
   if (NS_SUCCEEDED(rv)) {
     TrackImage(req);
   } else {
     // If we don't have a current URI, we might as well store this URI so people
     // know what we tried (and failed) to load.
-    if (!mCurrentRequest.Ptr())
+    if (!mCurrentRequest)
       mCurrentURI = aNewURI;
     FireEvent(NS_LITERAL_STRING("error"));
     return NS_OK;
   }
 
   return NS_OK;
 }
 
@@ -794,22 +806,22 @@ nsImageLoadingContent::UpdateImageState(
   
   // If we were blocked by server-based content policy, we claim to be
   // suppressed.  If we were blocked by type-based content policy, we claim to
   // be user-disabled.  Otherwise, claim to be broken.
   if (mImageBlockingStatus == nsIContentPolicy::REJECT_SERVER) {
     mSuppressed = PR_TRUE;
   } else if (mImageBlockingStatus == nsIContentPolicy::REJECT_TYPE) {
     mUserDisabled = PR_TRUE;
-  } else if (!mCurrentRequest.Ptr()) {
+  } else if (!mCurrentRequest) {
     // No current request means error, since we weren't disabled or suppressed
     mBroken = PR_TRUE;
   } else {
     PRUint32 currentLoadStatus;
-    nsresult rv = mCurrentRequest.Ptr()->GetImageStatus(&currentLoadStatus);
+    nsresult rv = mCurrentRequest->GetImageStatus(&currentLoadStatus);
     if (NS_FAILED(rv) || (currentLoadStatus & imgIRequest::STATUS_ERROR)) {
       mBroken = PR_TRUE;
     } else if (!(currentLoadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
       mLoading = PR_TRUE;
     }
   }
 
   NS_ASSERTION(thisContent->IsElement(), "Not an element?");
@@ -831,44 +843,35 @@ nsImageLoadingContent::UseAsPrimaryReque
   // Our state will change. Watch it.
   AutoStateChanger changer(this, aNotify);
 
   // Get rid if our existing images
   ClearPendingRequest(NS_BINDING_ABORTED);
   ClearCurrentRequest(NS_BINDING_ABORTED);
 
   // Clone the request we were given.
-  RequestWithState& req = PrepareNextRequest();
+  nsCOMPtr<imgIRequest>& req = PrepareNextRequest();;
   nsresult rv = aRequest->Clone(this, getter_AddRefs(req));
   if (NS_SUCCEEDED(rv))
     TrackImage(req);
   else
     return rv;
 
   return NS_OK;
 }
 
 nsIDocument*
-nsImageLoadingContent::GetOurOwnerDoc()
+nsImageLoadingContent::GetOurDocument()
 {
   nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
   NS_ENSURE_TRUE(thisContent, nsnull);
 
   return thisContent->GetOwnerDoc();
 }
 
-nsIDocument*
-nsImageLoadingContent::GetOurCurrentDoc()
-{
-  nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
-  NS_ENSURE_TRUE(thisContent, nsnull);
-
-  return thisContent->GetCurrentDoc();
-}
-
 nsresult
 nsImageLoadingContent::StringToURI(const nsAString& aSpec,
                                    nsIDocument* aDocument,
                                    nsIURI** aURI)
 {
   NS_PRECONDITION(aDocument, "Must have a document");
   NS_PRECONDITION(aURI, "Null out param");
 
@@ -899,29 +902,26 @@ nsImageLoadingContent::FireEvent(const n
 
   nsRefPtr<nsPLDOMEvent> event =
     new nsLoadBlockingPLDOMEvent(thisNode, aEventType, PR_FALSE, PR_FALSE);
   event->PostDOMEvent();
   
   return NS_OK;
 }
 
-nsImageLoadingContent::RequestWithState&
+nsCOMPtr<imgIRequest>&
 nsImageLoadingContent::PrepareNextRequest()
 {
   // If we don't have a usable current request, get rid of any half-baked
   // request that might be sitting there and make this one current.
-  if (!HaveSize(mCurrentRequest.Ptr())) {
-    PrepareCurrentRequest();
-    return mCurrentRequest;
-  }
+  if (!HaveSize(mCurrentRequest))
+    return PrepareCurrentRequest();
 
   // Otherwise, make it pending.
-  PreparePendingRequest();
-  return mPendingRequest;
+  return PreparePendingRequest();
 }
 
 void
 nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision)
 {
   // Sanity
   NS_ABORT_IF_FALSE(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
 
@@ -930,87 +930,93 @@ nsImageLoadingContent::SetBlockedRequest
   // new image is blocked, the old one should really be canceled with the
   // reason "image source changed". However, apparently there's some abuse
   // over in nsImageFrame where the displaying of the "broken" icon for the
   // next image depends on the cancel reason of the previous image. ugh.
   ClearPendingRequest(NS_ERROR_IMAGE_BLOCKED);
 
   // For the blocked case, we only want to cancel the existing current request
   // if size is not available. bz says the web depends on this behavior.
-  if (!HaveSize(mCurrentRequest.Ptr())) {
+  if (!HaveSize(mCurrentRequest)) {
 
     mImageBlockingStatus = aContentDecision;
     ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED);
 
     // We still want to remember what URI we were despite not having an actual
     // request.
     mCurrentURI = aURI;
   }
 }
 
-void
+nsCOMPtr<imgIRequest>&
 nsImageLoadingContent::PrepareCurrentRequest()
 {
   // Blocked images go through SetBlockedRequest, which is a separate path. For
   // everything else, we're unblocked.
   mImageBlockingStatus = nsIContentPolicy::ACCEPT;
 
   // Get rid of anything that was there previously.
   ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED);
 
   mCurrentRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
+
+  // Return a reference.
+  return mCurrentRequest;
 }
 
-void
+nsCOMPtr<imgIRequest>&
 nsImageLoadingContent::PreparePendingRequest()
 {
   // Get rid of anything that was there previously.
   ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED);
 
   mPendingRequestNeedsResetAnimation = mNewRequestsWillNeedAnimationReset;
+
+  // Return a reference.
+  return mPendingRequest;
 }
 
 void
 nsImageLoadingContent::ClearCurrentRequest(nsresult aReason)
 {
-  if (!mCurrentRequest.Ptr()) {
+  if (!mCurrentRequest) {
     // Even if we didn't have a current request, we might have been keeping
     // a URI as a placeholder for a failed load. Clear that now.
     mCurrentURI = nsnull;
     return;
   }
   NS_ABORT_IF_FALSE(!mCurrentURI,
                     "Shouldn't have both mCurrentRequest and mCurrentURI!");
 
   // Clean up the request.
   UntrackImage(mCurrentRequest);
-  mCurrentRequest.Ptr()->CancelAndForgetObserver(aReason);
-  mCurrentRequest.Clear();
+  mCurrentRequest->CancelAndForgetObserver(aReason);
+  mCurrentRequest = nsnull;
   mCurrentRequestNeedsResetAnimation = PR_FALSE;
 
   // We only block onload during the decoding of "current" images. This one is
   // going away, so we should unblock unconditionally here.
   SetBlockingOnload(PR_FALSE);
 }
 
 void
 nsImageLoadingContent::ClearPendingRequest(nsresult aReason)
 {
-  if (!mPendingRequest.Ptr())
+  if (!mPendingRequest)
     return;
 
   // Push a null JSContext on the stack so that code that runs within
   // the below code doesn't think it's being called by JS. See bug
   // 604262.
   nsCxPusher pusher;
   pusher.PushNull();
 
   UntrackImage(mPendingRequest);
-  mPendingRequest.Ptr()->CancelAndForgetObserver(aReason);
-  mPendingRequest.Clear();
+  mPendingRequest->CancelAndForgetObserver(aReason);
+  mPendingRequest = nsnull;
   mPendingRequestNeedsResetAnimation = PR_FALSE;
 }
 
 bool
 nsImageLoadingContent::HaveSize(imgIRequest *aImage)
 {
   // Handle the null case
   if (!aImage)
@@ -1025,100 +1031,62 @@ nsImageLoadingContent::HaveSize(imgIRequ
 void
 nsImageLoadingContent::SetBlockingOnload(bool aBlocking)
 {
   // If we're already in the desired state, we have nothing to do
   if (mBlockingOnload == aBlocking)
     return;
 
   // Get the document
-  nsIDocument* doc = GetOurOwnerDoc();
+  nsIDocument* doc = GetOurDocument();
 
   if (doc) {
     // Take the appropriate action
     if (aBlocking)
       doc->BlockOnload();
     else
       doc->UnblockOnload(PR_FALSE);
 
     // Update our state
     mBlockingOnload = aBlocking;
   }
 }
 
-void
-nsImageLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                                  nsIContent* aBindingParent,
-                                  bool aCompileEventHandlers)
+nsresult
+nsImageLoadingContent::TrackImage(imgIRequest* aImage)
 {
-  // We may be entering the document, so if our image should be tracked,
-  // track it.
-  if (!aDocument)
-    return;
-
-  if (mCurrentRequest.Flag())
-    aDocument->AddImage(mCurrentRequest.Ptr());
-  if (mPendingRequest.Flag())
-    aDocument->AddImage(mPendingRequest.Ptr());
-}
-
-void
-nsImageLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  // We may be leaving the document, so if our image is tracked, untrack it.
-  nsCOMPtr<nsIDocument> doc = GetOurCurrentDoc();
-  if (!doc)
-    return;
-
-  if (mCurrentRequest.Flag())
-    doc->RemoveImage(mCurrentRequest.Ptr());
-  if (mPendingRequest.Flag())
-    doc->RemoveImage(mPendingRequest.Ptr());
-}
-
-nsresult
-nsImageLoadingContent::TrackImage(RequestWithState& aImage)
-{
-  if (!aImage.Ptr())
+  if (!aImage)
     return NS_OK;
 
-  NS_ASSERTION(!aImage.Flag(), "Already tracked!?");
-
-  aImage.SetFlag(true);
-
-  nsIDocument* doc = GetOurCurrentDoc();
+  nsIDocument* doc = GetOurDocument();
   if (doc)
-    return doc->AddImage(aImage.Ptr());
+    return doc->AddImage(aImage);
   return NS_OK;
 }
 
 nsresult
-nsImageLoadingContent::UntrackImage(RequestWithState& aImage)
+nsImageLoadingContent::UntrackImage(imgIRequest* aImage)
 {
-  if (!aImage.Ptr())
+  if (!aImage)
     return NS_OK;
 
-  NS_ASSERTION(aImage.Flag(), "Not already tracked!?");
-
-  aImage.SetFlag(false);
-
-  // If GetOurCurrentDoc() returns null here, we've outlived our document.
+  // If GetOurDocument() returns null here, we've outlived our document.
   // That's fine, because the document empties out the tracker and unlocks
   // all locked images on destruction.
-  nsIDocument* doc = GetOurCurrentDoc();
+  nsIDocument* doc = GetOurDocument();
   if (doc)
-    return doc->RemoveImage(aImage.Ptr());
+    return doc->RemoveImage(aImage);
   return NS_OK;
 }
 
 
 void
 nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) const
 {
-  aDest->mCurrentRequest.SetPtr(nsContentUtils::GetStaticRequest(mCurrentRequest.Ptr()));
+  aDest->mCurrentRequest = nsContentUtils::GetStaticRequest(mCurrentRequest);
   aDest->TrackImage(aDest->mCurrentRequest);
   aDest->mForcedImageState = mForcedImageState;
   aDest->mImageBlockingStatus = mImageBlockingStatus;
   aDest->mLoadingEnabled = mLoadingEnabled;
   aDest->mStateChangerDepth = mStateChangerDepth;
   aDest->mIsImageStateForced = mIsImageStateForced;
   aDest->mLoading = mLoading;
   aDest->mBroken = mBroken;
--- a/content/base/src/nsImageLoadingContent.h
+++ b/content/base/src/nsImageLoadingContent.h
@@ -48,17 +48,16 @@
 #include "nsIImageLoadingContent.h"
 #include "nsINode.h"
 #include "imgIRequest.h"
 #include "prtypes.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
 #include "nsString.h"
 #include "nsEventStates.h"
-#include "mozilla/COMPtrAndFlag.h"
 
 class nsIURI;
 class nsIDocument;
 class imgILoader;
 class nsIIOService;
 
 class nsImageLoadingContent : public nsIImageLoadingContent
 {
@@ -134,24 +133,23 @@ protected:
    * @param aLoadFlags Optional parameter specifying load flags to use for
    *        the image load
    */
   nsresult LoadImage(nsIURI* aNewURI, bool aForce, bool aNotify,
                      nsIDocument* aDocument = nsnull,
                      nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL);
 
   /**
-   * helpers to get the document for this content (from the nodeinfo
-   * and such).  Not named GetOwnerDoc/GetCurrentDoc to prevent ambiguous
-   * method names in subclasses
+   * helper to get the document for this content (from the nodeinfo
+   * and such).  Not named GetDocument to prevent ambiguous method
+   * names in subclasses
    *
    * @return the document we belong to
    */
-  nsIDocument* GetOurOwnerDoc();
-  nsIDocument* GetOurCurrentDoc();
+  nsIDocument* GetOurDocument();
 
   /**
    * CancelImageRequests is called by subclasses when they want to
    * cancel all image requests (for example when the subclass is
    * somehow not an image anymore).
    */
   void CancelImageRequests(bool aNotify);
 
@@ -182,21 +180,16 @@ protected:
   void SetBlockingOnload(bool aBlocking);
 
   /**
    * Returns the CORS mode that will be used for all future image loads. The
    * default implementation returns CORS_NONE unconditionally.
    */
   virtual CORSMode GetCORSMode();
 
-  // Subclasses are *required* to call BindToTree/UnbindFromTree.
-  void BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                  nsIContent* aBindingParent, bool aCompileEventHandlers);
-  void UnbindFromTree(bool aDeep, bool aNullParent);
-
 private:
   /**
    * Struct used to manage the image observers.
    */
   struct ImageObserver {
     ImageObserver(imgIDecoderObserver* aObserver) :
       mObserver(aObserver),
       mNext(nsnull)
@@ -274,43 +267,39 @@ protected:
    * @param aDocument the document we belong to
    * @return the URI we want to be loading
    */
   nsresult StringToURI(const nsAString& aSpec, nsIDocument* aDocument,
                        nsIURI** aURI);
 
   void CreateStaticImageClone(nsImageLoadingContent* aDest) const;
 
-  // The flag on these pointers tells whether or not the image "should" be
-  // tracked by the document.  The only situation in which we should be
-  // tracked but aren't is when we are not in a document.
-  typedef mozilla::COMPtrAndFlag<imgIRequest> RequestWithState;
-
   /**
    * Prepare and returns a reference to the "next request". If there's already
    * a _usable_ current request (one with SIZE_AVAILABLE), this request is
    * "pending" until it becomes usable. Otherwise, this becomes the current
    * request.
    */
-   RequestWithState& PrepareNextRequest();
+   nsCOMPtr<imgIRequest>& PrepareNextRequest();
 
   /**
    * Called when we would normally call PrepareNextRequest(), but the request was
    * blocked.
    */
   void SetBlockedRequest(nsIURI* aURI, PRInt16 aContentDecision);
 
   /**
-   * Cleans up and cancels the appropriate request. Note that if you just want
+   * Returns a COMPtr reference to the current/pending image requests, cleaning
+   * up and canceling anything that was there before. Note that if you just want
    * to get rid of one of the requests, you should call
    * Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
    * aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
    */
-  void PrepareCurrentRequest();
-  void PreparePendingRequest();
+  nsCOMPtr<imgIRequest>& PrepareCurrentRequest();
+  nsCOMPtr<imgIRequest>& PreparePendingRequest();
 
   /**
    * Cancels and nulls-out the "current" and "pending" requests if they exist.
    */
   void ClearCurrentRequest(nsresult aReason);
   void ClearPendingRequest(nsresult aReason);
 
   /**
@@ -319,22 +308,22 @@ protected:
    */
   static bool HaveSize(imgIRequest *aImage);
 
   /**
    * Adds/Removes a given imgIRequest from our document's tracker.
    *
    * No-op if aImage is null.
    */
-  nsresult TrackImage(RequestWithState& aImage);
-  nsresult UntrackImage(RequestWithState& aImage);
+  nsresult TrackImage(imgIRequest* aImage);
+  nsresult UntrackImage(imgIRequest* aImage);
 
   /* MEMBERS */
-  RequestWithState mCurrentRequest;
-  RequestWithState mPendingRequest;
+  nsCOMPtr<imgIRequest> mCurrentRequest;
+  nsCOMPtr<imgIRequest> mPendingRequest;
 
   // If the image was blocked or if there was an error loading, it's nice to
   // still keep track of what the URI was despite not having an imgIRequest.
   // We only maintain this in those situations (in the common case, this is
   // always null).
   nsCOMPtr<nsIURI>      mCurrentURI;
 
 private:
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -57,16 +57,17 @@
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
 #include "nsBindingManager.h"
 #include "nsGenericHTMLElement.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif // MOZ_MEDIA
+#include "nsImageLoadingContent.h"
 #include "jsgc.h"
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla::dom;
 
 // This macro expects the ownerDocument of content_ to be in scope as
 // |nsIDocument* doc|
 // NOTE: AttributeChildRemoved doesn't use this macro but has a very similar use.
@@ -581,16 +582,23 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aNode));
       if (domMediaElem) {
         nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aNode);
         mediaElem->NotifyOwnerDocumentActivityChanged();
       }
     }
 #endif
 
+    // nsImageLoadingContent needs to know when its document changes
+    if (oldDoc != newDoc) {
+      nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aNode));
+      if (imageContent)
+        imageContent->NotifyOwnerDocumentChanged(oldDoc);
+    }
+
     if (elem) {
       elem->RecompileScriptEventListeners();
     }
 
     if (aCx && wrapper) {
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
       if (xpc) {
         JSObject *preservedWrapper = nsnull;
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -960,17 +960,17 @@ nsObjectLoadingContent::HasNewFrame(nsIO
   if (!mInstantiating && mType == eType_Plugin) {
     // Asynchronously call Instantiate
     // This can go away once plugin loading moves to content
     // This must be done asynchronously to ensure that the frame is correctly
     // initialized (has a view etc)
 
     // When in a plugin document, the document will take care of calling
     // instantiate
-    nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurOwnerDoc()));
+    nsCOMPtr<nsIPluginDocument> pDoc (do_QueryInterface(GetOurDocument()));
     if (pDoc) {
       bool willHandleInstantiation;
       pDoc->GetWillHandleInstantiation(&willHandleInstantiation);
       if (willHandleInstantiation) {
         return NS_OK;
       }
     }
 
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -139,17 +139,16 @@ public:
                            nsIAtom* aPrefix, const nsAString& aValue,
                            bool aNotify);
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
 
   virtual nsEventStates IntrinsicState() const;
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   nsresult CopyInnerTo(nsGenericElement* aDest) const;
 
   void MaybeLoadImage();
   virtual nsXPCClassInfo* GetClassInfo();
@@ -249,22 +248,22 @@ nsHTMLImageElement::GetDraggable(bool* a
 }
 
 NS_IMETHODIMP
 nsHTMLImageElement::GetComplete(bool* aComplete)
 {
   NS_PRECONDITION(aComplete, "Null out param!");
   *aComplete = PR_TRUE;
 
-  if (!mCurrentRequest.Ptr()) {
+  if (!mCurrentRequest) {
     return NS_OK;
   }
 
   PRUint32 status;
-  mCurrentRequest.Ptr()->GetImageStatus(&status);
+  mCurrentRequest->GetImageStatus(&status);
   *aComplete =
     (status &
      (imgIRequest::STATUS_LOAD_COMPLETE | imgIRequest::STATUS_ERROR)) != 0;
 
   return NS_OK;
 }
 
 nsSize
@@ -277,18 +276,18 @@ nsHTMLImageElement::GetWidthHeight()
   if (frame) {
     size = frame->GetContentRect().Size();
 
     size.width = nsPresContext::AppUnitsToIntCSSPixels(size.width);
     size.height = nsPresContext::AppUnitsToIntCSSPixels(size.height);
   } else {
     const nsAttrValue* value;
     nsCOMPtr<imgIContainer> image;
-    if (mCurrentRequest.Ptr()) {
-      mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
+    if (mCurrentRequest) {
+      mCurrentRequest->GetImage(getter_AddRefs(image));
     }
 
     if ((value = GetParsedAttr(nsGkAtoms::width)) &&
         value->Type() == nsAttrValue::eInteger) {
       size.width = value->GetIntegerValue();
     } else if (image) {
       image->GetWidth(&size.width);
     }
@@ -525,19 +524,16 @@ nsHTMLImageElement::BindToTree(nsIDocume
                                nsIContent* aBindingParent,
                                bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
     // FIXME: Bug 660963 it would be nice if we could just have
     // ClearBrokenState update our state and do it fast...
     ClearBrokenState();
     RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
     // If loading is temporarily disabled, don't even launch MaybeLoadImage.
     // Otherwise MaybeLoadImage may run later when someone has reenabled
     // loading.
@@ -546,23 +542,16 @@ nsHTMLImageElement::BindToTree(nsIDocume
         NS_NewRunnableMethod(this, &nsHTMLImageElement::MaybeLoadImage));
     }
   }
 
   return rv;
 }
 
 void
-nsHTMLImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
-  nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
-}
-
-void
 nsHTMLImageElement::MaybeLoadImage()
 {
   // Our base URI may have changed; claim that our URI changed, and the
   // nsImageLoadingContent will decide whether a new image load is warranted.
   // Note, check LoadingEnabled() after LoadImage call.
   nsAutoString uri;
   if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, uri) &&
       (NS_FAILED(LoadImage(uri, PR_FALSE, PR_TRUE)) ||
@@ -609,22 +598,22 @@ nsHTMLImageElement::Initialize(nsISuppor
 
 NS_IMETHODIMP
 nsHTMLImageElement::GetNaturalHeight(PRUint32* aNaturalHeight)
 {
   NS_ENSURE_ARG_POINTER(aNaturalHeight);
 
   *aNaturalHeight = 0;
 
-  if (!mCurrentRequest.Ptr()) {
+  if (!mCurrentRequest) {
     return NS_OK;
   }
   
   nsCOMPtr<imgIContainer> image;
-  mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
+  mCurrentRequest->GetImage(getter_AddRefs(image));
   if (!image) {
     return NS_OK;
   }
 
   PRInt32 height;
   if (NS_SUCCEEDED(image->GetHeight(&height))) {
     *aNaturalHeight = height;
   }
@@ -633,22 +622,22 @@ nsHTMLImageElement::GetNaturalHeight(PRU
 
 NS_IMETHODIMP
 nsHTMLImageElement::GetNaturalWidth(PRUint32* aNaturalWidth)
 {
   NS_ENSURE_ARG_POINTER(aNaturalWidth);
 
   *aNaturalWidth = 0;
 
-  if (!mCurrentRequest.Ptr()) {
+  if (!mCurrentRequest) {
     return NS_OK;
   }
   
   nsCOMPtr<imgIContainer> image;
-  mCurrentRequest.Ptr()->GetImage(getter_AddRefs(image));
+  mCurrentRequest->GetImage(getter_AddRefs(image));
   if (!image) {
     return NS_OK;
   }
 
   PRInt32 width;
   if (NS_SUCCEEDED(image->GetWidth(&width))) {
     *aNaturalWidth = width;
   }
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -2315,19 +2315,16 @@ nsHTMLInputElement::BindToTree(nsIDocume
                                nsIContent* aBindingParent,
                                bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
                                                      aBindingParent,
                                                      aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   if (mType == NS_FORM_INPUT_IMAGE) {
     // Our base URI may have changed; claim that our URI changed, and the
     // nsImageLoadingContent will decide whether a new image load is warranted.
     if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
       // FIXME: Bug 660963 it would be nice if we could just have
       // ClearBrokenState update our state and do it fast...
       ClearBrokenState();
       RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
@@ -2364,18 +2361,16 @@ nsHTMLInputElement::UnbindFromTree(bool 
   // nsGenericHTMLFormElement::UnbindFromTree() will unset the form and
   // that takes care of form's WillRemove so we just have to take care
   // of the case where we're removing from the document and we don't
   // have a form
   if (!mForm && mType == NS_FORM_INPUT_RADIO) {
     WillRemoveFromRadioGroup();
   }
 
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
-
   nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
 
   // GetCurrentDoc is returning nsnull so we can update the value
   // missing validity state to reflect we are no longer into a doc.
   UpdateValueMissingValidityState();
   // We might be no longer disabled because of parent chain changed.
   UpdateBarredFromConstraintValidation();
 
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -240,34 +240,30 @@ nsHTMLObjectElement::BindToTree(nsIDocum
                                 nsIContent *aBindingParent,
                                 bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
                                                      aBindingParent,
                                                      aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   // If we already have all the children, start the load.
   if (mIsDoneAddingChildren) {
     void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad;
     nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
   }
 
   return NS_OK;
 }
 
 void
 nsHTMLObjectElement::UnbindFromTree(bool aDeep,
                                     bool aNullParent)
 {
   RemovedFromDocument();
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
   nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 
 nsresult
 nsHTMLObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                              nsIAtom *aPrefix, const nsAString &aValue,
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -267,35 +267,31 @@ nsHTMLSharedObjectElement::BindToTree(ns
                                       nsIContent *aBindingParent,
                                       bool aCompileEventHandlers)
 {
   nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   // If we already have all the children, start the load.
   if (mIsDoneAddingChildren) {
     void (nsHTMLSharedObjectElement::*start)() =
       &nsHTMLSharedObjectElement::StartObjectLoad;
     nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start));
   }
 
   return NS_OK;
 }
 
 void
 nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
                                           bool aNullParent)
 {
   RemovedFromDocument();
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
   nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
 }
 
 
 
 nsresult
 nsHTMLSharedObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
                                    nsIAtom *aPrefix, const nsAString &aValue,
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -5338,17 +5338,16 @@ public:
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                 const nsAString* aValue, bool aNotify);
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
   virtual nsEventStates IntrinsicState() const;
 
   // imgIDecoderObserver
   NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
                           const PRUnichar *statusArg);
   // imgIContainerObserver
   NS_IMETHOD FrameChanged(imgIContainer *aContainer,
                           const nsIntRect *aDirtyRect);
@@ -5496,38 +5495,28 @@ nsSVGFEImageElement::BindToTree(nsIDocum
                                 nsIContent* aBindingParent,
                                 bool aCompileEventHandlers)
 {
   nsresult rv = nsSVGFEImageElementBase::BindToTree(aDocument, aParent,
                                                     aBindingParent,
                                                     aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   if (mStringAttributes[HREF].IsExplicitlySet()) {
     // FIXME: Bug 660963 it would be nice if we could just have
     // ClearBrokenState update our state and do it fast...
     ClearBrokenState();
     RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
     nsContentUtils::AddScriptRunner(
       NS_NewRunnableMethod(this, &nsSVGFEImageElement::MaybeLoadSVGImage));
   }
 
   return rv;
 }
 
-void
-nsSVGFEImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
-  nsSVGFEImageElementBase::UnbindFromTree(aDeep, aNullParent);
-}
-
 nsEventStates
 nsSVGFEImageElement::IntrinsicState() const
 {
   return nsSVGFEImageElementBase::IntrinsicState() |
     nsImageLoadingContent::ImageState();
 }
 
 //----------------------------------------------------------------------
--- a/content/svg/content/src/nsSVGImageElement.cpp
+++ b/content/svg/content/src/nsSVGImageElement.cpp
@@ -203,38 +203,28 @@ nsSVGImageElement::BindToTree(nsIDocumen
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers)
 {
   nsresult rv = nsSVGImageElementBase::BindToTree(aDocument, aParent,
                                                   aBindingParent,
                                                   aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
-                                    aCompileEventHandlers);
-
   if (mStringAttributes[HREF].IsExplicitlySet()) {
     // FIXME: Bug 660963 it would be nice if we could just have
     // ClearBrokenState update our state and do it fast...
     ClearBrokenState();
     RemoveStatesSilently(NS_EVENT_STATE_BROKEN);
     nsContentUtils::AddScriptRunner(
       NS_NewRunnableMethod(this, &nsSVGImageElement::MaybeLoadSVGImage));
   }
 
   return rv;
 }
 
-void
-nsSVGImageElement::UnbindFromTree(bool aDeep, bool aNullParent)
-{
-  nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
-  nsSVGImageElementBase::UnbindFromTree(aDeep, aNullParent);
-}
-
 nsEventStates
 nsSVGImageElement::IntrinsicState() const
 {
   return nsSVGImageElementBase::IntrinsicState() |
     nsImageLoadingContent::ImageState();
 }
 
 NS_IMETHODIMP_(bool)
--- a/content/svg/content/src/nsSVGImageElement.h
+++ b/content/svg/content/src/nsSVGImageElement.h
@@ -77,17 +77,16 @@ public:
   NS_FORWARD_NSIDOMSVGELEMENT(nsSVGImageElementBase::)
 
   // nsIContent interface
   virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
                                 const nsAString* aValue, bool aNotify);
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
 
   virtual nsEventStates IntrinsicState() const;
 
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
 
   // nsSVGPathGeometryElement methods:
   virtual void ConstructPath(gfxContext *aCtx);
 
--- a/modules/libpr0n/src/RasterImage.cpp
+++ b/modules/libpr0n/src/RasterImage.cpp
@@ -80,27 +80,33 @@ using namespace mozilla::imagelib;
 static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("CompressedImageAccounting");
 #else
 #define gCompressedImageAccountingLog
 #endif
 
 // Tweakable progressive decoding parameters
 static PRUint32 gDecodeBytesAtATime = 200000;
 static PRUint32 gMaxMSBeforeYield = 400;
+static PRUint32 gMaxBytesForSyncDecode = 150000;
 
 void
 RasterImage::SetDecodeBytesAtATime(PRUint32 aBytesAtATime)
 {
   gDecodeBytesAtATime = aBytesAtATime;
 }
 void
 RasterImage::SetMaxMSBeforeYield(PRUint32 aMaxMS)
 {
   gMaxMSBeforeYield = aMaxMS;
 }
+void
+RasterImage::SetMaxBytesForSyncDecode(PRUint32 aMaxBytes)
+{
+  gMaxBytesForSyncDecode = aMaxBytes;
+}
 
 /* We define our own error checking macros here for 2 reasons:
  *
  * 1) Most of the failures we encounter here will (hopefully) be
  * the result of decoding failures (ie, bad data) and not code
  * failures. As such, we don't want to clutter up debug consoles
  * with spurious messages about NS_ENSURE_SUCCESS failures.
  *
@@ -678,37 +684,35 @@ RasterImage::GetFrame(PRUint32 aWhichFra
     return NS_ERROR_FAILURE;
 
   // Disallowed in the API
   if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
     return NS_ERROR_FAILURE;
 
   nsresult rv = NS_OK;
 
-  PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
-
   if (mDecoded) {
     // If we have decoded data, and it is not a perfect match for what we are
     // looking for, we must discard to be able to generate the proper data.
-
+    PRUint32 desiredDecodeFlags = aFlags & DECODE_FLAGS_MASK;
     if (desiredDecodeFlags != mFrameDecodeFlags) {
       // if we can't discard, then we're screwed; we have no way
       // to re-decode.  Similarly if we aren't allowed to do a sync
       // decode.
       if (!(aFlags & FLAG_SYNC_DECODE))
         return NS_ERROR_NOT_AVAILABLE;
       if (!CanForciblyDiscard() || mDecoder || mAnim)
         return NS_ERROR_NOT_AVAILABLE;
   
       ForceDiscard();
+  
+      mFrameDecodeFlags = desiredDecodeFlags;
     }
   }
 
-  mFrameDecodeFlags = desiredDecodeFlags;
-
   // If the caller requested a synchronous decode, do it
   if (aFlags & FLAG_SYNC_DECODE) {
     rv = SyncDecode();
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // Get the frame. If it's not there, it's probably the caller's fault for
   // not waiting for the data to be loaded from the network or not passing
@@ -2377,22 +2381,23 @@ RasterImage::RequestDecode()
   // If we already have a pending worker, we're done
   if (mWorkerPending)
     return NS_OK;
 
   // If we've read all the data we have, we're done
   if (mBytesDecoded == mSourceData.Length())
     return NS_OK;
 
-  // If we can do decoding now, do so.  Small images will decode completely,
-  // large images will decode a bit and post themselves to the event loop
-  // to finish decoding.
-  if (!mDecoded && !mInDecoder && mHasSourceData)
-    return mWorker->Run();
-
+  // If it's a smallish image, it's not worth it to do things async
+  if (!mDecoded && !mInDecoder && mHasSourceData && (mSourceData.Length() < gMaxBytesForSyncDecode))
+    return SyncDecode();
+
+  // If we get this far, dispatch the worker. We do this instead of starting
+  // any immediate decoding to guarantee that all our decode notifications are
+  // dispatched asynchronously, and to ensure we stay responsive.
   return mWorker->Dispatch();
 }
 
 // Synchronously decodes as much data as possible
 nsresult
 RasterImage::SyncDecode()
 {
   nsresult rv;
--- a/modules/libpr0n/src/imgRequest.cpp
+++ b/modules/libpr0n/src/imgRequest.cpp
@@ -83,16 +83,17 @@
 
 #include "DiscardTracker.h"
 #include "nsAsyncRedirectVerifyHelper.h"
 
 #define DISCARD_PREF "image.mem.discardable"
 #define DECODEONDRAW_PREF "image.mem.decodeondraw"
 #define BYTESATATIME_PREF "image.mem.decode_bytes_at_a_time"
 #define MAXMS_PREF "image.mem.max_ms_before_yield"
+#define MAXBYTESFORSYNC_PREF "image.mem.max_bytes_for_sync_decode"
 #define SVG_MIMETYPE "image/svg+xml"
 
 using namespace mozilla;
 using namespace mozilla::imagelib;
 
 /* Kept up to date by a pref observer. */
 static bool gDecodeOnDraw = false;
 static bool gDiscardable = false;
@@ -126,16 +127,21 @@ ReloadPrefs()
   if (NS_SUCCEEDED(Preferences::GetInt(BYTESATATIME_PREF, &bytesAtATime))) {
     RasterImage::SetDecodeBytesAtATime(bytesAtATime);
   }
 
   if (NS_SUCCEEDED(Preferences::GetInt(MAXMS_PREF, &maxMS))) {
     RasterImage::SetMaxMSBeforeYield(maxMS);
   }
 
+  if (NS_SUCCEEDED(Preferences::GetInt(MAXBYTESFORSYNC_PREF,
+                                       &maxBytesForSync))) {
+    RasterImage::SetMaxBytesForSyncDecode(maxBytesForSync);
+  }
+
   // Discard timeout
   mozilla::imagelib::DiscardTracker::ReloadTimeout();
 }
 
 // Observer
 class imgRequestPrefObserver : public nsIObserver {
 public:
     NS_DECL_ISUPPORTS
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3271,16 +3271,19 @@ pref("image.mem.decodeondraw", true);
 pref("image.mem.min_discard_timeout_ms", 10000);
 
 // Chunk size for calls to the image decoders
 pref("image.mem.decode_bytes_at_a_time", 4096);
 
 // The longest time we can spend in an iteration of an async decode
 pref("image.mem.max_ms_before_yield", 5);
 
+// The maximum source data size for which we auto sync decode
+pref("image.mem.max_bytes_for_sync_decode", 150000);
+
 // WebGL prefs
 pref("webgl.force-enabled", false);
 pref("webgl.disabled", false);
 pref("webgl.shader_validator", true);
 pref("webgl.force_osmesa", false);
 pref("webgl.osmesalib", "");
 pref("webgl.verbose", false);
 pref("webgl.prefer-native-gl", false);
deleted file mode 100644
--- a/xpcom/glue/COMPtrAndFlag.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Kyle Huey <me@kylehuey.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef mozilla_PtrAndFlag_h__
-#define mozilla_PtrAndFlag_h__
-
-#include "nsCOMPtr.h"
-#include "mozilla/Types.h"
-
-namespace mozilla {
-
-namespace please_dont_use_this_directly {
-template <class T>
-class COMPtrAndFlagGetterAddRefs;
-}
-
-// A class designed to allow stealing a bit from an nsCOMPtr.
-template <class T>
-class COMPtrAndFlag
-{
-  // A RAII class that saves/restores the flag, allowing the COMPtr to be
-  // manipulated directly.
-  class AutoFlagPersister
-  {
-  public:
-    AutoFlagPersister(uintptr_t* aPtr)
-      : mPtr(aPtr), mFlag(*aPtr & 0x1)
-    {
-      if (mFlag)
-        *mPtr &= ~0x1;
-    }
-
-    ~AutoFlagPersister()
-    {
-      if (mFlag)
-        *mPtr |= 0x1;
-    }
-  private:
-    uintptr_t *mPtr;
-    bool mFlag;
-  };
-
-  template <class U>
-  friend class please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs;
-
-public:
-  COMPtrAndFlag()
-  {
-    Set(nsnull, false);
-  }
-
-  COMPtrAndFlag(T* aPtr, bool aFlag)
-  {
-    Set(aPtr, aFlag);
-  }
-
-  COMPtrAndFlag(const nsQueryInterface aPtr, bool aFlag)
-  {
-    Set(aPtr, aFlag);
-  }
-
-  COMPtrAndFlag(const already_AddRefed<T>& aPtr, bool aFlag)
-  {
-    Set(aPtr, aFlag);
-  }
-
-  ~COMPtrAndFlag()
-  {
-    // Make sure we unset the flag before nsCOMPtr's dtor tries to
-    // Release, or we might explode.
-    UnsetFlag();
-  }
-
-  COMPtrAndFlag<T>&
-  operator= (const COMPtrAndFlag<T>& rhs)
-  {
-    Set(rhs.Ptr(), rhs.Flag());
-    return *this;
-  }
-
-  void Set(T* aPtr, bool aFlag)
-  {
-    SetInternal(aPtr, aFlag);
-  }
-
-  void Set(const nsQueryInterface aPtr, bool aFlag)
-  {
-    SetInternal(aPtr, aFlag);
-  }
-
-  void Set(const already_AddRefed<T>& aPtr, bool aFlag)
-  {
-    SetInternal(aPtr, aFlag);
-  }
-
-  void UnsetFlag()
-  {
-    SetFlag(false);
-  }
-
-  void SetFlag(bool aFlag)
-  {
-    if (aFlag) {
-      *VoidPtr() |= 0x1;
-    } else {
-      *VoidPtr() &= ~0x1;
-    }
-  }
-
-  bool Flag() const
-  {
-    return *VoidPtr() & 0x1;
-  }
-
-  void SetPtr(T* aPtr)
-  {
-    SetInternal(aPtr);
-  }
-
-  void SetPtr(const nsQueryInterface aPtr)
-  {
-    SetInternal(aPtr);
-  }
-
-  void SetPtr(const already_AddRefed<T>& aPtr)
-  {
-    SetInternal(aPtr);
-  }
-
-  T* Ptr() const
-  {
-    return reinterpret_cast<T*>(*VoidPtr() & ~0x1);
-  }
-
-  void Clear()
-  {
-    Set(nsnull, false);
-  }
-
-private:
-  template<class PtrType>
-  void SetInternal(PtrType aPtr, bool aFlag)
-  {
-    UnsetFlag();
-    mCOMPtr = aPtr;
-    SetFlag(aFlag);
-  }
-
-  template<class PtrType>
-  void SetInternal(PtrType aPtr)
-  {
-    AutoFlagPersister saveFlag(VoidPtr());
-    mCOMPtr = aPtr;
-  }
-
-  uintptr_t* VoidPtr() const {
-    return (uintptr_t*)(&mCOMPtr);
-  }
-
-  // Don't modify this without using the AutoFlagPersister, or you will explode
-  nsCOMPtr<T> mCOMPtr;
-};
-
-namespace please_dont_use_this_directly {
-/*
-  ...
-
-  This class is designed to be used for anonymous temporary objects in the
-  argument list of calls that return COM interface pointers, e.g.,
-
-    COMPtrAndFlag<IFoo> fooP;
-    ...->GetAddRefedPointer(getter_AddRefs(fooP))
-
-  DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
-
-  When initialized with a |COMPtrAndFlag|, as in the example above, it returns
-  a |void**|, a |T**|, or an |nsISupports**| as needed, that the
-  outer call (|GetAddRefedPointer| in this case) can fill in.
-*/
-template <class T>
-class COMPtrAndFlagGetterAddRefs
-{
-  public:
-    explicit
-    COMPtrAndFlagGetterAddRefs( COMPtrAndFlag<T>& aSmartPtr )
-        : mTargetSmartPtr(aSmartPtr), mFlag(aSmartPtr.Flag())
-      {
-        if (mFlag)
-          aSmartPtr.UnsetFlag();
-      }
-
-    ~COMPtrAndFlagGetterAddRefs()
-      {
-        if (mFlag)
-          mTargetSmartPtr.SetFlag(true);
-      }
-
-    operator void**()
-      {
-        return reinterpret_cast<void**>(mTargetSmartPtr.VoidPtr());
-      }
-
-    operator T**()
-      {
-        return reinterpret_cast<T**>(mTargetSmartPtr.VoidPtr());
-      }
-
-    T*&
-    operator*()
-      {
-        return *reinterpret_cast<T**>(mTargetSmartPtr.VoidPtr());
-      }
-
-  private:
-    COMPtrAndFlag<T>& mTargetSmartPtr;
-    bool mFlag;
-};
-
-} // namespace please_dont_use_this_directly
-
-} // namespace mozilla
-
-template <class T>
-inline
-mozilla::please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs<T>
-getter_AddRefs( mozilla::COMPtrAndFlag<T>& aSmartPtr )
-  /*
-    Used around a |COMPtrWithFlag| when 
-    ...makes the class |COMPtrWithFlag::GetterAddRefs<T>| invisible.
-  */
-{
-  return mozilla::please_dont_use_this_directly::COMPtrAndFlagGetterAddRefs<T>(aSmartPtr);
-}
-
-
-#endif
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -114,17 +114,16 @@ EXPORTS = \
 		nsProxyRelease.h \
 		nsXPTCUtils.h \
 		nsCycleCollectorUtils.h \
 		$(NULL)
 
 EXPORTS_mozilla = \
   AutoRestore.h \
   BlockingResourceBase.h \
-  COMPtrAndFlag.h \
   CondVar.h \
   DeadlockDetector.h \
   FileUtils.h \
   GenericFactory.h \
   IntentionalCrash.h \
   Monitor.h \
   Mutex.h \
   ReentrantMonitor.h \
--- a/xpcom/tests/TestCOMPtr.cpp
+++ b/xpcom/tests/TestCOMPtr.cpp
@@ -35,17 +35,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <assert.h>
 #include <stdio.h>
 #include "nsCOMPtr.h"
 #include "nsISupports.h"
-#include "mozilla/COMPtrAndFlag.h"
 
 #define NS_IFOO_IID \
 { 0x6f7652e0,  0xee43, 0x11d1, \
  { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
 
 class IFoo : public nsISupports
   {
 		public:
@@ -583,53 +582,16 @@ main()
 
 		{
 			nsCOMPtr<nsISupports> supportsP;
 
 			AVoidPtrPtrContext( getter_AddRefs(supportsP) );
 			AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
 		}
 
-    {
-      IBar* ibar1 = new IBar;
-      mozilla::COMPtrAndFlag<IFoo> foop( do_QueryInterface(ibar1) , false);
-      if (foop.Flag())
-        return -1;
-      if (foop.Ptr() != ibar1)
-        return -1;
-
-      foop.SetFlag(true);
-      if (!foop.Flag())
-        return -1;
-      if (foop.Ptr() != ibar1)
-        return -1;
-
-      IBar* ibar2 = new IBar;
-      mozilla::COMPtrAndFlag<IFoo> foop2( do_QueryInterface(ibar2) , true);
-
-      if (!foop2.Flag())
-        return -1;
-      if (foop2.Ptr() != ibar2)
-        return -1;
-
-      foop2.SetFlag(false);
-      if (foop2.Flag())
-        return -1;
-      if (foop2.Ptr() != ibar2)
-        return -1;
-
-    }
-
-    {
-      mozilla::COMPtrAndFlag<nsISupports> supportsP;
-
-      AVoidPtrPtrContext( getter_AddRefs(supportsP) );
-      AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
-    }
-
 
     printf("\n### Test 25: will a static |nsCOMPtr| |Release| before program termination?\n");
     gFoop = do_QueryInterface(new IFoo);
     
     printf("<<main()\n");
     return 0;
   }