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
backs outd3b8c0394c5e
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;
   }