Bug 1310017 - Remove nsISupportsArray usage from nsITransferable and nsIFormatConverter. r=smaug
authorEric Rahm <erahm@mozilla.com>
Sun, 16 Oct 2016 12:43:56 -0700
changeset 318173 bd7461a1ed09447f4d38b4911f0e83933f9d875b
parent 318172 cb878465645099cd790e703a9d4eb84fbd358d92
child 318174 dbae54e61d06618ffd15321f5dc7d4f755314438
push id30830
push usercbook@mozilla.com
push dateMon, 17 Oct 2016 09:19:24 +0000
treeherdermozilla-central@94b0fddf96b4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1310017
milestone52.0a1
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
Bug 1310017 - Remove nsISupportsArray usage from nsITransferable and nsIFormatConverter. r=smaug This converts |nsITransferable.flavorsTransferableCanExport| and |nsITransferable.flavorsTransferableCanImport| to return a |nsIArray|. |nsIFormatConverter.getInputDataFlavors| and |nsIFormatConverter.getOutputDataFlavors| are updated as well.
dom/base/nsContentUtils.cpp
widget/cocoa/nsChildView.mm
widget/cocoa/nsClipboard.mm
widget/cocoa/nsDragService.mm
widget/gonk/nsClipboard.cpp
widget/gtk/nsClipboard.cpp
widget/gtk/nsDragService.cpp
widget/nsBaseDragService.cpp
widget/nsClipboardProxy.cpp
widget/nsHTMLFormatConverter.cpp
widget/nsHTMLFormatConverter.h
widget/nsIFormatConverter.idl
widget/nsITransferable.idl
widget/nsTransferable.cpp
widget/nsTransferable.h
widget/windows/nsClipboard.cpp
widget/windows/nsDataObj.cpp
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -62,16 +62,17 @@
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/TextEvents.h"
+#include "nsArrayUtils.h"
 #include "nsAString.h"
 #include "nsAttrName.h"
 #include "nsAttrValue.h"
 #include "nsAttrValueInlines.h"
 #include "nsBindingManager.h"
 #include "nsCaret.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsCharSeparatedTokenizer.h"
@@ -7688,21 +7689,21 @@ nsContentUtils::TransferableToIPCTransfe
                                               IPCDataTransfer* aIPCDataTransfer,
                                               bool aInSyncMessage,
                                               mozilla::dom::nsIContentChild* aChild,
                                               mozilla::dom::nsIContentParent* aParent)
 {
   MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
 
   if (aTransferable) {
-    nsCOMPtr<nsISupportsArray> flavorList;
+    nsCOMPtr<nsIArray> flavorList;
     aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
     if (flavorList) {
       uint32_t flavorCount = 0;
-      flavorList->Count(&flavorCount);
+      flavorList->GetLength(&flavorCount);
       for (uint32_t j = 0; j < flavorCount; ++j) {
         nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
         if (!flavor) {
           continue;
         }
 
         nsAutoCString flavorStr;
         flavor->GetData(flavorStr);
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -13,16 +13,17 @@
 #include "nsChildView.h"
 #include "nsCocoaWindow.h"
 
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 
+#include "nsArrayUtils.h"
 #include "nsObjCExceptions.h"
 #include "nsCOMPtr.h"
 #include "nsToolkit.h"
 #include "nsCRT.h"
 
 #include "nsFontMetrics.h"
 #include "nsIRollupListener.h"
 #include "nsViewManager.h"
@@ -126,17 +127,17 @@ extern "C" {
   CGError CGSNewRegionWithRectList(const CGRect *rects, int rectCount, CGSRegionObj *outRegion);
 }
 
 // defined in nsMenuBarX.mm
 extern NSMenu* sApplicationMenu; // Application menu shared by all menubars
 
 static bool gChildViewMethodsSwizzled = false;
 
-extern nsISupportsArray *gDraggedTransferables;
+extern nsIArray *gDraggedTransferables;
 
 ChildView* ChildViewMouseTracker::sLastMouseEventView = nil;
 NSEvent* ChildViewMouseTracker::sLastMouseMoveEvent = nil;
 NSWindow* ChildViewMouseTracker::sWindowUnderMouse = nil;
 NSPoint ChildViewMouseTracker::sLastScrollEventScreenLocation = NSZeroPoint;
 
 #ifdef INVALIDATE_DEBUGGING
 static void blinkRect(Rect* r);
@@ -5833,24 +5834,22 @@ PanGestureTypeForEvent(NSEvent* aEvent)
     NS_ERROR("failed InitWithCFURL");
     return nil;
   }
 
   if (!gDraggedTransferables)
     return nil;
 
   uint32_t transferableCount;
-  rv = gDraggedTransferables->Count(&transferableCount);
+  rv = gDraggedTransferables->GetLength(&transferableCount);
   if (NS_FAILED(rv))
     return nil;
 
   for (uint32_t i = 0; i < transferableCount; i++) {
-    nsCOMPtr<nsISupports> genericItem;
-    gDraggedTransferables->GetElementAt(i, getter_AddRefs(genericItem));
-    nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
+    nsCOMPtr<nsITransferable> item = do_QueryElementAt(gDraggedTransferables, i);
     if (!item) {
       NS_ERROR("no transferable");
       return nil;
     }
 
     item->SetTransferData(kFilePromiseDirectoryMime, macLocalFile, sizeof(nsIFile*));
 
     // now request the kFilePromiseMime data, which will invoke the data provider
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Logging.h"
 
 #include "mozilla/Unused.h"
 
 #include "gfxPlatform.h"
+#include "nsArrayUtils.h"
 #include "nsCOMPtr.h"
 #include "nsClipboard.h"
 #include "nsString.h"
 #include "nsISupportsPrimitives.h"
 #include "nsXPIDLString.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsMemory.h"
 #include "nsIFile.h"
@@ -141,28 +142,26 @@ nsClipboard::SetNativeClipboardData(int3
 }
 
 nsresult
 nsClipboard::TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteboard *cocoaPasteboard)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   // get flavor list that includes all acceptable flavors (including ones obtained through conversion)
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
   if (NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   uint32_t flavorCount;
-  flavorList->Count(&flavorCount);
+  flavorList->GetLength(&flavorCount);
 
   for (uint32_t i = 0; i < flavorCount; i++) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
-    nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
     if (!currentFlavor)
       continue;
 
     nsXPIDLCString flavorStr;
     currentFlavor->ToString(getter_Copies(flavorStr)); // i has a flavr
 
     // printf("looking for clipboard data of type %s\n", flavorStr.get());
 
@@ -312,33 +311,31 @@ nsClipboard::GetNativeClipboardData(nsIT
     cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
   } else {
     cocoaPasteboard = [NSPasteboard generalPasteboard];
   }
   if (!cocoaPasteboard)
     return NS_ERROR_FAILURE;
 
   // get flavor list that includes all acceptable flavors (including ones obtained through conversion)
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
   if (NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   uint32_t flavorCount;
-  flavorList->Count(&flavorCount);
+  flavorList->GetLength(&flavorCount);
 
   // If we were the last ones to put something on the pasteboard, then just use the cached
   // transferable. Otherwise clear it because it isn't relevant any more.
   if (mCachedClipboard == aWhichClipboard &&
       mChangeCount == [cocoaPasteboard changeCount]) {
     if (mTransferable) {
       for (uint32_t i = 0; i < flavorCount; i++) {
-        nsCOMPtr<nsISupports> genericFlavor;
-        flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
-        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+        nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
         if (!currentFlavor)
           continue;
 
         nsXPIDLCString flavorStr;
         currentFlavor->ToString(getter_Copies(flavorStr));
 
         nsCOMPtr<nsISupports> dataSupports;
         uint32_t dataSize = 0;
@@ -370,25 +367,24 @@ nsClipboard::HasDataMatchingFlavors(cons
 
   *outResult = false;
 
   if ((aWhichClipboard != kGlobalClipboard) || !aFlavorList)
     return NS_OK;
 
   // first see if we have data for this in our cached transferable
   if (mTransferable) {
-    nsCOMPtr<nsISupportsArray> transferableFlavorList;
+    nsCOMPtr<nsIArray> transferableFlavorList;
     nsresult rv = mTransferable->FlavorsTransferableCanImport(getter_AddRefs(transferableFlavorList));
     if (NS_SUCCEEDED(rv)) {
       uint32_t transferableFlavorCount;
-      transferableFlavorList->Count(&transferableFlavorCount);
+      transferableFlavorList->GetLength(&transferableFlavorCount);
       for (uint32_t j = 0; j < transferableFlavorCount; j++) {
-        nsCOMPtr<nsISupports> transferableFlavorSupports;
-        transferableFlavorList->GetElementAt(j, getter_AddRefs(transferableFlavorSupports));
-        nsCOMPtr<nsISupportsCString> currentTransferableFlavor(do_QueryInterface(transferableFlavorSupports));
+        nsCOMPtr<nsISupportsCString> currentTransferableFlavor =
+            do_QueryElementAt(transferableFlavorList, j);
         if (!currentTransferableFlavor)
           continue;
         nsXPIDLCString transferableFlavorStr;
         currentTransferableFlavor->ToString(getter_Copies(transferableFlavorStr));
 
         for (uint32_t k = 0; k < aLength; k++) {
           if (transferableFlavorStr.Equals(aFlavorList[k])) {
             *outResult = true;
@@ -451,27 +447,25 @@ nsClipboard::PasteboardDictFromTransfera
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if (!aTransferable)
     return nil;
 
   NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionary];
 
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
   if (NS_FAILED(rv))
     return nil;
 
   uint32_t flavorCount;
-  flavorList->Count(&flavorCount);
+  flavorList->GetLength(&flavorCount);
   for (uint32_t i = 0; i < flavorCount; i++) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
-    nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
     if (!currentFlavor)
       continue;
 
     nsXPIDLCString flavorStr;
     currentFlavor->ToString(getter_Copies(flavorStr));
 
     MOZ_LOG(sCocoaLog, LogLevel::Info, ("writing out clipboard data of type %s (%d)\n", flavorStr.get(), i));
 
@@ -773,9 +767,9 @@ nsClipboard::EmptyClipboard(int32_t aWhi
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboard::SupportsSelectionClipboard(bool* _retval)
 {
   *_retval = false;   // we don't support the selection clipboard by default.
   return NS_OK;
-}
\ No newline at end of file
+}
--- a/widget/cocoa/nsDragService.mm
+++ b/widget/cocoa/nsDragService.mm
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Logging.h"
 
 #include "nsDragService.h"
+#include "nsArrayUtils.h"
 #include "nsObjCExceptions.h"
 #include "nsITransferable.h"
 #include "nsString.h"
 #include "nsClipboard.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
 #include "nsPrimitiveHelpers.h"
@@ -382,36 +383,34 @@ NS_IMETHODIMP
 nsDragService::GetData(nsITransferable* aTransferable, uint32_t aItemIndex)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   if (!aTransferable)
     return NS_ERROR_FAILURE;
 
   // get flavor list that includes all acceptable flavors (including ones obtained through conversion)
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
   if (NS_FAILED(rv))
     return NS_ERROR_FAILURE;
 
   uint32_t acceptableFlavorCount;
-  flavorList->Count(&acceptableFlavorCount);
+  flavorList->GetLength(&acceptableFlavorCount);
 
   // if this drag originated within Mozilla we should just use the cached data from
   // when the drag started if possible
   if (mDataItems) {
     nsCOMPtr<nsISupports> currentTransferableSupports;
     mDataItems->GetElementAt(aItemIndex, getter_AddRefs(currentTransferableSupports));
     if (currentTransferableSupports) {
       nsCOMPtr<nsITransferable> currentTransferable(do_QueryInterface(currentTransferableSupports));
       if (currentTransferable) {
         for (uint32_t i = 0; i < acceptableFlavorCount; i++) {
-          nsCOMPtr<nsISupports> genericFlavor;
-          flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
-          nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+          nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
           if (!currentFlavor)
             continue;
           nsXPIDLCString flavorStr;
           currentFlavor->ToString(getter_Copies(flavorStr));
 
           nsCOMPtr<nsISupports> dataSupports;
           uint32_t dataSize = 0;
           rv = currentTransferable->GetTransferData(flavorStr, getter_AddRefs(dataSupports), &dataSize);
@@ -421,20 +420,17 @@ nsDragService::GetData(nsITransferable* 
           }
         }
       }
     }
   }
 
   // now check the actual clipboard for data
   for (uint32_t i = 0; i < acceptableFlavorCount; i++) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
-    nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
-
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
     if (!currentFlavor)
       continue;
 
     nsXPIDLCString flavorStr;
     currentFlavor->ToString(getter_Copies(flavorStr));
 
     MOZ_LOG(sCocoaLog, LogLevel::Info, ("nsDragService::GetData: looking for clipboard data of type %s\n", flavorStr.get()));
 
@@ -593,27 +589,25 @@ nsDragService::IsDataFlavorSupported(con
       mDataItems->GetElementAt(i, getter_AddRefs(currentTransferableSupports));
       if (!currentTransferableSupports)
         continue;
 
       nsCOMPtr<nsITransferable> currentTransferable(do_QueryInterface(currentTransferableSupports));
       if (!currentTransferable)
         continue;
 
-      nsCOMPtr<nsISupportsArray> flavorList;
+      nsCOMPtr<nsIArray> flavorList;
       nsresult rv = currentTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
       if (NS_FAILED(rv))
         continue;
 
       uint32_t flavorCount;
-      flavorList->Count(&flavorCount);
+      flavorList->GetLength(&flavorCount);
       for (uint32_t j = 0; j < flavorCount; j++) {
-        nsCOMPtr<nsISupports> genericFlavor;
-        flavorList->GetElementAt(j, getter_AddRefs(genericFlavor));
-        nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
+        nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, j);
         if (!currentFlavor)
           continue;
         nsXPIDLCString flavorStr;
         currentFlavor->ToString(getter_Copies(flavorStr));
         if (dataFlavor.Equals(flavorStr)) {
           *_retval = true;
           return NS_OK;
         }
--- a/widget/gonk/nsClipboard.cpp
+++ b/widget/gonk/nsClipboard.cpp
@@ -6,16 +6,17 @@
 
 #include "gfxDrawable.h"
 #include "gfxUtils.h"
 #include "ImageOps.h"
 #include "imgIContainer.h"
 #include "imgTools.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Preferences.h"
+#include "nsArrayUtils.h"
 #include "nsClipboardProxy.h"
 #include "nsISupportsPrimitives.h"
 #include "nsComponentManagerUtils.h"
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStringStream.h"
 #include "nsXULAppAPI.h"
 
@@ -68,24 +69,24 @@ nsClipboard::SetData(nsITransferable *aT
     }
     nsAutoString utf16string;
     wideString->GetData(utf16string);
     mClipboard->SetText(utf16string);
     return NS_OK;
   }
 
   // Get the types of supported flavors.
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
   if (!flavorList || NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
   uint32_t flavorCount = 0;
-  flavorList->Count(&flavorCount);
+  flavorList->GetLength(&flavorCount);
   bool imageAdded = false;
   for (uint32_t i = 0; i < flavorCount; ++i) {
     nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
 
     if (currentFlavor) {
       // MIME type
       nsXPIDLCString flavorStr;
       currentFlavor->ToString(getter_Copies(flavorStr));
@@ -198,26 +199,26 @@ nsClipboard::GetData(nsITransferable *aT
     }
     return NS_OK;
   }
 
   // Get flavor list that includes all acceptable flavors (including
   // ones obtained through conversion).
   // Note: We don't need to call nsITransferable::AddDataFlavor here
   //       because ContentParent already did.
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
 
   if (!flavorList || NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
   // Walk through flavors and see which flavor matches the one being pasted.
   uint32_t flavorCount;
-  flavorList->Count(&flavorCount);
+  flavorList->GetLength(&flavorCount);
 
   for (uint32_t i = 0; i < flavorCount; ++i) {
     nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
 
     if (currentFlavor) {
       // flavorStr is the mime type.
       nsXPIDLCString flavorStr;
       currentFlavor->ToString(getter_Copies(flavorStr));
--- a/widget/gtk/nsClipboard.cpp
+++ b/widget/gtk/nsClipboard.cpp
@@ -2,16 +2,17 @@
 /* vim:expandtab:shiftwidth=4:tabstop=4:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 
+#include "nsArrayUtils.h"
 #include "nsClipboard.h"
 #include "nsSupportsPrimitives.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsXPIDLString.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsIServiceManager.h"
 #include "nsImageToPixbuf.h"
@@ -153,31 +154,29 @@ nsClipboard::SetData(nsITransferable *aT
 
     // Clear out the clipboard in order to set the new data
     EmptyClipboard(aWhichClipboard);
 
     // List of suported targets
     GtkTargetList *list = gtk_target_list_new(nullptr, 0);
 
     // Get the types of supported flavors
-    nsCOMPtr<nsISupportsArray> flavors;
+    nsCOMPtr<nsIArray> flavors;
 
     nsresult rv =
         aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavors));
     if (!flavors || NS_FAILED(rv))
         return NS_ERROR_FAILURE;
 
     // Add all the flavors to this widget's supported type.
     bool imagesAdded = false;
     uint32_t count;
-    flavors->Count(&count);
+    flavors->GetLength(&count);
     for (uint32_t i=0; i < count; i++) {
-        nsCOMPtr<nsISupports> tastesLike;
-        flavors->GetElementAt(i, getter_AddRefs(tastesLike));
-        nsCOMPtr<nsISupportsCString> flavor = do_QueryInterface(tastesLike);
+        nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavors, i);
 
         if (flavor) {
             nsXPIDLCString flavorStr;
             flavor->ToString(getter_Copies(flavorStr));
 
             // special case text/unicode since we can handle all of
             // the string types
             if (!strcmp(flavorStr, kUnicodeMime)) {
@@ -253,30 +252,27 @@ nsClipboard::GetData(nsITransferable *aT
     clipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
 
     guchar        *data = nullptr;
     gint           length = 0;
     bool           foundData = false;
     nsAutoCString  foundFlavor;
 
     // Get a list of flavors this transferable can import
-    nsCOMPtr<nsISupportsArray> flavors;
+    nsCOMPtr<nsIArray> flavors;
     nsresult rv;
     rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavors));
     if (!flavors || NS_FAILED(rv))
         return NS_ERROR_FAILURE;
 
     uint32_t count;
-    flavors->Count(&count);
+    flavors->GetLength(&count);
     for (uint32_t i=0; i < count; i++) {
-        nsCOMPtr<nsISupports> genericFlavor;
-        flavors->GetElementAt(i, getter_AddRefs(genericFlavor));
-
         nsCOMPtr<nsISupportsCString> currentFlavor;
-        currentFlavor = do_QueryInterface(genericFlavor);
+        currentFlavor = do_QueryElementAt(flavors, i);
 
         if (currentFlavor) {
             nsXPIDLCString flavorStr;
             currentFlavor->ToString(getter_Copies(flavorStr));
 
             // Special case text/unicode since we can convert any
             // string into text/unicode
             if (!strcmp(flavorStr, kUnicodeMime)) {
--- a/widget/gtk/nsDragService.cpp
+++ b/widget/gtk/nsDragService.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=4 et sw=4 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDragService.h"
+#include "nsArrayUtils.h"
 #include "nsIObserverService.h"
 #include "nsWidgetsCID.h"
 #include "nsWindow.h"
 #include "nsIServiceManager.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIIOService.h"
 #include "nsIFileURL.h"
@@ -698,38 +699,36 @@ nsDragService::GetData(nsITransferable *
                ("*** warning: GetData \
                called without a valid target widget!\n"));
         return NS_ERROR_FAILURE;
     }
 
     // get flavor list that includes all acceptable flavors (including
     // ones obtained through conversion). Flavors are nsISupportsStrings
     // so that they can be seen from JS.
-    nsCOMPtr<nsISupportsArray> flavorList;
+    nsCOMPtr<nsIArray> flavorList;
     nsresult rv = aTransferable->FlavorsTransferableCanImport(
                         getter_AddRefs(flavorList));
     if (NS_FAILED(rv))
         return rv;
 
     // count the number of flavors
     uint32_t cnt;
-    flavorList->Count(&cnt);
+    flavorList->GetLength(&cnt);
     unsigned int i;
 
     // check to see if this is an internal list
     bool isList = IsTargetContextList();
 
     if (isList) {
         MOZ_LOG(sDragLm, LogLevel::Debug, ("it's a list..."));
         // find a matching flavor
         for (i = 0; i < cnt; ++i) {
-            nsCOMPtr<nsISupports> genericWrapper;
-            flavorList->GetElementAt(i, getter_AddRefs(genericWrapper));
             nsCOMPtr<nsISupportsCString> currentFlavor;
-            currentFlavor = do_QueryInterface(genericWrapper);
+            currentFlavor = do_QueryElementAt(flavorList, i);
             if (!currentFlavor)
                 continue;
 
             nsXPIDLCString flavorStr;
             currentFlavor->ToString(getter_Copies(flavorStr));
             MOZ_LOG(sDragLm,
                    LogLevel::Debug,
                    ("flavor is %s\n", (const char *)flavorStr));
@@ -767,20 +766,18 @@ nsDragService::GetData(nsITransferable *
         // if we got this far, we failed
         return NS_ERROR_FAILURE;
     }
 
     // Now walk down the list of flavors. When we find one that is
     // actually present, copy out the data into the transferable in that
     // format. SetTransferData() implicitly handles conversions.
     for ( i = 0; i < cnt; ++i ) {
-        nsCOMPtr<nsISupports> genericWrapper;
-        flavorList->GetElementAt(i,getter_AddRefs(genericWrapper));
         nsCOMPtr<nsISupportsCString> currentFlavor;
-        currentFlavor = do_QueryInterface(genericWrapper);
+        currentFlavor = do_QueryElementAt(flavorList, i);
         if (currentFlavor) {
             // find our gtk flavor
             nsXPIDLCString flavorStr;
             currentFlavor->ToString(getter_Copies(flavorStr));
             GdkAtom gdkFlavor = gdk_atom_intern(flavorStr, FALSE);
             MOZ_LOG(sDragLm, LogLevel::Debug,
                    ("looking for data in type %s, gdk flavor %ld\n",
                    static_cast<const char*>(flavorStr), gdkFlavor));
@@ -1028,30 +1025,27 @@ nsDragService::IsDataFlavorSupported(con
             return NS_OK;
         mSourceDataItems->Count(&numDragItems);
         for (uint32_t itemIndex = 0; itemIndex < numDragItems; ++itemIndex) {
             nsCOMPtr<nsISupports> genericItem;
             mSourceDataItems->GetElementAt(itemIndex,
                                            getter_AddRefs(genericItem));
             nsCOMPtr<nsITransferable> currItem(do_QueryInterface(genericItem));
             if (currItem) {
-                nsCOMPtr <nsISupportsArray> flavorList;
+                nsCOMPtr <nsIArray> flavorList;
                 currItem->FlavorsTransferableCanExport(
                           getter_AddRefs(flavorList));
                 if (flavorList) {
                     uint32_t numFlavors;
-                    flavorList->Count( &numFlavors );
+                    flavorList->GetLength( &numFlavors );
                     for ( uint32_t flavorIndex = 0;
                           flavorIndex < numFlavors ;
                           ++flavorIndex ) {
-                        nsCOMPtr<nsISupports> genericWrapper;
-                        flavorList->GetElementAt(flavorIndex,
-                                                getter_AddRefs(genericWrapper));
                         nsCOMPtr<nsISupportsCString> currentFlavor;
-                        currentFlavor = do_QueryInterface(genericWrapper);
+                        currentFlavor = do_QueryElementAt(flavorList, flavorIndex);
                         if (currentFlavor) {
                             nsXPIDLCString flavorStr;
                             currentFlavor->ToString(getter_Copies(flavorStr));
                             MOZ_LOG(sDragLm, LogLevel::Debug,
                                    ("checking %s against %s\n",
                                    (const char *)flavorStr, aDataFlavor));
                             if (strcmp(flavorStr, aDataFlavor) == 0) {
                                 MOZ_LOG(sDragLm, LogLevel::Debug,
@@ -1269,29 +1263,26 @@ nsDragService::GetSourceList(void)
 
         // check what flavours are supported so we can decide what other
         // targets to advertise.
         nsCOMPtr<nsISupports> genericItem;
         mSourceDataItems->GetElementAt(0, getter_AddRefs(genericItem));
         nsCOMPtr<nsITransferable> currItem(do_QueryInterface(genericItem));
 
         if (currItem) {
-            nsCOMPtr <nsISupportsArray> flavorList;
+            nsCOMPtr <nsIArray> flavorList;
             currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
             if (flavorList) {
                 uint32_t numFlavors;
-                flavorList->Count( &numFlavors );
+                flavorList->GetLength( &numFlavors );
                 for (uint32_t flavorIndex = 0;
                      flavorIndex < numFlavors ;
                      ++flavorIndex ) {
-                    nsCOMPtr<nsISupports> genericWrapper;
-                    flavorList->GetElementAt(flavorIndex,
-                                           getter_AddRefs(genericWrapper));
                     nsCOMPtr<nsISupportsCString> currentFlavor;
-                    currentFlavor = do_QueryInterface(genericWrapper);
+                    currentFlavor = do_QueryElementAt(flavorList, flavorIndex);
                     if (currentFlavor) {
                         nsXPIDLCString flavorStr;
                         currentFlavor->ToString(getter_Copies(flavorStr));
 
                         // check if text/x-moz-url is supported.
                         // If so, advertise
                         // text/uri-list.
                         if (strcmp(flavorStr, kURLMime) == 0) {
@@ -1308,29 +1299,26 @@ nsDragService::GetSourceList(void)
                 } // foreach flavor in item
             } // if valid flavor list
         } // if item is a transferable
     } else if (numDragItems == 1) {
         nsCOMPtr<nsISupports> genericItem;
         mSourceDataItems->GetElementAt(0, getter_AddRefs(genericItem));
         nsCOMPtr<nsITransferable> currItem(do_QueryInterface(genericItem));
         if (currItem) {
-            nsCOMPtr <nsISupportsArray> flavorList;
+            nsCOMPtr <nsIArray> flavorList;
             currItem->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
             if (flavorList) {
                 uint32_t numFlavors;
-                flavorList->Count( &numFlavors );
+                flavorList->GetLength( &numFlavors );
                 for (uint32_t flavorIndex = 0;
                      flavorIndex < numFlavors ;
                      ++flavorIndex ) {
-                    nsCOMPtr<nsISupports> genericWrapper;
-                    flavorList->GetElementAt(flavorIndex,
-                                             getter_AddRefs(genericWrapper));
                     nsCOMPtr<nsISupportsCString> currentFlavor;
-                    currentFlavor = do_QueryInterface(genericWrapper);
+                    currentFlavor = do_QueryElementAt(flavorList, flavorIndex);
                     if (currentFlavor) {
                         nsXPIDLCString flavorStr;
                         currentFlavor->ToString(getter_Copies(flavorStr));
                         GtkTargetEntry *target =
                           (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry));
                         target->target = g_strdup(flavorStr);
                         target->flags = 0;
                         MOZ_LOG(sDragLm, LogLevel::Debug,
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsBaseDragService.h"
 #include "nsITransferable.h"
 
 #include "nsIServiceManager.h"
 #include "nsITransferable.h"
-#include "nsISupportsArray.h"
 #include "nsSize.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
--- a/widget/nsClipboardProxy.cpp
+++ b/widget/nsClipboardProxy.cpp
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Unused.h"
+#include "nsArrayUtils.h"
 #include "nsClipboardProxy.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsXULAppAPI.h"
 #include "nsContentUtils.h"
 #include "nsStringStream.h"
 
@@ -42,21 +43,21 @@ nsClipboardProxy::SetData(nsITransferabl
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
 {
    nsTArray<nsCString> types;
   
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
   if (flavorList) {
     uint32_t flavorCount = 0;
-    flavorList->Count(&flavorCount);
+    flavorList->GetLength(&flavorCount);
     for (uint32_t j = 0; j < flavorCount; ++j) {
       nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
       if (flavor) {
         nsAutoCString flavorStr;
         flavor->GetData(flavorStr);
         if (flavorStr.Length()) {
           types.AppendElement(flavorStr);
         }
--- a/widget/nsHTMLFormatConverter.cpp
+++ b/widget/nsHTMLFormatConverter.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsHTMLFormatConverter.h"
 
+#include "nsArray.h"
 #include "nsCRT.h"
-#include "nsISupportsArray.h"
 #include "nsIComponentManager.h"
 #include "nsCOMPtr.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 
 #include "nsITransferable.h" // for mime defs, this is BAD
 
 // HTML convertor stuff
@@ -34,87 +34,79 @@ NS_IMPL_ISUPPORTS(nsHTMLFormatConverter,
 //
 // Creates a new list and returns the list of all the flavors this converter
 // knows how to import. In this case, it's just HTML.
 //
 // Flavors (strings) are wrapped in a primitive object so that JavaScript can
 // access them easily via XPConnect.
 //
 NS_IMETHODIMP
-nsHTMLFormatConverter::GetInputDataFlavors(nsISupportsArray **_retval)
+nsHTMLFormatConverter::GetInputDataFlavors(nsIArray **_retval)
 {
   if ( !_retval )
     return NS_ERROR_INVALID_ARG;
   
-  nsresult rv = NS_NewISupportsArray ( _retval );  // addrefs for us
-  if ( NS_SUCCEEDED(rv) )
-    rv = AddFlavorToList ( *_retval, kHTMLMime );
+  nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+  nsresult rv = AddFlavorToList ( array, kHTMLMime );
   
+  array.forget(_retval);
   return rv;
   
 } // GetInputDataFlavors
 
 
 //
 // GetOutputDataFlavors
 //
 // Creates a new list and returns the list of all the flavors this converter
 // knows how to export (convert). In this case, it's all sorts of things that HTML can be
 // converted to.
 //
 // Flavors (strings) are wrapped in a primitive object so that JavaScript can
 // access them easily via XPConnect.
 //
 NS_IMETHODIMP
-nsHTMLFormatConverter::GetOutputDataFlavors(nsISupportsArray **_retval)
+nsHTMLFormatConverter::GetOutputDataFlavors(nsIArray **_retval)
 {
   if ( !_retval )
     return NS_ERROR_INVALID_ARG;
   
-  nsresult rv = NS_NewISupportsArray ( _retval );  // addrefs for us
-  if ( NS_SUCCEEDED(rv) ) {
-    rv = AddFlavorToList ( *_retval, kHTMLMime );
-    if ( NS_FAILED(rv) )
-      return rv;
-#if NOT_NOW
-// pinkerton
-// no one uses this flavor right now, so it's just slowing things down. If anyone cares I
-// can put it back in.
-    rv = AddFlavorToList ( *_retval, kAOLMailMime );
-    if ( NS_FAILED(rv) )
-      return rv;
-#endif
-    rv = AddFlavorToList ( *_retval, kUnicodeMime );
-    if ( NS_FAILED(rv) )
-      return rv;
-  }
+  nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+  nsresult rv = AddFlavorToList ( array, kHTMLMime );
+  if ( NS_FAILED(rv) )
+    return rv;
+  rv = AddFlavorToList ( array, kUnicodeMime );
+  if ( NS_FAILED(rv) )
+    return rv;
+
+  array.forget(_retval);
   return rv;
 
 } // GetOutputDataFlavors
 
 
 //
 // AddFlavorToList
 //
 // Convenience routine for adding a flavor wrapped in an nsISupportsCString object
 // to a list
 //
 nsresult
-nsHTMLFormatConverter :: AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor )
+nsHTMLFormatConverter :: AddFlavorToList ( nsCOMPtr<nsIMutableArray>& inList, const char* inFlavor )
 {
   nsresult rv;
   
   nsCOMPtr<nsISupportsCString> dataFlavor =
       do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
   if ( dataFlavor ) {
     dataFlavor->SetData ( nsDependentCString(inFlavor) );
     // add to list as an nsISupports so the correct interface gets the addref
     // in AppendElement()
     nsCOMPtr<nsISupports> genericFlavor ( do_QueryInterface(dataFlavor) );
-    inList->AppendElement ( genericFlavor);
+    inList->AppendElement ( genericFlavor, /*weak =*/ false);
   }
   return rv;
 
 } // AddFlavorToList
 
 
 //
 // CanConvert
--- a/widget/nsHTMLFormatConverter.h
+++ b/widget/nsHTMLFormatConverter.h
@@ -1,32 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHTMLFormatConverter_h__
 #define nsHTMLFormatConverter_h__
 
+#include "nsCOMPtr.h"
 #include "nsIFormatConverter.h"
 #include "nsString.h"
 
+class nsIMutableArray;
+
 class nsHTMLFormatConverter : public nsIFormatConverter
 {
 public:
 
   nsHTMLFormatConverter();
 
   // nsISupports
   NS_DECL_ISUPPORTS
   NS_DECL_NSIFORMATCONVERTER
 
 protected:
   virtual ~nsHTMLFormatConverter();
 
-  nsresult AddFlavorToList ( nsISupportsArray* inList, const char* inFlavor ) ;
+  nsresult AddFlavorToList ( nsCOMPtr<nsIMutableArray>& inList, const char* inFlavor ) ;
 
   NS_IMETHOD ConvertFromHTMLToUnicode(const nsAutoString & aFromStr, nsAutoString & aToStr);
   NS_IMETHOD ConvertFromHTMLToAOLMail(const nsAutoString & aFromStr, nsAutoString & aToStr);
 
 };
 
 #endif // nsHTMLFormatConverter_h__
--- a/widget/nsIFormatConverter.idl
+++ b/widget/nsIFormatConverter.idl
@@ -1,35 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
-#include "nsISupportsArray.idl"
+#include "nsIArray.idl"
 
 
 [scriptable, uuid(948A0023-E3A7-11d2-96CF-0060B0FB9956)]
 interface nsIFormatConverter : nsISupports
 {  
   /**
     * Get the list of the "input" data flavors (mime types as nsISupportsCString),
     * in otherwords, the flavors that this converter can convert "from" (the 
     * incoming data to the converter).
     */
-  nsISupportsArray getInputDataFlavors ( ) ;
+  nsIArray getInputDataFlavors ( ) ;
 
   /**
     * Get the list of the "output" data flavors (mime types as nsISupportsCString),
     * in otherwords, the flavors that this converter can convert "to" (the 
     * outgoing data to the converter).
     *
     * @param  aDataFlavorList fills list with supported flavors
     */
-  nsISupportsArray getOutputDataFlavors ( ) ;
+  nsIArray getOutputDataFlavors ( ) ;
 
   /**
     * Determines whether a conversion from one flavor to another is supported
     *
     * @param  aFromFormatConverter flavor to convert from
     * @param  aFromFormatConverter flavor to convert to
     */
   boolean canConvert ( in string aFromDataFlavor, in string aToDataFlavor ) ;
--- a/widget/nsITransferable.idl
+++ b/widget/nsITransferable.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "nsIArray.idl"
 #include "nsISupports.idl"
-#include "nsISupportsArray.idl"
 #include "nsIFormatConverter.idl"
 #include "nsIContentPolicyBase.idl"
 
 interface nsIPrincipal;
 
 %{ C++
 
 // these probably shouldn't live here, but in some central repository shared
@@ -118,17 +118,17 @@ interface nsITransferable : nsISupports
 
   /**
     * Computes a list of flavors (mime types as nsISupportsCString) that the transferable 
     * can export, either through intrinsic knowledge or output data converters.
     *
     * @param  aDataFlavorList fills list with supported flavors. This is a copy of
     *          the internal list, so it may be edited w/out affecting the transferable.
     */
-  nsISupportsArray flavorsTransferableCanExport ( ) ;
+  nsIArray flavorsTransferableCanExport ( ) ;
 
   /**
     * Given a flavor retrieve the data. 
     *
     * @param  aFlavor (in parameter) the flavor of data to retrieve
     * @param  aData the data. Some variant of class in nsISupportsPrimitives.idl
     * @param  aDataLen the length of the data
     */
@@ -156,17 +156,17 @@ interface nsITransferable : nsISupports
 
   /**
     * Computes a list of flavors (mime types as nsISupportsCString) that the transferable can
     * accept into it, either through intrinsic knowledge or input data converters.
     *
     * @param  outFlavorList fills list with supported flavors. This is a copy of
     *          the internal list, so it may be edited w/out affecting the transferable.
     */
-  nsISupportsArray flavorsTransferableCanImport ( ) ;
+  nsIArray flavorsTransferableCanImport ( ) ;
 
   /**
     * Sets the data in the transferable with the specified flavor. The transferable
     * will maintain its own copy the data, so it is not necessary to do that beforehand.
     *
     * @param  aFlavor the flavor of data that is being set
     * @param  aData the data, either some variant of class in nsISupportsPrimitives.idl,
     *         an nsIFile, or an nsIFlavorDataProvider (see above)
--- a/widget/nsTransferable.cpp
+++ b/widget/nsTransferable.cpp
@@ -3,22 +3,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
 Notes to self:
 
 - at some point, strings will be accessible from JS, so we won't have to wrap
    flavors in an nsISupportsCString. Until then, we're kinda stuck with
-   this crappy API of nsISupportsArrays.
+   this crappy API of nsIArrays.
 
 */
 
 
 #include "nsTransferable.h"
+#include "nsArray.h"
+#include "nsArrayUtils.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFormatConverter.h"
 #include "nsIContentPolicy.h"
 #include "nsIComponentManager.h"
 #include "nsCOMPtr.h"
 #include "nsXPCOM.h"
@@ -255,35 +257,34 @@ nsTransferable::Init(nsILoadContext* aCo
 
 //
 // GetTransferDataFlavors
 //
 // Returns a copy of the internal list of flavors. This does NOT take into
 // account any converter that may be registered. This list consists of
 // nsISupportsCString objects so that the flavor list can be accessed from JS.
 //
-nsresult
-nsTransferable::GetTransferDataFlavors(nsISupportsArray ** aDataFlavorList)
+already_AddRefed<nsIMutableArray>
+nsTransferable::GetTransferDataFlavors()
 {
   MOZ_ASSERT(mInitialized);
 
-  nsresult rv = NS_NewISupportsArray ( aDataFlavorList );
-  if (NS_FAILED(rv)) return rv;
+  nsCOMPtr<nsIMutableArray> array = nsArray::Create();
 
   for (size_t i = 0; i < mDataArray.Length(); ++i) {
     DataStruct& data = mDataArray.ElementAt(i);
     nsCOMPtr<nsISupportsCString> flavorWrapper = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
     if ( flavorWrapper ) {
       flavorWrapper->SetData ( data.GetFlavor() );
       nsCOMPtr<nsISupports> genericWrapper ( do_QueryInterface(flavorWrapper) );
-      (*aDataFlavorList)->AppendElement( genericWrapper );
+      array->AppendElement( genericWrapper, /*weak =*/ false );
     }
   }
 
-  return NS_OK;
+  return array.forget();
 }
 
 
 //
 // GetTransferData
 //
 // Returns the data of the requested flavor, obtained from either having the data on hand or
 // using a converter to get it. The data is wrapped in a nsISupports primitive so that it is
@@ -523,97 +524,95 @@ NS_IMETHODIMP nsTransferable::GetConvert
 
 //
 // FlavorsTransferableCanImport
 //
 // Computes a list of flavors that the transferable can accept into it, either through
 // intrinsic knowledge or input data converters.
 //
 NS_IMETHODIMP
-nsTransferable::FlavorsTransferableCanImport(nsISupportsArray **_retval)
+nsTransferable::FlavorsTransferableCanImport(nsIArray **_retval)
 {
   MOZ_ASSERT(mInitialized);
 
   NS_ENSURE_ARG_POINTER(_retval);
 
   // Get the flavor list, and on to the end of it, append the list of flavors we
   // can also get to through a converter. This is so that we can just walk the list
   // in one go, looking for the desired flavor.
-  GetTransferDataFlavors(_retval);                        // addrefs
+  nsCOMPtr<nsIMutableArray> array = GetTransferDataFlavors();
   nsCOMPtr<nsIFormatConverter> converter;
   GetConverter(getter_AddRefs(converter));
   if ( converter ) {
-    nsCOMPtr<nsISupportsArray> convertedList;
+    nsCOMPtr<nsIArray> convertedList;
     converter->GetInputDataFlavors(getter_AddRefs(convertedList));
 
     if ( convertedList ) {
       uint32_t importListLen;
-      convertedList->Count(&importListLen);
+      convertedList->GetLength(&importListLen);
 
       for (uint32_t i = 0; i < importListLen; ++i ) {
-        nsCOMPtr<nsISupports> genericFlavor;
-        convertedList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
-
-        nsCOMPtr<nsISupportsCString> flavorWrapper ( do_QueryInterface (genericFlavor) );
+        nsCOMPtr<nsISupportsCString> flavorWrapper =
+            do_QueryElementAt(convertedList, i);
         nsAutoCString flavorStr;
         flavorWrapper->GetData( flavorStr );
 
         if (GetDataForFlavor (mDataArray, flavorStr.get())
             == mDataArray.NoIndex) // Don't append if already in intrinsic list
-          (*_retval)->AppendElement (genericFlavor);
+          array->AppendElement (flavorWrapper, /*weak =*/ false);
       } // foreach flavor that can be converted to
     }
   } // if a converter exists
 
+  array.forget(_retval);
   return NS_OK;
 } // FlavorsTransferableCanImport
 
 
 //
 // FlavorsTransferableCanExport
 //
 // Computes a list of flavors that the transferable can export, either through
 // intrinsic knowledge or output data converters.
 //
 NS_IMETHODIMP
-nsTransferable::FlavorsTransferableCanExport(nsISupportsArray **_retval)
+nsTransferable::FlavorsTransferableCanExport(nsIArray **_retval)
 {
   MOZ_ASSERT(mInitialized);
 
   NS_ENSURE_ARG_POINTER(_retval);
 
   // Get the flavor list, and on to the end of it, append the list of flavors we
   // can also get to through a converter. This is so that we can just walk the list
   // in one go, looking for the desired flavor.
-  GetTransferDataFlavors(_retval);  // addrefs
+  nsCOMPtr<nsIMutableArray> array = GetTransferDataFlavors();
   nsCOMPtr<nsIFormatConverter> converter;
   GetConverter(getter_AddRefs(converter));
   if ( converter ) {
-    nsCOMPtr<nsISupportsArray> convertedList;
+    nsCOMPtr<nsIArray> convertedList;
     converter->GetOutputDataFlavors(getter_AddRefs(convertedList));
 
     if ( convertedList ) {
       uint32_t importListLen;
-      convertedList->Count(&importListLen);
+      convertedList->GetLength(&importListLen);
 
       for ( uint32_t i=0; i < importListLen; ++i ) {
-        nsCOMPtr<nsISupports> genericFlavor;
-        convertedList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
-
-        nsCOMPtr<nsISupportsCString> flavorWrapper ( do_QueryInterface (genericFlavor) );
+        nsCOMPtr<nsISupportsCString> flavorWrapper =
+            do_QueryElementAt(convertedList, i);
         nsAutoCString flavorStr;
         flavorWrapper->GetData( flavorStr );
 
         if (GetDataForFlavor (mDataArray, flavorStr.get())
             == mDataArray.NoIndex) // Don't append if already in intrinsic list
-          (*_retval)->AppendElement (genericFlavor);
+          array->AppendElement (flavorWrapper, /*weak =*/ false);
       } // foreach flavor that can be converted to
     }
   } // if a converter exists
 
+  array.forget(_retval);
   return NS_OK;
 } // FlavorsTransferableCanExport
 
 NS_IMETHODIMP
 nsTransferable::GetIsPrivateData(bool *aIsPrivateData)
 {
   MOZ_ASSERT(mInitialized);
 
--- a/widget/nsTransferable.h
+++ b/widget/nsTransferable.h
@@ -9,16 +9,17 @@
 #include "nsIContentPolicyBase.h"
 #include "nsIFormatConverter.h"
 #include "nsITransferable.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsIPrincipal.h"
 
+class nsIMutableArray;
 class nsString;
 
 //
 // DataStruct
 //
 // Holds a flavor (a mime type) that describes the data and the associated data.
 //
 struct DataStruct
@@ -64,17 +65,17 @@ public:
     // nsISupports
   NS_DECL_ISUPPORTS
   NS_DECL_NSITRANSFERABLE
 
 protected:
   virtual ~nsTransferable();
 
     // get flavors w/out converter
-  nsresult GetTransferDataFlavors(nsISupportsArray** aDataFlavorList);
+  already_AddRefed<nsIMutableArray> GetTransferDataFlavors();
  
   nsTArray<DataStruct> mDataArray;
   nsCOMPtr<nsIFormatConverter> mFormatConv;
   bool mPrivateData;
   nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
   nsContentPolicyType mContentPolicyType;
 #if DEBUG
   bool mInitialized;
--- a/widget/windows/nsClipboard.cpp
+++ b/widget/windows/nsClipboard.cpp
@@ -6,16 +6,17 @@
 #include "nsClipboard.h"
 #include <ole2.h>
 #include <shlobj.h>
 #include <intshcut.h>
 
 // shellapi.h is needed to build with WIN32_LEAN_AND_MEAN
 #include <shellapi.h>
 
+#include "nsArrayUtils.h"
 #include "nsCOMPtr.h"
 #include "nsDataObj.h"
 #include "nsIClipboardOwner.h"
 #include "nsString.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsIFormatConverter.h"
 #include "nsITransferable.h"
 #include "nsCOMPtr.h"
@@ -152,28 +153,26 @@ nsresult nsClipboard::SetupNativeDataObj
 
   nsDataObj * dObj = static_cast<nsDataObj *>(aDataObj);
 
   // Now give the Transferable to the DataObject 
   // for getting the data out of it
   dObj->SetTransferable(aTransferable);
 
   // Get the transferable list of data flavors
-  nsCOMPtr<nsISupportsArray> dfList;
+  nsCOMPtr<nsIArray> dfList;
   aTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList));
 
   // Walk through flavors that contain data and register them
   // into the DataObj as supported flavors
   uint32_t i;
   uint32_t cnt;
-  dfList->Count(&cnt);
+  dfList->GetLength(&cnt);
   for (i=0;i<cnt;i++) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    dfList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
-    nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericFlavor) );
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(dfList, i);
     if ( currentFlavor ) {
       nsXPIDLCString flavorStr;
       currentFlavor->ToString(getter_Copies(flavorStr));
       // When putting data onto the clipboard, we want to maintain kHTMLMime
       // ("text/html") and not map it to CF_HTML here since this will be done below.
       UINT format = GetFormat(flavorStr, false);
 
       // Now tell the native IDataObject about both our mime type and 
@@ -586,29 +585,27 @@ nsresult nsClipboard::GetDataFromDataObj
   // make sure we have a good transferable
   if ( !aTransferable )
     return NS_ERROR_INVALID_ARG;
 
   nsresult res = NS_ERROR_FAILURE;
 
   // get flavor list that includes all flavors that can be written (including ones 
   // obtained through conversion)
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   res = aTransferable->FlavorsTransferableCanImport ( getter_AddRefs(flavorList) );
   if ( NS_FAILED(res) )
     return NS_ERROR_FAILURE;
 
   // Walk through flavors and see which flavor is on the clipboard them on the native clipboard,
   uint32_t i;
   uint32_t cnt;
-  flavorList->Count(&cnt);
+  flavorList->GetLength(&cnt);
   for (i=0;i<cnt;i++) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    flavorList->GetElementAt ( i, getter_AddRefs(genericFlavor) );
-    nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericFlavor) );
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
     if ( currentFlavor ) {
       nsXPIDLCString flavorStr;
       currentFlavor->ToString(getter_Copies(flavorStr));
       UINT format = GetFormat(flavorStr);
 
       // Try to get the data using the desired flavor. This might fail, but all is
       // not lost.
       void* data = nullptr;
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/ArrayUtils.h"
 
 #include <ole2.h>
 #include <shlobj.h>
 
 #include "nsDataObj.h"
+#include "nsArrayUtils.h"
 #include "nsClipboard.h"
 #include "nsReadableUtils.h"
 #include "nsITransferable.h"
 #include "nsISupportsPrimitives.h"
 #include "IEnumFE.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsXPIDLString.h"
 #include "nsImageClipboard.h"
@@ -1200,27 +1201,25 @@ nsDataObj :: GetFileContentsInternetShor
 
 // check if specified flavour is present in the transferable
 bool nsDataObj :: IsFlavourPresent(const char *inFlavour)
 {
   bool retval = false;
   NS_ENSURE_TRUE(mTransferable, false);
   
   // get the list of flavors available in the transferable
-  nsCOMPtr<nsISupportsArray> flavorList;
+  nsCOMPtr<nsIArray> flavorList;
   mTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
   NS_ENSURE_TRUE(flavorList, false);
 
   // try to find requested flavour
   uint32_t cnt;
-  flavorList->Count(&cnt);
+  flavorList->GetLength(&cnt);
   for (uint32_t i = 0; i < cnt; ++i) {
-    nsCOMPtr<nsISupports> genericFlavor;
-    flavorList->GetElementAt (i, getter_AddRefs(genericFlavor));
-    nsCOMPtr<nsISupportsCString> currentFlavor (do_QueryInterface(genericFlavor));
+    nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
     if (currentFlavor) {
       nsAutoCString flavorStr;
       currentFlavor->GetData(flavorStr);
       if (flavorStr.Equals(inFlavour)) {
         retval = true;         // found it!
         break;
       }
     }