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 425779 bd7461a1ed09447f4d38b4911f0e83933f9d875b
parent 425778 cb878465645099cd790e703a9d4eb84fbd358d92
child 425780 e3dc02ffe8efca9aa1c859c9b49029ff9012e46e
child 425781 5c0d5d6a8d2e81ef54a94a1affe6764ce7b8aa65
child 425831 4444ba6dddfa7d41b70697502f3b022843b3bff8
child 425839 3d6634d8986f0f9ae98770ad3241445af68ed34f
child 425909 dbae54e61d06618ffd15321f5dc7d4f755314438
push id32504
push userbmo:gasolin@mozilla.com
push dateMon, 17 Oct 2016 02:37:54 +0000
reviewerssmaug
bugs1310017
milestone52.0a1
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;
       }
     }