Bug 1477578: De-XPCOMify feed handling code. r?Gijs draft
authorKris Maglione <maglione.k@gmail.com>
Sat, 21 Jul 2018 23:24:41 -0700
changeset 821290 bea4234d0a974a08e1b209ae1a9443c66e48625f
parent 821289 c02b9a9add579bb99e1488b9e8e924f903208d6a
push id117050
push usermaglione.k@gmail.com
push dateSun, 22 Jul 2018 17:42:49 +0000
reviewersGijs
bugs1477578
milestone63.0a1
Bug 1477578: De-XPCOMify feed handling code. r?Gijs MozReview-Commit-ID: 2xjTDtvxt4W
browser/base/content/browser-feeds.js
browser/components/feeds/BrowserFeeds.manifest
browser/components/feeds/FeedConverter.js
browser/components/feeds/FeedResults.jsm
browser/components/feeds/FeedWriter.js
browser/components/feeds/WebContentConverter.js
browser/components/feeds/moz.build
browser/components/feeds/nsIFeedResultService.idl
browser/components/feeds/nsIWebContentConverterRegistrar.idl
browser/components/feeds/test/chrome/test_423060.xul
browser/components/preferences/in-content/main.js
browser/modules/Feeds.jsm
toolkit/components/feeds/FeedProcessor.js
toolkit/components/feeds/FeedProcessor.jsm
toolkit/components/feeds/FeedProcessor.manifest
toolkit/components/feeds/moz.build
toolkit/components/feeds/nsIFeed.idl
toolkit/components/feeds/nsIFeedContainer.idl
toolkit/components/feeds/nsIFeedElementBase.idl
toolkit/components/feeds/nsIFeedEntry.idl
toolkit/components/feeds/nsIFeedGenerator.idl
toolkit/components/feeds/nsIFeedListener.idl
toolkit/components/feeds/nsIFeedPerson.idl
toolkit/components/feeds/nsIFeedProcessor.idl
toolkit/components/feeds/nsIFeedResult.idl
toolkit/components/feeds/nsIFeedTextConstruct.idl
toolkit/components/feeds/test/head.js
toolkit/components/feeds/test/test_xml.js
toolkit/components/feeds/test/xml/rfc4287/entry_author.xml
toolkit/components/feeds/test/xml/rfc4287/entry_content.xml
toolkit/components/feeds/test/xml/rfc4287/entry_content_encoded.xml
toolkit/components/feeds/test/xml/rfc4287/entry_content_html.xml
toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml.xml
toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml_with_markup.xml
toolkit/components/feeds/test/xml/rfc4287/entry_contributor.xml
toolkit/components/feeds/test/xml/rfc4287/entry_html_cdata.xml
toolkit/components/feeds/test/xml/rfc4287/entry_id.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore2.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_IANA.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_alt_extension.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure_populate_enclosures.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_otherURI_alt.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_payment_alt.xml
toolkit/components/feeds/test/xml/rfc4287/entry_link_random.xml
toolkit/components/feeds/test/xml/rfc4287/entry_published.xml
toolkit/components/feeds/test/xml/rfc4287/entry_rights_normalized.xml
toolkit/components/feeds/test/xml/rfc4287/entry_summary.xml
toolkit/components/feeds/test/xml/rfc4287/entry_title.xml
toolkit/components/feeds/test/xml/rfc4287/entry_title_normalized.xml
toolkit/components/feeds/test/xml/rfc4287/entry_updated.xml
toolkit/components/feeds/test/xml/rfc4287/entry_w_content_encoded.xml
toolkit/components/feeds/test/xml/rfc4287/entry_xhtml_baseURI_with_amp.xml
toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase.xml
toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase_on_link.xml
toolkit/components/feeds/test/xml/rfc4287/feed_atom_rights_xhtml.xml
toolkit/components/feeds/test/xml/rfc4287/feed_author_email.xml
toolkit/components/feeds/test/xml/rfc4287/feed_author_email_2.xml
toolkit/components/feeds/test/xml/rfc4287/feed_author_name.xml
toolkit/components/feeds/test/xml/rfc4287/feed_author_surrounded.xml
toolkit/components/feeds/test/xml/rfc4287/feed_author_uri.xml
toolkit/components/feeds/test/xml/rfc4287/feed_comment_rss_extra_att.xml
toolkit/components/feeds/test/xml/rfc4287/feed_contributor.xml
toolkit/components/feeds/test/xml/rfc4287/feed_icon.xml
toolkit/components/feeds/test/xml/rfc4287/feed_id.xml
toolkit/components/feeds/test/xml/rfc4287/feed_id_extra_att.xml
toolkit/components/feeds/test/xml/rfc4287/feed_logo.xml
toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml.xml
toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml_nested_divs.xml
toolkit/components/feeds/test/xml/rfc4287/feed_updated.xml
toolkit/components/feeds/test/xml/rss1/feed_description.xml
toolkit/components/feeds/test/xml/rss1/feed_image.xml
toolkit/components/feeds/test/xml/rss1/feed_link.xml
toolkit/components/feeds/test/xml/rss1/feed_textInput.xml
toolkit/components/feeds/test/xml/rss1/feed_title.xml
toolkit/components/feeds/test/xml/rss1/feed_title_extra_att.xml
toolkit/components/feeds/test/xml/rss1/item_2_dc_description.xml
toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher.xml
toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher_extra_att_invalid_rdf.xml
toolkit/components/feeds/test/xml/rss1/item_dc_creator.xml
toolkit/components/feeds/test/xml/rss1/item_dc_description.xml
toolkit/components/feeds/test/xml/rss1/item_dc_description_normalized.xml
toolkit/components/feeds/test/xml/rss1/item_description.xml
toolkit/components/feeds/test/xml/rss1/item_id.xml
toolkit/components/feeds/test/xml/rss1/item_link.xml
toolkit/components/feeds/test/xml/rss1/item_link_normalized.xml
toolkit/components/feeds/test/xml/rss1/item_title.xml
toolkit/components/feeds/test/xml/rss1/item_title_normalized.xml
toolkit/components/feeds/test/xml/rss1/item_updated_dcterms.xml
toolkit/components/feeds/test/xml/rss1/item_wiki_importance_extra_att.xml
toolkit/components/feeds/test/xml/rss2/feed_category.xml
toolkit/components/feeds/test/xml/rss2/feed_cloud.xml
toolkit/components/feeds/test/xml/rss2/feed_copyright.xml
toolkit/components/feeds/test/xml/rss2/feed_copyright_linebreak.xml
toolkit/components/feeds/test/xml/rss2/feed_data_outside_channel.xml
toolkit/components/feeds/test/xml/rss2/feed_dc_contributor.xml
toolkit/components/feeds/test/xml/rss2/feed_dc_creator.xml
toolkit/components/feeds/test/xml/rss2/feed_description.xml
toolkit/components/feeds/test/xml/rss2/feed_description_html.xml
toolkit/components/feeds/test/xml/rss2/feed_description_html_cdata.xml
toolkit/components/feeds/test/xml/rss2/feed_docs.xml
toolkit/components/feeds/test/xml/rss2/feed_image_desc.xml
toolkit/components/feeds/test/xml/rss2/feed_image_desc_width_height.xml
toolkit/components/feeds/test/xml/rss2/feed_image_required.xml
toolkit/components/feeds/test/xml/rss2/feed_language.xml
toolkit/components/feeds/test/xml/rss2/feed_lastBuildDate.xml
toolkit/components/feeds/test/xml/rss2/feed_managingEditor.xml
toolkit/components/feeds/test/xml/rss2/feed_managingEditor_extra_att.xml
toolkit/components/feeds/test/xml/rss2/feed_multiple_categories.xml
toolkit/components/feeds/test/xml/rss2/feed_pubDate.xml
toolkit/components/feeds/test/xml/rss2/feed_rating.xml
toolkit/components/feeds/test/xml/rss2/feed_skipDays.xml
toolkit/components/feeds/test/xml/rss2/feed_skipHours.xml
toolkit/components/feeds/test/xml/rss2/feed_textinput.xml
toolkit/components/feeds/test/xml/rss2/feed_ttl.xml
toolkit/components/feeds/test/xml/rss2/feed_webMaster.xml
toolkit/components/feeds/test/xml/rss2/feed_wfw_commentapi.xml
toolkit/components/feeds/test/xml/rss2/feed_wfw_commentrss.xml
toolkit/components/feeds/test/xml/rss2/feed_wiki.xml
toolkit/components/feeds/test/xml/rss2/feed_wiki_unusual_prefix.xml
toolkit/components/feeds/test/xml/rss2/item_author.xml
toolkit/components/feeds/test/xml/rss2/item_category.xml
toolkit/components/feeds/test/xml/rss2/item_comments.xml
toolkit/components/feeds/test/xml/rss2/item_content_encoded.xml
toolkit/components/feeds/test/xml/rss2/item_description.xml
toolkit/components/feeds/test/xml/rss2/item_description_2.xml
toolkit/components/feeds/test/xml/rss2/item_description_cdata.xml
toolkit/components/feeds/test/xml/rss2/item_description_decode_entities.xml
toolkit/components/feeds/test/xml/rss2/item_description_normalized.xml
toolkit/components/feeds/test/xml/rss2/item_description_normalized_nohtml.xml
toolkit/components/feeds/test/xml/rss2/item_enclosure.xml
toolkit/components/feeds/test/xml/rss2/item_enclosure_duplicates2.xml
toolkit/components/feeds/test/xml/rss2/item_guid.xml
toolkit/components/feeds/test/xml/rss2/item_guid_bogus_url.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_default.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false_uppercase.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_true_uppercase.xml
toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_unknown_value.xml
toolkit/components/feeds/test/xml/rss2/item_guid_normalized.xml
toolkit/components/feeds/test/xml/rss2/item_guid_with_link.xml
toolkit/components/feeds/test/xml/rss2/item_link.xml
toolkit/components/feeds/test/xml/rss2/item_link_normalized.xml
toolkit/components/feeds/test/xml/rss2/item_plain_desc.xml
toolkit/components/feeds/test/xml/rss2/item_populated_enclosures.xml
toolkit/components/feeds/test/xml/rss2/item_pubDate.xml
toolkit/components/feeds/test/xml/rss2/item_published.xml
toolkit/components/feeds/test/xml/rss2/item_title.xml
toolkit/components/feeds/test/xml/rss2/item_title_normalized.xml
toolkit/components/feeds/test/xml/rss2/item_updated_dcdate.xml
toolkit/components/feeds/test/xml/rss2/items_2_titles.xml
toolkit/components/feeds/test/xml/rss2/mrss_content.xml
toolkit/components/feeds/test/xml/rss2/mrss_content2.xml
toolkit/components/feeds/test/xml/rss2/mrss_content_429049.xml
toolkit/components/feeds/test/xml/rss2/mrss_content_multiple.xml
toolkit/components/feeds/test/xml/rss2/mrss_content_populate_enclosure.xml
toolkit/components/feeds/test/xml/rss2/mrss_group_content.xml
toolkit/components/feeds/test/xml/rss2/mrss_group_content_populate_enclosure.xml
toolkit/components/places/nsLivemarkService.js
--- a/browser/base/content/browser-feeds.js
+++ b/browser/base/content/browser-feeds.js
@@ -1,15 +1,19 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
 
 ChromeUtils.defineModuleGetter(this, "DeferredTask",
                                "resource://gre/modules/DeferredTask.jsm");
+ChromeUtils.defineModuleGetter(this, "Feed",
+                               "resource://gre/modules/FeedProcessor.jsm");
+ChromeUtils.defineModuleGetter(this, "FeedResults",
+                               "resource:///modules/FeedResults.jsm");
 
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 
 const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
 
 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
@@ -48,82 +52,85 @@ const EXECUTABLE_PREFS = new Set([
 ]);
 
 const VALID_ACTIONS = new Set(["ask", "reader", "bookmarks"]);
 const VALID_READERS = new Set(["web", "client", "default", "bookmarks"]);
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "SHOULD_LOG",
                                       "feeds.log", false);
 
+XPCOMUtils.defineLazyServiceGetter(this, "wccr",
+                                   "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1");
+
 function LOG(str) {
   if (SHOULD_LOG)
     dump("*** Feeds: " + str + "\n");
 }
 
 function getPrefActionForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_ACTION;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_ACTION;
 
     default:
       return PREF_SELECTED_ACTION;
   }
 }
 
 function getPrefReaderForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_READER;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_READER;
 
     default:
       return PREF_SELECTED_READER;
   }
 }
 
 function getPrefWebForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_WEB;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_WEB;
 
     default:
       return PREF_SELECTED_WEB;
   }
 }
 
 function getPrefAppForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_APP;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_APP;
 
     default:
       return PREF_SELECTED_APP;
   }
 }
 
 /**
  * Maps a feed type to a maybe-feed mimetype.
  */
 function getMimeTypeForFeedType(aFeedType) {
   switch (aFeedType) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return TYPE_MAYBE_VIDEO_FEED;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return TYPE_MAYBE_AUDIO_FEED;
 
     default:
       return TYPE_MAYBE_FEED;
   }
 }
 
 /**
@@ -468,29 +475,27 @@ var FeedHandler = {
       case PREF_VIDEO_SELECTED_READER:
       case PREF_VIDEO_SELECTED_WEB:
       case PREF_AUDIO_SELECTED_READER:
       case PREF_AUDIO_SELECTED_WEB:
       case PREF_SELECTED_ACTION:
       case PREF_VIDEO_SELECTED_ACTION:
       case PREF_AUDIO_SELECTED_ACTION:
         const response = {
-         default: this._getReaderForType(Ci.nsIFeed.TYPE_FEED),
-         [Ci.nsIFeed.TYPE_AUDIO]: this._getReaderForType(Ci.nsIFeed.TYPE_AUDIO),
-         [Ci.nsIFeed.TYPE_VIDEO]: this._getReaderForType(Ci.nsIFeed.TYPE_VIDEO)
+         default: this._getReaderForType(Feed.TYPE_FEED),
+         [Feed.TYPE_AUDIO]: this._getReaderForType(Feed.TYPE_AUDIO),
+         [Feed.TYPE_VIDEO]: this._getReaderForType(Feed.TYPE_VIDEO)
         };
         Services.mm.broadcastAsyncMessage("FeedWriter:PreferenceUpdated",
                                           response);
         break;
     }
   },
 
   _initSubscriptionUIResponse(feedType) {
-    const wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-               getService(Ci.nsIWebContentConverterService);
     const handlersRaw = wccr.getContentHandlers(getMimeTypeForFeedType(feedType));
     const handlers = [];
     for (let handler of handlersRaw) {
       LOG(`Handler found: ${handler}`);
       handlers.push({
         name: handler.name,
         uri: handler.uri
       });
@@ -607,37 +612,32 @@ var FeedHandler = {
         this._setPref(readerPref, settings.reader);
         handler = null;
 
         switch (settings.reader) {
           case "web":
             // This is a web set URI by content using window.registerContentHandler()
             // Lets make sure we know about it before setting it
             const webPref = getPrefWebForType(settings.feedType);
-            let wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                       getService(Ci.nsIWebContentConverterService);
             // If the user provided an invalid web URL this function won't give us a reference
             handler = wccr.getWebContentHandlerByURI(getMimeTypeForFeedType(settings.feedType), settings.uri);
             if (handler) {
               this._setPref(webPref, settings.uri, true);
               if (settings.useAsDefault) {
                 wccr.setAutoHandler(getMimeTypeForFeedType(settings.feedType), handler);
               }
               msg.target.messageManager
                  .sendAsyncMessage("FeedWriter:SetFeedPrefsAndSubscribeResponse",
                                   { redirect: handler.getHandlerURI(settings.feedLocation) });
             } else {
               LOG(`No handler found for web ${settings.feedType} ${settings.uri}`);
             }
             break;
           default:
-            const feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
-                                getService(Ci.nsIFeedResultService);
-
-            feedService.addToClientReader(settings.feedLocation,
+            FeedResults.addToClientReader(settings.feedLocation,
                                           settings.feedTitle,
                                           settings.feedSubtitle,
                                           settings.feedType,
                                           settings.reader);
          }
          break;
       case "FeedConverter:ExecuteClientApp":
         // Always check feedHandler is from a set array of executable prefs
--- a/browser/components/feeds/BrowserFeeds.manifest
+++ b/browser/components/feeds/BrowserFeeds.manifest
@@ -4,15 +4,13 @@
 #
 #   browser:        {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
 #   mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
 
 component {229fa115-9412-4d32-baf3-2fc407f76fb1} FeedConverter.js
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.video.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.audio.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
-component {2376201c-bbc6-472f-9b62-7548040a61c6} FeedConverter.js
-contract @mozilla.org/browser/feeds/result-service;1 {2376201c-bbc6-472f-9b62-7548040a61c6}
 component {49bb6593-3aff-4eb3-a068-2712c28bd58e} FeedWriter.js
 contract @mozilla.org/browser/feeds/result-writer;1 {49bb6593-3aff-4eb3-a068-2712c28bd58e}
 component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js
 contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc}
 category app-startup WebContentConverter service,@mozilla.org/embeddor.implemented/web-content-handler-registrar;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110}
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedConverter.js
@@ -1,28 +1,34 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+"use strict";
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
+ChromeUtils.defineModuleGetter(this, "Feed",
+                               "resource://gre/modules/FeedProcessor.jsm");
+ChromeUtils.defineModuleGetter(this, "FeedProcessor",
+                               "resource://gre/modules/FeedProcessor.jsm");
+ChromeUtils.defineModuleGetter(this, "FeedResults",
+                               "resource:///modules/FeedResults.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "wccr",
+                                   "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1");
+
 function LOG(str) {
   dump("*** " + str + "\n");
 }
 
-const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
-const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
-const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
-
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
-const TYPE_ANY = "*/*";
 
 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
 const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
 const PREF_SELECTED_ACTION = "browser.feeds.handler";
 const PREF_SELECTED_READER = "browser.feeds.handler.default";
 
 const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
 const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
@@ -31,59 +37,59 @@ const PREF_VIDEO_SELECTED_READER = "brow
 
 const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
 const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
 const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
 const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
 
 function getPrefAppForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_APP;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_APP;
 
     default:
       return PREF_SELECTED_APP;
   }
 }
 
 function getPrefWebForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_WEB;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_WEB;
 
     default:
       return PREF_SELECTED_WEB;
   }
 }
 
 function getPrefActionForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_ACTION;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_ACTION;
 
     default:
       return PREF_SELECTED_ACTION;
   }
 }
 
 function getPrefReaderForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_READER;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_READER;
 
     default:
       return PREF_SELECTED_READER;
   }
 }
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "gCanFrameFeeds",
@@ -171,52 +177,46 @@ FeedConverter.prototype = {
     // handler for other stream types. In those cases, the user will always see
     // the preview page and have to select a handler. We can guess and show
     // a client handler, but will not be able to show web handlers for those
     // types.
     //
     // If this is just a feed, not some kind of specialized application, then
     // auto-handlers can be set and we should obey them.
     try {
-      let feedService =
-          Cc["@mozilla.org/browser/feeds/result-service;1"].
-          getService(Ci.nsIFeedResultService);
       if (!this._forcePreviewPage && result.doc) {
-        let feed = result.doc.QueryInterface(Ci.nsIFeed);
+        let feed = result.doc;
         let handler = Services.prefs.getCharPref(getPrefActionForType(feed.type), "ask");
 
         if (handler != "ask") {
           if (handler == "reader")
             handler = Services.prefs.getCharPref(getPrefReaderForType(feed.type), "bookmarks");
           switch (handler) {
             case "web":
-              let wccr =
-                  Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                  getService(Ci.nsIWebContentConverterService);
-              if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
+              if ((feed.type == Feed.TYPE_FEED &&
                    wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
+                  (feed.type == Feed.TYPE_VIDEO &&
                    wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
+                  (feed.type == Feed.TYPE_AUDIO &&
                    wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
                 wccr.loadPreferredHandler(this._request);
                 return;
               }
               break;
 
             default:
               LOG("unexpected handler: " + handler);
               // fall through -- let feed service handle error
             case "bookmarks":
             case "client":
             case "default":
               try {
                 let title = feed.title ? feed.title.plainText() : "";
                 let desc = feed.subtitle ? feed.subtitle.plainText() : "";
-                feedService.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
+                FeedResults.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
                 return;
               } catch (ex) { /* fallback to preview mode */ }
           }
         }
       }
 
       let chromeChannel;
 
@@ -227,17 +227,17 @@ FeedConverter.prototype = {
 
       // If there was no automatic handler, or this was a podcast,
       // photostream or some other kind of application, show the preview page
       // if the parser returned a document.
       if (result.doc) {
 
         // Store the result in the result service so that the display
         // page can access it.
-        feedService.addFeedResult(result);
+        FeedResults.addFeedResult(result);
 
         // Now load the actual XUL document.
         let aboutFeedsURI = Services.io.newURI("about:feeds");
         chromeChannel = Services.io.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
         chromeChannel.originalURI = result.uri;
 
         // carry the origin attributes from the channel that loaded the feed.
         chromeChannel.owner =
@@ -294,26 +294,21 @@ FeedConverter.prototype = {
     } catch (ex) {
       this._sniffed = true;
     }
 
     this._request = request;
 
     // Save and reset the forced state bit early, in case there's some kind of
     // error.
-    let feedService =
-        Cc["@mozilla.org/browser/feeds/result-service;1"].
-        getService(Ci.nsIFeedResultService);
-    this._forcePreviewPage = feedService.forcePreviewPage;
-    feedService.forcePreviewPage = false;
+    this._forcePreviewPage = FeedResults.forcePreviewPage;
+    FeedResults.forcePreviewPage = false;
 
     // Parse feed data as it comes in
-    this._processor =
-        Cc["@mozilla.org/feed-processor;1"].
-        createInstance(Ci.nsIFeedProcessor);
+    this._processor = new FeedProcessor();
     this._processor.listener = this;
     this._processor.parseAsync(null, channel.URI);
 
     this._processor.onStartRequest(request, context);
   },
 
   /**
    * See nsIRequestObserver.idl
@@ -321,143 +316,16 @@ FeedConverter.prototype = {
   onStopRequest(request, context, status) {
     if (this._processor)
       this._processor.onStopRequest(request, context, status);
   },
 
   /**
    * See nsISupports.idl
    */
-  QueryInterface: ChromeUtils.generateQI(["nsIFeedResultListener",
-                                          "nsIStreamConverter",
+  QueryInterface: ChromeUtils.generateQI(["nsIStreamConverter",
                                           "nsIStreamListener",
                                           "nsIRequestObserver"]),
 };
 
-/**
- * Keeps parsed FeedResults around for use elsewhere in the UI after the stream
- * converter completes.
- */
-function FeedResultService() {
-}
-
-FeedResultService.prototype = {
-  classID: Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}"),
-
-  /**
-   * A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
-   * value in case the same URI is requested concurrently.
-   */
-  _results: { },
-
-  /**
-   * See nsIFeedResultService.idl
-   */
-  forcePreviewPage: false,
-
-  /**
-   * See nsIFeedResultService.idl
-   */
-  addToClientReader(spec, title, subtitle, feedType, feedReader) {
-    if (!feedReader) {
-      feedReader = "default";
-    }
-
-    let handler = Services.prefs.getCharPref(getPrefActionForType(feedType), "bookmarks");
-    if (handler == "ask" || handler == "reader")
-      handler = feedReader;
-
-    switch (handler) {
-    case "client":
-      Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
-                                     { spec,
-                                       title,
-                                       subtitle,
-                                       feedHandler: getPrefAppForType(feedType) });
-      break;
-    case "default":
-      // Default system feed reader
-      Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
-                                     { spec,
-                                       title,
-                                       subtitle,
-                                       feedHandler: "default" });
-      break;
-    default:
-      // "web" should have been handled elsewhere
-      LOG("unexpected handler: " + handler);
-      // fall through
-    case "bookmarks":
-      Services.cpmm.sendAsyncMessage("FeedConverter:addLiveBookmark",
-                                     { spec, title });
-      break;
-    }
-  },
-
-  /**
-   * See nsIFeedResultService.idl
-   */
-  addFeedResult(feedResult) {
-    if (feedResult.uri == null)
-      throw new Error("null URI!");
-    if (feedResult.uri == null)
-      throw new Error("null feedResult!");
-    let spec = feedResult.uri.spec;
-    if (!this._results[spec])
-      this._results[spec] = [];
-    this._results[spec].push(feedResult);
-  },
-
-  /**
-   * See nsIFeedResultService.idl
-   */
-  getFeedResult(uri) {
-    if (uri == null)
-      throw new Error("null URI!");
-    let resultList = this._results[uri.spec];
-    for (let result of resultList) {
-      if (result.uri == uri)
-        return result;
-    }
-    return null;
-  },
-
-  /**
-   * See nsIFeedResultService.idl
-   */
-  removeFeedResult(uri) {
-    if (uri == null)
-      throw new Error("null URI!");
-    let resultList = this._results[uri.spec];
-    if (!resultList)
-      return;
-    let deletions = 0;
-    for (let i = 0; i < resultList.length; ++i) {
-      if (resultList[i].uri == uri) {
-        delete resultList[i];
-        ++deletions;
-      }
-    }
-
-    // send the holes to the end
-    resultList.sort();
-    // and trim the list
-    resultList.splice(resultList.length - deletions, deletions);
-    if (resultList.length == 0)
-      delete this._results[uri.spec];
-  },
-
-  createInstance(outer, iid) {
-    if (outer != null)
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    return this.QueryInterface(iid);
-  },
-
-  QueryInterface: ChromeUtils.generateQI(["nsIFeedResultService",
-                                          "nsIFactory"]),
-};
-
-
-var components = [FeedConverter,
-                  FeedResultService];
-
+var components = [FeedConverter];
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
copy from browser/components/feeds/FeedConverter.js
copy to browser/components/feeds/FeedResults.jsm
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedResults.jsm
@@ -1,366 +1,74 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+"use strict";
+
+var EXPORTED_SYMBOLS = ["FeedResults"];
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
+ChromeUtils.defineModuleGetter(this, "Feed",
+                               "resource://gre/modules/FeedProcessor.jsm");
+
 function LOG(str) {
   dump("*** " + str + "\n");
 }
 
-const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
-const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
-const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
-
-const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
-const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
-const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
-const TYPE_ANY = "*/*";
-
 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
-const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
 const PREF_SELECTED_ACTION = "browser.feeds.handler";
-const PREF_SELECTED_READER = "browser.feeds.handler.default";
 
 const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
-const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
 const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
-const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
 
 const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
-const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
 const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
-const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
 
 function getPrefAppForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_APP;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_APP;
 
     default:
       return PREF_SELECTED_APP;
   }
 }
 
-function getPrefWebForType(t) {
-  switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
-      return PREF_VIDEO_SELECTED_WEB;
-
-    case Ci.nsIFeed.TYPE_AUDIO:
-      return PREF_AUDIO_SELECTED_WEB;
-
-    default:
-      return PREF_SELECTED_WEB;
-  }
-}
-
 function getPrefActionForType(t) {
   switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
+    case Feed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_ACTION;
 
-    case Ci.nsIFeed.TYPE_AUDIO:
+    case Feed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_ACTION;
 
     default:
       return PREF_SELECTED_ACTION;
   }
 }
 
-function getPrefReaderForType(t) {
-  switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
-      return PREF_VIDEO_SELECTED_READER;
-
-    case Ci.nsIFeed.TYPE_AUDIO:
-      return PREF_AUDIO_SELECTED_READER;
-
-    default:
-      return PREF_SELECTED_READER;
-  }
-}
-
-XPCOMUtils.defineLazyPreferenceGetter(this, "gCanFrameFeeds",
-  "browser.feeds.unsafelyFrameFeeds", false);
-
-
-function FeedConverter() {
-}
-FeedConverter.prototype = {
-  classID: Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}"),
-
-  /**
-   * This is the downloaded text data for the feed.
-   */
-  _data: null,
-
-  /**
-   * This is the object listening to the conversion, which is ultimately the
-   * docshell for the load.
-   */
-  _listener: null,
-
-  /**
-   * Records if the feed was sniffed
-   */
-  _sniffed: false,
-
-  /**
-   * See nsIStreamConverter.idl
-   */
-  convert(sourceStream, sourceType, destinationType,
-          context) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /**
-   * See nsIStreamConverter.idl
-   */
-  asyncConvertData(sourceType, destinationType,
-                   listener, context) {
-    this._listener = listener;
-  },
-
-  /**
-   * Whether or not the preview page is being forced.
-   */
-  _forcePreviewPage: false,
-
-  /**
-   * Release our references to various things once we're done using them.
-   */
-  _releaseHandles() {
-    this._listener = null;
-    this._request = null;
-    this._processor = null;
-  },
-
-  /**
-   * See nsIFeedResultListener.idl
-   */
-  handleResult(result) {
-    // Feeds come in various content types, which our feed sniffer coerces to
-    // the maybe.feed type. However, feeds are used as a transport for
-    // different data types, e.g. news/blogs (traditional feed), video/audio
-    // (podcasts) and photos (photocasts, photostreams). Each of these is
-    // different in that there's a different class of application suitable for
-    // handling feeds of that type, but without a content-type differentiation
-    // it is difficult for us to disambiguate.
-    //
-    // The other problem is that if the user specifies an auto-action handler
-    // for one feed application, the fact that the content type is shared means
-    // that all other applications will auto-load with that handler too,
-    // regardless of the content-type.
-    //
-    // This means that content-type alone is not enough to determine whether
-    // or not a feed should be auto-handled. This means that for feeds we need
-    // to always use this stream converter, even when an auto-action is
-    // specified, not the basic one provided by WebContentConverter. This
-    // converter needs to consume all of the data and parse it, and based on
-    // that determination make a judgment about type.
-    //
-    // Since there are no content types for this content, and I'm not going to
-    // invent any, the upshot is that while a user can set an auto-handler for
-    // generic feed content, the system will prevent them from setting an auto-
-    // handler for other stream types. In those cases, the user will always see
-    // the preview page and have to select a handler. We can guess and show
-    // a client handler, but will not be able to show web handlers for those
-    // types.
-    //
-    // If this is just a feed, not some kind of specialized application, then
-    // auto-handlers can be set and we should obey them.
-    try {
-      let feedService =
-          Cc["@mozilla.org/browser/feeds/result-service;1"].
-          getService(Ci.nsIFeedResultService);
-      if (!this._forcePreviewPage && result.doc) {
-        let feed = result.doc.QueryInterface(Ci.nsIFeed);
-        let handler = Services.prefs.getCharPref(getPrefActionForType(feed.type), "ask");
-
-        if (handler != "ask") {
-          if (handler == "reader")
-            handler = Services.prefs.getCharPref(getPrefReaderForType(feed.type), "bookmarks");
-          switch (handler) {
-            case "web":
-              let wccr =
-                  Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                  getService(Ci.nsIWebContentConverterService);
-              if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
-                   wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
-                   wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
-                   wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
-                wccr.loadPreferredHandler(this._request);
-                return;
-              }
-              break;
-
-            default:
-              LOG("unexpected handler: " + handler);
-              // fall through -- let feed service handle error
-            case "bookmarks":
-            case "client":
-            case "default":
-              try {
-                let title = feed.title ? feed.title.plainText() : "";
-                let desc = feed.subtitle ? feed.subtitle.plainText() : "";
-                feedService.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
-                return;
-              } catch (ex) { /* fallback to preview mode */ }
-          }
-        }
-      }
-
-      let chromeChannel;
-
-      // handling a redirect, hence forwarding the loadInfo from the old channel
-      // to the newchannel.
-      let oldChannel = this._request.QueryInterface(Ci.nsIChannel);
-      let loadInfo = oldChannel.loadInfo;
-
-      // If there was no automatic handler, or this was a podcast,
-      // photostream or some other kind of application, show the preview page
-      // if the parser returned a document.
-      if (result.doc) {
-
-        // Store the result in the result service so that the display
-        // page can access it.
-        feedService.addFeedResult(result);
-
-        // Now load the actual XUL document.
-        let aboutFeedsURI = Services.io.newURI("about:feeds");
-        chromeChannel = Services.io.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
-        chromeChannel.originalURI = result.uri;
-
-        // carry the origin attributes from the channel that loaded the feed.
-        chromeChannel.owner =
-          Services.scriptSecurityManager.createCodebasePrincipal(aboutFeedsURI,
-                                                                 loadInfo.originAttributes);
-      } else {
-        chromeChannel = Services.io.newChannelFromURIWithLoadInfo(result.uri, loadInfo);
-      }
-
-      chromeChannel.loadGroup = this._request.loadGroup;
-      chromeChannel.asyncOpen2(this._listener);
-    } finally {
-      this._releaseHandles();
-    }
-  },
-
-  /**
-   * See nsIStreamListener.idl
-   */
-  onDataAvailable(request, context, inputStream,
-                  sourceOffset, count) {
-    if (this._processor)
-      this._processor.onDataAvailable(request, context, inputStream,
-                                      sourceOffset, count);
-  },
-
-  /**
-   * See nsIRequestObserver.idl
-   */
-  onStartRequest(request, context) {
-    let channel = request.QueryInterface(Ci.nsIChannel);
-
-    let {loadInfo} = channel;
-    if ((loadInfo.frameOuterWindowID || loadInfo.outerWindowID) != loadInfo.topOuterWindowID &&
-        !gCanFrameFeeds) {
-      // We don't care about frame loads:
-      return;
-    }
-
-    // Check for a header that tells us there was no sniffing
-    // The value doesn't matter.
-    try {
-      let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
-      // Make sure to check requestSucceeded before the potentially-throwing
-      // getResponseHeader.
-      if (!httpChannel.requestSucceeded) {
-        // Just give up, but don't forget to cancel the channel first!
-        request.cancel(Cr.NS_BINDING_ABORTED);
-        return;
-      }
-
-      // Note: this throws if the header is not set.
-      httpChannel.getResponseHeader("X-Moz-Is-Feed");
-    } catch (ex) {
-      this._sniffed = true;
-    }
-
-    this._request = request;
-
-    // Save and reset the forced state bit early, in case there's some kind of
-    // error.
-    let feedService =
-        Cc["@mozilla.org/browser/feeds/result-service;1"].
-        getService(Ci.nsIFeedResultService);
-    this._forcePreviewPage = feedService.forcePreviewPage;
-    feedService.forcePreviewPage = false;
-
-    // Parse feed data as it comes in
-    this._processor =
-        Cc["@mozilla.org/feed-processor;1"].
-        createInstance(Ci.nsIFeedProcessor);
-    this._processor.listener = this;
-    this._processor.parseAsync(null, channel.URI);
-
-    this._processor.onStartRequest(request, context);
-  },
-
-  /**
-   * See nsIRequestObserver.idl
-   */
-  onStopRequest(request, context, status) {
-    if (this._processor)
-      this._processor.onStopRequest(request, context, status);
-  },
-
-  /**
-   * See nsISupports.idl
-   */
-  QueryInterface: ChromeUtils.generateQI(["nsIFeedResultListener",
-                                          "nsIStreamConverter",
-                                          "nsIStreamListener",
-                                          "nsIRequestObserver"]),
-};
-
 /**
  * Keeps parsed FeedResults around for use elsewhere in the UI after the stream
  * converter completes.
  */
-function FeedResultService() {
-}
-
-FeedResultService.prototype = {
-  classID: Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}"),
-
+var FeedResults = {
   /**
    * A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
    * value in case the same URI is requested concurrently.
    */
   _results: { },
 
-  /**
-   * See nsIFeedResultService.idl
-   */
   forcePreviewPage: false,
 
-  /**
-   * See nsIFeedResultService.idl
-   */
   addToClientReader(spec, title, subtitle, feedType, feedReader) {
     if (!feedReader) {
       feedReader = "default";
     }
 
     let handler = Services.prefs.getCharPref(getPrefActionForType(feedType), "bookmarks");
     if (handler == "ask" || handler == "reader")
       handler = feedReader;
@@ -387,47 +95,38 @@ FeedResultService.prototype = {
       // fall through
     case "bookmarks":
       Services.cpmm.sendAsyncMessage("FeedConverter:addLiveBookmark",
                                      { spec, title });
       break;
     }
   },
 
-  /**
-   * See nsIFeedResultService.idl
-   */
   addFeedResult(feedResult) {
     if (feedResult.uri == null)
       throw new Error("null URI!");
     if (feedResult.uri == null)
       throw new Error("null feedResult!");
     let spec = feedResult.uri.spec;
     if (!this._results[spec])
       this._results[spec] = [];
     this._results[spec].push(feedResult);
   },
 
-  /**
-   * See nsIFeedResultService.idl
-   */
   getFeedResult(uri) {
     if (uri == null)
       throw new Error("null URI!");
     let resultList = this._results[uri.spec];
     for (let result of resultList) {
       if (result.uri == uri)
         return result;
     }
     return null;
   },
 
-  /**
-   * See nsIFeedResultService.idl
-   */
   removeFeedResult(uri) {
     if (uri == null)
       throw new Error("null URI!");
     let resultList = this._results[uri.spec];
     if (!resultList)
       return;
     let deletions = 0;
     for (let i = 0; i < resultList.length; ++i) {
@@ -439,25 +138,9 @@ FeedResultService.prototype = {
 
     // send the holes to the end
     resultList.sort();
     // and trim the list
     resultList.splice(resultList.length - deletions, deletions);
     if (resultList.length == 0)
       delete this._results[uri.spec];
   },
-
-  createInstance(outer, iid) {
-    if (outer != null)
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    return this.QueryInterface(iid);
-  },
-
-  QueryInterface: ChromeUtils.generateQI(["nsIFeedResultService",
-                                          "nsIFactory"]),
 };
-
-
-var components = [FeedConverter,
-                  FeedResultService];
-
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -2,16 +2,20 @@
 /* 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/. */
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+ChromeUtils.defineModuleGetter(this, "Feed",
+                               "resource://gre/modules/FeedProcessor.jsm");
+ChromeUtils.defineModuleGetter(this, "FeedResults",
+                               "resource:///modules/FeedResults.jsm");
 
 const FEEDWRITER_CID = Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}");
 const FEEDWRITER_CONTRACTID = "@mozilla.org/browser/feeds/result-writer;1";
 
 function LOG(str) {
   let shouldLog = Services.prefs.getBoolPref("feeds.log", false);
 
   if (shouldLog)
@@ -79,26 +83,21 @@ function FeedWriter() {
     this._window.QueryInterface(Ci.nsIInterfaceRequestor).
                  getInterface(Ci.nsIDocShell).
                  QueryInterface(Ci.nsIInterfaceRequestor).
                  getInterface(Ci.nsIContentFrameMessageManager));
 }
 
 FeedWriter.prototype = {
   _getPropertyAsBag(container, property) {
-    return container.fields.getProperty(property).
-                     QueryInterface(Ci.nsIPropertyBag2);
+    return container.fields.get(property);
   },
 
   _getPropertyAsString(container, property) {
-    try {
-      return container.fields.getPropertyAsAString(property);
-    } catch (e) {
-    }
-    return "";
+    return container.fields.get(property);
   },
 
   _setContentText(id, text) {
     let element = this._document.getElementById(id);
     let textNode = text.createDocumentFragment(element);
     while (element.hasChildNodes())
       element.firstChild.remove();
     element.appendChild(textNode);
@@ -202,91 +201,90 @@ FeedWriter.prototype = {
   __feedType: null,
   _getFeedType() {
     if (this.__feedType != null)
       return this.__feedType;
 
     try {
       // grab the feed because it's got the feed.type in it.
       let container = this._getContainer();
-      let feed = container.QueryInterface(Ci.nsIFeed);
+      let feed = container;
       this.__feedType = feed.type;
       return feed.type;
     } catch (ex) { }
 
-    return Ci.nsIFeed.TYPE_FEED;
+    return Feed.TYPE_FEED;
   },
 
   /**
    * Writes the feed title into the preview document.
    * @param   container
    *          The feed container
    */
   _setTitleText(container) {
     if (container.title) {
       let title = container.title.plainText();
       this._setContentText(TITLE_ID, container.title);
       this._document.title = title;
     }
 
-    let feed = container.QueryInterface(Ci.nsIFeed);
+    let feed = container;
     if (feed && feed.subtitle)
       this._setContentText(SUBTITLE_ID, container.subtitle);
   },
 
   /**
    * Writes the title image into the preview document if one is present.
    * @param   container
    *          The feed container
    */
   _setTitleImage(container) {
     try {
       let parts = container.image;
 
       // Set up the title image (supplied by the feed)
       let feedTitleImage = this._document.getElementById("feedTitleImage");
       this._safeSetURIAttribute(feedTitleImage, "src",
-                                parts.getPropertyAsAString("url"));
+                                parts.get("url"));
 
       // Set up the title image link
       let feedTitleLink = this._document.getElementById("feedTitleLink");
 
       let titleText = this._getFormattedString("linkTitleTextFormat",
-                                               [parts.getPropertyAsAString("title")]);
+                                               [parts.get("title")]);
       let feedTitleText = this._document.getElementById("feedTitleText");
-      let titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
+      let titleImageWidth = parseInt(parts.get("width")) + 15;
 
       // Fix the margin on the main title, so that the image doesn't run over
       // the underline
       feedTitleLink.setAttribute("title", titleText);
       feedTitleText.style.marginRight = titleImageWidth + "px";
 
       this._safeSetURIAttribute(feedTitleLink, "href",
-                                parts.getPropertyAsAString("link"));
+                                parts.get("link"));
     } catch (e) {
       LOG("Failed to set Title Image (this is benign): " + e);
     }
   },
 
   /**
    * Writes all entries contained in the feed.
    * @param   container
    *          The container of entries in the feed
    */
   _writeFeedContent(container) {
     // Build the actual feed content
-    let feed = container.QueryInterface(Ci.nsIFeed);
+    let feed = container;
     if (feed.items.length == 0)
       return;
 
     let feedContent = this._document.getElementById("feedContent");
 
     for (let i = 0; i < feed.items.length; ++i) {
-      let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
-      entry.QueryInterface(Ci.nsIFeedContainer);
+      let entry = feed.items[i];
 
       let entryContainer = this._document.createElementNS(HTML_NS, "div");
       entryContainer.className = "entry";
 
       // If the entry has a title, make it a link
       if (entry.title) {
         let a = this._document.createElementNS(HTML_NS, "a");
         let span = this._document.createElementNS(HTML_NS, "span");
@@ -381,38 +379,38 @@ FeedWriter.prototype = {
    */
   _buildEnclosureDiv(entry) {
     let enclosuresDiv = this._document.createElementNS(HTML_NS, "div");
     enclosuresDiv.className = "enclosures";
 
     enclosuresDiv.appendChild(this._document.createTextNode(this._getString("mediaLabel")));
 
     for (let i_enc = 0; i_enc < entry.enclosures.length; ++i_enc) {
-      let enc = entry.enclosures.queryElementAt(i_enc, Ci.nsIWritablePropertyBag2);
+      let enc = entry.enclosures[i_enc];
 
-      if (!(enc.hasKey("url")))
+      if (!(enc.has("url")))
         continue;
 
       let enclosureDiv = this._document.createElementNS(HTML_NS, "div");
       enclosureDiv.setAttribute("class", "enclosure");
 
       let mozicon = "moz-icon://.txt?size=16";
       let type_text = null;
       let size_text = null;
 
-      if (enc.hasKey("type")) {
+      if (enc.has("type")) {
         type_text = enc.get("type");
-        if (enc.hasKey("typeDesc"))
+        if (enc.has("typeDesc"))
           type_text = enc.get("typeDesc");
 
         if (type_text && type_text.length > 0)
           mozicon = "moz-icon://goat?size=16&contentType=" + enc.get("type");
       }
 
-      if (enc.hasKey("length") && /^[0-9]+$/.test(enc.get("length"))) {
+      if (enc.has("length") && /^[0-9]+$/.test(enc.get("length"))) {
         let enc_size = convertByteUnits(parseInt(enc.get("length")));
 
         size_text = this._getFormattedString("enclosureSizeText",
                                              [enc_size[0],
                                              this._getString(enc_size[1])]);
       }
 
       let iconimg = this._document.createElementNS(HTML_NS, "img");
@@ -444,24 +442,20 @@ FeedWriter.prototype = {
 
   /**
    * Gets a valid nsIFeedContainer object from the parsed nsIFeedResult.
    * Displays error information if there was one.
    * @returns A valid nsIFeedContainer object containing the contents of
    *          the feed.
    */
   _getContainer() {
-    let feedService =
-        Cc["@mozilla.org/browser/feeds/result-service;1"].
-        getService(Ci.nsIFeedResultService);
-
     let result;
     try {
       result =
-        feedService.getFeedResult(this._getOriginalURI(this._window));
+        FeedResults.getFeedResult(this._getOriginalURI(this._window));
     } catch (e) {
       LOG("Subscribe Preview: feed not available?!");
     }
 
     if (result.bozo) {
       LOG("Subscribe Preview: feed result is bozo?!");
     }
 
@@ -498,42 +492,42 @@ FeedWriter.prototype = {
     this._mm.sendAsyncMessage("FeedWriter:ChooseClientApp",
                               { title: this._getString("chooseApplicationDialogTitle"),
                                 feedType: this._getFeedType() });
   },
 
   _setSubscribeUsingLabel() {
     let stringLabel = "subscribeFeedUsing";
     switch (this._getFeedType()) {
-      case Ci.nsIFeed.TYPE_VIDEO:
+      case Feed.TYPE_VIDEO:
         stringLabel = "subscribeVideoPodcastUsing";
         break;
 
-      case Ci.nsIFeed.TYPE_AUDIO:
+      case Feed.TYPE_AUDIO:
         stringLabel = "subscribeAudioPodcastUsing";
         break;
     }
 
     let subscribeUsing = this._document.getElementById("subscribeUsingDescription");
     let textNode = this._document.createTextNode(this._getString(stringLabel));
     subscribeUsing.insertBefore(textNode, subscribeUsing.firstChild);
   },
 
   _setAlwaysUseLabel() {
     let checkbox = this._document.getElementById("alwaysUse");
     if (checkbox && this._handlersList) {
       let handlerName = this._handlersList.selectedOptions[0]
                             .textContent;
       let stringLabel = "alwaysUseForFeeds";
       switch (this._getFeedType()) {
-        case Ci.nsIFeed.TYPE_VIDEO:
+        case Feed.TYPE_VIDEO:
           stringLabel = "alwaysUseForVideoPodcasts";
           break;
 
-        case Ci.nsIFeed.TYPE_AUDIO:
+        case Feed.TYPE_AUDIO:
           stringLabel = "alwaysUseForAudioPodcasts";
           break;
       }
 
       let label = this._getFormattedString(stringLabel, [handlerName]);
 
       let checkboxText = this._document.getElementById("checkboxText");
       if (checkboxText.lastChild.nodeType == checkboxText.TEXT_NODE) {
@@ -613,21 +607,21 @@ FeedWriter.prototype = {
       return;
     LOG("UI init");
 
     let feedType = this._getFeedType();
 
     // change the background
     let header = this._document.getElementById("feedHeader");
     switch (feedType) {
-      case Ci.nsIFeed.TYPE_VIDEO:
+      case Feed.TYPE_VIDEO:
         header.className = "videoPodcastBackground";
         break;
 
-      case Ci.nsIFeed.TYPE_AUDIO:
+      case Feed.TYPE_AUDIO:
         header.className = "audioPodcastBackground";
         break;
 
       default:
         header.className = "feedBackground";
     }
 
     let liveBookmarksMenuItem = this._document.getElementById("liveBookmarksMenuItem");
@@ -707,21 +701,21 @@ FeedWriter.prototype = {
     // Set up the "Subscribe Now" button
     this._document.getElementById("subscribeButton")
         .addEventListener("click", this);
 
     // first-run ui
     if (setupMessage.showFirstRunUI) {
       let textfeedinfo1, textfeedinfo2;
       switch (feedType) {
-        case Ci.nsIFeed.TYPE_VIDEO:
+        case Feed.TYPE_VIDEO:
           textfeedinfo1 = "feedSubscriptionVideoPodcast1";
           textfeedinfo2 = "feedSubscriptionVideoPodcast2";
           break;
-        case Ci.nsIFeed.TYPE_AUDIO:
+        case Feed.TYPE_AUDIO:
           textfeedinfo1 = "feedSubscriptionAudioPodcast1";
           textfeedinfo2 = "feedSubscriptionAudioPodcast2";
           break;
         default:
           textfeedinfo1 = "feedSubscriptionFeed1";
           textfeedinfo2 = "feedSubscriptionFeed2";
       }
 
@@ -900,19 +894,17 @@ FeedWriter.prototype = {
 
     this._selectedApp = undefined;
     this._selectedAppMenuItem = null;
     this._defaultHandlerMenuItem = null;
   },
 
   _removeFeedFromCache() {
     if (this._window && this._feedURI) {
-      let feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
-                        getService(Ci.nsIFeedResultService);
-      feedService.removeFeedResult(this._feedURI);
+      FeedResults.removeFeedResult(this._feedURI);
       this._feedURI = null;
     }
   },
 
   subscribe() {
     if (!this._window) {
       return;
     }
--- a/browser/components/feeds/WebContentConverter.js
+++ b/browser/components/feeds/WebContentConverter.js
@@ -1,23 +1,26 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+"use strict";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "wccr",
+                                   "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1");
+
 function LOG(str) {
   // dump("*** " + str + "\n");
 }
 
-const WCCR_CONTRACTID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
 const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
 
 const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
 const WCC_CLASSNAME = "Web Service Handler";
 
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_ANY = "*/*";
 
@@ -37,19 +40,16 @@ function WebContentConverter() {
 }
 WebContentConverter.prototype = {
   convert() { },
   asyncConvertData() { },
   onDataAvailable() { },
   onStopRequest() { },
 
   onStartRequest(request, context) {
-    let wccr =
-        Cc[WCCR_CONTRACTID].
-        getService(Ci.nsIWebContentConverterService);
     wccr.loadPreferredHandler(request);
   },
 
   QueryInterface: ChromeUtils.generateQI(["nsIStreamConverter",
                                           "nsIStreamListener"]),
 };
 
 let WebContentConverterFactory = {
@@ -236,16 +236,17 @@ const Utils = {
       return this._mappings[aContentType];
     return aContentType;
   }
 };
 
 function WebContentConverterRegistrar() {
   this._contentTypes = {};
   this._autoHandleContentTypes = {};
+  this.wrappedJSObject = this;
 }
 
 WebContentConverterRegistrar.prototype = {
   get stringBundle() {
     let sb = Services.strings.createBundle(STRING_BUNDLE_URI);
     delete WebContentConverterRegistrar.prototype.stringBundle;
     return WebContentConverterRegistrar.prototype.stringBundle = sb;
   },
@@ -884,29 +885,29 @@ WebContentConverterRegistrar.prototype =
   },
 
   classID: WCCR_CLASSID,
 
   /**
    * See nsISupports
    */
   QueryInterface: ChromeUtils.generateQI(
-     [Ci.nsIWebContentConverterService,
-      Ci.nsIWebContentHandlerRegistrar,
+     [Ci.nsIWebContentHandlerRegistrar,
       Ci.nsIObserver,
       Ci.nsIFactory]),
 
   _xpcom_categories: [{
     category: "app-startup",
     service: true
   }]
 };
 
 function WebContentConverterRegistrarContent() {
   this._contentTypes = {};
+  this.wrappedJSObject = this;
 }
 
 WebContentConverterRegistrarContent.prototype = {
 
   /**
    * Load the auto handler, content handler and protocol tables from
    * preferences.
    */
@@ -1065,16 +1066,15 @@ WebContentConverterRegistrarContent.prot
 
   classID: WCCR_CLASSID,
 
   /**
    * See nsISupports
    */
   QueryInterface: ChromeUtils.generateQI(
                      [Ci.nsIWebContentHandlerRegistrar,
-                      Ci.nsIWebContentConverterService,
                       Ci.nsIFactory])
 };
 
 this.NSGetFactory =
   (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) ?
     XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrarContent]) :
     XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrar]);
--- a/browser/components/feeds/moz.build
+++ b/browser/components/feeds/moz.build
@@ -5,34 +5,31 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini']
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
 JAR_MANIFESTS += ['jar.mn']
 
-XPIDL_SOURCES += [
-    'nsIFeedResultService.idl',
-    'nsIWebContentConverterRegistrar.idl',
-]
-
-XPIDL_MODULE = 'browser-feeds'
-
 SOURCES += [
     'nsFeedSniffer.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'BrowserFeeds.manifest',
     'FeedConverter.js',
     'FeedWriter.js',
     'WebContentConverter.js',
 ]
 
+EXTRA_JS_MODULES += [
+    'FeedResults.jsm',
+]
+
 FINAL_LIBRARY = 'browsercomps'
 
 for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
     DEFINES[var] = CONFIG[var]
 
 LOCAL_INCLUDES += [
     '../build',
 ]
deleted file mode 100644
--- a/browser/components/feeds/nsIFeedResultService.idl
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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"
-interface nsIURI;
-interface nsIRequest;
-interface nsIFeedResult;
-
-/**
- * nsIFeedResultService provides a globally-accessible object for retrieving
- * the results of feed processing.
- */
-[scriptable, uuid(95309fd2-7b3a-47fb-97f3-5c460d9473cd)]
-interface nsIFeedResultService : nsISupports
-{
-  /**
-   * When set to true, forces the preview page to be displayed, regardless
-   * of the user's preferences.
-   */
-  attribute boolean forcePreviewPage;
-
-  /**
-   * Adds a URI to the user's specified external feed handler, or live
-   * bookmarks.
-   * @param   uri
-   *          The uri of the feed to add.
-   * @param   title
-   *          The title of the feed to add.
-   * @param   subtitle
-   *          The subtitle of the feed to add.
-   * @param   feedType
-   *          The nsIFeed type of the feed.  See nsIFeed.idl
-   * @param   feedReader
-   *          The type of feed reader we're using (client, bookmarks, default)
-   *          If this parameter is null, the type is set to default
-   */
-  void addToClientReader(in AUTF8String uri,
-                         in AString title,
-                         in AString subtitle,
-                         in unsigned long feedType,
-                         [optional] in AString feedReader);
-
-  /**
-   * Registers a Feed Result object with a globally accessible service
-   * so that it can be accessed by a singleton method outside the usual
-   * flow of control in document loading.
-   *
-   * @param   feedResult
-   *          An object implementing nsIFeedResult representing the feed.
-   */
-  void addFeedResult(in nsIFeedResult feedResult);
-
-  /**
-   * Gets a Feed Handler object registered using addFeedResult.
-   *
-   * @param   uri
-   *          The URI of the feed a handler is being requested for
-   */
-  nsIFeedResult getFeedResult(in nsIURI uri);
-
-  /**
-   * Unregisters a Feed Handler object registered using addFeedResult.
-   * @param   uri
-   *          The feed URI the handler was registered under. This must be
-   *          the same *instance* the feed was registered under.
-   */
-  void removeFeedResult(in nsIURI uri);
-};
deleted file mode 100644
--- a/browser/components/feeds/nsIWebContentConverterRegistrar.idl
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIMIMEInfo.idl"
-#include "nsIWebContentHandlerRegistrar.idl"
-
-interface nsIRequest;
-
-[scriptable, uuid(eb361098-5158-4b21-8f98-50b445f1f0b2)]
-interface nsIWebContentHandlerInfo : nsIHandlerApp
-{
-  /**
-   * The content type handled by the handler
-   */
-  readonly attribute AString contentType;
-
-  /**
-   * The uri of the handler, with an embedded %s where the URI of the loaded
-   * document will be encoded.
-   */
-  readonly attribute AString uri;
-
-  /** 
-   * Gets the service URL Spec, with the loading document URI encoded in it.
-   * @param   uri
-   *          The URI of the document being loaded
-   * @returns The URI of the service with the loading document URI encoded in 
-   *          it.
-   */
-  AString getHandlerURI(in AString uri);
-};
-
-[scriptable, uuid(de7cc06e-e778-45cb-b7db-7a114e1e75b1)]
-interface nsIWebContentConverterService : nsIWebContentHandlerRegistrar
-{
-  /**
-   * Specifies the handler to be used to automatically handle all links of a
-   * certain content type from now on. 
-   * @param   contentType
-   *          The content type to automatically load with the specified handler
-   * @param   handler
-   *          A web service handler. If this is null, no automatic action is
-   *          performed and the user must choose.
-   * @throws  NS_ERROR_NOT_AVAILABLE if the service refered to by |handler| is 
-   *          not already registered.
-   */
-  void setAutoHandler(in AString contentType, in nsIWebContentHandlerInfo handler);
-
-  /**
-   * Gets the auto handler specified for a particular content type
-   * @param   contentType
-   *          The content type to look up an auto handler for.
-   * @returns The web service handler that will automatically handle all 
-   *          documents of the specified type. null if there is no automatic
-   *          handler. (Handlers may be registered, just none of them specified
-   *          as "automatic").
-   */
-  nsIWebContentHandlerInfo getAutoHandler(in AString contentType);
-
-  /**
-   * Gets a web handler for the specified service URI
-   * @param   contentType
-   *          The content type of the service being located
-   * @param   uri
-   *          The service URI of the handler to locate.
-   * @returns A web service handler that uses the specified uri.
-   */
-  nsIWebContentHandlerInfo getWebContentHandlerByURI(in AString contentType, 
-                                                     in AString uri);
-
-  /**
-   * Loads the preferred handler when content of a registered type is about
-   * to be loaded.
-   * @param   request
-   *          The nsIRequest for the load of the content
-   */
-  void loadPreferredHandler(in nsIRequest request);
-
-  /**
-   * Removes a registered protocol handler
-   * @param   protocol
-   *          The protocol scheme to remove a service handler for
-   * @param   uri
-   *          The uri of the service handler to remove
-   */
-  void removeProtocolHandler(in AString protocol, in AString uri);
-
-  /**
-   * Removes a registered content handler
-   * @param   contentType
-   *          The content type to remove a service handler for
-   * @param   uri
-   *          The uri of the service handler to remove
-   */
-  void removeContentHandler(in AString contentType, in AString uri);
-
-  /**
-   * Gets the list of content handlers for a particular type.
-   * @param   contentType
-   *          The content type to get handlers for
-   * @returns An array of nsIWebContentHandlerInfo objects
-   */
-  void getContentHandlers(in AString contentType,
-                          [optional] out unsigned long count,
-                          [retval,array,size_is(count)] out nsIWebContentHandlerInfo handlers);
-
-  /**
-   * Resets the list of available content handlers to the default set from
-   * the distribution.
-   * @param   contentType
-   *          The content type to reset handlers for
-   */
-  void resetHandlersForType(in AString contentType);
-};
-
--- a/browser/components/feeds/test/chrome/test_423060.xul
+++ b/browser/components/feeds/test/chrome/test_423060.xul
@@ -20,17 +20,17 @@
 
     /* Turn off the first run UI */
     var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
     prefBranch.setBoolPref("browser.feeds.showFirstRunUI", false);
 
     /* register a handler for the feed type */
     const MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
     var handlerPage = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/demohandler.html?feedurl=%s";
-    var wccr = Cc[wccrID].getService(Ci.nsIWebContentConverterService);
+    var wccr = Cc[wccrID].getService().wrappedJSObject;
     wccr.registerContentHandler(MAYBE_FEED, handlerPage, "Demo handler", null);
     var demoHandler = wccr.getWebContentHandlerByURI(MAYBE_FEED, handlerPage);
     wccr.setAutoHandler(MAYBE_FEED, demoHandler);
 
     /* Don't show the preview page */
     prefBranch.setCharPref("browser.feeds.handler", "reader");
 
     function finishUp() {
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -16,17 +16,17 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "CloudStorage",
   "resource://gre/modules/CloudStorage.jsm");
 
 XPCOMUtils.defineLazyServiceGetters(this, {
   gCategoryManager: ["@mozilla.org/categorymanager;1", "nsICategoryManager"],
   gHandlerService: ["@mozilla.org/uriloader/handler-service;1", "nsIHandlerService"],
   gMIMEService: ["@mozilla.org/mime;1", "nsIMIMEService"],
-  gWebContentContentConverterService: ["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1", "nsIWebContentConverterService"],
+  gWebContentContentConverterService: ["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"],
 });
 
 // Constants & Enumeration Values
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
 const TYPE_PDF = "application/pdf";
 
--- a/browser/modules/Feeds.jsm
+++ b/browser/modules/Feeds.jsm
@@ -9,40 +9,37 @@ var EXPORTED_SYMBOLS = [ "Feeds" ];
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 ChromeUtils.defineModuleGetter(this, "BrowserUtils",
                                "resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
                                "resource:///modules/BrowserWindowTracker.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "registrar",
+                                   "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1");
+
 var Feeds = {
   // Listeners are added in nsBrowserGlue.js
   receiveMessage(aMessage) {
     let data = aMessage.data;
     switch (aMessage.name) {
       case "WCCR:registerProtocolHandler": {
-        let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                          getService(Ci.nsIWebContentHandlerRegistrar);
         registrar.registerProtocolHandler(data.protocol, data.uri, data.title,
                                           aMessage.target);
         break;
       }
 
       case "WCCR:registerContentHandler": {
-        let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                          getService(Ci.nsIWebContentHandlerRegistrar);
         registrar.registerContentHandler(data.contentType, data.uri, data.title,
                                          aMessage.target);
         break;
       }
 
       case "WCCR:setAutoHandler": {
-        let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                          getService(Ci.nsIWebContentConverterService);
         registrar.setAutoHandler(data.contentType, data.handler);
         break;
       }
 
       case "FeedConverter:addLiveBookmark": {
         let topWindow = BrowserWindowTracker.getTopWindow();
         topWindow.PlacesCommandHook.addLiveBookmark(data.spec, data.title)
                                    .catch(Cu.reportError);
rename from toolkit/components/feeds/FeedProcessor.js
rename to toolkit/components/feeds/FeedProcessor.jsm
--- a/toolkit/components/feeds/FeedProcessor.js
+++ b/toolkit/components/feeds/FeedProcessor.jsm
@@ -1,47 +1,23 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+"use strict";
+
+var EXPORTED_SYMBOLS = ["FeedProcessor", "Feed"];
 
 function LOG(str) {
   dump("*** " + str + "\n");
 }
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-const FP_CONTRACTID = "@mozilla.org/feed-processor;1";
-const FP_CLASSID = Components.ID("{26acb1f0-28fc-43bc-867a-a46aabc85dd4}");
-const FP_CLASSNAME = "Feed Processor";
-const FR_CONTRACTID = "@mozilla.org/feed-result;1";
-const FR_CLASSID = Components.ID("{072a5c3d-30c6-4f07-b87f-9f63d51403f2}");
-const FR_CLASSNAME = "Feed Result";
-const FEED_CONTRACTID = "@mozilla.org/feed;1";
-const FEED_CLASSID = Components.ID("{5d0cfa97-69dd-4e5e-ac84-f253162e8f9a}");
-const FEED_CLASSNAME = "Feed";
-const ENTRY_CONTRACTID = "@mozilla.org/feed-entry;1";
-const ENTRY_CLASSID = Components.ID("{8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f}");
-const ENTRY_CLASSNAME = "Feed Entry";
-const TEXTCONSTRUCT_CONTRACTID = "@mozilla.org/feed-textconstruct;1";
-const TEXTCONSTRUCT_CLASSID =
-  Components.ID("{b992ddcd-3899-4320-9909-924b3e72c922}");
-const TEXTCONSTRUCT_CLASSNAME = "Feed Text Construct";
-const GENERATOR_CONTRACTID = "@mozilla.org/feed-generator;1";
-const GENERATOR_CLASSID =
-  Components.ID("{414af362-9ad8-4296-898e-62247f25a20e}");
-const GENERATOR_CLASSNAME = "Feed Generator";
-const PERSON_CONTRACTID = "@mozilla.org/feed-person;1";
-const PERSON_CLASSID = Components.ID("{95c963b7-20b2-11db-92f6-001422106990}");
-const PERSON_CLASSNAME = "Feed Person";
-
-const IO_CONTRACTID = "@mozilla.org/network/io-service;1";
-const BAG_CONTRACTID = "@mozilla.org/hash-property-bag;1";
-const ARRAY_CONTRACTID = "@mozilla.org/array;1";
 const SAX_CONTRACTID = "@mozilla.org/saxparser/xmlreader;1";
 const PARSERUTILS_CONTRACTID = "@mozilla.org/parserutils;1";
 
 const gMimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
 
 const XMLNS = "http://www.w3.org/XML/1998/namespace";
 const RSS090NS = "http://my.netscape.com/rdf/simple/0.9/";
 
@@ -62,52 +38,34 @@ function isArray(a) {
 function isObject(a) {
   return (a && typeof a == "object") || isFunction(a);
 }
 
 function isFunction(a) {
   return typeof a == "function";
 }
 
-function isIID(a, iid) {
-  var rv = false;
-  try {
-    a.QueryInterface(iid);
-    rv = true;
-  } catch (e) {
-  }
-  return rv;
-}
-
-function isIArray(a) {
-  return isIID(a, Ci.nsIArray);
-}
-
-function isIFeedContainer(a) {
-  return isIID(a, Ci.nsIFeedContainer);
-}
-
 function stripTags(someHTML) {
   return someHTML.replace(/<[^>]+>/g, "");
 }
 
 /**
  * Searches through an array of links and returns a JS array
  * of matching property bags.
  */
 const IANA_URI = "http://www.iana.org/assignments/relation/";
 function findAtomLinks(rel, links) {
   var rvLinks = [];
   for (var i = 0; i < links.length; ++i) {
-    var linkElement = links.queryElementAt(i, Ci.nsIPropertyBag2);
+    var linkElement = links[i];
     // atom:link MUST have @href
-    if (bagHasKey(linkElement, "href")) {
+    if (linkElement.has("href")) {
       var relAttribute = null;
-      if (bagHasKey(linkElement, "rel"))
-        relAttribute = linkElement.getPropertyAsAString("rel");
+      if (linkElement.has("rel"))
+        relAttribute = linkElement.get("rel");
       if ((!relAttribute && rel == "alternate") || relAttribute == rel) {
         rvLinks.push(linkElement);
         continue;
       }
       // catch relations specified by IANA URI
       if (relAttribute == IANA_URI + rel) {
         rvLinks.push(linkElement);
       }
@@ -120,42 +78,19 @@ function xmlEscape(s) {
   s = s.replace(/&/g, "&amp;");
   s = s.replace(/>/g, "&gt;");
   s = s.replace(/</g, "&lt;");
   s = s.replace(/"/g, "&quot;");
   s = s.replace(/'/g, "&apos;");
   return s;
 }
 
-function arrayContains(array, element) {
-  for (var i = 0; i < array.length; ++i) {
-    if (array[i] == element) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// XXX add hasKey to nsIPropertyBag
-function bagHasKey(bag, key) {
-  try {
-    bag.getProperty(key);
-    return true;
-  } catch (e) {
-    return false;
-  }
-}
-
 function makePropGetter(key) {
-  return function FeedPropGetter(bag) {
-    try {
-      return bag.getProperty(key);
-    } catch (e) {
-    }
-    return null;
+  return function FeedPropGetter(map) {
+    return map.get(key);
   };
 }
 
 const RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
 // namespace map
 var gNamespaces = {
   "http://webns.net/mvcb/": "admin",
   "http://backend.userland.com/rss": "",
@@ -191,99 +126,112 @@ FeedResult.prototype = {
   version: null,
   headers: null,
   uri: null,
   stylesheet: null,
 
   registerExtensionPrefix: function FR_registerExtensionPrefix(ns, prefix) {
     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
   },
-
-  // XPCOM stuff
-  classID: FR_CLASSID,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFeedResult])
 };
 
-function Feed() {
-  this.subtitle = null;
-  this.title = null;
-  this.items = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-  this.link = null;
-  this.id = null;
-  this.generator = null;
-  this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-  this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-  this.baseURI = null;
-  this.enclosureCount = 0;
-  this.type = Ci.nsIFeed.TYPE_FEED;
+class FeedContainer {
+  _atomLinksToURI() {
+    var links = this.fields.get("links");
+    var alternates = findAtomLinks("alternate", links);
+    if (alternates.length > 0) {
+      var href = alternates[0].get("href");
+      var base;
+      if (alternates[0].has("xml:base"))
+        base = alternates[0].get("xml:base");
+      this.link = this._resolveURI(href, base);
+    }
+  }
+
+
+  _resolveURI(linkSpec, baseSpec) {
+    var uri = null;
+    try {
+      var base = baseSpec ? strToURI(baseSpec, this.baseURI) : this.baseURI;
+      uri = strToURI(linkSpec, base);
+    } catch (e) {
+      LOG(e);
+    }
+
+    return uri;
+  }
+
+  // reset the bag to raw contents, not text constructs
+  _resetBagMembersToRawText(fieldLists) {
+    for (var i = 0; i < fieldLists.length; i++) {
+      for (var j = 0; j < fieldLists[i].length; j++) {
+        if (this.fields.has(fieldLists[i][j])) {
+          var textConstruct = this.fields.get(fieldLists[i][j]);
+          this.fields.set(fieldLists[i][j], textConstruct.text);
+        }
+      }
+    }
+  }
 }
 
-Feed.prototype = {
-  searchLists: {
-    title: ["title", "rss1:title", "atom03:title", "atom:title"],
-    subtitle: ["description", "dc:description", "rss1:description",
-               "atom03:tagline", "atom:subtitle"],
-    items: ["items", "atom03_entries", "entries"],
-    id: ["atom:id", "rdf:about"],
-    generator: ["generator"],
-    authors: ["authors"],
-    contributors: ["contributors"],
-    link:  [["link", strToURI], ["rss1:link", strToURI]],
-    categories: ["categories", "dc:subject"],
-    rights: ["atom03:rights", "atom:rights"],
-    cloud: ["cloud"],
-    image: ["image", "rss1:image", "atom:logo"],
-    textInput: ["textInput", "rss1:textinput"],
-    skipDays: ["skipDays"],
-    skipHours: ["skipHours"],
-    updated: ["pubDate", "lastBuildDate", "atom03:modified", "dc:date",
-              "dcterms:modified", "atom:updated"]
-  },
+class Feed extends FeedContainer {
+  constructor() {
+    super();
+    this.subtitle = null;
+    this.title = null;
+    this.items = [];
+    this.link = null;
+    this.id = null;
+    this.generator = null;
+    this.authors = [];
+    this.contributors = [];
+    this.baseURI = null;
+    this.enclosureCount = 0;
+    this.type = Feed.TYPE_FEED;
+  }
 
-  normalize: function Feed_normalize() {
+  normalize() {
     fieldsToObj(this, this.searchLists);
     if (this.skipDays)
-      this.skipDays = this.skipDays.getProperty("days");
+      this.skipDays = this.skipDays.get("days");
     if (this.skipHours)
-      this.skipHours = this.skipHours.getProperty("hours");
+      this.skipHours = this.skipHours.get("hours");
 
     if (this.updated)
       this.updated = dateParse(this.updated);
 
     // Assign Atom link if needed
-    if (bagHasKey(this.fields, "links"))
+    if (this.fields.has("links"))
       this._atomLinksToURI();
 
     this._calcEnclosureCountAndFeedType();
 
     // Resolve relative image links
-    if (this.image && bagHasKey(this.image, "url"))
+    if (this.image && this.image.has("url"))
       this._resolveImageLink();
 
     this._resetBagMembersToRawText([this.searchLists.subtitle,
                                     this.searchLists.title]);
-  },
+  }
 
-  _calcEnclosureCountAndFeedType: function Feed_calcEnclosureCountAndFeedType() {
+  _calcEnclosureCountAndFeedType() {
     var entries_with_enclosures = 0;
     var audio_count = 0;
     var image_count = 0;
     var video_count = 0;
     var other_count = 0;
 
     for (var i = 0; i < this.items.length; ++i) {
-      var entry = this.items.queryElementAt(i, Ci.nsIFeedEntry);
-      entry.QueryInterface(Ci.nsIFeedContainer);
-
+      var entry = this.items[i];
       if (entry.enclosures && entry.enclosures.length > 0) {
         ++entries_with_enclosures;
 
         for (var e = 0; e < entry.enclosures.length; ++e) {
-          var enc = entry.enclosures.queryElementAt(e, Ci.nsIWritablePropertyBag2);
-          if (enc.hasKey("type")) {
+          var enc = entry.enclosures[e];
+          if (enc.has("type")) {
             var enctype = enc.get("type");
 
             if (/^audio/.test(enctype)) {
               ++audio_count;
             } else if (/^image/.test(enctype)) {
               ++image_count;
             } else if (/^video/.test(enctype)) {
               ++video_count;
@@ -292,310 +240,277 @@ Feed.prototype = {
             }
           } else {
             ++other_count;
           }
         }
       }
     }
 
-    var feedtype = Ci.nsIFeed.TYPE_FEED;
+    var feedtype = Feed.TYPE_FEED;
 
     // For a feed to be marked as TYPE_VIDEO, TYPE_AUDIO and TYPE_IMAGE,
     // we enforce two things:
     //
     //    1. all entries must have at least one enclosure
     //    2. all enclosures must be video for TYPE_VIDEO, audio for TYPE_AUDIO or image
     //       for TYPE_IMAGE
     //
     // Otherwise it's a TYPE_FEED.
     if (entries_with_enclosures == this.items.length && other_count == 0) {
       if (audio_count > 0 && !video_count && !image_count) {
-        feedtype = Ci.nsIFeed.TYPE_AUDIO;
+        feedtype = Feed.TYPE_AUDIO;
 
       } else if (image_count > 0 && !audio_count && !video_count) {
-        feedtype = Ci.nsIFeed.TYPE_IMAGE;
+        feedtype = Feed.TYPE_IMAGE;
 
       } else if (video_count > 0 && !audio_count && !image_count) {
-        feedtype = Ci.nsIFeed.TYPE_VIDEO;
+        feedtype = Feed.TYPE_VIDEO;
       }
     }
 
     this.type = feedtype;
     this.enclosureCount = other_count + video_count + audio_count + image_count;
-  },
+  }
 
-  _atomLinksToURI: function Feed_linkToURI() {
-    var links = this.fields.getPropertyAsInterface("links", Ci.nsIArray);
-    var alternates = findAtomLinks("alternate", links);
-    if (alternates.length > 0) {
-      var href = alternates[0].getPropertyAsAString("href");
-      var base;
-      if (bagHasKey(alternates[0], "xml:base"))
-        base = alternates[0].getPropertyAsAString("xml:base");
-      this.link = this._resolveURI(href, base);
-    }
-  },
+  _resolveImageLink() {
+    var base;
+    if (this.image.has("xml:base"))
+      base = this.image.get("xml:base");
+    var url = this._resolveURI(this.image.get("url"), base);
+    if (url)
+      this.image.set("url", url.spec);
+  }
+}
 
-  _resolveImageLink: function Feed_resolveImageLink() {
-    var base;
-    if (bagHasKey(this.image, "xml:base"))
-      base = this.image.getPropertyAsAString("xml:base");
-    var url = this._resolveURI(this.image.getPropertyAsAString("url"), base);
-    if (url)
-      this.image.setPropertyAsAString("url", url.spec);
-  },
+Object.assign(Feed.prototype, {
+  TYPE_FEED: 0,
+  TYPE_AUDIO: 1,
+  TYPE_IMAGE: 2,
+  TYPE_VIDEO: 4,
+});
 
-  _resolveURI: function Feed_resolveURI(linkSpec, baseSpec) {
-    var uri = null;
-    try {
-      var base = baseSpec ? strToURI(baseSpec, this.baseURI) : this.baseURI;
-      uri = strToURI(linkSpec, base);
-    } catch (e) {
-      LOG(e);
-    }
-
-    return uri;
-  },
-
-  // reset the bag to raw contents, not text constructs
-  _resetBagMembersToRawText: function Feed_resetBagMembers(fieldLists) {
-    for (var i = 0; i < fieldLists.length; i++) {
-      for (var j = 0; j < fieldLists[i].length; j++) {
-        if (bagHasKey(this.fields, fieldLists[i][j])) {
-          var textConstruct = this.fields.getProperty(fieldLists[i][j]);
-          this.fields.setPropertyAsAString(fieldLists[i][j],
-                                           textConstruct.text);
-        }
-      }
-    }
-  },
-
-  // XPCOM stuff
-  classID: FEED_CLASSID,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFeed, Ci.nsIFeedContainer])
+Feed.prototype.searchLists = {
+  title: ["title", "rss1:title", "atom03:title", "atom:title"],
+  subtitle: ["description", "dc:description", "rss1:description",
+             "atom03:tagline", "atom:subtitle"],
+  items: ["items", "atom03_entries", "entries"],
+  id: ["atom:id", "rdf:about"],
+  generator: ["generator"],
+  authors: ["authors"],
+  contributors: ["contributors"],
+  link:  [["link", strToURI], ["rss1:link", strToURI]],
+  categories: ["categories", "dc:subject"],
+  rights: ["atom03:rights", "atom:rights"],
+  cloud: ["cloud"],
+  image: ["image", "rss1:image", "atom:logo"],
+  textInput: ["textInput", "rss1:textinput"],
+  skipDays: ["skipDays"],
+  skipHours: ["skipHours"],
+  updated: ["pubDate", "lastBuildDate", "atom03:modified", "dc:date",
+            "dcterms:modified", "atom:updated"]
 };
 
-function Entry() {
-  this.summary = null;
-  this.content = null;
-  this.title = null;
-  this.fields = Cc["@mozilla.org/hash-property-bag;1"].
-    createInstance(Ci.nsIWritablePropertyBag2);
-  this.link = null;
-  this.id = null;
-  this.baseURI = null;
-  this.updated = null;
-  this.published = null;
-  this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-  this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-}
+class Entry extends FeedContainer {
+  constructor() {
+    super();
+    this.summary = null;
+    this.content = null;
+    this.title = null;
+    this.fields = new Map();
+    this.link = null;
+    this.id = null;
+    this.baseURI = null;
+    this.updated = null;
+    this.published = null;
+    this.authors = [];
+    this.contributors = [];
+  }
 
-Entry.prototype = {
-  fields: null,
-  enclosures: null,
-  mediaContent: null,
-
-  searchLists: {
-    title: ["title", "rss1:title", "atom03:title", "atom:title"],
-    link: [["link", strToURI], ["rss1:link", strToURI]],
-    id: [["guid", makePropGetter("guid")], "rdf:about",
-         "atom03:id", "atom:id"],
-    authors: ["authors"],
-    contributors: ["contributors"],
-    summary: ["description", "rss1:description", "dc:description",
-              "atom03:summary", "atom:summary"],
-    content: ["content:encoded", "atom03:content", "atom:content"],
-    rights: ["atom03:rights", "atom:rights"],
-    published: ["pubDate", "atom03:issued", "dcterms:issued", "atom:published"],
-    updated: ["pubDate", "atom03:modified", "dc:date", "dcterms:modified",
-              "atom:updated"]
-  },
-
-  normalize: function Entry_normalize() {
+  normalize() {
     fieldsToObj(this, this.searchLists);
 
     // Assign Atom link if needed
-    if (bagHasKey(this.fields, "links"))
+    if (this.fields.has("links"))
       this._atomLinksToURI();
 
     // Populate enclosures array
     this._populateEnclosures();
 
     // The link might be a guid w/ permalink=true
-    if (!this.link && bagHasKey(this.fields, "guid")) {
-      var guid = this.fields.getProperty("guid");
+    if (!this.link && this.fields.has("guid")) {
+      var guid = this.fields.get("guid");
       var isPermaLink = true;
 
-      if (bagHasKey(guid, "isPermaLink"))
-        isPermaLink = guid.getProperty("isPermaLink").toLowerCase() != "false";
+      if (guid.has("isPermaLink"))
+        isPermaLink = guid.get("isPermaLink").toLowerCase() != "false";
 
       if (guid && isPermaLink)
-        this.link = strToURI(guid.getProperty("guid"));
+        this.link = strToURI(guid.get("guid"));
     }
 
     if (this.updated)
       this.updated = dateParse(this.updated);
     if (this.published)
       this.published = dateParse(this.published);
 
     this._resetBagMembersToRawText([this.searchLists.content,
                                     this.searchLists.summary,
                                     this.searchLists.title]);
-  },
+  }
 
-  _populateEnclosures: function Entry_populateEnclosures() {
-    if (bagHasKey(this.fields, "links"))
+  _populateEnclosures() {
+    if (this.fields.has("links"))
       this._atomLinksToEnclosures();
 
     // Add RSS2 enclosure to enclosures
-    if (bagHasKey(this.fields, "enclosure"))
+    if (this.fields.has("enclosure"))
       this._enclosureToEnclosures();
 
     // Add media:content to enclosures
-    if (bagHasKey(this.fields, "mediacontent"))
+    if (this.fields.has("mediacontent"))
       this._mediaToEnclosures("mediacontent");
 
     // Add media:thumbnail to enclosures
-    if (bagHasKey(this.fields, "mediathumbnail"))
+    if (this.fields.has("mediathumbnail"))
       this._mediaToEnclosures("mediathumbnail");
 
     // Add media:content in media:group to enclosures
-    if (bagHasKey(this.fields, "mediagroup"))
+    if (this.fields.has("mediagroup"))
       this._mediaToEnclosures("mediagroup", "mediacontent");
-  },
+  }
 
-  __enclosure_map: null,
-
-  _addToEnclosures: function Entry_addToEnclosures(new_enc) {
+  _addToEnclosures(new_enc) {
     // items we add to the enclosures array get displayed in the FeedWriter and
     // they must have non-empty urls.
-    if (!bagHasKey(new_enc, "url") || new_enc.getPropertyAsAString("url") == "")
+    if (!new_enc.has("url") || new_enc.get("url") == "")
       return;
 
     if (this.__enclosure_map == null)
       this.__enclosure_map = {};
 
-    var previous_enc = this.__enclosure_map[new_enc.getPropertyAsAString("url")];
+    var previous_enc = this.__enclosure_map[new_enc.get("url")];
 
     if (previous_enc != undefined) {
-      previous_enc.QueryInterface(Ci.nsIWritablePropertyBag2);
-
-      if (!bagHasKey(previous_enc, "type") && bagHasKey(new_enc, "type")) {
-        previous_enc.setPropertyAsAString("type", new_enc.getPropertyAsAString("type"));
+      if (!previous_enc.has("type") && new_enc.has("type")) {
+        previous_enc.set("type", new_enc.get("type"));
         try {
-          let handlerInfoWrapper = gMimeService.getFromTypeAndExtension(new_enc.getPropertyAsAString("type"), null);
+          let handlerInfoWrapper = gMimeService.getFromTypeAndExtension(new_enc.get("type"), null);
           if (handlerInfoWrapper && handlerInfoWrapper.description) {
-            previous_enc.setPropertyAsAString("typeDesc", handlerInfoWrapper.description);
+            previous_enc.set("typeDesc", handlerInfoWrapper.description);
           }
         } catch (ext) {}
       }
 
-      if (!bagHasKey(previous_enc, "length") && bagHasKey(new_enc, "length"))
-        previous_enc.setPropertyAsAString("length", new_enc.getPropertyAsAString("length"));
+      if (!previous_enc.has("length") && new_enc.has("length"))
+        previous_enc.set("length", new_enc.get("length"));
 
       return;
     }
 
     if (this.enclosures == null) {
-      this.enclosures = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
-      this.enclosures.QueryInterface(Ci.nsIMutableArray);
+      this.enclosures = [];
     }
 
-    this.enclosures.appendElement(new_enc);
-    this.__enclosure_map[new_enc.getPropertyAsAString("url")] = new_enc;
-  },
+    this.enclosures.push(new_enc);
+    this.__enclosure_map[new_enc.get("url")] = new_enc;
+  }
 
-  _atomLinksToEnclosures: function Entry_linkToEnclosure() {
-    var links = this.fields.getPropertyAsInterface("links", Ci.nsIArray);
+  _atomLinksToEnclosures() {
+    var links = this.fields.get("links");
     var enc_links = findAtomLinks("enclosure", links);
     if (enc_links.length == 0)
       return;
 
     for (var i = 0; i < enc_links.length; ++i) {
       var link = enc_links[i];
 
       // an enclosure must have an href
-      if (!(link.getProperty("href")))
+      if (!(link.get("href")))
         return;
 
-      var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+      var enc = new Map();
 
       // copy Atom bits over to equivalent enclosure bits
-      enc.setPropertyAsAString("url", link.getPropertyAsAString("href"));
-      if (bagHasKey(link, "type"))
-        enc.setPropertyAsAString("type", link.getPropertyAsAString("type"));
-      if (bagHasKey(link, "length"))
-        enc.setPropertyAsAString("length", link.getPropertyAsAString("length"));
+      enc.set("url", link.get("href"));
+      if (link.has("type"))
+        enc.set("type", link.get("type"));
+      if (link.has("length"))
+        enc.set("length", link.get("length"));
 
       this._addToEnclosures(enc);
     }
-  },
+  }
 
-  _enclosureToEnclosures: function Entry_enclosureToEnclosures() {
-    var enc = this.fields.getPropertyAsInterface("enclosure", Ci.nsIPropertyBag2);
+  _enclosureToEnclosures() {
+    var enc = this.fields.get("enclosure");
 
-    if (!(enc.getProperty("url")))
+    if (!(enc.get("url")))
       return;
 
     this._addToEnclosures(enc);
-  },
+  }
 
-  _mediaToEnclosures: function Entry_mediaToEnclosures(mediaType, contentType) {
+  _mediaToEnclosures(mediaType, contentType) {
     var content;
 
     // If a contentType is specified, the mediaType is a simple propertybag,
     // and the contentType is an array inside it.
     if (contentType) {
-      var group = this.fields.getPropertyAsInterface(mediaType, Ci.nsIPropertyBag2);
-      content = group.getPropertyAsInterface(contentType, Ci.nsIArray);
+      var group = this.fields.get(mediaType);
+      content = group.get(contentType);
     } else {
-      content = this.fields.getPropertyAsInterface(mediaType, Ci.nsIArray);
+      content = this.fields.get(mediaType);
     }
 
     for (var i = 0; i < content.length; ++i) {
-      var contentElement = content.queryElementAt(i, Ci.nsIWritablePropertyBag2);
+      var contentElement = content[i];
 
       // media:content don't require url, but if it's not there, we should
       // skip it.
-      if (!bagHasKey(contentElement, "url"))
+      if (!contentElement.has("url"))
         continue;
 
-      var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+      var enc = new Map();
 
       // copy media:content bits over to equivalent enclosure bits
-      enc.setPropertyAsAString("url", contentElement.getPropertyAsAString("url"));
-      if (bagHasKey(contentElement, "type")) {
-        enc.setPropertyAsAString("type", contentElement.getPropertyAsAString("type"));
+      enc.set("url", contentElement.get("url"));
+      if (contentElement.has("type")) {
+        enc.set("type", contentElement.get("type"));
       } else if (mediaType == "mediathumbnail") {
         // thumbnails won't have a type, but default to image types
-        enc.setPropertyAsAString("type", "image/*");
-        enc.setPropertyAsBool("thumbnail", true);
+        enc.set("type", "image/*");
+        enc.set("thumbnail", true);
       }
 
-      if (bagHasKey(contentElement, "fileSize")) {
-        enc.setPropertyAsAString("length", contentElement.getPropertyAsAString("fileSize"));
+      if (contentElement.has("fileSize")) {
+        enc.set("length", contentElement.get("fileSize"));
       }
 
       this._addToEnclosures(enc);
     }
-  },
+  }
+}
 
-  // XPCOM stuff
-  classID: ENTRY_CLASSID,
-  QueryInterface: ChromeUtils.generateQI(
-    [Ci.nsIFeedEntry, Ci.nsIFeedContainer]
-  )
+Entry.prototype.searchLists = {
+  title: ["title", "rss1:title", "atom03:title", "atom:title"],
+  link: [["link", strToURI], ["rss1:link", strToURI]],
+  id: [["guid", makePropGetter("guid")], "rdf:about",
+       "atom03:id", "atom:id"],
+  authors: ["authors"],
+  contributors: ["contributors"],
+  summary: ["description", "rss1:description", "dc:description",
+            "atom03:summary", "atom:summary"],
+  content: ["content:encoded", "atom03:content", "atom:content"],
+  rights: ["atom03:rights", "atom:rights"],
+  published: ["pubDate", "atom03:issued", "dcterms:issued", "atom:published"],
+  updated: ["pubDate", "atom03:modified", "dc:date", "dcterms:modified",
+            "atom:updated"]
 };
 
-Entry.prototype._atomLinksToURI = Feed.prototype._atomLinksToURI;
-Entry.prototype._resolveURI = Feed.prototype._resolveURI;
-Entry.prototype._resetBagMembersToRawText =
-   Feed.prototype._resetBagMembersToRawText;
-
 // TextConstruct represents and element that could contain (X)HTML
 function TextConstruct() {
   this.lang = null;
   this.base = null;
   this.type = "text";
   this.text = null;
   this.parserUtils = Cc[PARSERUTILS_CONTRACTID].getService(Ci.nsIParserUtils);
 }
@@ -626,20 +541,16 @@ TextConstruct.prototype = {
       isXML = false;
     else
       return null;
 
     let flags = Ci.nsIParserUtils.SanitizerDropForms;
     return this.parserUtils.parseFragment(this.text, flags, isXML,
                                           this.base, element);
   },
-
-  // XPCOM stuff
-  classID: TEXTCONSTRUCT_CLASSID,
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIFeedTextConstruct])
 };
 
 // Generator represents the software that produced the feed
 function Generator() {
   this.lang = null;
   this.agent = null;
   this.version = null;
   this.uri = null;
@@ -664,40 +575,29 @@ Generator.prototype = {
 
     // RSS1
     uriAttribute = this._attributes.getValueFromName(RDF_NS, "resource");
     if (uriAttribute) {
       this.agent = uriAttribute;
       this.uri = strToURI(uriAttribute, this.baseURI);
     }
   },
-
-  // XPCOM stuff
-  classID: GENERATOR_CLASSID,
-  QueryInterface: ChromeUtils.generateQI(
-    [Ci.nsIFeedGenerator, Ci.nsIFeedElementBase]
-  )
 };
 
 function Person() {
   this.name = null;
   this.uri = null;
   this.email = null;
 
   // nsIFeedElementBase
   this.attributes = null;
   this.baseURI = null;
 }
 
 Person.prototype = {
-  // XPCOM stuff
-  classID: PERSON_CLASSID,
-  QueryInterface: ChromeUtils.generateQI(
-    [Ci.nsIFeedPerson, Ci.nsIFeedElementBase]
-  )
 };
 
 /**
  * Map a list of fields into properties on a container.
  *
  * @param container An nsIFeedContainer
  * @param fields A list of fields to search for. List members can
  *               be a list, in which case the second member is
@@ -706,61 +606,47 @@ Person.prototype = {
 function fieldsToObj(container, fields) {
   var props, prop, field, searchList;
   for (var key in fields) {
     searchList = fields[key];
     for (var i = 0; i < searchList.length; ++i) {
       props = searchList[i];
       prop = null;
       field = isArray(props) ? props[0] : props;
-      try {
-        prop = container.fields.getProperty(field);
-      } catch (e) {
-      }
+      prop = container.fields.get(field);
       if (prop) {
         prop = isArray(props) ? props[1](prop) : prop;
         container[key] = prop;
       }
     }
   }
 }
 
-/**
- * Lower cases an element's localName property
- * @param   element A DOM element.
- *
- * @returns The lower case localName property of the specified element
- */
-function LC(element) {
-  return element.localName.toLowerCase();
-}
-
 // TODO move these post-processor functions
 // create a generator element
 function atomGenerator(s, generator) {
-  generator.QueryInterface(Ci.nsIFeedGenerator);
   generator.agent = s.trim();
   return generator;
 }
 
 // post-process atom:logo to create an RSS2-like structure
 function atomLogo(s, logo) {
-  logo.setPropertyAsAString("url", s.trim());
+  logo.set("url", s.trim());
 }
 
 // post-process an RSS category, map it to the Atom fields.
 function rssCatTerm(s, cat) {
   // add slash handling?
-  cat.setPropertyAsAString("term", s.trim());
+  cat.set("term", s.trim());
   return cat;
 }
 
 // post-process a GUID
 function rssGuid(s, guid) {
-  guid.setPropertyAsAString("guid", s.trim());
+  guid.set("guid", s.trim());
   return guid;
 }
 
 // post-process an RSS author element
 //
 // It can contain a field like this:
 //
 //  <author>lawyer@boyer.net (Lawyer Boyer)</author>
@@ -768,17 +654,16 @@ function rssGuid(s, guid) {
 // or, delightfully, a field like this:
 //
 //  <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
 //
 // We want to split this up and assign it to corresponding Atom
 // fields.
 //
 function rssAuthor(s, author) {
-  author.QueryInterface(Ci.nsIFeedPerson);
   // check for RSS2 string format
   var chars = s.trim();
   var matches = chars.match(/(.*)\((.*)\)/);
   var emailCheck =
     /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
   if (matches) {
     var match1 = matches[1].trim();
     var match2 = matches[2].trim();
@@ -802,21 +687,17 @@ function rssAuthor(s, author) {
   return author;
 }
 
 //
 // skipHours and skipDays map to arrays, so we need to change the
 // string to an nsISupports in order to stick it in there.
 //
 function rssArrayElement(s) {
-  var str = Cc["@mozilla.org/supports-string;1"].
-              createInstance(Ci.nsISupportsString);
-  str.data = s;
-  str.QueryInterface(Ci.nsISupportsString);
-  return str;
+  return s;
 }
 
 /**
  * Tries parsing a string through the JavaScript Date object.
  * @param aDateString
  *        A string that is supposedly an RFC822 or RFC3339 date.
  * @return A Date.toUTCString, or null if the string can't be parsed.
  */
@@ -1021,17 +902,17 @@ function WrapperElementInfo(fieldName) {
   this.isWrapper = true;
   this.fieldName = fieldName;
 }
 
 /** *** The Processor *****/
 function FeedProcessor() {
   this._reader = Cc[SAX_CONTRACTID].createInstance(Ci.nsISAXXMLReader);
   this._buf =  "";
-  this._feed = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+  this._feed = new Map();
   this._handlerStack = [];
   this._xmlBaseStack = []; // sparse array keyed to nesting depth
   this._depth = 0;
   this._state = "START";
   this._result = null;
   this._extensionHandler = null;
   this._xhtmlHandler = null;
   this._haveSentResult = false;
@@ -1075,43 +956,43 @@ function FeedProcessor() {
     },
 
     /** ******* RSS2 **********/
     "IN_RSS2": {
       "channel": new WrapperElementInfo("channel")
     },
 
     "IN_CHANNEL": {
-      "item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
-      "managingEditor": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "item": new ElementInfo("items", Entry, null, true),
+      "managingEditor": new ElementInfo("authors", Person,
                                         rssAuthor, true),
-      "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:creator": new ElementInfo("authors", Person,
                                     rssAuthor, true),
-      "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:author": new ElementInfo("authors", Person,
                                    rssAuthor, true),
-      "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+      "dc:contributor": new ElementInfo("contributors", Person,
                                          rssAuthor, true),
       "category": new ElementInfo("categories", null, rssCatTerm, true),
       "cloud": new ElementInfo("cloud", null, null, false),
       "image": new ElementInfo("image", null, null, false),
       "textInput": new ElementInfo("textInput", null, null, false),
       "skipDays": new ElementInfo("skipDays", null, null, false),
       "skipHours": new ElementInfo("skipHours", null, null, false),
-      "generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+      "generator": new ElementInfo("generator", Generator,
                                    atomGenerator, false),
     },
 
     "IN_ITEMS": {
-      "author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "author": new ElementInfo("authors", Person,
                                 rssAuthor, true),
-      "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:creator": new ElementInfo("authors", Person,
                                     rssAuthor, true),
-      "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:author": new ElementInfo("authors", Person,
                                    rssAuthor, true),
-      "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+      "dc:contributor": new ElementInfo("contributors", Person,
                                          rssAuthor, true),
       "category": new ElementInfo("categories", null, rssCatTerm, true),
       "enclosure": new ElementInfo("enclosure", null, null, false),
       "media:content": new ElementInfo("mediacontent", null, null, true),
       "media:group": new ElementInfo("mediagroup", null, null, false),
       "media:thumbnail": new ElementInfo("mediathumbnail", null, null, true),
       "guid": new ElementInfo("guid", null, rssGuid, false)
     },
@@ -1130,100 +1011,100 @@ function FeedProcessor() {
     },
 
     /** ******* RSS1 **********/
     "IN_RDF": {
       // If we hit a rss1:channel, we can verify that we have RSS1
       "rss1:channel": new FeedElementInfo("rdf_channel", "rss1"),
       "rss1:image": new ElementInfo("image", null, null, false),
       "rss1:textinput": new ElementInfo("textInput", null, null, false),
-      "rss1:item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
+      "rss1:item": new ElementInfo("items", Entry, null, true),
     },
 
     "IN_RDF_CHANNEL": {
       "admin:generatorAgent": new ElementInfo("generator",
-                                              Cc[GENERATOR_CONTRACTID],
+                                              Generator,
                                               null, false),
-      "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:creator": new ElementInfo("authors", Person,
                                     rssAuthor, true),
-      "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "dc:author": new ElementInfo("authors", Person,
                                    rssAuthor, true),
-      "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+      "dc:contributor": new ElementInfo("contributors", Person,
                                          rssAuthor, true),
     },
 
     /** ******* ATOM 1.0 **********/
     "IN_ATOM": {
-      "atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "atom:author": new ElementInfo("authors", Person,
                                      null, true),
-      "atom:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+      "atom:generator": new ElementInfo("generator", Generator,
                                         atomGenerator, false),
-      "atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+      "atom:contributor": new ElementInfo("contributors", Person,
                                           null, true),
       "atom:link": new ElementInfo("links", null, null, true),
       "atom:logo": new ElementInfo("atom:logo", null, atomLogo, false),
-      "atom:entry": new ElementInfo("entries", Cc[ENTRY_CONTRACTID],
+      "atom:entry": new ElementInfo("entries", Entry,
                                     null, true)
     },
 
     "IN_ENTRIES": {
-      "atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "atom:author": new ElementInfo("authors", Person,
                                      null, true),
-      "atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+      "atom:contributor": new ElementInfo("contributors", Person,
                                           null, true),
       "atom:link": new ElementInfo("links", null, null, true),
     },
 
     /** ******* ATOM 0.3 **********/
     "IN_ATOM03": {
-      "atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "atom03:author": new ElementInfo("authors", Person,
                                        null, true),
       "atom03:contributor": new ElementInfo("contributors",
-                                            Cc[PERSON_CONTRACTID],
+                                            Person,
                                             null, true),
       "atom03:link": new ElementInfo("links", null, null, true),
-      "atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
+      "atom03:entry": new ElementInfo("atom03_entries", Entry,
                                       null, true),
-      "atom03:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+      "atom03:generator": new ElementInfo("generator", Generator,
                                           atomGenerator, false),
     },
 
     "IN_ATOM03_ENTRIES": {
-      "atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+      "atom03:author": new ElementInfo("authors", Person,
                                        null, true),
       "atom03:contributor": new ElementInfo("contributors",
-                                            Cc[PERSON_CONTRACTID],
+                                            Person,
                                             null, true),
       "atom03:link": new ElementInfo("links", null, null, true),
-      "atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
+      "atom03:entry": new ElementInfo("atom03_entries", Entry,
                                       null, true)
     }
   };
 }
 
 // See startElement for a long description of how feeds are processed.
 FeedProcessor.prototype = {
 
   // Set ourselves as the SAX handler, and set the base URI
   _init: function FP_init(uri) {
     this._reader.contentHandler = this;
     this._reader.errorHandler = this;
-    this._result = Cc[FR_CONTRACTID].createInstance(Ci.nsIFeedResult);
+    this._result = new FeedResult();
     if (uri) {
       this._result.uri = uri;
       this._reader.baseURI = uri;
       this._xmlBaseStack[0] = uri;
     }
   },
 
   // This function is called once we figure out what type of feed
   // we're dealing with. Some feed types require digging a bit further
   // than the root.
   _docVerified: function FP_docVerified(version) {
-    this._result.doc = Cc[FEED_CONTRACTID].createInstance(Ci.nsIFeed);
+    this._result.doc = new Feed();
     this._result.doc.baseURI =
       this._xmlBaseStack[this._xmlBaseStack.length - 1];
     this._result.doc.fields = this._feed;
     this._result.version = version;
   },
 
   // When we're done with the feed, let the listener know what
   // happened.
@@ -1454,69 +1335,62 @@ FeedProcessor.prototype = {
   // Handle our more complicated elements--those that contain
   // attributes and child elements.
   _processComplexElement:
   function FP__processComplexElement(elementInfo, attributes) {
     var obj;
 
     // If the container is an entry/item, it'll need to have its
     // more esoteric properties put in the 'fields' property bag.
-    if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID]) {
-      obj = elementInfo.containerClass.createInstance(Ci.nsIFeedEntry);
+    if (elementInfo.containerClass == Entry) {
+      obj = new elementInfo.containerClass();
       obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
       this._mapAttributes(obj.fields, attributes);
     } else if (elementInfo.containerClass) {
-      obj = elementInfo.containerClass.createInstance(Ci.nsIFeedElementBase);
+      obj = new elementInfo.containerClass();
       obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
       obj.attributes = attributes; // just set the SAX attributes
     } else {
-      obj = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+      obj = new Map();
       this._mapAttributes(obj, attributes);
     }
 
     // We should have a container/propertyBag that's had its
     // attributes processed. Now we need to attach it to its
     // container.
     var newProp;
 
     // First we'll see what's on top of the stack.
     var container = this._stack[this._stack.length - 1][0];
 
     // Check to see if it has the property
-    var prop;
-    try {
-      prop = container.getProperty(elementInfo.fieldName);
-    } catch (e) {
-    }
+    var prop = container.get(elementInfo.fieldName);
 
     if (elementInfo.isArray) {
       if (!prop) {
-        container.setPropertyAsInterface(elementInfo.fieldName,
-                                         Cc[ARRAY_CONTRACTID].
-                                         createInstance(Ci.nsIMutableArray));
+        container.set(elementInfo.fieldName, []);
       }
 
-      newProp = container.getProperty(elementInfo.fieldName);
+      newProp = container.get(elementInfo.fieldName);
       // XXX This QI should not be necessary, but XPConnect seems to fly
       // off the handle in the browser, and loses track of the interface
       // on large files. Bug 335638.
-      newProp.QueryInterface(Ci.nsIMutableArray);
-      newProp.appendElement(obj);
+      newProp.push(obj);
 
       // If new object is an nsIFeedContainer, we want to deal with
       // its member nsIPropertyBag instead.
-      if (isIFeedContainer(obj))
+      if (obj instanceof FeedContainer)
         newProp = obj.fields;
 
     } else {
       // If it doesn't, set it.
       if (!prop) {
-        container.setPropertyAsInterface(elementInfo.fieldName, obj);
+        container.set(elementInfo.fieldName, obj);
       }
-      newProp = container.getProperty(elementInfo.fieldName);
+      newProp = container.get(elementInfo.fieldName);
     }
 
     // make our new state name, and push the property onto the stack
     var newState = "IN_" + elementInfo.fieldName.toUpperCase();
     this._stack.push([newProp, newState, obj]);
     return newState;
   },
 
@@ -1524,37 +1398,37 @@ FeedProcessor.prototype = {
   // model for a given feed. We use helper functions to do the
   // munging, but we need to identify array types here, so the munging
   // happens only to the last element of an array.
   _closeComplexElement: function FP__closeComplexElement(elementInfo) {
     var stateTuple = this._stack.pop();
     var container = stateTuple[0];
     var containerParent = stateTuple[2];
     var element = null;
-    var isArray = isIArray(container);
+    var isArray = Array.isArray(container);
 
     // If it's an array and we have to post-process,
     // grab the last element
     if (isArray)
-      element = container.queryElementAt(container.length - 1, Ci.nsISupports);
+      element = container[container.length - 1];
     else
       element = container;
 
     // Run the post-processing function if there is one.
     if (elementInfo.closeFunc)
       element = elementInfo.closeFunc(this._buf, element);
 
     // If an nsIFeedContainer was on top of the stack,
     // we need to normalize it
-    if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID])
+    if (elementInfo.containerClass == Entry)
       containerParent.normalize();
 
     // If it's an array, re-set the last element
     if (isArray)
-      container.replaceElementAt(element, container.length - 1);
+      container[container.length - 1] = element;
   },
 
   _prefixForNS: function FP_prefixForNS(uri) {
     if (!uri)
       return "";
     var prefix = gNamespaces[uri];
     if (prefix)
       return prefix + ":";
@@ -1564,17 +1438,17 @@ FeedProcessor.prototype = {
   },
 
   _mapAttributes: function FP__mapAttributes(bag, attributes) {
     // Cycle through the attributes, and set our properties using the
     // prefix:localNames we find in our namespace dictionary.
     for (var i = 0; i < attributes.length; ++i) {
       var key = this._prefixForNS(attributes.getURI(i)) + attributes.getLocalName(i);
       var val = attributes.getValue(i);
-      bag.setPropertyAsAString(key, val);
+      bag.set(key, val);
     }
   },
 
   // Only for RSS2esque formats
   _findRSSVersion: function FP__findRSSVersion(attributes) {
     var versionAttr = attributes.getValueFromName("", "version").trim();
     var versions = { "0.91": "rss091",
                      "0.92": "rss092",
@@ -1604,26 +1478,23 @@ FeedProcessor.prototype = {
 
     // Grab the top of the stack
     var top = this._stack[this._stack.length - 1];
     if (!top)
       return;
 
     var container = top[0];
     // Grab the last element if it's an array
-    if (isIArray(container)) {
+    if (Array.isArray(container)) {
       var contract = this._handlerStack[this._depth].containerClass;
       // check if it's something specific, but not an entry
-      if (contract && contract != Cc[ENTRY_CONTRACTID]) {
-        var el = container.queryElementAt(container.length - 1,
-                                          Ci.nsIFeedElementBase);
+      if (contract && contract != Entry) {
+        var el = container[container.length - 1];
         // XXX there must be a way to flatten these interfaces
-        if (contract == Cc[PERSON_CONTRACTID])
-          el.QueryInterface(Ci.nsIFeedPerson);
-        else
+        if (contract != Person)
           return; // don't know about this interface
 
         let propName = localName;
         var prefix = gNamespaces[uri];
 
         // synonyms
         if ((uri == "" ||
              prefix &&
@@ -1643,29 +1514,27 @@ FeedProcessor.prototype = {
             el[propName] = propValue;
           }
         } catch (e) {
           // ignore XPConnect errors
         }
         // the rest of the function deals with entry- and feed-level stuff
         return;
       }
-      container = container.queryElementAt(container.length - 1,
-                                           Ci.nsIWritablePropertyBag2);
+      container = container[container.length - 1];
     }
 
     // Make the buffer our new property
     var propName = this._prefixForNS(uri) + localName;
 
     // But, it could be something containing HTML. If so,
     // we need to know about that.
     if (this._textConstructs[propName] != null &&
         this._handlerStack[this._depth].containerClass !== null) {
-      var newProp = Cc[TEXTCONSTRUCT_CONTRACTID].
-                    createInstance(Ci.nsIFeedTextConstruct);
+      var newProp = new TextConstruct();
       newProp.text = chars;
       // Look up the default type in our table
       var type = this._textConstructs[propName];
       var typeAttribute = attributes.getValueFromName("", "type");
       if (this._result.version == "atom" && typeAttribute != null) {
         type = typeAttribute;
       } else if (this._result.version == "atom03" && typeAttribute != null) {
         if (typeAttribute.toLowerCase().includes("xhtml")) {
@@ -1674,24 +1543,24 @@ FeedProcessor.prototype = {
           type = "html";
         } else if (typeAttribute.toLowerCase().includes("text")) {
           type = "text";
         }
       }
 
       // If it's rss feed-level description, it's not supposed to have html
       if (this._result.version.includes("rss") &&
-          this._handlerStack[this._depth].containerClass != ENTRY_CONTRACTID) {
+          this._handlerStack[this._depth].containerClass != Entry) {
         type = "text";
       }
       newProp.type = type;
       newProp.base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
-      container.setPropertyAsInterface(propName, newProp);
+      container.set(propName, newProp);
     } else {
-      container.setPropertyAsAString(propName, chars);
+      container.set(propName, chars);
     }
   },
 
   // Sometimes, we'll hand off SAX handling duties to an XHTMLHandler
   // (see above) that will scrape out non-XHTML stuff, normalize
   // namespaces, and remove the wrapper div from Atom 1.0. When the
   // XHTMLHandler is done, it'll callback here.
   returnFromXHTMLHandler:
@@ -1701,35 +1570,27 @@ FeedProcessor.prototype = {
 
     // Grab the top of the stack
     var top = this._stack[this._stack.length - 1];
     if (!top)
       return;
     var container = top[0];
 
     // Assign the property
-    var newProp =  newProp = Cc[TEXTCONSTRUCT_CONTRACTID].
-                   createInstance(Ci.nsIFeedTextConstruct);
+    var newProp =  newProp = new TextConstruct();
     newProp.text = chars;
     newProp.type = "xhtml";
     newProp.base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
-    container.setPropertyAsInterface(this._prefixForNS(uri) + localName,
-                                     newProp);
+    container.set(this._prefixForNS(uri) + localName,
+                  newProp);
 
     // XHTML will cause us to peek too far. The XHTML handler will
     // send us an end element to call. RFC4287-valid feeds allow a
     // more graceful way to handle this. Unfortunately, we can't count
     // on compliance at this point.
     this.endElement(uri, localName, qName);
   },
 
-  // XPCOM stuff
-  classID: FP_CLASSID,
   QueryInterface: ChromeUtils.generateQI(
-    [Ci.nsIFeedProcessor, Ci.nsISAXContentHandler, Ci.nsISAXErrorHandler,
+    [Ci.nsISAXContentHandler, Ci.nsISAXErrorHandler,
      Ci.nsIStreamListener, Ci.nsIRequestObserver]
   )
 };
-
-var components = [FeedProcessor, FeedResult, Feed, Entry,
-                  TextConstruct, Generator, Person];
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
deleted file mode 100644
--- a/toolkit/components/feeds/FeedProcessor.manifest
+++ /dev/null
@@ -1,14 +0,0 @@
-component {072a5c3d-30c6-4f07-b87f-9f63d51403f2} FeedProcessor.js
-contract @mozilla.org/feed-result;1 {072a5c3d-30c6-4f07-b87f-9f63d51403f2}
-component {5d0cfa97-69dd-4e5e-ac84-f253162e8f9a} FeedProcessor.js
-contract @mozilla.org/feed;1 {5d0cfa97-69dd-4e5e-ac84-f253162e8f9a}
-component {8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f} FeedProcessor.js
-contract @mozilla.org/feed-entry;1 {8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f}
-component {b992ddcd-3899-4320-9909-924b3e72c922} FeedProcessor.js
-contract @mozilla.org/feed-textconstruct;1 {b992ddcd-3899-4320-9909-924b3e72c922}
-component {414af362-9ad8-4296-898e-62247f25a20e} FeedProcessor.js
-contract @mozilla.org/feed-generator;1 {414af362-9ad8-4296-898e-62247f25a20e}
-component {95c963b7-20b2-11db-92f6-001422106990} FeedProcessor.js
-contract @mozilla.org/feed-person;1 {95c963b7-20b2-11db-92f6-001422106990}
-component {26acb1f0-28fc-43bc-867a-a46aabc85dd4} FeedProcessor.js
-contract @mozilla.org/feed-processor;1 {26acb1f0-28fc-43bc-867a-a46aabc85dd4}
--- a/toolkit/components/feeds/moz.build
+++ b/toolkit/components/feeds/moz.build
@@ -4,31 +4,15 @@
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox', 'RSS Discovery and Preview')
 
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
 
-XPIDL_SOURCES += [
-    'nsIFeed.idl',
-    'nsIFeedContainer.idl',
-    'nsIFeedElementBase.idl',
-    'nsIFeedEntry.idl',
-    'nsIFeedGenerator.idl',
-    'nsIFeedListener.idl',
-    'nsIFeedPerson.idl',
-    'nsIFeedProcessor.idl',
-    'nsIFeedResult.idl',
-    'nsIFeedTextConstruct.idl',
-]
-
-XPIDL_MODULE = 'feeds'
-
-EXTRA_COMPONENTS += [
-    'FeedProcessor.js',
-    'FeedProcessor.manifest',
+EXTRA_JS_MODULES += [
+    'FeedProcessor.jsm',
 ]
 
 XPCSHELL_TESTS_MANIFESTS += [
     'test/xpcshell.ini'
 ]
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeed.idl
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIFeedContainer.idl"
-
-interface nsIArray;
-interface nsIFeedGenerator;
-
-/**
- * An nsIFeed represents a single Atom or RSS feed.
- */
-[scriptable, uuid(3b8aae33-80e2-4efa-99c8-a6c5b99f76ea)]
-interface nsIFeed : nsIFeedContainer
-{
-  /** 
-  * Uses description, subtitle, and extensions
-  * to generate a summary. 
-  */
-  attribute nsIFeedTextConstruct subtitle;
-
-  // All content classifies as a "feed" - it is the transport.
-  const unsigned long TYPE_FEED = 0;
-  const unsigned long TYPE_AUDIO = 1;
-  const unsigned long TYPE_IMAGE = 2;
-  const unsigned long TYPE_VIDEO = 4;
-
-  /**
-  * The type of feed. For example, a podcast would be TYPE_AUDIO.
-  */
-  readonly attribute unsigned long type;
-  
-  /**
-  * The total number of enclosures found in the feed.
-  */
-  attribute long enclosureCount;
-
-  /**
-  * The items or entries in feed.
-  */
-  attribute nsIArray items;
-
-  /**
-  * No one really knows what cloud is for.
-  *
-  * It supposedly enables some sort of interaction with an XML-RPC or
-  * SOAP service.
-  */
-  attribute nsIWritablePropertyBag2 cloud;
-
-  /**
-  * Information about the software that produced the feed.
-  */
-  attribute nsIFeedGenerator generator;
-
-  /**
-  * An image url and some metadata (as defined by RSS2).
-  *
-  */
-  attribute nsIWritablePropertyBag2 image;
-
-  /**
-  * No one really knows what textInput is for.
-  *
-  * See
-  * <http://www.cadenhead.org/workbench/news/2894/rss-joy-textinput>
-  * for more details.
-  */
-  attribute nsIWritablePropertyBag2 textInput;
-
-  /**
-  * Days to skip fetching. This field was supposed to designate
-  * intervals for feed fetching. It's not generally implemented. For
-  * example, if this array contained "Monday", aggregators should not
-  * fetch the feed on Mondays.
-  */
-  attribute nsIArray skipDays;
-
- /**
-  * Hours to skip fetching. This field was supposed to designate
-  * intervals for feed fetching. It's not generally implemented. See
-  * <http://blogs.law.harvard.edu/tech/rss> for more information.
-  */
-  attribute nsIArray skipHours;
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedContainer.idl
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIFeedElementBase.idl"
-
-interface nsIURI;
-interface nsIWritablePropertyBag2;
-interface nsIArray;
-interface nsIFeedTextConstruct;
-
-/**
- * A shared base for feeds and items, which are pretty similar,
- * but they have some divergent attributes and require
- * different convenience methods.
- */ 
-[scriptable, uuid(577a1b4c-b3d4-4c76-9cf8-753e6606114f)]
-interface nsIFeedContainer : nsIFeedElementBase
-{
-  /**
-  * Many feeds contain an ID distinct from their URI, and
-  * entries have standard fields for this in all major formats.
-  */
-  attribute AString id;
-
-  /**
-  * The fields found in the document. Common Atom
-  * and RSS fields are normalized. This includes some namespaced
-  * extensions such as dc:subject and content:encoded. 
-  * Consumers can avoid normalization by checking the feed type
-  * and accessing specific fields.
-  *
-  * Common namespaces are accessed using prefixes, like get("dc:subject");.
-  * See nsIFeedResult::registerExtensionPrefix.
-  */
-  attribute nsIWritablePropertyBag2 fields;
-
-  /**
-   * Sometimes there's no title, or the title contains markup, so take
-   * care in decoding the attribute.
-   */
-  attribute nsIFeedTextConstruct title;
-
-  /**
-  * Returns the primary link for the feed or entry.
-  */
-  attribute nsIURI link;
-
-  /**
-  * Returns all links for a feed or entry.
-  */
-  attribute nsIArray links;
-
-  /**
-  * Returns the categories found in a feed or entry.
-  */
-  attribute nsIArray categories;
-
-  /**
-   * The rights or license associated with a feed or entry.
-   */
-  attribute nsIFeedTextConstruct rights;
-
-  /**
-   * A list of nsIFeedPersons that authored the feed.
-   */
-  attribute nsIArray authors;
-
-  /**
-   * A list of nsIFeedPersons that contributed to the feed.
-   */
-  attribute nsIArray contributors;
-
-  /**
-   * The date the feed was updated, in RFC822 form. Parsable by JS
-   * and mail code.
-   */
-  attribute AString updated;
-
-  /**
-  * Syncs a container's fields with its convenience attributes.
-  */
-  void normalize();
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedElementBase.idl
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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"
-
-interface nsISAXAttributes;
-interface nsIURI;
-
-/**
- *  An nsIFeedGenerator represents the software used to create a feed.
- */ 
-[scriptable, uuid(5215291e-fa0a-40c2-8ce7-e86cd1a1d3fa)]
-interface nsIFeedElementBase : nsISupports
-{
-  /**
-   * The attributes found on the element. Most interfaces provide convenience
-   * accessors for their standard fields, so this useful only when looking for
-   * an extension.
-   */
-  attribute nsISAXAttributes attributes;
-
-  /**
-   * The baseURI for the Entry or Feed.
-   */
-  attribute nsIURI baseURI;
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedEntry.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIFeedContainer.idl"
-interface nsIArray;
-
-/**
- * An nsIFeedEntry represents an Atom or RSS entry/item. Summary
- * and/or full-text content may be available, but callers will have to
- * check both.
- */
-[scriptable, uuid(31bfd5b4-8ff5-4bfd-a8cb-b3dfbd4f0a5b)]
-interface nsIFeedEntry : nsIFeedContainer {
-
-  /**
-  * Uses description, subtitle, summary, content and extensions
-  * to generate a summary. 
-  * 
-  */
-  attribute nsIFeedTextConstruct summary;
-
-  /**
-   * The date the entry was published, in RFC822 form. Parsable by JS
-   * and mail code.
-   */
-  attribute AString published;
-
-  /**
-  * Uses atom:content and content:encoded to provide
-  * a 'full text' view of an entry.
-  *
-  */
-  attribute nsIFeedTextConstruct content;
-
-  /**
-  * Enclosures are podcasts, photocasts, etc.
-  */
-  attribute nsIArray enclosures;
-
-  /**
-  * Enclosures, etc. that might be displayed inline.
-  */
-  attribute nsIArray mediaContent;
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedGenerator.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIFeedElementBase.idl"
-
-interface nsIURI;
-
-/**
- *  An nsIFeedGenerator represents the software used to create a feed.
- */ 
-[scriptable, uuid(0fecd56b-bd92-481b-a486-b8d489cdd385)]
-interface nsIFeedGenerator : nsIFeedElementBase
-{
-  /**
-   * The name of the software.
-   */
-  attribute AString agent;
-
-  /**
-   * The version of the software.
-   */
-  attribute AString version;
-
-  /**
-   * A URI associated with the software.
-   */
-  attribute nsIURI uri;
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedListener.idl
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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"
-interface nsIFeedResult;
-interface nsIFeedEntry;
-
-/**
- * nsIFeedResultListener defines a callback used when feed processing
- * completes.
- */
-[scriptable, uuid(4d2ebe88-36eb-4e20-bcd1-997b3c1f24ce)]
-interface nsIFeedResultListener : nsISupports 
-{
-   /** 
-   * Always called, even after an error. There could be new feed-level
-   * data available at this point, if it followed or was interspersed
-   * with the items. Fire-and-Forget implementations only need this.
-   * 
-   * @param result
-   *        An object implementing nsIFeedResult representing the feed 
-   *        and its metadata. 
-   */
-   void handleResult(in nsIFeedResult result);
-};
-
-
-/**
- * nsIFeedProgressListener defines callbacks used during feed
- * processing.
- */
-[scriptable, uuid(ebfd5de5-713c-40c0-ad7c-f095117fa580)]
-interface nsIFeedProgressListener : nsIFeedResultListener {
-  
-   /**
-   * ReportError will be called in the event of fatal
-   * XML errors, or if the document is not a feed. The bozo 
-   * bit will be set if the error was due to a fatal error. 
-   * 
-   * @param errorText
-   *        A short description of the error.
-   * @param lineNumber
-   *        The line on which the error occurred.
-   */
-   void reportError(in AString errorText, in long lineNumber, 
-                    in boolean bozo);
-   
-   /**
-   * StartFeed will be called as soon as a reasonable start to
-   * a feed is detected. 
-   *  
-   * @param result
-   *        An object implementing nsIFeedResult representing the feed 
-   *        and its metadata. At this point, the result has version 
-   *        information.
-   */
-   void handleStartFeed(in nsIFeedResult result);
-
-   /**
-   * Called when the first entry/item is encountered. In Atom, all
-   * feed data is required to preceed the entries. In RSS, the data
-   * usually does. If the type is one of the entry/item-only types,
-   * this event will not be called.
-   *
-   * @param result
-   *        An object implementing nsIFeedResult representing the feed 
-   *        and its metadata. At this point, the result will likely have
-   *        most of its feed-level metadata.
-   */
-   void handleFeedAtFirstEntry(in nsIFeedResult result); 
-
-   /**
-   * Called after each entry/item. If the document is a standalone
-   * item or entry, this HandleFeedAtFirstEntry will not have been
-   * called. Also, this entry's parent field will be null.
-   * 
-   * @param entry
-   *        An object implementing nsIFeedEntry that represents the latest
-   *        entry encountered.
-   * @param result
-   *        An object implementing nsIFeedResult representing the feed 
-   *        and its metadata. 
-   */
-   void handleEntry(in nsIFeedEntry entry, in nsIFeedResult result);
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedPerson.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIFeedElementBase.idl"
-
-interface nsIURI;
-
-/**
- *  An nsIFeedPerson represents an author or contributor of a feed.
- */ 
-[scriptable, uuid(29cbd45f-f2d3-4b28-b557-3ab7a61ecde4)]
-interface nsIFeedPerson : nsIFeedElementBase
-{
-  /**
-   * The name of the person.
-   */
-  attribute AString name;
-
-  /**
-   * An email address associated with the person.
-   */
-  attribute AString email;
-
-  /**
-   * A URI associated with the person (e.g. a homepage).
-   */
-  attribute nsIURI uri;
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedProcessor.idl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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 "nsIStreamListener.idl"
-
-interface nsIURI;
-interface nsIFeedResultListener;
-interface nsIInputStream;
-
-/**
- * An nsIFeedProcessor parses feeds, triggering callbacks based on
- * their contents.
- */
-[scriptable, uuid(8a0b2908-21b0-45d7-b14d-30df0f92afc7)]
-interface nsIFeedProcessor : nsIStreamListener {
-
-  /**
-   * The listener that will respond to feed events. 
-   */
-  attribute nsIFeedResultListener listener;
-
-  // Level is where to listen for the extension, a constant: FEED,
-  // ENTRY, BOTH.
-  //
-  // XXX todo void registerExtensionHandler(in
-  // nsIFeedExtensionHandler, in long level);
-  
-  /**
-   * Parse a feed asynchronously. The caller must then call the
-   * nsIFeedProcessor's nsIStreamListener methods to drive the
-   * parse. Do not call the other parse methods during an asynchronous
-   * parse.
-   *
-   * @param requestObserver The observer to notify on start/stop. This
-   *                        argument can be null.
-   * @param uri The base URI.
-   */
-  void parseAsync(in nsIRequestObserver requestObserver, in nsIURI uri);
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedResult.idl
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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"
-interface nsIFeedContainer;
-interface nsIProperties;
-interface nsIURI;
-
-/**
- * The nsIFeedResult interface provides access to HTTP and parsing
- * metadata for a feed or entry.
- */
-[scriptable, uuid(7a180b78-0f46-4569-8c22-f3d720ea1c57)]
-interface nsIFeedResult : nsISupports {
-   
-  /** 
-  * The Feed parser will set the bozo bit when a feed triggers a fatal
-  * error during XML parsing. There may be entries and feed metadata
-  * that were parsed before the error.  Thanks to Tim Bray for
-  * suggesting this terminology.
-  * <http://www.tbray.org/ongoing/When/200x/2004/01/11/PostelPilgrim>
-  */
-  attribute boolean bozo;
-  
-  /**
-  * The parsed feed or entry. 
-  *
-  * Will be null if a non-feed is processed.
-  */
-  attribute nsIFeedContainer doc;
-
-  /** 
-  * The address from which the feed was fetched. 
-  */
-  attribute nsIURI uri;
-
-  /** 
-  * Feed Version: 
-  * atom, rss2, rss09, rss091, rss091userland, rss092, rss1, atom03, 
-  * atomEntry, rssItem
-  *
-  * Will be null if a non-feed is processed.
-  */
-  attribute AString version;
-
-  /**
-  * An XSLT stylesheet available to transform the source of the
-  * feed. Some feeds include this information in a processing
-  * instruction. It's generally intended for clients with specific
-  * feed capabilities.
-  */
-  attribute nsIURI stylesheet;
-
-  /**
-  * HTTP response headers that accompanied the feed. 
-  */
-  attribute nsIProperties headers;
-
-  /**
-  * Registers a prefix used to access an extension in the feed/entry 
-  */
-  void registerExtensionPrefix(in AString aNamespace, in AString aPrefix);
-};
deleted file mode 100644
--- a/toolkit/components/feeds/nsIFeedTextConstruct.idl
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; 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"
-
-interface nsIURI;
-
-webidl DocumentFragment;
-webidl Element;
-
-/**
- * nsIFeedTextConstructs represent feed text fields that can contain
- * one of text, HTML, or XHTML. Some extension elements also have "type"
- * parameters, and this interface could be used there as well.
- */ 
-[scriptable, uuid(fc97a2a9-d649-4494-931e-db81a156c873)]
-interface nsIFeedTextConstruct : nsISupports 
-{
-  /**
-   * If the text construct contains (X)HTML, relative references in
-   * the content should be resolved against this base URI.
-   */
-  attribute nsIURI base;
-
-  /**
-   * The language of the text. For example, "en-US" for US English.
-   */
-  attribute AString lang;
-
-  /**
-   * One of "text", "html", or "xhtml". If the type is (x)html, a '<'
-   * character represents markup. To display that character, an escape
-   * such as &lt; must be used. If the type is "text", the '<'
-   * character represents the character itself, and such text should
-   * not be embedded in markup without escaping it first.
-   */
-  attribute AString type;
-
-  /**
-   * The content of the text construct.
-   */
-  attribute AString text;
-
-  /**
-   * Returns the text of the text construct, with all markup stripped 
-   * and all entities decoded. If the type attribute's value is "text",
-   * this function returns the value of the text attribute unchanged.
-   */
-  AString plainText();
-
-  /**
-   * Return an nsIDocumentFragment containing the text and markup.
-   */
-  DocumentFragment createDocumentFragment(in Element element);
-};
- 
--- a/toolkit/components/feeds/test/head.js
+++ b/toolkit/components/feeds/test/head.js
@@ -1,13 +1,15 @@
 "use strict";
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 
+ChromeUtils.import("resource://gre/modules/FeedProcessor.jsm");
+
 function readTestData(testFile) {
   var testcase = {};
 
   // Got a feed file, now we need to parse out the Description and Expect headers.
   var istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   try {
     istream.init(testFile, 0x01, parseInt("0444", 8), 0);
     istream.QueryInterface(Ci.nsILineInputStream);
--- a/toolkit/components/feeds/test/test_xml.js
+++ b/toolkit/components/feeds/test/test_xml.js
@@ -31,28 +31,25 @@ ChromeUtils.import("resource://gre/modul
 // were parsed correctly.
 function FeedListener(testcase) {
   this.testcase = testcase;
 }
 
 FeedListener.prototype = {
   handleResult(result) {
     var feed = result.doc;
-    try {
-      info("Testing feed " + this.testcase.file.path);
-      Assert.ok(isIID(feed, Ci.nsIFeed), "Has feed interface");
+
+    info("Testing feed " + this.testcase.file.path);
+    Assert.ok(feed, "Feed exists");
 
-      // eslint-disable-next-line no-eval
-      if (!eval(this.testcase.expect)) {
-        Assert.ok(false, "expect failed for " + this.testcase.desc);
-      } else {
-        Assert.ok(true, "expect passed for " + this.testcase.desc);
-      }
-    } catch (e) {
-      Assert.ok(false, "expect failed for " + this.testcase.desc + " ---- " + e.message);
+    // eslint-disable-next-line no-eval
+    if (!eval(this.testcase.expect)) {
+      Assert.ok(false, "expect failed for " + this.testcase.desc);
+    } else {
+      Assert.ok(true, "expect passed for " + this.testcase.desc);
     }
 
     run_next_test();
   }
 };
 
 function createTest(data) {
   return function() {
@@ -61,17 +58,17 @@ function createTest(data) {
     if (data.base == null) {
       uri = NetUtil.newURI("http://example.org/" + data.path);
     } else {
       uri = data.base;
     }
 
     info("Testing " + data.file.leafName);
 
-    var parser = Cc["@mozilla.org/feed-processor;1"].createInstance(Ci.nsIFeedProcessor);
+    var parser = new FeedProcessor();
     var stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
     stream.init(data.file, 0x01, parseInt("0444", 8), 0);
     var bStream = Cc["@mozilla.org/network/buffered-input-stream;1"].createInstance(Ci.nsIBufferedInputStream);
     bStream.init(stream, 4096);
     parser.listener = new FeedListener(data);
 
     try {
       let channel = Cc["@mozilla.org/network/input-stream-channel;1"].
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_author.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_author.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
+Expect: feed.items[0].authors[0].name=='John Doe Entry';
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_content.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_content.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry summary works
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.plainText() == "test content";
+Expect: feed.items[1].content.plainText() == "test content";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_content_encoded.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_content_encoded.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content:encoded and xhtml works
-Expect: var content = feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.plainText(); content == "should appear";
+Expect: var content = feed.items[1].content.plainText(); content == "should appear";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux"
       xmlns:content="http://purl.org/rss/1.0/modules/content/">
 
   <title>hmm</title>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_content_html.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_content_html.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content html works
-Expect: var content = feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.plainText(); content == "test content";
+Expect: var content = feed.items[1].content.plainText(); content == "test content";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content xhtml works
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.plainText() == "test content";
+Expect: feed.items[1].content.plainText() == "test content";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml_with_markup.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_content_xhtml_with_markup.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content xhtml works
-Expect: var content = feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.text; content == "<b>test</b> content";
+Expect: var content = feed.items[1].content.text; content == "<b>test</b> content";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_contributor.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_contributor.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe Entry';
+Expect: feed.items[0].contributors[0].name=='John Doe Entry';
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_html_cdata.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_html_cdata.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: HTML title w/ CDATA
-Expect: var title = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).title.plainText(); title == "<title>";
+Expect: var title = feed.items[0].title.plainText(); title == "<title>";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 <id>http://atomtests.philringnalda.com/tests/item/title/html-cdata.atom</id>
 <title>Atom item title html cdata</title>
 <updated>2005-12-18T00:13:00Z</updated>
 <author>
   <name>Phil Ringnalda</name>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_id.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_id.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry id
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).id == "http://foo.example.com/hmm/ok,2006,07,11";
+Expect: feed.items[1].id == "http://foo.example.com/hmm/ok,2006,07,11";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore2.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_2alts_allcore2.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_IANA.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_IANA.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with IANA URI link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_alt_extension.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_alt_extension.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item enclosure works
-Expect: var links = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('links'); links.QueryInterface(Components.interfaces.nsIArray); var link = links.queryElementAt(0, Components.interfaces.nsIPropertyBag2); ((link.getProperty('length') == '24986239') && (link.getProperty('type') == 'audio/mpeg') && (link.getProperty('href') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
+Expect: var links = feed.items[0].fields.get('links'); var link = links[0]; ((link.get('length') == '24986239') && (link.get('type') == 'audio/mpeg') && (link.get('href') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure_populate_enclosures.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_enclosure_populate_enclosures.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item enclosure added to enclosures
-Expect: var encs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).enclosures; encs.QueryInterface(Components.interfaces.nsIArray); var enc = encs.queryElementAt(0, Components.interfaces.nsIPropertyBag2); ((enc.getProperty('length') == '24986239') && (enc.getProperty('type') == 'audio/mpeg') && (enc.getProperty('url') == 'http://dallas.example.com/joebob_050689.mp3'));
+Expect: var encs = feed.items[0].enclosures; var enc = encs[0]; ((enc.get('length') == '24986239') && (enc.get('type') == 'audio/mpeg') && (enc.get('url') == 'http://dallas.example.com/joebob_050689.mp3'));
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_otherURI_alt.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_otherURI_alt.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_payment_alt.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_payment_alt.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_link_random.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_link_random.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with random link relations
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.snellspace.com/public/linktests/alternate";
+Expect: feed.items[0].link.spec == "http://www.snellspace.com/public/linktests/alternate";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:snellspace.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-01-18T15:10:00Z</updated>
   <author><name>James Snell</name></author>
   <link href="http://www.intertwingly.net/wiki/pie/LinkConformanceTests" />
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_published.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_published.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom published works
-Expect: var entry = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry); entry.published == 'Tue, 09 Dec 2003 18:30:02 GMT'
+Expect: var entry = feed.items[0]; entry.published == 'Tue, 09 Dec 2003 18:30:02 GMT'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_rights_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_rights_normalized.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry rights works normalized
-Expect:      feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).rights.plainText() == "test rights"
+Expect:      feed.items[0].rights.plainText() == "test rights"
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
   </title>
   <entry>
     <rights type="xhtml">
       <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> rights</div>
     </rights>
   </entry>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_summary.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_summary.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry summary xhtml works
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).summary.plainText() == "test summary";
+Expect: feed.items[1].summary.plainText() == "test summary";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux"
       xmlns:content="http://purl.org/rss/1.0/modules/content/">
 
   <title>hmm</title>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_title.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_title.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom feed and entry with random attributes works
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).title.text == "test";
+Expect: feed.items[1].title.text == "test";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_title_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_title_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry title normalized
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).title.text == "test";
+Expect: feed.items[1].title.text == "test";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_updated.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_updated.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom updated works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
+Expect: feed.items[0].updated == 'Sat, 13 Dec 2003 18:30:02 GMT'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_w_content_encoded.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_w_content_encoded.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content:encoded and xhtml works
-Expect: var content = feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).content.text; content == "<b>test</b> content";
+Expect: var content = feed.items[1].content.text; content == "<b>test</b> content";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux"
       xmlns:content="http://purl.org/rss/1.0/modules/content/">
 
   <title>hmm</title>
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_xhtml_baseURI_with_amp.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_xhtml_baseURI_with_amp.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry content xhtml works with a base URI that contains an ampersand.
 Base: http://www.travellerspoint.com/photo_gallery_feed.cfm?tags=Canada&onlyShowFeatured=true
-Expect: var frag = null; var content = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).content; Cu.importGlobalProperties(["DOMParser"]);  var parser = new DOMParser(); var doc = parser.parseFromString("<div/>", "text/xml"); frag = content.createDocumentFragment(doc.documentElement); notEqual(frag, null, "frag is not null"); true;
+Expect: var frag = null; var content = feed.items[0].content; Cu.importGlobalProperties(["DOMParser"]);  var parser = new DOMParser(); var doc = parser.parseFromString("<div/>", "text/xml"); frag = content.createDocumentFragment(doc.documentElement); notEqual(frag, null, "frag is not null"); true;
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://www.example.org"
       foo:quux="quuux">
 
   <title>hmm</title>
 
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with xml:base
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.example.org/foo";
+Expect: feed.items[0].link.spec == "http://www.example.org/foo";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <id>tag:example.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-06-18T6:23:00Z</updated>
   <link href="http://www.example.org" />
   
--- a/toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase_on_link.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/entry_xmlBase_on_link.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom entry with xml:base
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == "http://www.example.org/bar/foo";
+Expect: feed.items[0].link.spec == "http://www.example.org/bar/foo";
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <id>tag:example.com,2006:/atom/conformance/linktest/</id>
   <title>Atom Link Tests</title>
   <updated>2005-06-18T16:13:00Z</updated>
   <link href="http://www.example.org" />
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_atom_rights_xhtml.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_atom_rights_xhtml.xml
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom rights works with HTML
-Expect: feed.fields.getProperty('atom:rights') != null
+Expect: feed.fields.get('atom:rights') != null
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
   </title>
   <rights type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><i>test</i> rights</div>
   </rights>
   <summary type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><div><div>test</div> summary</div></div>
   </summary>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_email.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_email.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email=='hmm@example.com';
+Expect: feed.authors[0].email=='hmm@example.com';
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 <title>test title</title>
 <author>
 <email>hmm@example.com</email>
 <name>foo</name>
 </author>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_email_2.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_email_2.xml
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).email=='bar@example.com';
+Expect: feed.authors[1].email=='bar@example.com';
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 <title>test title</title>
 <author>
 <email>hmm@example.com</email>
 <name>foo</name>
 </author>
 <author>
 <email>bar@example.com</email>
 <name>foo</name>
 </author>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_name.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_name.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='foo';
+Expect: feed.authors[0].name=='foo';
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 <title>test title</title>
 <author>
 <name>foo</name>
 </author>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_surrounded.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_surrounded.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name=='John Doe';
+Expect: feed.authors[0].name=='John Doe';
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_author_uri.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_author_uri.xml
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author uri works
-Expect: feed.authors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec =='http://example.com/';
+Expect: feed.authors[1].uri.spec =='http://example.com/';
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
 <title>test title</title>
 <author>
 <email>hmm@example.com</email>
 <name>foo</name>
 <uri>http://example.org</uri>
 </author>
 <author>
 <email>bar@example.com</email>
 <name>foo</name>
 <uri>http://example.com/</uri>
 </author>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_comment_rss_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_comment_rss_extra_att.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: wfw works with extra attribute
-Expect: feed.fields.getProperty('wfw:commentRss') == 'http://example.org'
+Expect: feed.fields.get('wfw:commentRss') == 'http://example.org'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://example.org"
       xmlns:bla="http://wellformedweb.org/CommentAPI/">
 
   <title>Example Feed</title>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_contributor.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_contributor.xml
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom contributor uri works
-Expect: feed.contributors.queryElementAt(1, Components.interfaces.nsIFeedPerson).uri.spec=='http://example.com/';
+Expect: feed.contributors[1].uri.spec=='http://example.com/';
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title>test title</title>
   <contributor>
     <email>hmm@example.com</email>
     <name>foo</name>
     <uri>http://example.org</uri>
   </contributor>
   <contributor>
     <email>bar@example.com</email>
     <name>foo</name>
     <uri>http://example.com</uri>
   </contributor>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_icon.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_icon.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom icon works
-Expect: feed.fields.getProperty('atom:icon') == 'http://example.org/favicon.ico'
+Expect: feed.fields.get('atom:icon') == 'http://example.org/favicon.ico'
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title>test title</title>
   <icon>http://example.org/favicon.ico</icon>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_id.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_id.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom author name works
-Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' && feed.id == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
+Expect: feed.fields.get('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' && feed.id == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_id_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_id_extra_att.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom feed id works with extra attribute
-Expect: feed.fields.getProperty('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
+Expect: feed.fields.get('atom:id') == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom"
       xmlns:foo="http://example.org">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_logo.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_logo.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom logo works
-Expect: feed.image.getProperty('url') == 'http://example.org/logo.jpg'
+Expect: feed.image.get('url') == 'http://example.org/logo.jpg'
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title>test title</title>
   <logo xml:base="http://example.org/">logo.jpg</logo>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom rights works
-Expect:      feed.fields.getProperty('atom:rights') != null
+Expect:      feed.fields.get('atom:rights') != null
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
   </title>
   <rights type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> rights</div>
   </rights>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml_nested_divs.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_rights_xhtml_nested_divs.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: atom rights works with nested divs
-Expect: feed.fields.getProperty('atom:rights') != null
+Expect: feed.fields.get('atom:rights') != null
 
 -->
 <feed xmlns="http://www.w3.org/2005/Atom">
   <title type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><b>test</b> title</div>
   </title>
   <rights type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml"><div><div>test</div> rights</div></div>
   </rights>
-</feed>
\ No newline at end of file
+</feed>
--- a/toolkit/components/feeds/test/xml/rfc4287/feed_updated.xml
+++ b/toolkit/components/feeds/test/xml/rfc4287/feed_updated.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: raw atom updated works
-Expect: feed.fields.getProperty('atom:updated') == '2003-12-13T18:30:02Z'
+Expect: feed.fields.get('atom:updated') == '2003-12-13T18:30:02Z'
 
 -->
 
 <feed xmlns="http://www.w3.org/2005/Atom">
 
   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
--- a/toolkit/components/feeds/test/xml/rss1/feed_description.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_description.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed description works
-Expect: feed.fields.getProperty('rss1:description') == 'a description'
+Expect: feed.fields.get('rss1:description') == 'a description'
 
 -->
 <rdf:RDF 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns="http://purl.org/rss/1.0/"
 >
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
     <link>http://xml.com/pub</link>
     <description>a description</description>
   </channel>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/feed_image.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_image.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ image
-Expect: ((feed.image.getProperty('rss1:link') == 'http://www.xml.com') && (feed.image.getProperty('rss1:url') == 'http://xml.com/universal/images/xml_tiny.gif'))
+Expect: ((feed.image.get('rss1:link') == 'http://www.xml.com') && (feed.image.get('rss1:url') == 'http://xml.com/universal/images/xml_tiny.gif'))
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
 
   <channel rdf:about="http://www.xml.com/xml/news.rss">
@@ -31,9 +31,9 @@ Expect: ((feed.image.getProperty('rss1:l
       infrastructure of the Internet.
     </dc:description>
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
     <dc:subject>XML</dc:subject>
   </item> 
 
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/feed_link.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_link.xml
@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed title works normalized
-Expect: feed.fields.getProperty('rss1:link') == 'http://xml.com/pub'
+Expect: feed.fields.get('rss1:link') == 'http://xml.com/pub'
 
 -->
 <rdf:RDF 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns="http://purl.org/rss/1.0/"
 >
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
     <link>http://xml.com/pub</link>
   </channel>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/feed_textInput.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_textInput.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ textinput
-Expect: feed.textInput.getProperty('rdf:about') == 'http://search.xml.com'
+Expect: feed.textInput.get('rdf:about') == 'http://search.xml.com'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -32,9 +32,9 @@ Expect: feed.textInput.getProperty('rdf:
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
     <dc:subject>XML</dc:subject>
   </item> 
   <item>
 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/feed_title.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_title.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed title works
-Expect: feed.fields.getProperty('rss1:title') == 'Test'
+Expect: feed.fields.get('rss1:title') == 'Test'
 
 -->
 <rdf:RDF 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns="http://purl.org/rss/1.0/"
 >
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
   </channel>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/feed_title_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rss1/feed_title_extra_att.xml
@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed title works
-Expect: feed.fields.getProperty('rss1:title') == 'Test'
+Expect: feed.fields.get('rss1:title') == 'Test'
 
 -->
 <rdf:RDF 
     xmlns:foo="http://example.org"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns="http://purl.org/rss/1.0/"
 >
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title foo:bar="baz">Test</title>
   </channel>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_2_dc_description.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_2_dc_description.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item 2 dc:description
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).fields.getProperty('dc:description') == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.'
+Expect: feed.items[1].fields.get('dc:description') == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -26,9 +26,9 @@ Expect: feed.items.queryElementAt(1, Com
     <dc:subject>XML</dc:subject>-->
   </item> 
   <item>
    <dc:description>
       XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
     </dc:description>
     <title>XML: A Disruptive Technology</title> 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item 2 dc:publisher
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).fields.getProperty('dc:publisher') == 'The O\'Reilly Network'
+Expect: feed.items[1].fields.get('dc:publisher') == 'The O\'Reilly Network'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -27,9 +27,9 @@ Expect: feed.items.queryElementAt(1, Com
   </item> 
   <item>
  <dc:publisher>The O'Reilly Network</dc:publisher>
    <dc:description>
       XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
     </dc:description>
     <title>XML: A Disruptive Technology</title> 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher_extra_att_invalid_rdf.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_2_dc_publisher_extra_att_invalid_rdf.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item 2 dc:publisher
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).fields.getProperty('dc:publisher') == 'The O\'Reilly Network'
+Expect: feed.items[1].fields.get('dc:publisher') == 'The O\'Reilly Network'
 
 -->
 <rdf:RDF 
  xmlns:foo="http://example.org"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
@@ -28,9 +28,9 @@ Expect: feed.items.queryElementAt(1, Com
   </item> 
   <item>
  <dc:publisher foo:bar="baz">The O'Reilly Network</dc:publisher>
    <dc:description>
       XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
     </dc:description>
     <title>XML: A Disruptive Technology</title> 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_dc_creator.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_dc_creator.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item dc:description
-Expect: var author = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors.queryElementAt(0, Components.interfaces.nsIFeedPerson); (author.name == "Simon St.Laurent" && author.email == "simonstl@simonstl.com")
+Expect: var author = feed.items[0].authors[0]; (author.name == "Simon St.Laurent" && author.email == "simonstl@simonstl.com")
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -26,9 +26,9 @@ Expect: var author = feed.items.queryEle
   </item> 
   <item>
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:description>
       XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
     </dc:description>
     <title>XML: A Disruptive Technology</title> 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_dc_description.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_dc_description.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item dc:description
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('dc:description') == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.'
+Expect: feed.items[0].fields.get('dc:description') == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -27,9 +27,9 @@ Expect: feed.items.queryElementAt(0, Com
   </item> 
   <item>
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:description>
       XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet 2.
     </dc:description>
     <title>XML: A Disruptive Technology</title> 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_dc_description_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_dc_description_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item dc:description
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.plainText() == 'XML is...'
+Expect: feed.items[0].summary.plainText() == 'XML is...'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
--- a/toolkit/components/feeds/test/xml/rss1/item_description.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_description.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item desc normalized
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.plainText() == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.'
+Expect: feed.items[0].summary.plainText() == 'XML is placing increasingly heavy loads on the existing technical infrastructure of the Internet.'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
--- a/toolkit/components/feeds/test/xml/rss1/item_id.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_id.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item rdf:about
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).id == 'http://example.com/hmm'
+Expect: feed.items[0].id == 'http://example.com/hmm'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
--- a/toolkit/components/feeds/test/xml/rss1/item_link.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_link.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item link
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('rss1:link') == 'http://c.moreover.com/click/here.pl?r123'
+Expect: feed.items[0].fields.get('rss1:link') == 'http://c.moreover.com/click/here.pl?r123'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -24,9 +24,9 @@ Expect: feed.items.queryElementAt(0, Com
    <!-- <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
     <dc:subject>XML</dc:subject>-->
   </item> 
   <item>
 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_link_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_link_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item link
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == 'http://c.moreover.com/click/here.pl?r123'
+Expect: feed.items[0].link.spec == 'http://c.moreover.com/click/here.pl?r123'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -24,9 +24,9 @@ Expect: feed.items.queryElementAt(0, Com
    <!-- <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
     <dc:subject>XML</dc:subject>-->
   </item> 
   <item>
 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_title.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_title.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item title
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('rss1:title') == 'XML: A Disruptive Technology'
+Expect: feed.items[0].fields.get('rss1:title') == 'XML: A Disruptive Technology'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
@@ -23,9 +23,9 @@ Expect: feed.items.queryElementAt(0, Com
     </dc:description>
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:subject>XML</dc:subject>-->
   </item> 
   <item>
 
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss1/item_title_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_title_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item title normalized
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).title.text == 'XML: A Disruptive Technology'
+Expect: feed.items[0].title.text == 'XML: A Disruptive Technology'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
     <title>Test</title>
--- a/toolkit/components/feeds/test/xml/rss1/item_updated_dcterms.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_updated_dcterms.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed updated
-Expect:  feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
+Expect:  feed.items[0].updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'
  xmlns:dcterms='http://purl.org/dc/terms/'>
   <channel rdf:about="http://www.xml.com/xml/news.rss">
--- a/toolkit/components/feeds/test/xml/rss1/item_wiki_importance_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rss1/item_wiki_importance_extra_att.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: RSS1 feed w/ item wiki:importance with extra attribute
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).fields.getProperty('wiki:importance') == 'major'
+Expect: feed.items[1].fields.get('wiki:importance') == 'major'
 
 -->
 <rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc='http://purl.org/dc/elements/1.1/'
  xmlns:w="http://purl.org/rss/1.0/modules/wiki/"
  xmlns:foo="http://example.org">
@@ -26,9 +26,9 @@ Expect: feed.items.queryElementAt(1, Com
     <dc:publisher>The O'Reilly Network</dc:publisher>
     <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
     <dc:rights>Copyright &#169; 2000 O'Reilly &amp; Associates, Inc.</dc:rights>
     <dc:subject>XML</dc:subject>-->
   </item> 
   <item>
     <w:importance foo:bar="baz">major</w:importance>
   </item>
-</rdf:RDF>
\ No newline at end of file
+</rdf:RDF>
--- a/toolkit/components/feeds/test/xml/rss2/feed_category.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_category.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel category works 
-Expect:      feed.categories.queryElementAt(0, Components.interfaces.nsIPropertyBag).getProperty('term') == 'hmm'
+Expect:      feed.categories[0].get('term') == 'hmm'
 
 -->
 <rss version="2.0" >
 <channel>
 <category>hmm</category>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_cloud.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_cloud.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel cloud works
-Expect:      ((feed.cloud.getProperty('domain')=="rpc.sys.com") && (feed.cloud.getProperty('port')=="80") && (feed.cloud.getProperty('path')=="/RPC2") && (feed.cloud.getProperty('registerProcedure')=="pingMe") && (feed.cloud.getProperty('protocol')=="soap"))
+Expect:      ((feed.cloud.get('domain')=="rpc.sys.com") && (feed.cloud.get('port')=="80") && (feed.cloud.get('path')=="/RPC2") && (feed.cloud.get('registerProcedure')=="pingMe") && (feed.cloud.get('protocol')=="soap"))
 
 -->
 <rss version="2.0" >
 <channel>
 <cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_copyright.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_copyright.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.fields.getProperty('copyright') == 'copyright 2006'
+Expect:      feed.fields.get('copyright') == 'copyright 2006'
 
 -->
 <rss version="2.0" >
 <channel>
 <copyright>copyright 2006</copyright>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_copyright_linebreak.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_copyright_linebreak.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.fields.getProperty('copyright') == 'copyright 2005'
+Expect:      feed.fields.get('copyright') == 'copyright 2005'
 
 -->
 <rss version="2.0" >
 <channel>
 <copyright>copyright 2005
 
 
 </copyright>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_data_outside_channel.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_data_outside_channel.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.fields.getProperty('copyright') == 'copyright 2006'
+Expect:      feed.fields.get('copyright') == 'copyright 2006'
 
 -->
 <rss version="2.0" >
 <dc:creator xmlns:dc="http://example.org">heynow</dc:creator>
 <channel>
 <copyright>copyright 2006</copyright>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_dc_contributor.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_dc_contributor.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.contributors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name == 'them';
+Expect:      feed.contributors[0].name == 'them';
 
 -->
 <rss version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 <dc:contributor>them</dc:contributor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_dc_creator.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_dc_creator.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect: feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).name == 'me'
+Expect: feed.authors[0].name == 'me'
 
 -->
 <rss version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_description.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_description.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel description works 
-Expect: var desc = feed.fields.getProperty('description'); desc == 'test';
+Expect: var desc = feed.fields.get('description'); desc == 'test';
 
 -->
 <rss version="2.0" >
 <channel>
 <description>test</description>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_description_html.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_description_html.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel description works w/html
-Expect:      feed.fields.getProperty('description') == '<b>test</b>'
+Expect:      feed.fields.get('description') == '<b>test</b>'
 
 -->
 <rss version="2.0" >
 <channel>
 <description>&lt;b>test&lt;/b></description>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_description_html_cdata.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_description_html_cdata.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel description works w/ html & CDATA 
-Expect:      feed.fields.getProperty('description') == '<b>test</b>'
+Expect:      feed.fields.get('description') == '<b>test</b>'
 
 -->
 <rss version="2.0" >
 <channel>
 <description><![CDATA[<b>test</b>]]></description>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_docs.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_docs.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel docs works
-Expect:      feed.fields.getProperty('docs') == 'http://example.org'
+Expect:      feed.fields.get('docs') == 'http://example.org'
 
 -->
 <rss version="2.0" >
 <channel>
 <docs>http://example.org</docs>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_image_desc.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_image_desc.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel image description and required fields work
-Expect: ((feed.image.getProperty('title') == 'A picture') && (feed.image.getProperty('link') == 'http://example.org') && (feed.image.getProperty('url') == 'http://example.org/a.jpg') && (feed.image.getProperty('description') == 'Yo!'))
+Expect: ((feed.image.get('title') == 'A picture') && (feed.image.get('link') == 'http://example.org') && (feed.image.get('url') == 'http://example.org/a.jpg') && (feed.image.get('description') == 'Yo!'))
 
 -->
 <rss version="2.0" >
 <channel>
 <image>
   <link>http://example.org</link>
   <title>A picture</title>
   <url>http://example.org/a.jpg</url>
   <description>Yo!</description>
 </image>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_image_desc_width_height.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_image_desc_width_height.xml
@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel image required fields work
-Expect: ((feed.image.getProperty('title') == 'A picture') && (feed.image.getProperty('link') == 'http://example.org') && (feed.image.getProperty('url') == 'http://example.org/a.jpg') && (feed.image.getProperty('description') == 'Yo!') && (feed.image.getProperty('width') == '42') && (feed.image.getProperty('height') == '43'))
+Expect: ((feed.image.get('title') == 'A picture') && (feed.image.get('link') == 'http://example.org') && (feed.image.get('url') == 'http://example.org/a.jpg') && (feed.image.get('description') == 'Yo!') && (feed.image.get('width') == '42') && (feed.image.get('height') == '43'))
 
 -->
 <rss version="2.0" >
 <channel>
 <image>
   <link>http://example.org</link>
   <title>A picture</title>
   <url>http://example.org/a.jpg</url>
   <description>Yo!</description>
   <width>42</width>
   <height>43</height>
 </image>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_image_required.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_image_required.xml
@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel image required fields work
-Expect: ((feed.image.getProperty('title') == 'A picture') && (feed.image.getProperty('link') == 'http://example.org') && (feed.image.getProperty('url') == 'http://example.org/a.jpg'))
+Expect: ((feed.image.get('title') == 'A picture') && (feed.image.get('link') == 'http://example.org') && (feed.image.get('url') == 'http://example.org/a.jpg'))
 
 -->
 <rss version="2.0" >
 <channel>
 <image>
   <link>http://example.org</link>
   <title>A picture</title>
   <url>http://example.org/a.jpg</url>
 </image>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_language.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_language.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel language works 
-Expect:      feed.fields.getProperty('language') == 'en-us'
+Expect:      feed.fields.get('language') == 'en-us'
 
 -->
 <rss version="2.0" >
 <channel>
 <language>en-us</language>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_lastBuildDate.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_lastBuildDate.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel lastBuildDate works 
-Expect:      feed.fields.getProperty('lastBuildDate') == 'Sat, 07 Sep 2002 00:00:01 GMT'
+Expect:      feed.fields.get('lastBuildDate') == 'Sat, 07 Sep 2002 00:00:01 GMT'
 
 -->
 <rss version="2.0" >
 <channel>
 <lastBuildDate>Sat, 07 Sep 2002 00:00:01 GMT</lastBuildDate>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_managingEditor.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_managingEditor.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel managingEditor works 
-Expect:      feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email == 'example@example.com'
+Expect:      feed.authors[0].email == 'example@example.com'
 
 -->
 <rss version="2.0" >
 <channel>
 <managingEditor>example@example.com</managingEditor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_managingEditor_extra_att.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_managingEditor_extra_att.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel managingEditor works 
-Expect:      feed.authors.queryElementAt(0, Components.interfaces.nsIFeedPerson).email == 'example@example.com'
+Expect:      feed.authors[0].email == 'example@example.com'
 
 -->
 <rss version="2.0" >
 <channel>
 <managingEditor foo:bar="baz" xmlns:foo="http://example.org">example@example.com</managingEditor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_multiple_categories.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_multiple_categories.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel category works 
-Expect:      feed.categories.queryElementAt(2, Components.interfaces.nsIPropertyBag).getProperty('term') == 'hmm2'
+Expect:      feed.categories[2].get('term') == 'hmm2'
 
 -->
 <rss version="2.0" >
 <channel>
 <category>hmm0</category>
 <category>hmm1</category>
 <category>hmm2</category>
 <category>hmm3</category>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_pubDate.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_pubDate.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel pubDate works 
-Expect:      feed.fields.getProperty('pubDate') == 'Sat, 07 Sep 2002 00:00:01 GMT'
+Expect:      feed.fields.get('pubDate') == 'Sat, 07 Sep 2002 00:00:01 GMT'
 
 -->
 <rss version="2.0" >
 <channel>
 <pubDate>Sat, 07 Sep 2002 00:00:01 GMT</pubDate>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_rating.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_rating.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel rating works
-Expect: feed.fields.getProperty('rating') == '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l by "webmaster@example.com" on "2006.01.29T10:09-0800" r (n 0 s 0 v 0 l 0))'
+Expect: feed.fields.get('rating') == '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l by "webmaster@example.com" on "2006.01.29T10:09-0800" r (n 0 s 0 v 0 l 0))'
 
 -->
 <rss version="2.0" >
 <channel>
 <rating>(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l by "webmaster@example.com" on "2006.01.29T10:09-0800" r (n 0 s 0 v 0 l 0))</rating>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_skipDays.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_skipDays.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel skipDays works
-Expect: ((feed.skipDays.queryElementAt(0, Components.interfaces.nsISupportsString) == 'Sunday') && (feed.skipDays.queryElementAt(1, Components.interfaces.nsISupportsString) == 'Monday'))
+Expect: ((feed.skipDays[0] == 'Sunday') && (feed.skipDays[1] == 'Monday'))
 
 -->
 <rss version="2.0" >
 <channel>
 <skipDays>
   <day>Sunday</day>
   <day>Monday</day>
 </skipDays>
--- a/toolkit/components/feeds/test/xml/rss2/feed_skipHours.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_skipHours.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel skipHours works
-Expect: ((feed.skipHours.queryElementAt(0, Components.interfaces.nsISupportsString) == '0') && (feed.skipHours.queryElementAt(4, Components.interfaces.nsISupportsString) == '23'))
+Expect: ((feed.skipHours[0] == '0') && (feed.skipHours[4] == '23'))
 
 -->
 <rss version="2.0" >
 <channel>
 <skipHours>
   <hour>0</hour>
   <hour>1</hour>
   <hour>2</hour>
--- a/toolkit/components/feeds/test/xml/rss2/feed_textinput.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_textinput.xml
@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel textInput works
-Expect: ((feed.textInput.getProperty('description') == 'Your aggregator supports the textInput element. What software are you using?') && (feed.textInput.getProperty('link') == 'http://www.cadenhead.org/textinput.php') && (feed.textInput.getProperty('name') == 'query') && (feed.textInput.getProperty('title') == 'TextInput Inquiry'))
+Expect: ((feed.textInput.get('description') == 'Your aggregator supports the textInput element. What software are you using?') && (feed.textInput.get('link') == 'http://www.cadenhead.org/textinput.php') && (feed.textInput.get('name') == 'query') && (feed.textInput.get('title') == 'TextInput Inquiry'))
 
 -->
 <rss version="2.0" >
 <channel>
 <textInput>
   <description>Your aggregator supports the textInput element. What software are you using?</description>
   <link>http://www.cadenhead.org/textinput.php</link>
   <name>query</name>
   <title>TextInput Inquiry</title>
 </textInput>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_ttl.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_ttl.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel ttl works
-Expect: feed.fields.getProperty('ttl') == '60'
+Expect: feed.fields.get('ttl') == '60'
 
 -->
 <rss version="2.0" >
 <channel>
 <ttl>60</ttl>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_webMaster.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_webMaster.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel webMaster works 
-Expect:      feed.fields.getProperty('webMaster') == 'example@example.com'
+Expect:      feed.fields.get('webMaster') == 'example@example.com'
 
 -->
 <rss version="2.0" >
 <channel>
 <webMaster>example@example.com</webMaster>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_wfw_commentapi.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_wfw_commentapi.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.fields.getProperty('wfw:comment') == 'http://example.org'
+Expect:      feed.fields.get('wfw:comment') == 'http://example.org'
 
 -->
 <rss xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <wfw:comment>http://example.org</wfw:comment>
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 <dc:contributor>them</dc:contributor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_wfw_commentrss.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_wfw_commentrss.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel copyright works 
-Expect:      feed.fields.getProperty('wfw:commentRss') == 'http://example.org'
+Expect:      feed.fields.get('wfw:commentRss') == 'http://example.org'
 
 -->
 <rss xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 <wfw:commentRss>http://example.org</wfw:commentRss>
 <dc:contributor>them</dc:contributor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_wiki.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_wiki.xml
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel unusual prefixed ext works 
-Expect:      feed.fields.getProperty('wiki:version') == '1'
+Expect:      feed.fields.get('wiki:version') == '1'
  
 -->
 <rss 
 xmlns:w='http://purl.org/rss/1.0/modules/wiki/'
 xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 <w:version>1</w:version>
 <wfw:commentRss>http://example.org</wfw:commentRss>
 <dc:contributor>them</dc:contributor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/feed_wiki_unusual_prefix.xml
+++ b/toolkit/components/feeds/test/xml/rss2/feed_wiki_unusual_prefix.xml
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel unusual prefixed ext works 
-Expect:      feed.fields.getProperty('wiki:version') == '1'
+Expect:      feed.fields.get('wiki:version') == '1'
  
 -->
 <rss 
 xmlns:w='http://purl.org/rss/1.0/modules/wiki/'
 xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0" >
 <channel xmlns:dc="http://purl.org/dc/elements/1.1/">
 <copyright>copyright 2006</copyright>
 <dc:creator>me</dc:creator>
 <w:version>1</w:version>
 <wfw:commentRss>http://example.org</wfw:commentRss>
 <dc:contributor>them</dc:contributor>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/item_author.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_author.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item author works
-Expect: var authors = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).authors; var author = authors.queryElementAt(0, Components.interfaces.nsIFeedPerson); ((author.name == 'Joe Bob Briggs'));
+Expect: var authors = feed.items[0].authors; var author = authors[0]; ((author.name == 'Joe Bob Briggs'));
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
 </item>
--- a/toolkit/components/feeds/test/xml/rss2/item_category.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_category.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item category works
-Expect: var cats = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('categories'); cats.QueryInterface(Components.interfaces.nsIArray); var cat = cats.queryElementAt(0, Components.interfaces.nsIPropertyBag); ((cat.getProperty('domain') == 'foo') && (cat.getProperty('term') == 'bar'));
+Expect: var cats = feed.items[0].fields.get('categories'); var cat = cats[0]; ((cat.get('domain') == 'foo') && (cat.get('term') == 'bar'));
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
 <category domain="foo">bar</category>
--- a/toolkit/components/feeds/test/xml/rss2/item_comments.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_comments.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item comments works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('comments') == 'http://example.org'
+Expect: feed.items[0].fields.get('comments') == 'http://example.org'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <title>test</title>
 <!--<author>jbb@dallas.example.com (Joe Bob Briggs)</author>-->
 <comments>http://example.org</comments>
--- a/toolkit/components/feeds/test/xml/rss2/item_content_encoded.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_content_encoded.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item title works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).content.plainText() == 'foobar'
+Expect: feed.items[0].content.plainText() == 'foobar'
 
 -->
 <rss version="2.0" >
 <channel>
 <item xmlns:c="http://purl.org/rss/1.0/modules/content/">
   <title>test</title>
   <c:encoded>foobar</c:encoded>
 </item>
--- a/toolkit/components/feeds/test/xml/rss2/item_description.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc encoded works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
+Expect: feed.items[0].summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <comments>http://example.org</comments>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
--- a/toolkit/components/feeds/test/xml/rss2/item_description_2.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description_2.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc encoded works
-Expect: feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
+Expect: feed.items[1].summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
   <description>hmmm</description>
 </item>
 <item>
--- a/toolkit/components/feeds/test/xml/rss2/item_description_cdata.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description_cdata.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc CDATA works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
+Expect: feed.items[0].summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <comments>http://example.org</comments>
--- a/toolkit/components/feeds/test/xml/rss2/item_description_decode_entities.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description_decode_entities.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
 Description: item desc encoded, double-escaped entity
-Expect: var summary = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary; summary.plainText() == "test D\u00e9sol\u00e9e";
+Expect: var summary = feed.items[0].summary; summary.plainText() == "test D\u00e9sol\u00e9e";
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <comments>http://example.org</comments>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
--- a/toolkit/components/feeds/test/xml/rss2/item_description_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc encoded, normalied works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
+Expect: feed.items[0].summary.text == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <comments>http://example.org</comments>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
--- a/toolkit/components/feeds/test/xml/rss2/item_description_normalized_nohtml.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_description_normalized_nohtml.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc encoded, normalized works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.plainText() == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week Valley Girl came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
+Expect: feed.items[0].summary.plainText() == 'I\'m headed for France. I wasn\'t gonna go this year, but then last week Valley Girl came out and I said to myself, Joe Bob, you gotta get out of the country for a while.'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <comments>http://example.org</comments>
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <title>test</title>
--- a/toolkit/components/feeds/test/xml/rss2/item_enclosure.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_enclosure.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item enclosure works
-Expect: var enc = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('enclosure'); enc.QueryInterface(Components.interfaces.nsIPropertyBag); ((enc.getProperty('length') == '24986239') && (enc.getProperty('type') == 'audio/mpeg') && (enc.getProperty('url') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
+Expect: var enc = feed.items[0].fields.get('enclosure'); ((enc.get('length') == '24986239') && (enc.get('type') == 'audio/mpeg') && (enc.get('url') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_enclosure_duplicates2.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_enclosure_duplicates2.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: feed with duplicate enclosures on a single item with different data available
-Expect: var enc = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('enclosure'); enc.QueryInterface(Components.interfaces.nsIPropertyBag); ((enc.getProperty('length') == '24986239') && (enc.getProperty('type') == 'video/mpeg') && (feed.type == 4) && (feed.enclosureCount == 1) );
+Expect: var enc = feed.items[0].fields.get('enclosure'); ((enc.get('length') == '24986239') && (enc.get('type') == 'video/mpeg') && (feed.type == 4) && (feed.enclosureCount == 1) );
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 
 <item>
 <enclosure url="http://dallas.example.com/joebob_050689.mpeg" /> 
 <media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_050689.mpeg" /> 
--- a/toolkit/components/feeds/test/xml/rss2/item_guid.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid.xml
@@ -1,21 +1,21 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid works
-Expect: var guid = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('guid'); guid.QueryInterface(Components.interfaces.nsIPropertyBag2); guid.getProperty('guid') == 'asdf';
+Expect: var guid = feed.items[0].fields.get('guid'); guid.get('guid') == 'asdf';
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <comments>http://example.org</comments>
 <title>test</title>
 <guid>asdf</guid>
 <category domain="foo">bar</category>
 
 <description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description></item>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_bogus_url.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_bogus_url.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item copes with bogus guid
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link == null;
+Expect: feed.items[0].link == null;
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid works
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == 'http://www.example.org/';
+Expect: var link = feed.items[0].link; link.spec == 'http://www.example.org/';
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_default.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_default.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid works
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == 'http://www.example.org/';
+Expect: var link = feed.items[0].link; link.spec == 'http://www.example.org/';
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid should not map to link when isPermaLink=false
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link == null;
+Expect: var link = feed.items[0].link; link == null;
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false_uppercase.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_false_uppercase.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid should not map to link when isPermaLink=FaLsE
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link == null;
+Expect: var link = feed.items[0].link; link == null;
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_true_uppercase.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_true_uppercase.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid should map to link when isPermaLink=TrUe
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == "http://www.example.org/";
+Expect: var link = feed.items[0].link; link.spec == "http://www.example.org/";
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_unknown_value.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_isPermaLink_unknown_value.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid should map to link when isPermaLink=meatcake or other unknown values
-Expect: var link = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link; link.spec == "http://www.example.org/";
+Expect: var link = feed.items[0].link; link.spec == "http://www.example.org/";
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item guid works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).id == 'asdf';
+Expect: feed.items[0].id == 'asdf';
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_guid_with_link.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_guid_with_link.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item prefers link to guid
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == 'http://link.example.org/';
+Expect: feed.items[0].link.spec == 'http://link.example.org/';
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_link.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_link.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item comments works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('link') == 'http://dallas.example.com/1983/05/06/joebob.htm'
+Expect: feed.items[0].fields.get('link') == 'http://dallas.example.com/1983/05/06/joebob.htm'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <title>test</title>
 <!--<author>jbb@dallas.example.com (Joe Bob Briggs)</author>-->
 <comments>http://example.org</comments>
--- a/toolkit/components/feeds/test/xml/rss2/item_link_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_link_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item link normalized works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).link.spec == 'http://dallas.example.com/1983/05/06/joebob.htm'
+Expect: feed.items[0].link.spec == 'http://dallas.example.com/1983/05/06/joebob.htm'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 <title>test</title>
 <!--<author>jbb@dallas.example.com (Joe Bob Briggs)</author>-->
 <comments>http://example.org</comments>
--- a/toolkit/components/feeds/test/xml/rss2/item_plain_desc.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_plain_desc.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item desc plain text works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).summary.text == "I'm headed for France. I wasn't gonna go this year, but then last week \"Valley Girl\" came out and I said to myself, Joe Bob, you gotta get out of the country for a while."
+Expect: feed.items[0].summary.text == "I'm headed for France. I wasn't gonna go this year, but then last week \"Valley Girl\" came out and I said to myself, Joe Bob, you gotta get out of the country for a while."
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
 <comments>http://example.org</comments>
--- a/toolkit/components/feeds/test/xml/rss2/item_populated_enclosures.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_populated_enclosures.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item enclosure is added to enclosures array
-Expect: var encs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).enclosures; encs.QueryInterface(Components.interfaces.nsIArray); var enc = encs.queryElementAt(0, Components.interfaces.nsIPropertyBag2); ((enc.getProperty('length') == '24986239') && (enc.getProperty('type') == 'audio/mpeg') && (enc.getProperty('url') == 'http://dallas.example.com/joebob_050689.mp3'));
+Expect: var encs = feed.items[0].enclosures; var enc = encs[0]; ((enc.get('length') == '24986239') && (enc.get('type') == 'audio/mpeg') && (enc.get('url') == 'http://dallas.example.com/joebob_050689.mp3'));
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
 
 <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/item_pubDate.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_pubDate.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: entry pubDate works 
-Expect:      feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).published == 'Tue, 02 Sep 2003 00:00:01 GMT'
+Expect:      feed.items[0].published == 'Tue, 02 Sep 2003 00:00:01 GMT'
 
 -->
 <rss version="2.0" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
 <item>
 <pubDate>Tue, 02 Sep 2003 00:00:01 GMT</pubDate>
 </item>
 </channel>
--- a/toolkit/components/feeds/test/xml/rss2/item_published.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_published.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: entry published works 
-Expect:      feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).published == 'Sat, 07 Sep 2002 00:00:01 GMT'
+Expect:      feed.items[0].published == 'Sat, 07 Sep 2002 00:00:01 GMT'
 
 -->
 <rss version="2.0" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
 <item>
 <dcterms:issued>Sat, 07 Sep 2002 00:00:01 GMT</dcterms:issued>
 </item>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/item_title.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_title.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item title works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('title') == 'test'
+Expect: feed.items[0].fields.get('title') == 'test'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
   <title>test</title>
 </item>
 </channel>
--- a/toolkit/components/feeds/test/xml/rss2/item_title_normalized.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_title_normalized.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: item title works
-Expect: feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).title.text == 'test'
+Expect: feed.items[0].title.text == 'test'
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
   <title>test</title>
 </item>
 </channel>
--- a/toolkit/components/feeds/test/xml/rss2/item_updated_dcdate.xml
+++ b/toolkit/components/feeds/test/xml/rss2/item_updated_dcdate.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: channel pubDate works 
-Expect:      feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
+Expect:      feed.items[0].updated == 'Sat, 07 Sep 2002 00:00:01 GMT'
 
 -->
 <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
 <channel>
 <item>
 <dc:date>Sat, 07 Sep 2002 00:00:01 GMT</dc:date>
 </item>
 </channel>
-</rss>
\ No newline at end of file
+</rss>
--- a/toolkit/components/feeds/test/xml/rss2/items_2_titles.xml
+++ b/toolkit/components/feeds/test/xml/rss2/items_2_titles.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: 2 items title works
-Expect: ((feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).title.text == 'test') && (feed.items.queryElementAt(1, Components.interfaces.nsIFeedEntry).title.text == 'test #2'))
+Expect: ((feed.items[0].title.text == 'test') && (feed.items[1].title.text == 'test #2'))
 
 -->
 <rss version="2.0" >
 <channel>
 <item>
   <title>test</title>
 </item>
 <item>
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss content works
-Expect: var enc = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getPropertyAsInterface('mediacontent', Components.interfaces.nsIArray).queryElementAt(0, Components.interfaces.nsIPropertyBag); Assert.equal(enc.getProperty('fileSize'), '24986239', 'file size is correct'); Assert.equal(enc.getProperty('type'), 'video/mpeg', 'type is correct'); Assert.equal(enc.getProperty('url'), 'http://dallas.example.com/joebob_050689.mpeg', 'url is correct'); Assert.equal(feed.type, 4, 'Feed type is correct'); Assert.equal(feed.enclosureCount,1, 'Enclosure count is correct'); true;
+Expect: var enc = feed.items[0].fields.get('mediacontent')[0]; Assert.equal(enc.get('fileSize'), '24986239', 'file size is correct'); Assert.equal(enc.get('type'), 'video/mpeg', 'type is correct'); Assert.equal(enc.get('url'), 'http://dallas.example.com/joebob_050689.mpeg', 'url is correct'); Assert.equal(feed.type, 4, 'Feed type is correct'); Assert.equal(feed.enclosureCount,1, 'Enclosure count is correct'); true;
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_050689.mpeg" />
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content2.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content2.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss content with a thumbnail
-Expect: var enc = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getPropertyAsInterface('mediacontent', Components.interfaces.nsIArray).queryElementAt(0, Components.interfaces.nsIPropertyBag); Assert.equal(enc.getProperty('fileSize'), '24986239', 'file size is correct'); Assert.equal(enc.getProperty('type'), 'video/mpeg', 'type is correct'); Assert.equal(enc.getProperty('url'), 'http://dallas.example.com/joebob_050689.mpeg', 'url is correct'); Assert.equal(feed.type, 0, 'Feed type is correct'); Assert.equal(feed.enclosureCount,2, 'Enclosure count is correct'); true;
+Expect: var enc = feed.items[0].fields.get('mediacontent')[0]; Assert.equal(enc.get('fileSize'), '24986239', 'file size is correct'); Assert.equal(enc.get('type'), 'video/mpeg', 'type is correct'); Assert.equal(enc.get('url'), 'http://dallas.example.com/joebob_050689.mpeg', 'url is correct'); Assert.equal(feed.type, 0, 'Feed type is correct'); Assert.equal(feed.enclosureCount,2, 'Enclosure count is correct'); true;
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_050689.mpeg" />
 <media:thumbnail url="http://dallas.example.com/joebob_050689.jpg"  width="75" height="50"/>
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content_429049.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content_429049.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: this tests bug 429049.  the item with a valid url is added to the enclosures array and the item with an empty url does not.
-Expect: var encs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).enclosures; encs.QueryInterface(Components.interfaces.nsIArray); (encs.length == 1);
+Expect: var encs = feed.items[0].enclosures; (encs.length == 1);
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 
 <item>
 <media:content fileSize="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content_multiple.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content_multiple.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss content with multiple media:content items works
-Expect: var mcs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('mediacontent'); mcs.QueryInterface(Components.interfaces.nsIArray); var enc1 = mcs.queryElementAt(0, Components.interfaces.nsIPropertyBag); var enc2 = mcs.queryElementAt(1, Components.interfaces.nsIPropertyBag); ((enc1.getProperty('fileSize') == '24986239') && (enc1.getProperty('type') == 'video/mpeg') && (enc1.getProperty('url') == 'http://dallas.example.com/joebob_1.mpeg') && (enc2.getProperty('fileSize') == '30000000') && (enc2.getProperty('type') == 'video/mpeg') && (enc2.getProperty('url') == 'http://dallas.example.com/joebob_2.mpeg') && (feed.type == 4) && (feed.enclosureCount == 2));
+Expect: var mcs = feed.items[0].fields.get('mediacontent'); var enc1 = mcs[0]; var enc2 = mcs[1]; ((enc1.get('fileSize') == '24986239') && (enc1.get('type') == 'video/mpeg') && (enc1.get('url') == 'http://dallas.example.com/joebob_1.mpeg') && (enc2.get('fileSize') == '30000000') && (enc2.get('type') == 'video/mpeg') && (enc2.get('url') == 'http://dallas.example.com/joebob_2.mpeg') && (feed.type == 4) && (feed.enclosureCount == 2));
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:content fileSize="24986239" type="video/mpeg" url="http://dallas.example.com/joebob_1.mpeg" /> 
 <media:content fileSize="30000000" type="video/mpeg" url="http://dallas.example.com/joebob_2.mpeg" /> 
--- a/toolkit/components/feeds/test/xml/rss2/mrss_content_populate_enclosure.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_content_populate_enclosure.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss content added to enclosures array
-Expect: var encs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).enclosures; encs.QueryInterface(Components.interfaces.nsIArray); var enc = encs.queryElementAt(0, Components.interfaces.nsIPropertyBag); ((enc.getProperty('length') == '24986239') && (enc.getProperty('type') == 'audio/mpeg') && (enc.getProperty('url') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
+Expect: var encs = feed.items[0].enclosures; var enc = encs[0]; ((enc.get('length') == '24986239') && (enc.get('type') == 'audio/mpeg') && (enc.get('url') == 'http://dallas.example.com/joebob_050689.mp3') && (feed.type == 1) && (feed.enclosureCount == 1));
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:content fileSize="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" /> 
 <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
--- a/toolkit/components/feeds/test/xml/rss2/mrss_group_content.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_group_content.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss group content works
-Expect: var mg = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).fields.getProperty('mediagroup'); mg.QueryInterface(Components.interfaces.nsIPropertyBag); var mcs = mg.getProperty("mediacontent"); mcs.QueryInterface(Components.interfaces.nsIArray); var mc1 = mcs.queryElementAt(0, Components.interfaces.nsIPropertyBag); var mc2 = mcs.queryElementAt(1, Components.interfaces.nsIPropertyBag); ((mc1.getProperty('fileSize') == '400') && (mc1.getProperty('type') == 'audio/mpeg') && (mc1.getProperty('url') == 'http://dallas.example.com/joebob_050689_2.mp3') && (mc2.getProperty('fileSize') == '200') && (mc2.getProperty('type') == 'audio/mpeg') && (mc2.getProperty('url') == 'http://dallas.example.com/joebob_050689_1.mp3'));
+Expect: var mg = feed.items[0].fields.get('mediagroup'); var mcs = mg.get("mediacontent"); var mc1 = mcs[0]; var mc2 = mcs[1]; ((mc1.get('fileSize') == '400') && (mc1.get('type') == 'audio/mpeg') && (mc1.get('url') == 'http://dallas.example.com/joebob_050689_2.mp3') && (mc2.get('fileSize') == '200') && (mc2.get('type') == 'audio/mpeg') && (mc2.get('url') == 'http://dallas.example.com/joebob_050689_1.mp3'));
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:group>
   <media:content fileSize="400" type="audio/mpeg" url="http://dallas.example.com/joebob_050689_2.mp3" /> 
--- a/toolkit/components/feeds/test/xml/rss2/mrss_group_content_populate_enclosure.xml
+++ b/toolkit/components/feeds/test/xml/rss2/mrss_group_content_populate_enclosure.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 <!--
 
 Description: mrss group content works
-Expect: var encs = feed.items.queryElementAt(0, Components.interfaces.nsIFeedEntry).enclosures; encs.QueryInterface(Components.interfaces.nsIArray); var enc1 = encs.queryElementAt(0, Components.interfaces.nsIPropertyBag); var enc2 = encs.queryElementAt(1, Components.interfaces.nsIPropertyBag); ((enc1.getProperty('length') == '400') && (enc1.getProperty('type') == 'audio/mpeg') && (enc1.getProperty('url') == 'http://dallas.example.com/joebob_050689_2.mp3') && (enc2.getProperty('length') == '200') && (enc2.getProperty('type') == 'audio/mpeg') && (enc2.getProperty('url') == 'http://dallas.example.com/joebob_050689_1.mp3'));
+Expect: var encs = feed.items[0].enclosures; var enc1 = encs[0]; var enc2 = encs[1]; ((enc1.get('length') == '400') && (enc1.get('type') == 'audio/mpeg') && (enc1.get('url') == 'http://dallas.example.com/joebob_050689_2.mp3') && (enc2.get('length') == '200') && (enc2.get('type') == 'audio/mpeg') && (enc2.get('url') == 'http://dallas.example.com/joebob_050689_1.mp3'));
 
 
 -->
 <rss xmlns:media="http://search.yahoo.com/mrss" version="2.0" >
 <channel>
 <item>
 
 <media:group>
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -1,16 +1,18 @@
 /* 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/. */
 
 // Modules and services.
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.defineModuleGetter(this, "FeedProcessor",
+                               "resource://gre/modules/FeedProcessor.jsm");
 ChromeUtils.defineModuleGetter(this, "PlacesUtils",
                                "resource://gre/modules/PlacesUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "NetUtil",
                                "resource://gre/modules/NetUtil.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "history", function() {
   let livemarks = PlacesUtils.livemarks;
   // Lazily add an history observer when it's actually needed.
@@ -793,27 +795,27 @@ LivemarkLoadListener.prototype = {
         Services.scriptSecurityManager
                 .createCodebasePrincipal(this._livemark.feedURI, {});
 
       // Enforce well-formedness because the existing code does
       if (!aResult || !aResult.doc || aResult.bozo) {
         throw new Components.Exception("", Cr.NS_ERROR_FAILURE);
       }
 
-      let feed = aResult.doc.QueryInterface(Ci.nsIFeed);
+      let feed = aResult.doc;
       let siteURI = this._livemark.siteURI;
       if (feed.link && (!siteURI || !feed.link.equals(siteURI))) {
         siteURI = feed.link;
         this._livemark.writeSiteURI(siteURI);
       }
 
       // Insert feed items.
       let livemarkChildren = [];
       for (let i = 0; i < feed.items.length; ++i) {
-        let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
+        let entry = feed.items[i];
         let uri = entry.link || siteURI;
         if (!uri) {
           continue;
         }
 
         try {
           Services.scriptSecurityManager
                   .checkLoadURIWithPrincipal(feedPrincipal, uri,
@@ -846,18 +848,17 @@ LivemarkLoadListener.prototype = {
   onStartRequest(aRequest, aContext) {
     if (this._isAborted) {
       throw new Components.Exception("", Cr.NS_ERROR_UNEXPECTED);
     }
 
     let channel = aRequest.QueryInterface(Ci.nsIChannel);
     try {
       // Parse feed data as it comes in
-      this._processor = Cc["@mozilla.org/feed-processor;1"].
-                        createInstance(Ci.nsIFeedProcessor);
+      this._processor = new FeedProcessor();
       this._processor.listener = this;
       this._processor.parseAsync(null, channel.URI);
       this._processor.onStartRequest(aRequest, aContext);
     } catch (ex) {
       Cu.reportError("Livemark Service: feed processor received an invalid channel for " + channel.URI.spec);
       this.abort(ex);
     }
   },
@@ -908,16 +909,15 @@ LivemarkLoadListener.prototype = {
 
   // nsIInterfaceRequestor
   getInterface(aIID) {
     return this.QueryInterface(aIID);
   },
 
   // nsISupports
   QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIFeedResultListener,
     Ci.nsIStreamListener,
     Ci.nsIRequestObserver,
     Ci.nsIInterfaceRequestor
   ])
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([LivemarkService]);