Bug 784726 - 'Remove old IPC::URI'. r=cjones+khuey.
authorBen Turner <bent.mozilla@gmail.com>
Thu, 23 Aug 2012 12:33:46 -0700
changeset 103201 c813eeb62b92f836087e0a44aa8288b28d14050d
parent 103200 7f81af866697da01f611c31c07bb3847cfe52b2d
child 103202 9fbe008c291f3e983e5a3618c3b9a4f6f6dd2558
push id13877
push userbturner@mozilla.com
push dateThu, 23 Aug 2012 19:36:07 +0000
treeherdermozilla-inbound@c813eeb62b92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs784726
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 784726 - 'Remove old IPC::URI'. r=cjones+khuey.
content/base/src/nsDOMFile.cpp
dom/base/Navigator.cpp
dom/browser-element/BrowserElementParent.cpp
dom/indexedDB/ipc/IndexedDBChild.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PBlobStream.ipdl
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
dom/ipc/PContentPermissionRequest.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
image/decoders/icon/android/nsIconChannel.cpp
ipc/glue/IPCSerializableParams.ipdlh
ipc/glue/InputStreamParams.ipdlh
ipc/glue/InputStreamUtils.cpp
ipc/glue/InputStreamUtils.h
ipc/glue/Makefile.in
ipc/glue/URIParams.ipdlh
ipc/glue/URIUtils.cpp
ipc/glue/URIUtils.h
ipc/glue/ipdl.mk
ipc/glue/nsIIPCSerializableURI.h
ipc/ipdl/ipdl/type.py
ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl
modules/libjar/Makefile.in
modules/libjar/nsJARURI.cpp
modules/libjar/nsJARURI.h
modules/libjar/objs.mk
netwerk/base/public/Makefile.in
netwerk/base/public/nsIIPCSerializableObsolete.idl
netwerk/base/src/nsBufferedStreams.cpp
netwerk/base/src/nsFileStreams.cpp
netwerk/base/src/nsFileStreams.h
netwerk/base/src/nsMIMEInputStream.cpp
netwerk/base/src/nsSimpleNestedURI.cpp
netwerk/base/src/nsSimpleNestedURI.h
netwerk/base/src/nsSimpleURI.cpp
netwerk/base/src/nsSimpleURI.h
netwerk/base/src/nsStandardURL.cpp
netwerk/base/src/nsStandardURL.h
netwerk/cookie/CookieServiceChild.cpp
netwerk/cookie/CookieServiceParent.cpp
netwerk/cookie/CookieServiceParent.h
netwerk/cookie/PCookieService.ipdl
netwerk/ipc/NeckoMessageUtils.h
netwerk/protocol/about/nsAboutProtocolHandler.cpp
netwerk/protocol/about/nsAboutProtocolHandler.h
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/ftp/FTPChannelParent.cpp
netwerk/protocol/ftp/FTPChannelParent.h
netwerk/protocol/ftp/PFTPChannel.ipdl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/HttpChannelParent.h
netwerk/protocol/http/HttpChannelParentListener.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/websocket/PWebSocket.ipdl
netwerk/protocol/websocket/WebSocketChannelChild.cpp
netwerk/protocol/websocket/WebSocketChannelParent.cpp
netwerk/protocol/websocket/WebSocketChannelParent.h
netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
netwerk/protocol/wyciwyg/WyciwygChannelParent.h
toolkit/components/places/History.cpp
uriloader/exthandler/ExternalHelperAppParent.cpp
uriloader/exthandler/ExternalHelperAppParent.h
uriloader/exthandler/nsExternalHelperAppService.cpp
uriloader/prefetch/OfflineCacheUpdateChild.cpp
uriloader/prefetch/OfflineCacheUpdateParent.cpp
uriloader/prefetch/OfflineCacheUpdateParent.h
uriloader/prefetch/POfflineCacheUpdate.ipdl
widget/xpwidgets/nsFilePickerProxy.cpp
xpcom/io/nsMultiplexInputStream.cpp
xpcom/io/nsStringStream.cpp
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -13,17 +13,16 @@
 #include "nsICharsetDetector.h"
 #include "nsICharsetConverterManager.h"
 #include "nsIClassInfo.h"
 #include "nsIConverterInputStream.h"
 #include "nsIDocument.h"
 #include "nsIFileStreams.h"
 #include "nsIInputStream.h"
 #include "nsIIPCSerializableInputStream.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "nsIMIMEService.h"
 #include "nsIPlatformCharset.h"
 #include "nsISeekableStream.h"
 #include "nsIUnicharInputStream.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIUUIDGenerator.h"
@@ -43,68 +42,57 @@ using namespace mozilla::dom;
 
 // XXXkhuey the input stream that we pass out of a DOMFile
 // can outlive the actual DOMFile object.  Thus, we must
 // ensure that the buffer underlying the stream we get
 // from NS_NewByteInputStream is held alive as long as the
 // stream is.  We do that by passing back this class instead.
 class DataOwnerAdapter MOZ_FINAL : public nsIInputStream,
                                    public nsISeekableStream,
-                                   public nsIIPCSerializableObsolete,
-                                   public nsIClassInfo,
                                    public nsIIPCSerializableInputStream
 {
   typedef nsDOMMemoryFile::DataOwner DataOwner;
 public:
   static nsresult Create(DataOwner* aDataOwner,
                          uint32_t aStart,
                          uint32_t aLength,
                          nsIInputStream** _retval);
 
   NS_DECL_ISUPPORTS
 
   // These are mandatory.
   NS_FORWARD_NSIINPUTSTREAM(mStream->)
   NS_FORWARD_NSISEEKABLESTREAM(mSeekableStream->)
 
-  // These are optional. We use a conditional QI to keep them from being called
-  // if the underlying stream doesn't QI to either interface.
-  NS_FORWARD_NSIIPCSERIALIZABLEOBSOLETE(mSerializableObsolete->)
-  NS_FORWARD_NSICLASSINFO(mClassInfo->)
+  // This is optional. We use a conditional QI to keep it from being called
+  // if the underlying stream doesn't support it.
   NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(mSerializableInputStream->)
 
 private:
   DataOwnerAdapter(DataOwner* aDataOwner,
                    nsIInputStream* aStream)
     : mDataOwner(aDataOwner), mStream(aStream),
       mSeekableStream(do_QueryInterface(aStream)),
-      mSerializableObsolete(do_QueryInterface(aStream)),
-      mClassInfo(do_QueryInterface(aStream)),
       mSerializableInputStream(do_QueryInterface(aStream))
   {
     NS_ASSERTION(mSeekableStream, "Somebody gave us the wrong stream!");
   }
 
   nsRefPtr<DataOwner> mDataOwner;
   nsCOMPtr<nsIInputStream> mStream;
   nsCOMPtr<nsISeekableStream> mSeekableStream;
-  nsCOMPtr<nsIIPCSerializableObsolete> mSerializableObsolete;
-  nsCOMPtr<nsIClassInfo> mClassInfo;
   nsCOMPtr<nsIIPCSerializableInputStream> mSerializableInputStream;
 };
 
 NS_IMPL_THREADSAFE_ADDREF(DataOwnerAdapter)
 NS_IMPL_THREADSAFE_RELEASE(DataOwnerAdapter)
 
 NS_INTERFACE_MAP_BEGIN(DataOwnerAdapter)
   NS_INTERFACE_MAP_ENTRY(nsIInputStream)
   NS_INTERFACE_MAP_ENTRY(nsISeekableStream)
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableObsolete,
-                                     mSerializableObsolete)
-  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIClassInfo, mClassInfo)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
                                      mSerializableInputStream)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
 NS_INTERFACE_MAP_END
 
 nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
                                   uint32_t aStart,
                                   uint32_t aLength,
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -34,16 +34,18 @@
 #include "mozilla/Hal.h"
 #include "nsIWebNavigation.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
 #include "MobileConnection.h"
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
+#include "nsNetUtil.h"
+#include "nsIHttpChannel.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "MediaManager.h"
 #endif
 #ifdef MOZ_B2G_RIL
 #include "TelephonyFactory.h"
 #endif
 #ifdef MOZ_B2G_BT
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -12,16 +12,17 @@
 #undef CreateEvent
 #endif
 
 #include "BrowserElementParent.h"
 #include "nsHTMLIFrameElement.h"
 #include "nsOpenWindowEventDetail.h"
 #include "nsEventDispatcher.h"
 #include "nsIDOMCustomEvent.h"
+#include "nsIInterfaceRequestorUtils.h"
 #include "nsVariant.h"
 
 using mozilla::dom::Element;
 using mozilla::dom::TabParent;
 
 namespace {
 
 /**
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/basictypes.h"
 
 #include "IndexedDBChild.h"
 
 #include "nsIAtom.h"
+#include "nsIInputStream.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/ContentChild.h"
 
 #include "AsyncConnectionHelper.h"
 #include "DatabaseInfo.h"
 #include "IDBEvents.h"
 #include "IDBFactory.h"
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -89,16 +89,17 @@
 
 #include "mozilla/dom/indexedDB/PIndexedDBChild.h"
 #include "mozilla/dom/sms/SmsChild.h"
 #include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
 
 #include "nsDOMFile.h"
 #include "nsIRemoteBlob.h"
 #include "StructuredCloneUtils.h"
+#include "URIUtils.h"
 
 using namespace mozilla::docshell;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::sms;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
@@ -619,22 +620,22 @@ ContentChild::AllocPNecko()
 bool 
 ContentChild::DeallocPNecko(PNeckoChild* necko)
 {
     delete necko;
     return true;
 }
 
 PExternalHelperAppChild*
-ContentChild::AllocPExternalHelperApp(const IPC::URI& uri,
+ContentChild::AllocPExternalHelperApp(const OptionalURIParams& uri,
                                       const nsCString& aMimeContentType,
                                       const nsCString& aContentDisposition,
                                       const bool& aForceSave,
                                       const int64_t& aContentLength,
-                                      const IPC::URI& aReferrer)
+                                      const OptionalURIParams& aReferrer)
 {
     ExternalHelperAppChild *child = new ExternalHelperAppChild();
     child->AddRef();
     return child;
 }
 
 bool
 ContentChild::DeallocPExternalHelperApp(PExternalHelperAppChild* aService)
@@ -780,19 +781,22 @@ ContentChild::RecvNotifyAlertsObserver(c
             }
         }
         ++i;
     }
     return true;
 }
 
 bool
-ContentChild::RecvNotifyVisited(const IPC::URI& aURI)
+ContentChild::RecvNotifyVisited(const URIParams& aURI)
 {
-    nsCOMPtr<nsIURI> newURI(aURI);
+    nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
+    if (!newURI) {
+        return false;
+    }
     History::GetService()->NotifyVisited(newURI);
     return true;
 }
 
 bool
 ContentChild::RecvAsyncMessage(const nsString& aMsg,
                                      const ClonedMessageData& aData)
 {
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -17,32 +17,39 @@
 struct ChromePackage;
 class nsIDOMBlob;
 class nsIObserver;
 struct ResourceMapping;
 struct OverrideMapping;
 
 namespace mozilla {
 
+namespace ipc {
+class OptionalURIParams;
+class URIParams;
+}// namespace ipc
+
 namespace layers {
 class PCompositorChild;
-}
+} // namespace layers
 
 namespace dom {
 
 class AlertObserver;
 class PrefObserver;
 class ConsoleListener;
 class PStorageChild;
 class ClonedMessageData;
 
 class ContentChild : public PContentChild
 {
     typedef layers::PCompositorChild PCompositorChild;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
+    typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
+    typedef mozilla::ipc::URIParams URIParams;
 
 public:
     ContentChild();
     virtual ~ContentChild();
 
     struct AppInfo
     {
         nsCString version;
@@ -106,38 +113,38 @@ public:
                                      const int32_t&,
                                      const int32_t&);
     virtual bool DeallocPAudio(PAudioChild*);
 
     virtual PNeckoChild* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoChild*);
 
     virtual PExternalHelperAppChild *AllocPExternalHelperApp(
-            const IPC::URI& uri,
+            const OptionalURIParams& uri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const bool& aForceSave,
             const int64_t& aContentLength,
-            const IPC::URI& aReferrer);
+            const OptionalURIParams& aReferrer);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppChild *aService);
 
     virtual PSmsChild* AllocPSms();
     virtual bool DeallocPSms(PSmsChild*);
 
     virtual PStorageChild* AllocPStorage(const StorageConstructData& aData);
     virtual bool DeallocPStorage(PStorageChild* aActor);
 
     virtual bool RecvRegisterChrome(const InfallibleTArray<ChromePackage>& packages,
                                     const InfallibleTArray<ResourceMapping>& resources,
                                     const InfallibleTArray<OverrideMapping>& overrides,
                                     const nsCString& locale);
 
     virtual bool RecvSetOffline(const bool& offline);
 
-    virtual bool RecvNotifyVisited(const IPC::URI& aURI);
+    virtual bool RecvNotifyVisited(const URIParams& aURI);
     // auto remove when alertfinished is received.
     nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
 
     virtual bool RecvPreferenceUpdate(const PrefSetting& aPref);
 
     virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
 
     virtual bool RecvAsyncMessage(const nsString& aMsg,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -71,16 +71,17 @@
 #include "nsServiceManagerUtils.h"
 #include "nsSystemInfo.h"
 #include "nsThreadUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "SandboxHal.h"
 #include "StructuredCloneUtils.h"
 #include "TabParent.h"
+#include "URIUtils.h"
 
 #ifdef ANDROID
 # include "gfxAndroidPlatform.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
 # include "nsExceptionHandler.h"
 # include "nsICrashReporter.h"
@@ -1342,22 +1343,22 @@ ContentParent::AllocPNecko()
 bool 
 ContentParent::DeallocPNecko(PNeckoParent* necko)
 {
     delete necko;
     return true;
 }
 
 PExternalHelperAppParent*
-ContentParent::AllocPExternalHelperApp(const IPC::URI& uri,
+ContentParent::AllocPExternalHelperApp(const OptionalURIParams& uri,
                                        const nsCString& aMimeContentType,
                                        const nsCString& aContentDisposition,
                                        const bool& aForceSave,
                                        const int64_t& aContentLength,
-                                       const IPC::URI& aReferrer)
+                                       const OptionalURIParams& aReferrer)
 {
     ExternalHelperAppParent *parent = new ExternalHelperAppParent(uri, aContentLength);
     parent->AddRef();
     parent->Init(this, aMimeContentType, aContentDisposition, aForceSave, aReferrer);
     return parent;
 }
 
 bool
@@ -1419,53 +1420,62 @@ ContentParent::RequestRunToCompletion()
 #endif
         mRunToCompletionDepth = 1;
         mShouldCallUnblockChild = true;
     }
     return !!mRunToCompletionDepth;
 }
 
 bool
-ContentParent::RecvStartVisitedQuery(const IPC::URI& aURI)
+ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
 {
-    nsCOMPtr<nsIURI> newURI(aURI);
+    nsCOMPtr<nsIURI> newURI = DeserializeURI(aURI);
+    if (!newURI) {
+        return false;
+    }
     nsCOMPtr<IHistory> history = services::GetHistoryService();
     NS_ABORT_IF_FALSE(history, "History must exist at this point.");
     if (history) {
-      history->RegisterVisitedCallback(newURI, nullptr);
+        history->RegisterVisitedCallback(newURI, nullptr);
     }
     return true;
 }
 
 
 bool
-ContentParent::RecvVisitURI(const IPC::URI& uri,
-                                   const IPC::URI& referrer,
-                                   const uint32_t& flags)
+ContentParent::RecvVisitURI(const URIParams& uri,
+                            const OptionalURIParams& referrer,
+                            const uint32_t& flags)
 {
-    nsCOMPtr<nsIURI> ourURI(uri);
-    nsCOMPtr<nsIURI> ourReferrer(referrer);
+    nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
+    if (!ourURI) {
+        return false;
+    }
+    nsCOMPtr<nsIURI> ourReferrer = DeserializeURI(referrer);
     nsCOMPtr<IHistory> history = services::GetHistoryService();
     NS_ABORT_IF_FALSE(history, "History must exist at this point");
     if (history) {
-      history->VisitURI(ourURI, ourReferrer, flags);
+        history->VisitURI(ourURI, ourReferrer, flags);
     }
     return true;
 }
 
 
 bool
-ContentParent::RecvSetURITitle(const IPC::URI& uri,
-                                      const nsString& title)
+ContentParent::RecvSetURITitle(const URIParams& uri,
+                               const nsString& title)
 {
-    nsCOMPtr<nsIURI> ourURI(uri);
+    nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
+    if (!ourURI) {
+        return false;
+    }
     nsCOMPtr<IHistory> history = services::GetHistoryService();
     NS_ABORT_IF_FALSE(history, "History must exist at this point");
     if (history) {
-      history->SetURITitle(ourURI, title);
+        history->SetURITitle(ourURI, title);
     }
     return true;
 }
 
 bool
 ContentParent::RecvShowFilePicker(const int16_t& mode,
                                   const int16_t& selectedType,
                                   const bool& addToRecentDocs,
@@ -1536,22 +1546,26 @@ ContentParent::RecvShowFilePicker(const 
         file->GetPath(filePath);
         files->AppendElement(filePath);
     }
 
     return true;
 }
 
 bool
-ContentParent::RecvLoadURIExternal(const IPC::URI& uri)
+ContentParent::RecvLoadURIExternal(const URIParams& uri)
 {
     nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
-    if (!extProtService)
+    if (!extProtService) {
         return true;
-    nsCOMPtr<nsIURI> ourURI(uri);
+    }
+    nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
+    if (!ourURI) {
+        return false;
+    }
     extProtService->LoadURI(ourURI, nullptr);
     return true;
 }
 
 /* void onDispatchedEvent (in nsIThreadInternal thread); */
 NS_IMETHODIMP
 ContentParent::OnDispatchedEvent(nsIThreadInternal *thread)
 {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -27,37 +27,40 @@
 
 class mozIApplication;
 class nsFrameMessageManager;
 class nsIDOMBlob;
 
 namespace mozilla {
 
 namespace ipc {
+class OptionalURIParams;
+class URIParams;
 class TestShellParent;
-}
+} // namespace ipc
 
 namespace layers {
 class PCompositorParent;
-}
+} // namespace layers
 
 namespace dom {
 
 class TabParent;
 class PStorageParent;
 class ClonedMessageData;
 
 class ContentParent : public PContentParent
                     , public nsIObserver
                     , public nsIThreadObserver
                     , public nsIDOMGeoPositionCallback
 {
-private:
     typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
+    typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
     typedef mozilla::ipc::TestShellParent TestShellParent;
+    typedef mozilla::ipc::URIParams URIParams;
     typedef mozilla::layers::PCompositorParent PCompositorParent;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
     /**
      * Start up the content-process machinery.  This might include
      * scheduling pre-launch tasks.
      */
@@ -193,22 +196,22 @@ private:
                                      const int32_t&,
                                      const int32_t&);
     virtual bool DeallocPAudio(PAudioParent*);
 
     virtual PNeckoParent* AllocPNecko();
     virtual bool DeallocPNecko(PNeckoParent* necko);
 
     virtual PExternalHelperAppParent* AllocPExternalHelperApp(
-            const IPC::URI& uri,
+            const OptionalURIParams& aUri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const bool& aForceSave,
             const int64_t& aContentLength,
-            const IPC::URI& aReferrer);
+            const OptionalURIParams& aReferrer);
     virtual bool DeallocPExternalHelperApp(PExternalHelperAppParent* aService);
 
     virtual PSmsParent* AllocPSms();
     virtual bool DeallocPSms(PSmsParent*);
 
     virtual PStorageParent* AllocPStorage(const StorageConstructData& aData);
     virtual bool DeallocPStorage(PStorageParent* aActor);
 
@@ -221,23 +224,23 @@ private:
     virtual bool RecvGetClipboardText(const int32_t& whichClipboard, nsString* text);
     virtual bool RecvEmptyClipboard();
     virtual bool RecvClipboardHasText(bool* hasText);
 
     virtual bool RecvGetSystemColors(const uint32_t& colorsCount, InfallibleTArray<uint32_t>* colors);
     virtual bool RecvGetIconForExtension(const nsCString& aFileExt, const uint32_t& aIconSize, InfallibleTArray<uint8_t>* bits);
     virtual bool RecvGetShowPasswordSetting(bool* showPassword);
 
-    virtual bool RecvStartVisitedQuery(const IPC::URI& uri);
+    virtual bool RecvStartVisitedQuery(const URIParams& uri);
 
-    virtual bool RecvVisitURI(const IPC::URI& uri,
-                              const IPC::URI& referrer,
+    virtual bool RecvVisitURI(const URIParams& uri,
+                              const OptionalURIParams& referrer,
                               const uint32_t& flags);
 
-    virtual bool RecvSetURITitle(const IPC::URI& uri,
+    virtual bool RecvSetURITitle(const URIParams& uri,
                                  const nsString& title);
     
     virtual bool RecvShowFilePicker(const int16_t& mode,
                                     const int16_t& selectedType,
                                     const bool& addToRecentDocs,
                                     const nsString& title,
                                     const nsString& defaultFile,
                                     const nsString& defaultExtension,
@@ -246,17 +249,17 @@ private:
                                     InfallibleTArray<nsString>* files,
                                     int16_t* retValue,
                                     nsresult* result);
  
     virtual bool RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
                                            const nsString& aText, const bool& aTextClickable,
                                            const nsString& aCookie, const nsString& aName);
 
-    virtual bool RecvLoadURIExternal(const IPC::URI& uri);
+    virtual bool RecvLoadURIExternal(const URIParams& uri);
 
     virtual bool RecvSyncMessage(const nsString& aMsg,
                                  const ClonedMessageData& aData,
                                  InfallibleTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData);
 
     virtual bool RecvAddGeolocationListener();
--- a/dom/ipc/PBlobStream.ipdl
+++ b/dom/ipc/PBlobStream.ipdl
@@ -1,14 +1,14 @@
 /* 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 protocol PBlob;
-include IPCSerializableParams;
+include InputStreamParams;
 
 namespace mozilla {
 namespace dom {
 
 protocol PBlobStream
 {
   manager PBlob;
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -8,28 +8,26 @@
 include protocol PBlob;
 include protocol PContent;
 include protocol PContentDialog;
 include protocol PDocumentRenderer;
 include protocol PContentPermissionRequest;
 include protocol PRenderFrame;
 include protocol POfflineCacheUpdate;
 include protocol PIndexedDB;
+include DOMTypes;
+include URIParams;
 
 include "gfxMatrix.h";
 include "FrameMetrics.h";
 include "IPC/nsGUIEventIPC.h";
 include "mozilla/dom/TabMessageUtils.h";
 include "mozilla/dom/PermissionMessageUtils.h";
 include "mozilla/layout/RenderFrameUtils.h";
-include "mozilla/net/NeckoMessageUtils.h";
 
-include DOMTypes;
-
-using IPC::URI;
 using IPC::Principal;
 using gfxMatrix;
 using gfxRect;
 using gfxSize;
 using mozilla::layers::LayersBackend;
 using mozilla::layers::FrameMetrics;
 using mozilla::layout::ScrollingBehavior;
 using mozilla::WindowsHandle;
@@ -225,18 +223,18 @@ parent:
      *   Why this argument? If the document was not found in an offline cache 
      *   before load and refers a manifest and this manifest itself has not 
      *   been changed since the last fetch, we will not do the application 
      *   cache group update. But we must cache the document (identified by the
      *   documentURI). This argument will ensure that a previously uncached 
      *   document will get cached and that we don't re-cache a document that 
      *   has already been cached (stickDocument=false).
      */
-    POfflineCacheUpdate(URI manifestURI, URI documentURI, nsCString clientID,
-                        bool stickDocument);
+    POfflineCacheUpdate(URIParams manifestURI, URIParams documentURI,
+                        nsCString clientID, bool stickDocument);
 
     sync PIndexedDB(nsCString asciiOrigin)
         returns (bool allowed);
 
     /**
      * window.open from inside <iframe mozbrowser> is special.  When the child
      * process calls window.open, it creates a new PBrowser (in its own
      * process), then calls BrowserFrameOpenWindow on it.
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -13,32 +13,31 @@ include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PHal;
 include protocol PIndexedDB;
 include protocol PMemoryReportRequest;
 include protocol PNecko;
 include protocol PSms;
 include protocol PStorage;
 include protocol PTestShell;
+include DOMTypes;
+include URIParams;
 
 include "mozilla/chrome/RegistryMessageUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
 include "mozilla/dom/TabMessageUtils.h";
 
 include "nsGeoPositionIPCSerialiser.h";
 
-include DOMTypes;
-
 using GeoPosition;
 using PrefTuple;
 
 using ChromePackage;
 using ResourceMapping;
 using OverrideMapping;
-using IPC::URI;
 using IPC::Permission;
 using mozilla::null_t;
 using mozilla::void_t;
 using mozilla::dom::NativeThreadId;
 using gfxIntSize;
 
 namespace mozilla {
 namespace dom {
@@ -203,17 +202,17 @@ child:
      */
     SetProcessAttributes(uint64_t id, bool isForApp, bool isForBrowser);
 
     RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                    OverrideMapping[] overrides, nsCString locale);
 
     async SetOffline(bool offline);
 
-    async NotifyVisited(URI uri);
+    async NotifyVisited(URIParams uri);
 
     PreferenceUpdate(PrefSetting pref);
 
     NotifyAlertsObserver(nsCString topic, nsString data);
 
     GeolocationUpdate(GeoPosition somewhere);
 
     // nsIPermissionManager messages
@@ -254,47 +253,47 @@ parent:
     PNecko();
 
     PSms();
     
     PStorage(StorageConstructData data);
 
     // Services remoting
 
-    async StartVisitedQuery(URI uri);
-    async VisitURI(URI uri, URI referrer, uint32_t flags);
-    async SetURITitle(URI uri, nsString title);
+    async StartVisitedQuery(URIParams uri);
+    async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
+    async SetURITitle(URIParams uri, nsString title);
     
     // filepicker remoting
     sync ShowFilePicker(int16_t mode, int16_t selectedType, bool addToRecentDocs,
                         nsString title, nsString defaultFile, nsString defaultExtension,
                         nsString[] filters, nsString[] filterNames)
         returns (nsString[] files, int16_t retValue, nsresult result);
 
-    async LoadURIExternal(URI uri);
+    async LoadURIExternal(URIParams uri);
 
     // PrefService message
     sync ReadPrefsArray() returns (PrefSetting[] prefs);
 
     sync ReadFontList() returns (FontListEntry[] retValue);
 
     sync SyncMessage(nsString aMessage, ClonedMessageData aData)
       returns (nsString[] retval);
 
     ShowAlertNotification(nsString imageUrl, 
                           nsString title, 
                           nsString text, 
                           bool textClickable,
                           nsString cookie,
                           nsString name);
 
-    PExternalHelperApp(URI uri, nsCString aMimeContentType,
+    PExternalHelperApp(OptionalURIParams uri, nsCString aMimeContentType,
                        nsCString aContentDisposition, bool aForceSave,
-                       int64_t aContentLength, URI aReferrer);
-    
+                       int64_t aContentLength, OptionalURIParams aReferrer);
+
     AddGeolocationListener();
     RemoveGeolocationListener();
 
     ConsoleMessage(nsString message);
     ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                 uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                 nsCString category); 
 
@@ -322,9 +321,9 @@ parent:
     // Notify the parent of the presence or absence of private docshells
     PrivateDocShellsExist(bool aExist);
 
 both:
      AsyncMessage(nsString aMessage, ClonedMessageData aData);
 };
 
 }
-}
+}
\ No newline at end of file
--- a/dom/ipc/PContentPermissionRequest.ipdl
+++ b/dom/ipc/PContentPermissionRequest.ipdl
@@ -1,16 +1,13 @@
 /* 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 protocol PBrowser;
-include "mozilla/net/NeckoMessageUtils.h";
-
-using IPC::URI;
 
 namespace mozilla {
 namespace dom {
 
 protocol PContentPermissionRequest
 {
   manager PBrowser;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1025,18 +1025,18 @@ TabChild::RecvActivateFrameEvent(const n
   NS_ENSURE_TRUE(chromeHandler, true);
   nsRefPtr<ContentListener> listener = new ContentListener(this);
   NS_ENSURE_TRUE(listener, true);
   chromeHandler->AddEventListener(aType, listener, capture);
   return true;
 }
 
 POfflineCacheUpdateChild*
-TabChild::AllocPOfflineCacheUpdate(const URI& manifestURI,
-            const URI& documentURI,
+TabChild::AllocPOfflineCacheUpdate(const URIParams& manifestURI,
+            const URIParams& documentURI,
             const nsCString& clientID,
             const bool& stickDocument)
 {
   NS_RUNTIMEABORT("unused");
   return nullptr;
 }
 
 bool
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -240,18 +240,18 @@ public:
       child->mIPCOpen = true;
       return request;
     }
 #endif /* DEBUG */
 
     virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
 
-    virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URI& manifestURI,
-            const URI& documentURI,
+    virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URIParams& manifestURI,
+            const URIParams& documentURI,
             const nsCString& clientID,
             const bool& stickDocument);
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);
 
     nsIWebNavigation* WebNavigation() { return mWebNav; }
 
     JSContext* GetJSContext() { return mCx; }
 
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -949,18 +949,18 @@ TabParent::AllocPRenderFrame(ScrollingBe
 bool
 TabParent::DeallocPRenderFrame(PRenderFrameParent* aFrame)
 {
   delete aFrame;
   return true;
 }
 
 mozilla::docshell::POfflineCacheUpdateParent*
-TabParent::AllocPOfflineCacheUpdate(const URI& aManifestURI,
-                                    const URI& aDocumentURI,
+TabParent::AllocPOfflineCacheUpdate(const URIParams& aManifestURI,
+                                    const URIParams& aDocumentURI,
                                     const nsCString& aClientID,
                                     const bool& stickDocument)
 {
   nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
     new mozilla::docshell::OfflineCacheUpdateParent();
 
   nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aClientID,
                                  stickDocument);
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -154,18 +154,18 @@ public:
                            const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRenderer(PDocumentRendererParent* actor);
 
     virtual PContentPermissionRequestParent*
     AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
     virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestParent* actor);
 
     virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
-            const URI& aManifestURI,
-            const URI& aDocumentURI,
+            const URIParams& aManifestURI,
+            const URIParams& aDocumentURI,
             const nsCString& aClientID,
             const bool& stickDocument);
     virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateParent* actor);
 
     JSBool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIAUTHPROMPTPROVIDER
--- a/image/decoders/icon/android/nsIconChannel.cpp
+++ b/image/decoders/icon/android/nsIconChannel.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdlib.h>
 #include "mozilla/dom/ContentChild.h"
 #include "nsIURL.h"
 #include "nsXULAppAPI.h"
 #include "AndroidBridge.h"
 #include "nsIconChannel.h"
+#include "nsIStringStream.h"
+#include "nsNetUtil.h"
 
 NS_IMPL_ISUPPORTS2(nsIconChannel,
                    nsIRequest,
                    nsIChannel)
 
 using namespace mozilla;
 using mozilla::dom::ContentChild;
 
rename from ipc/glue/IPCSerializableParams.ipdlh
rename to ipc/glue/InputStreamParams.ipdlh
--- a/ipc/glue/IPCSerializableParams.ipdlh
+++ b/ipc/glue/InputStreamParams.ipdlh
@@ -62,11 +62,10 @@ struct MIMEInputStreamParams
 {
   OptionalInputStreamParams optionalStream;
   nsCString headers;
   nsCString contentLength;
   bool startedReading;
   bool addContentLength;
 };
 
-
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/InputStreamUtils.cpp
+++ b/ipc/glue/InputStreamUtils.cpp
@@ -37,24 +37,24 @@ SerializeInputStream(nsIInputStream* aIn
                      InputStreamParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aInputStream);
 
   nsCOMPtr<nsIIPCSerializableInputStream> serializable =
     do_QueryInterface(aInputStream);
   if (!serializable) {
-    NS_WARNING("Input stream is not serializable!");
-    return;
+    MOZ_NOT_REACHED("Input stream is not serializable!");
   }
 
   serializable->Serialize(aParams);
 
-  NS_WARN_IF_FALSE(aParams.type() != InputStreamParams::T__None,
-                   "Serialize failed!");
+  if (aParams.type() == InputStreamParams::T__None) {
+    MOZ_NOT_REACHED("Serialize failed!");
+  }
 }
 
 void
 SerializeInputStream(nsIInputStream* aInputStream,
                      OptionalInputStreamParams& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/ipc/glue/InputStreamUtils.h
+++ b/ipc/glue/InputStreamUtils.h
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ipc_InputStreamUtils_h
 #define mozilla_ipc_InputStreamUtils_h
 
-#include "mozilla/ipc/IPCSerializableParams.h"
+#include "mozilla/ipc/InputStreamParams.h"
 #include "nsCOMPtr.h"
 #include "nsIInputStream.h"
 
 namespace mozilla {
 namespace ipc {
 
 void
 SerializeInputStream(nsIInputStream* aInputStream,
--- a/ipc/glue/Makefile.in
+++ b/ipc/glue/Makefile.in
@@ -35,19 +35,23 @@ EXPORTS_mozilla/ipc = \
   SharedMemory.h \
   SharedMemoryBasic.h \
   SharedMemoryBasic_chromium.h \
   SharedMemorySysV.h \
   Shmem.h \
   SyncChannel.h \
   ScopedXREEmbed.h \
   Transport.h \
+  URIUtils.h \
   $(NULL)
 
-EXPORTS = nsIIPCSerializableInputStream.h
+EXPORTS = \
+  nsIIPCSerializableInputStream.h \
+  nsIIPCSerializableURI.h \
+  $(NULL)
 
 ifeq ($(OS_ARCH),WINNT) #{
 EXPORTS_mozilla/ipc += \
   Transport_win.h \
   $(NULL)
 else
 # POSIX
 EXPORTS_mozilla/ipc += \
@@ -74,16 +78,17 @@ CPPSRCS += \
   ProcessChild.cpp \
   ProtocolUtils.cpp \
   RPCChannel.cpp \
   ScopedXREEmbed.cpp \
   SharedMemory.cpp \
   Shmem.cpp \
   StringUtil.cpp \
   SyncChannel.cpp \
+  URIUtils.cpp \
   $(NULL)
 
 ifeq ($(OS_ARCH),WINNT) #{
 CPPSRCS += \
   SharedMemory_windows.cpp \
   Transport_win.cpp \
   WindowsMessageLoop.cpp \
   CrossProcessMutex_windows.cpp \
new file mode 100644
--- /dev/null
+++ b/ipc/glue/URIParams.ipdlh
@@ -0,0 +1,78 @@
+/* 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 "IPC/IPCMessageUtils.h";
+
+using mozilla::void_t;
+
+namespace mozilla {
+namespace ipc {
+
+struct SimpleURIParams
+{
+  nsCString scheme;
+  nsCString path;
+  nsCString ref;
+  bool isMutable;
+};
+
+struct StandardURLSegment
+{
+  uint32_t position;
+  int32_t length;
+};
+
+struct StandardURLParams
+{
+  uint32_t urlType;
+  int32_t port;
+  int32_t defaultPort;
+  nsCString spec;
+  StandardURLSegment scheme;
+  StandardURLSegment authority;
+  StandardURLSegment username;
+  StandardURLSegment password;
+  StandardURLSegment host;
+  StandardURLSegment path;
+  StandardURLSegment filePath;
+  StandardURLSegment directory;
+  StandardURLSegment baseName;
+  StandardURLSegment extension;
+  StandardURLSegment query;
+  StandardURLSegment ref;
+  nsCString originCharset;
+  bool isMutable;
+  bool supportsFileURL;
+  uint32_t hostEncoding;
+};
+
+struct JARURIParams
+{
+  URIParams jarFile;
+  URIParams jarEntry;
+  nsCString charset;
+};
+
+struct GenericURIParams
+{
+  nsCString spec;
+  nsCString charset;
+};
+
+union URIParams
+{
+  SimpleURIParams;
+  StandardURLParams;
+  JARURIParams;
+  GenericURIParams;
+};
+
+union OptionalURIParams
+{
+  void_t;
+  URIParams;
+};
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/URIUtils.cpp
@@ -0,0 +1,207 @@
+/* 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 "URIUtils.h"
+
+#include "nsIIPCSerializableURI.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Util.h"
+#include "nsComponentManagerUtils.h"
+#include "nsDebug.h"
+#include "nsID.h"
+#include "nsJARURI.h"
+#include "nsNetCID.h"
+#include "nsNetUtil.h"
+#include "nsThreadUtils.h"
+
+using namespace mozilla::ipc;
+using mozilla::ArrayLength;
+
+namespace {
+
+NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
+NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
+NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
+
+struct StringWithLengh
+{
+  const char* string;
+  size_t length;
+};
+
+#define STRING_WITH_LENGTH(_str) \
+  { _str, ArrayLength(_str) - 1 }
+
+const StringWithLengh kGenericURIAllowedSchemes[] = {
+  STRING_WITH_LENGTH("about:"),
+  STRING_WITH_LENGTH("javascript:"),
+  STRING_WITH_LENGTH("javascript")
+};
+
+#undef STRING_WITH_LENGTH
+
+} // anonymous namespace
+
+namespace mozilla {
+namespace ipc {
+
+void
+SerializeURI(nsIURI* aURI,
+             URIParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aURI);
+
+  nsCOMPtr<nsIIPCSerializableURI> serializable = do_QueryInterface(aURI);
+  if (serializable) {
+    serializable->Serialize(aParams);
+    if (aParams.type() == URIParams::T__None) {
+      MOZ_NOT_REACHED("Serialize failed!");
+    }
+    return;
+  }
+
+  nsCString scheme;
+  if (NS_FAILED(aURI->GetScheme(scheme))) {
+    MOZ_NOT_REACHED("This must never fail!");
+  }
+
+  bool allowed = false;
+
+  for (size_t i = 0; i < ArrayLength(kGenericURIAllowedSchemes); i++) {
+    const StringWithLengh& entry = kGenericURIAllowedSchemes[i];
+    if (scheme.EqualsASCII(entry.string, entry.length)) {
+      allowed = true;
+      break;
+    }
+  }
+
+  if (!allowed) {
+    MOZ_NOT_REACHED("All IPDL URIs must be serializable or an allowed "
+                    "scheme!");
+  }
+
+  GenericURIParams params;
+  if (NS_FAILED(aURI->GetSpec(params.spec())) ||
+      NS_FAILED(aURI->GetOriginCharset(params.charset()))) {
+    MOZ_NOT_REACHED("This must never fail!");
+  }
+
+  aParams = params;
+}
+
+void
+SerializeURI(nsIURI* aURI,
+             OptionalURIParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  if (aURI) {
+    URIParams params;
+    SerializeURI(aURI, params);
+    aParams = params;
+  }
+  else {
+    aParams = mozilla::void_t();
+  }
+}
+
+already_AddRefed<nsIURI>
+DeserializeURI(const URIParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIURI> uri;
+
+  if (aParams.type() != URIParams::TGenericURIParams) {
+    nsCOMPtr<nsIIPCSerializableURI> serializable;
+
+    switch (aParams.type()) {
+      case URIParams::TSimpleURIParams:
+        serializable = do_CreateInstance(kSimpleURICID);
+        break;
+
+      case URIParams::TStandardURLParams:
+        serializable = do_CreateInstance(kStandardURLCID);
+        break;
+
+      case URIParams::TJARURIParams:
+        serializable = do_CreateInstance(kJARURICID);
+        break;
+
+      default:
+        MOZ_NOT_REACHED("Unknown params!");
+    }
+
+    MOZ_ASSERT(serializable);
+
+    if (!serializable->Deserialize(aParams)) {
+      MOZ_ASSERT(false, "Deserialize failed!");
+      return nullptr;
+    }
+
+    uri = do_QueryInterface(serializable);
+    MOZ_ASSERT(uri);
+
+    return uri.forget();
+  }
+
+  MOZ_ASSERT(aParams.type() == URIParams::TGenericURIParams);
+
+  const GenericURIParams& params = aParams.get_GenericURIParams();
+
+  if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), params.spec(),
+                          params.charset().get()))) {
+    NS_WARNING("Failed to make new URI!");
+    return nullptr;
+  }
+
+  nsCString scheme;
+  if (NS_FAILED(uri->GetScheme(scheme))) {
+    MOZ_NOT_REACHED("This must never fail!");
+  }
+
+  bool allowed = false;
+
+  for (size_t i = 0; i < ArrayLength(kGenericURIAllowedSchemes); i++) {
+    const StringWithLengh& entry = kGenericURIAllowedSchemes[i];
+    if (scheme.EqualsASCII(entry.string, entry.length)) {
+      allowed = true;
+      break;
+    }
+  }
+
+  if (!allowed) {
+    MOZ_ASSERT(false, "This type of URI is not allowed!");
+    return nullptr;
+  }
+
+  return uri.forget();
+}
+
+already_AddRefed<nsIURI>
+DeserializeURI(const OptionalURIParams& aParams)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  nsCOMPtr<nsIURI> uri;
+
+  switch (aParams.type()) {
+    case OptionalURIParams::Tvoid_t:
+      break;
+
+    case OptionalURIParams::TURIParams:
+      uri = DeserializeURI(aParams.get_URIParams());
+      break;
+
+    default:
+      MOZ_NOT_REACHED("Unknown params!");
+  }
+
+  return uri.forget();
+}
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/URIUtils.h
@@ -0,0 +1,32 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_ipc_URIUtils_h
+#define mozilla_ipc_URIUtils_h
+
+#include "mozilla/ipc/URIParams.h"
+#include "nsCOMPtr.h"
+#include "nsIURI.h"
+
+namespace mozilla {
+namespace ipc {
+
+void
+SerializeURI(nsIURI* aURI,
+             URIParams& aParams);
+
+void
+SerializeURI(nsIURI* aURI,
+             OptionalURIParams& aParams);
+
+already_AddRefed<nsIURI>
+DeserializeURI(const URIParams& aParams);
+
+already_AddRefed<nsIURI>
+DeserializeURI(const OptionalURIParams& aParams);
+
+} // namespace ipc
+} // namespace mozilla
+
+#endif // mozilla_ipc_URIUtils_h
--- a/ipc/glue/ipdl.mk
+++ b/ipc/glue/ipdl.mk
@@ -1,5 +1,8 @@
 # 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/.
 
-IPDLSRCS = IPCSerializableParams.ipdlh
+IPDLSRCS = \
+  InputStreamParams.ipdlh \
+  URIParams.ipdlh \
+  $(NULL)
new file mode 100644
--- /dev/null
+++ b/ipc/glue/nsIIPCSerializableURI.h
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_ipc_nsIIPCSerializableURI_h
+#define mozilla_ipc_nsIIPCSerializableURI_h
+
+#include "nsISupports.h"
+#include "mozilla/Attributes.h"
+
+namespace mozilla {
+namespace ipc {
+class URIParams;
+}
+}
+
+#define NS_IIPCSERIALIZABLEURI_IID \
+  {0xfee3437d, 0x3daf, 0x411f, {0xb0, 0x1d, 0xdc, 0xd4, 0x88, 0x55, 0xe3, 0xd}}
+
+class NS_NO_VTABLE nsIIPCSerializableURI : public nsISupports
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIPCSERIALIZABLEURI_IID)
+
+  virtual void
+  Serialize(mozilla::ipc::URIParams& aParams) = 0;
+
+  virtual bool
+  Deserialize(const mozilla::ipc::URIParams& aParams) = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableURI,
+                              NS_IIPCSERIALIZABLEURI_IID)
+
+#define NS_DECL_NSIIPCSERIALIZABLEURI \
+  virtual void \
+  Serialize(mozilla::ipc::URIParams&) MOZ_OVERRIDE; \
+  virtual bool \
+  Deserialize(const mozilla::ipc::URIParams&) MOZ_OVERRIDE;
+
+#define NS_FORWARD_NSIIPCSERIALIZABLEURI(_to) \
+  virtual void \
+  Serialize(mozilla::ipc::URIParams& aParams) MOZ_OVERRIDE \
+  { _to Serialize(aParams); } \
+  virtual bool \
+  Deserialize(const mozilla::ipc::URIParams& aParams) MOZ_OVERRIDE \
+  { return _to Deserialize(aParams); }
+
+#define NS_FORWARD_SAFE_NSIIPCSERIALIZABLEURI(_to) \
+  virtual void \
+  Serialize(mozilla::ipc::URIParams& aParams) MOZ_OVERRIDE \
+  { if (_to) { _to->Serialize(aParams); } } \
+  virtual bool \
+  Deserialize(const mozilla::ipc::URIParams& aParams) MOZ_OVERRIDE \
+  { if (_to) { return _to->Deserialize(aParams); } return false; }
+
+#endif // mozilla_ipc_nsIIPCSerializableURI_h
--- a/ipc/ipdl/ipdl/type.py
+++ b/ipc/ipdl/ipdl/type.py
@@ -799,16 +799,20 @@ class GatherDecls(TcheckVisitor):
         if using.type.basename() == fullname:
             fullname = None
         if fullname == 'mozilla::ipc::Shmem':
             ipdltype = ShmemType(using.type.spec)
         elif fullname == 'mozilla::ipc::FileDescriptor':
             ipdltype = FDType(using.type.spec)
         else:
             ipdltype = ImportedCxxType(using.type.spec)
+            existingType = self.symtab.lookup(ipdltype.fullname())
+            if existingType and existingType.fullname == ipdltype.fullname():
+                using.decl = existingType
+                return
         using.decl = self.declare(
             loc=using.loc,
             type=ipdltype,
             shortname=using.type.basename(),
             fullname=fullname)
 
     def visitProtocol(self, p):
         # protocol scope
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/ipdl/ok/multipleUsingCxxTypes.ipdl
@@ -0,0 +1,7 @@
+using mozilla::void_t;
+using mozilla::void_t;
+
+protocol multipleUsingCxxTypes {
+child:
+    Msg(void_t foo);
+};
--- a/modules/libjar/Makefile.in
+++ b/modules/libjar/Makefile.in
@@ -32,9 +32,11 @@ LIBXUL_LIBRARY = 1
 
 
 CPPSRCS		= $(MODULES_LIBJAR_LCPPSRCS)
 
 XPIDLSRCS	= $(MODULES_LIBJAR_LXPIDLSRCS)
 
 EXPORTS		= $(MODULES_LIBJAR_LEXPORTS)
 
+include $(topsrcdir)/config/config.mk
+include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -1,28 +1,33 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "base/basictypes.h"
+
 #include "nsJARURI.h"
 #include "nsNetUtil.h"
 #include "nsIIOService.h"
 #include "nsIStandardURL.h"
 #include "nsCRT.h"
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsIZipReader.h"
 #include "nsReadableUtils.h"
 #include "nsAutoPtr.h"
 #include "nsNetCID.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIProgrammingLanguage.h"
+#include "mozilla/ipc/URIUtils.h"
+
+using namespace mozilla::ipc;
 
 static NS_DEFINE_CID(kJARURICID, NS_JARURI_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
  
 nsJARURI::nsJARURI()
 {
 }
@@ -37,16 +42,17 @@ NS_IMPL_THREADSAFE_RELEASE(nsJARURI)
 NS_INTERFACE_MAP_BEGIN(nsJARURI)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJARURI)
   NS_INTERFACE_MAP_ENTRY(nsIURI)
   NS_INTERFACE_MAP_ENTRY(nsIURL)
   NS_INTERFACE_MAP_ENTRY(nsIJARURI)
   NS_INTERFACE_MAP_ENTRY(nsISerializable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY(nsINestedURI)
+  NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
   // see nsJARURI::Equals
   if (aIID.Equals(NS_GET_IID(nsJARURI)))
       foundInterface = reinterpret_cast<nsISupports*>(this);
   else
 NS_INTERFACE_MAP_END
 
 nsresult
 nsJARURI::Init(const char *charsetHint)
@@ -811,8 +817,57 @@ nsJARURI::GetInnerURI(nsIURI **uri)
 }
 
 NS_IMETHODIMP
 nsJARURI::GetInnermostURI(nsIURI** uri)
 {
     return NS_ImplGetInnermostURI(this, uri);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsIIPCSerializableURI methods:
+
+void
+nsJARURI::Serialize(URIParams& aParams)
+{
+    JARURIParams params;
+
+    SerializeURI(mJARFile, params.jarFile());
+    SerializeURI(mJAREntry, params.jarEntry());
+    params.charset() = mCharsetHint;
+
+    aParams = params;
+}
+
+bool
+nsJARURI::Deserialize(const URIParams& aParams)
+{
+    if (aParams.type() != URIParams::TJARURIParams) {
+        NS_ERROR("Received unknown parameters from the other process!");
+        return false;
+    }
+
+    const JARURIParams& params = aParams.get_JARURIParams();
+
+    nsCOMPtr<nsIURI> file = DeserializeURI(params.jarFile());
+    if (!file) {
+        NS_ERROR("Couldn't deserialize jar file URI!");
+        return false;
+    }
+
+    nsCOMPtr<nsIURI> entry = DeserializeURI(params.jarEntry());
+    if (!entry) {
+        NS_ERROR("Couldn't deserialize jar entry URI!");
+        return false;
+    }
+
+    nsCOMPtr<nsIURL> entryURL = do_QueryInterface(entry);
+    if (!entryURL) {
+        NS_ERROR("Couldn't QI jar entry URI to nsIURL!");
+        return false;
+    }
+
+    mJARFile.swap(file);
+    mJAREntry.swap(entryURL);
+    mCharsetHint = params.charset();
+
+    return true;
+}
--- a/modules/libjar/nsJARURI.h
+++ b/modules/libjar/nsJARURI.h
@@ -8,16 +8,17 @@
 #define nsJARURI_h__
 
 #include "nsIJARURI.h"
 #include "nsISerializable.h"
 #include "nsIClassInfo.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsINestedURI.h"
+#include "nsIIPCSerializableURI.h"
 
 #define NS_THIS_JARURI_IMPL_CID                      \
 { /* 9a55f629-730b-4d08-b75b-fa7d9570a691 */         \
     0x9a55f629,                                      \
     0x730b,                                          \
     0x4d08,                                          \
     {0xb7, 0x5b, 0xfa, 0x7d, 0x95, 0x70, 0xa6, 0x91} \
 }
@@ -31,26 +32,28 @@
     0x4ded,                                          \
     {0xa4, 0x6d, 0x98, 0x29, 0xd3, 0xcc, 0xa4, 0x62} \
 }
 
 
 class nsJARURI : public nsIJARURI,
                  public nsISerializable,
                  public nsIClassInfo,
-                 public nsINestedURI
+                 public nsINestedURI,
+                 public nsIIPCSerializableURI
 {
-public:    
+public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSIURL
     NS_DECL_NSIJARURI
     NS_DECL_NSISERIALIZABLE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSINESTEDURI
+    NS_DECL_NSIIPCSERIALIZABLEURI
 
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_THIS_JARURI_IMPL_CID)
 
     // nsJARURI
     nsJARURI();
     virtual ~nsJARURI();
    
     nsresult Init(const char *charsetHint);
--- a/modules/libjar/objs.mk
+++ b/modules/libjar/objs.mk
@@ -10,16 +10,17 @@ MODULES_LIBJAR_LCPPSRCS = \
 		nsJARFactory.cpp \
 		nsJARProtocolHandler.cpp \
 		nsJARChannel.cpp  \
 		nsJARURI.cpp  \
 		$(NULL)
 
 MODULES_LIBJAR_LEXPORTS = \
 		zipstruct.h \
+		nsJARURI.h \
 		nsZipArchive.h \
 		$(NULL)
 
 MODULES_LIBJAR_LXPIDLSRCS = \
 		nsIZipReader.idl \
 		nsIJARChannel.idl \
 		nsIJARURI.idl \
 		nsIJARProtocolHandler.idl \
--- a/netwerk/base/public/Makefile.in
+++ b/netwerk/base/public/Makefile.in
@@ -47,17 +47,16 @@ XPIDLSRCS	= \
 		nsICryptoHMAC.idl \
 		nsIDownloader.idl \
 		nsIEncodedChannel.idl \
 		nsIFileStreams.idl \
 		nsIIncrementalDownload.idl \
 		nsIInputStreamPump.idl \
 		nsIInputStreamChannel.idl \
                 nsIIOService2.idl \
-                nsIIPCSerializableObsolete.idl \
 		nsIMIMEInputStream.idl \
 		nsINetAddr.idl \
                 nsINetworkLinkService.idl \
 		nsIPermission.idl \
 		nsIPermissionManager.idl \
 		nsIPrivateBrowsingService.idl \
 		nsIProgressEventSink.idl \
 		nsIPrompt.idl \
deleted file mode 100644
--- a/netwerk/base/public/nsIIPCSerializableObsolete.idl
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
-/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
-/* 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"
-
-%{C++
-namespace IPC {
-class Message;
-}
-%}
-
-[ptr] native ConstMessage(const IPC::Message);
-[ptr] native Message(IPC::Message);
-[ptr] native Iterator(void*);
-
-[noscript, uuid(1f605ac7-666b-471f-9864-1a21a95f11c4)]
-interface nsIIPCSerializableObsolete : nsISupports
-{
-  [notxpcom] boolean read(in ConstMessage msg, in Iterator iter);
-  [notxpcom] void write(in Message msg);
-};
--- a/netwerk/base/src/nsBufferedStreams.cpp
+++ b/netwerk/base/src/nsBufferedStreams.cpp
@@ -7,17 +7,16 @@
 
 #include "nsAlgorithm.h"
 #include "nsBufferedStreams.h"
 #include "nsStreamUtils.h"
 #include "nsCRT.h"
 #include "nsNetCID.h"
 #include "nsIClassInfoImpl.h"
 #include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/IPCSerializableParams.h"
 
 #ifdef DEBUG_brendan
 # define METERING
 #endif
 
 #ifdef METERING
 # include <stdio.h>
 # define METER(x)       x
--- a/netwerk/base/src/nsFileStreams.cpp
+++ b/netwerk/base/src/nsFileStreams.cpp
@@ -23,17 +23,17 @@
 #include "prerror.h"
 #include "nsCRT.h"
 #include "nsIFile.h"
 #include "nsDirectoryIndexStream.h"
 #include "nsMimeTypes.h"
 #include "nsReadLine.h"
 #include "nsNetUtil.h"
 #include "nsIClassInfoImpl.h"
-#include "mozilla/ipc/IPCSerializableParams.h"
+#include "mozilla/ipc/InputStreamUtils.h"
 
 #define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
 
 typedef mozilla::ipc::FileDescriptor::PlatformHandleType FileHandleType;
 
 using namespace mozilla::ipc;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -324,17 +324,16 @@ NS_IMPL_RELEASE_INHERITED(nsFileInputStr
 
 NS_IMPL_CLASSINFO(nsFileInputStream, NULL, nsIClassInfo::THREADSAFE,
                   NS_LOCALFILEINPUTSTREAM_CID)
 
 NS_INTERFACE_MAP_BEGIN(nsFileInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIFileInputStream)
     NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
-    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
     NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
     NS_IMPL_QUERY_CLASSINFO(nsFileInputStream)
 NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
 
 NS_IMPL_CI_INTERFACE_GETTER4(nsFileInputStream,
                              nsIInputStream,
                              nsIFileInputStream,
                              nsISeekableStream,
@@ -468,57 +467,16 @@ nsFileInputStream::Seek(int32_t aWhence,
         } else {
             return NS_BASE_STREAM_CLOSED;
         }
     }
 
     return nsFileStreamBase::Seek(aWhence, aOffset);
 }
 
-bool
-nsFileInputStream::Read(const IPC::Message *aMsg, void **aIter)
-{
-    using IPC::ReadParam;
-
-    nsCString path;
-    bool followLinks;
-    int32_t flags;
-    if (!ReadParam(aMsg, aIter, &path) ||
-        !ReadParam(aMsg, aIter, &followLinks) ||
-        !ReadParam(aMsg, aIter, &flags))
-        return false;
-
-    nsCOMPtr<nsIFile> file;
-    nsresult rv = NS_NewNativeLocalFile(path, followLinks, getter_AddRefs(file));
-    if (NS_FAILED(rv))
-        return false;
-
-    // IO flags = -1 means readonly, and
-    // permissions are unimportant since we're reading
-    rv = Init(file, -1, -1, flags);
-    if (NS_FAILED(rv))
-        return false;
-
-    return true;
-}
-
-void
-nsFileInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    nsCString path;
-    mFile->GetNativePath(path);
-    WriteParam(aMsg, path);
-    bool followLinks;
-    mFile->GetFollowLinks(&followLinks);
-    WriteParam(aMsg, followLinks);
-    WriteParam(aMsg, mBehaviorFlags);
-}
-
 void
 nsFileInputStream::Serialize(InputStreamParams& aParams)
 {
     FileInputStreamParams params;
 
     if (mFD) {
         FileHandleType fd = FileHandleType(PR_FileDesc2NativeHandle(mFD));
         NS_ASSERTION(fd, "This should never be null!");
@@ -594,17 +552,16 @@ NS_IMPL_CLASSINFO(nsPartialFileInputStre
                   NS_PARTIALLOCALFILEINPUTSTREAM_CID)
 
 // Don't forward to nsFileInputStream as we don't want to QI to
 // nsIFileInputStream
 NS_INTERFACE_MAP_BEGIN(nsPartialFileInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIInputStream)
     NS_INTERFACE_MAP_ENTRY(nsIPartialFileInputStream)
     NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
-    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
     NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
     NS_IMPL_QUERY_CLASSINFO(nsPartialFileInputStream)
 NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
 
 NS_IMPL_CI_INTERFACE_GETTER4(nsPartialFileInputStream,
                              nsIInputStream,
                              nsIPartialFileInputStream,
                              nsISeekableStream,
@@ -703,67 +660,16 @@ nsPartialFileInputStream::Seek(int32_t a
 
     nsresult rv = nsFileInputStream::Seek(NS_SEEK_SET, offset);
     if (NS_SUCCEEDED(rv)) {
         mPosition = offset - mStart;
     }
     return rv;
 }
 
-bool
-nsPartialFileInputStream::Read(const IPC::Message *aMsg, void **aIter)
-{
-    using IPC::ReadParam;
-
-    // Grab our members first.
-    uint64_t start;
-    uint64_t length;
-    if (!ReadParam(aMsg, aIter, &start) ||
-        !ReadParam(aMsg, aIter, &length))
-        return false;
-
-    // Then run base class deserialization.
-    if (!nsFileInputStream::Read(aMsg, aIter))
-        return false;
-
-    // Set members.
-    mStart = start;
-    mLength = length;
-
-    // XXX This isn't really correct, we should probably set this to whatever
-    //     the sender had. However, it doesn't look like nsFileInputStream deals
-    //     with sending a partially-consumed stream either, so...
-    mPosition = 0;
-
-    // Mirror nsPartialFileInputStream::Init here. We can't call it directly
-    // because nsFileInputStream::Read() already calls the base class Init
-    // method.
-    return NS_SUCCEEDED(nsFileInputStream::Seek(NS_SEEK_SET, start));
-}
-
-void
-nsPartialFileInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    // Write our members first.
-    WriteParam(aMsg, mStart);
-    WriteParam(aMsg, mLength);
-
-    // XXX This isn't really correct, we should probably send this too. However,
-    //     it doesn't look like nsFileInputStream deals with sending a
-    //     partially-consumed stream either, so...
-    if (mPosition) {
-      NS_WARNING("No support for sending a partially-consumed input stream!");
-    }
-
-    // Now run base class serialization.
-    nsFileInputStream::Write(aMsg);
-}
-
 void
 nsPartialFileInputStream::Serialize(InputStreamParams& aParams)
 {
     // Serialize the base class first.
     InputStreamParams fileParams;
     nsFileInputStream::Serialize(fileParams);
 
     if (fileParams.type() != InputStreamParams::TFileInputStreamParams) {
@@ -1069,9 +975,9 @@ nsFileStream::GetLastModified(int64_t* _
     }
     else {
         *_retval = modTime / int64_t(PR_USEC_PER_MSEC);
     }
 
     return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
--- a/netwerk/base/src/nsFileStreams.h
+++ b/netwerk/base/src/nsFileStreams.h
@@ -13,17 +13,16 @@
 #include "nsIOutputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsISeekableStream.h"
 #include "nsILineInputStream.h"
 #include "nsCOMPtr.h"
 #include "prlog.h"
 #include "prio.h"
 #include "nsIIPCSerializableInputStream.h"
-#include "nsIIPCSerializableObsolete.h"
 
 template<class CharType> class nsLineBuffer;
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsFileStreamBase : public nsISeekableStream
 {
 public:
@@ -98,24 +97,22 @@ protected:
     inline nsresult DoPendingOpen();
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 class nsFileInputStream : public nsFileStreamBase,
                           public nsIFileInputStream,
                           public nsILineInputStream,
-                          public nsIIPCSerializableObsolete,
                           public nsIIPCSerializableInputStream
 {
 public:
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIFILEINPUTSTREAM
     NS_DECL_NSILINEINPUTSTREAM
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
 
     NS_IMETHOD Close();
     NS_IMETHOD Available(uint64_t* _retval)
     {
         return nsFileStreamBase::Available(_retval);
     }
     NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* _retval);
@@ -179,17 +176,16 @@ protected:
 
 class nsPartialFileInputStream : public nsFileInputStream,
                                  public nsIPartialFileInputStream
 {
 public:
     using nsFileInputStream::Init;
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSIPARTIALFILEINPUTSTREAM
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
 
     nsPartialFileInputStream()
       : mStart(0), mLength(0), mPosition(0)
     { }
 
     NS_IMETHOD Tell(int64_t *aResult);
     NS_IMETHOD Available(uint64_t *aResult);
--- a/netwerk/base/src/nsMIMEInputStream.cpp
+++ b/netwerk/base/src/nsMIMEInputStream.cpp
@@ -16,17 +16,16 @@
 #include "nsIMIMEInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsIStringStream.h"
 #include "nsString.h"
 #include "nsMIMEInputStream.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIIPCSerializableInputStream.h"
 #include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/IPCSerializableParams.h"
 
 using namespace mozilla::ipc;
 
 class nsMIMEInputStream : public nsIMIMEInputStream,
                           public nsISeekableStream,
                           public nsIIPCSerializableInputStream
 {
 public:
--- a/netwerk/base/src/nsSimpleNestedURI.cpp
+++ b/netwerk/base/src/nsSimpleNestedURI.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "IPCMessageUtils.h"
-#include "mozilla/net/NeckoMessageUtils.h"
+#include "base/basictypes.h"
 
 #include "nsSimpleNestedURI.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsNetUtil.h"
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsSimpleNestedURI, nsSimpleURI, nsINestedURI)
 
@@ -50,42 +49,16 @@ nsSimpleNestedURI::Write(nsIObjectOutput
     nsresult rv = nsSimpleURI::Write(aStream);
     if (NS_FAILED(rv)) return rv;
 
     rv = aStream->WriteCompoundObject(mInnerURI, NS_GET_IID(nsIURI),
                                       true);
     return rv;
 }
 
-// nsIIPCSerializableObsolete
-
-bool
-nsSimpleNestedURI::Read(const IPC::Message *aMsg, void **aIter)
-{
-    if (!nsSimpleURI::Read(aMsg, aIter))
-        return false;
-
-    IPC::URI uri;
-    if (!ReadParam(aMsg, aIter, &uri))
-        return false;
-
-    mInnerURI = uri;
-
-    return true;
-}
-
-void
-nsSimpleNestedURI::Write(IPC::Message *aMsg)
-{
-    nsSimpleURI::Write(aMsg);
-
-    IPC::URI uri(mInnerURI);
-    WriteParam(aMsg, uri);
-}
-
 // nsINestedURI
 
 NS_IMETHODIMP
 nsSimpleNestedURI::GetInnerURI(nsIURI** uri)
 {
     NS_ENSURE_TRUE(mInnerURI, NS_ERROR_NOT_INITIALIZED);
     
     return NS_EnsureSafeToReturn(mInnerURI, uri);
--- a/netwerk/base/src/nsSimpleNestedURI.h
+++ b/netwerk/base/src/nsSimpleNestedURI.h
@@ -31,17 +31,16 @@ public:
     }
 
     // Constructor that should generally be used when constructing an object of
     // this class with |operator new|.
     nsSimpleNestedURI(nsIURI* innerURI);
 
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSINESTEDURI
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
 
     // Overrides for various methods nsSimpleURI implements follow.
   
     // nsSimpleURI overrides
     virtual nsresult EqualsInternal(nsIURI* other,
                                     RefHandlingEnum refHandlingMode,
                                     bool* result);
     virtual nsSimpleURI* StartClone(RefHandlingEnum refHandlingMode);
--- a/netwerk/base/src/nsSimpleURI.cpp
+++ b/netwerk/base/src/nsSimpleURI.cpp
@@ -15,16 +15,20 @@
 #include "nsURLHelper.h"
 #include "nsNetCID.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsEscape.h"
 #include "nsError.h"
 #include "nsIProgrammingLanguage.h"
 #include "mozilla/Util.h" // for DebugOnly
+#include "nsIIPCSerializableURI.h"
+#include "mozilla/ipc/URIUtils.h"
+
+using namespace mozilla::ipc;
 
 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsSimpleURI methods:
 
@@ -36,18 +40,18 @@ nsSimpleURI::nsSimpleURI()
 
 nsSimpleURI::~nsSimpleURI()
 {
 }
 
 NS_IMPL_ADDREF(nsSimpleURI)
 NS_IMPL_RELEASE(nsSimpleURI)
 NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
-NS_INTERFACE_TABLE5(nsSimpleURI, nsIURI, nsISerializable,
-                    nsIIPCSerializableObsolete, nsIClassInfo, nsIMutable)
+NS_INTERFACE_TABLE5(nsSimpleURI, nsIURI, nsISerializable, nsIClassInfo,
+                    nsIMutable, nsIIPCSerializableURI)
 NS_INTERFACE_TABLE_TO_MAP_SEGUE
   if (aIID.Equals(kThisSimpleURIImplementationCID))
     foundInterface = static_cast<nsIURI*>(this);
   else
   NS_INTERFACE_MAP_ENTRY(nsISizeOf)
 NS_INTERFACE_MAP_END
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -113,51 +117,61 @@ nsSimpleURI::Write(nsIObjectOutputStream
         rv = aStream->WriteStringZ(mRef.get());
         if (NS_FAILED(rv)) return rv;
     }
 
     return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIIPCSerializableObsolete methods:
+// nsIIPCSerializableURI methods:
+
+void
+nsSimpleURI::Serialize(URIParams& aParams)
+{
+    SimpleURIParams params;
+
+    params.scheme() = mScheme;
+    params.path() = mPath;
+    if (mIsRefValid) {
+      params.ref() = mRef;
+    }
+    else {
+      params.ref().SetIsVoid(true);
+    }
+    params.isMutable() = mMutable;
+
+    aParams = params;
+}
 
 bool
-nsSimpleURI::Read(const IPC::Message *aMsg, void **aIter)
+nsSimpleURI::Deserialize(const URIParams& aParams)
 {
-    bool isMutable, isRefValid;
-    if (!ReadParam(aMsg, aIter, &isMutable) ||
-        !ReadParam(aMsg, aIter, &mScheme) ||
-        !ReadParam(aMsg, aIter, &mPath) ||
-        !ReadParam(aMsg, aIter, &isRefValid))
+    if (aParams.type() != URIParams::TSimpleURIParams) {
+        NS_ERROR("Received unknown parameters from the other process!");
         return false;
+    }
 
-    mMutable = isMutable;
-    mIsRefValid = isRefValid;
+    const SimpleURIParams& params = aParams.get_SimpleURIParams();
 
-    if (mIsRefValid) {
-        return ReadParam(aMsg, aIter, &mRef);
+    mScheme = params.scheme();
+    mPath = params.path();
+    if (params.ref().IsVoid()) {
+        mRef.Truncate();
+        mIsRefValid = false;
     }
-    mRef.Truncate(); // invariant: mRef should be empty when it's not valid
+    else {
+        mRef = params.ref();
+        mIsRefValid = true;
+    }
+    mMutable = params.isMutable();
 
     return true;
 }
 
-void
-nsSimpleURI::Write(IPC::Message *aMsg)
-{
-    WriteParam(aMsg, bool(mMutable));
-    WriteParam(aMsg, mScheme);
-    WriteParam(aMsg, mPath);
-    WriteParam(aMsg, mIsRefValid);
-    if (mIsRefValid) {
-        WriteParam(aMsg, mRef);
-    }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsIURI methods:
 
 NS_IMETHODIMP
 nsSimpleURI::GetSpec(nsACString &result)
 {
     result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
     if (mIsRefValid) {
--- a/netwerk/base/src/nsSimpleURI.h
+++ b/netwerk/base/src/nsSimpleURI.h
@@ -4,44 +4,44 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsSimpleURI_h__
 #define nsSimpleURI_h__
 
 #include "nsIURL.h"
 #include "nsAgg.h"
 #include "nsISerializable.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "nsString.h"
 #include "nsIClassInfo.h"
 #include "nsIMutable.h"
 #include "nsISizeOf.h"
+#include "nsIIPCSerializableURI.h"
 
 #define NS_THIS_SIMPLEURI_IMPLEMENTATION_CID         \
 { /* 0b9bb0c2-fee6-470b-b9b9-9fd9462b5e19 */         \
     0x0b9bb0c2,                                      \
     0xfee6,                                          \
     0x470b,                                          \
     {0xb9, 0xb9, 0x9f, 0xd9, 0x46, 0x2b, 0x5e, 0x19} \
 }
 
 class nsSimpleURI : public nsIURI,
                     public nsISerializable,
-                    public nsIIPCSerializableObsolete,
                     public nsIClassInfo,
                     public nsIMutable,
-                    public nsISizeOf
+                    public nsISizeOf,
+                    public nsIIPCSerializableURI
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSISERIALIZABLE
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSIMUTABLE
+    NS_DECL_NSIIPCSERIALIZABLEURI
 
     // nsSimpleURI methods:
 
     nsSimpleURI();
     virtual ~nsSimpleURI();
 
     // nsISizeOf
     // Among the sub-classes that inherit (directly or indirectly) from
--- a/netwerk/base/src/nsStandardURL.cpp
+++ b/netwerk/base/src/nsStandardURL.cpp
@@ -18,16 +18,19 @@
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIIDNService.h"
 #include "nsNetUtil.h"
 #include "prlog.h"
 #include "nsAutoPtr.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsVoidArray.h"
+#include "mozilla/ipc/URIUtils.h"
+
+using namespace mozilla::ipc;
 
 static NS_DEFINE_CID(kThisImplCID, NS_THIS_STANDARDURL_IMPL_CID);
 static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
 
 nsIIDNService *nsStandardURL::gIDN = nullptr;
 nsICharsetConverterManager *nsStandardURL::gCharsetMgr = nullptr;
 bool nsStandardURL::gInitialized = false;
 bool nsStandardURL::gEscapeUTF8 = true;
@@ -868,30 +871,16 @@ nsStandardURL::WriteSegment(nsIBinaryOut
     if (NS_FAILED(rv)) return rv;
 
     rv = stream->Write32(uint32_t(seg.mLen));
     if (NS_FAILED(rv)) return rv;
 
     return NS_OK;
 }
 
-bool
-nsStandardURL::ReadSegment(const IPC::Message *aMsg, void **aIter, URLSegment &seg)
-{
-    return (IPC::ReadParam(aMsg, aIter, &seg.mPos) &&
-            IPC::ReadParam(aMsg, aIter, &seg.mLen));
-}
-
-void
-nsStandardURL::WriteSegment(IPC::Message *aMsg, const URLSegment &seg)
-{
-    IPC::WriteParam(aMsg, seg.mPos);
-    IPC::WriteParam(aMsg, seg.mLen);
-}
-
 /* static */ void
 nsStandardURL::PrefsChanged(nsIPrefBranch *prefs, const char *pref)
 {
     bool val;
 
     LOG(("nsStandardURL::PrefsChanged [pref=%s]\n", pref));
 
 #define PREF_CHANGED(p) ((pref == nullptr) || !strcmp(pref, p))
@@ -932,19 +921,19 @@ NS_IMPL_RELEASE(nsStandardURL)
 
 NS_INTERFACE_MAP_BEGIN(nsStandardURL)
     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL)
     NS_INTERFACE_MAP_ENTRY(nsIURI)
     NS_INTERFACE_MAP_ENTRY(nsIURL)
     NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
     NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
     NS_INTERFACE_MAP_ENTRY(nsISerializable)
-    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
     NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     NS_INTERFACE_MAP_ENTRY(nsIMutable)
+    NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableURI)
     // see nsStandardURL::Equals
     if (aIID.Equals(kThisImplCID))
         foundInterface = static_cast<nsIURI *>(this);
     else
     NS_INTERFACE_MAP_ENTRY(nsISizeOf)
 NS_INTERFACE_MAP_END
 
 //----------------------------------------------------------------------------
@@ -2871,113 +2860,124 @@ nsStandardURL::Write(nsIObjectOutputStre
     if (NS_FAILED(rv)) return rv;
 
     // mSpecEncoding and mHostA are just caches that can be recovered as needed.
 
     return NS_OK;
 }
 
 //---------------------------------------------------------------------------
-// nsStandardURL::nsIIPCSerializableObsolete
+// nsStandardURL::nsIIPCSerializableURI
 //---------------------------------------------------------------------------
 
+inline
+mozilla::ipc::StandardURLSegment
+ToIPCSegment(const nsStandardURL::URLSegment& aSegment)
+{
+    return mozilla::ipc::StandardURLSegment(aSegment.mPos, aSegment.mLen);
+}
+
+inline
+nsStandardURL::URLSegment
+FromIPCSegment(const mozilla::ipc::StandardURLSegment& aSegment)
+{
+    return nsStandardURL::URLSegment(aSegment.position(), aSegment.length());
+}
+
+void
+nsStandardURL::Serialize(URIParams& aParams)
+{
+    StandardURLParams params;
+
+    params.urlType() = mURLType;
+    params.port() = mPort;
+    params.defaultPort() = mDefaultPort;
+    params.spec() = mSpec;
+    params.scheme() = ToIPCSegment(mScheme);
+    params.authority() = ToIPCSegment(mAuthority);
+    params.username() = ToIPCSegment(mUsername);
+    params.password() = ToIPCSegment(mPassword);
+    params.host() = ToIPCSegment(mHost);
+    params.path() = ToIPCSegment(mPath);
+    params.filePath() = ToIPCSegment(mFilepath);
+    params.directory() = ToIPCSegment(mDirectory);
+    params.baseName() = ToIPCSegment(mBasename);
+    params.extension() = ToIPCSegment(mExtension);
+    params.query() = ToIPCSegment(mQuery);
+    params.ref() = ToIPCSegment(mRef);
+    params.originCharset() = mOriginCharset;
+    params.isMutable() = !!mMutable;
+    params.supportsFileURL() = !!mSupportsFileURL;
+    params.hostEncoding() = mHostEncoding;
+    // mSpecEncoding and mHostA are just caches that can be recovered as needed.
+
+    aParams = params;
+}
+
 bool
-nsStandardURL::Read(const IPC::Message *aMsg, void **aIter)
+nsStandardURL::Deserialize(const URIParams& aParams)
 {
-    using IPC::ReadParam;
-    
     NS_PRECONDITION(!mHostA, "Shouldn't have cached ASCII host");
     NS_PRECONDITION(mSpecEncoding == eEncoding_Unknown,
                     "Shouldn't have spec encoding here");
     NS_PRECONDITION(!mFile, "Shouldn't have cached file");
-    
-    uint32_t urlType;
-    if (!ReadParam(aMsg, aIter, &urlType))
+
+    if (aParams.type() != URIParams::TStandardURLParams) {
+        NS_ERROR("Received unknown parameters from the other process!");
         return false;
-    
-    mURLType = urlType;
+    }
+
+    const StandardURLParams& params = aParams.get_StandardURLParams();
+
+    mURLType = params.urlType();
     switch (mURLType) {
         case URLTYPE_STANDARD:
             mParser = net_GetStdURLParser();
             break;
         case URLTYPE_AUTHORITY:
             mParser = net_GetAuthURLParser();
             break;
         case URLTYPE_NO_AUTHORITY:
             mParser = net_GetNoAuthURLParser();
             break;
         default:
             NS_NOTREACHED("bad urlType");
             return false;
     }
 
-    uint32_t hostEncoding;
-    bool isMutable, supportsFileURL;
-    if (!ReadParam(aMsg, aIter, &mPort) ||
-        !ReadParam(aMsg, aIter, &mDefaultPort) ||
-        !ReadParam(aMsg, aIter, &mSpec) ||
-        !ReadSegment(aMsg, aIter, mScheme) ||
-        !ReadSegment(aMsg, aIter, mAuthority) ||
-        !ReadSegment(aMsg, aIter, mUsername) ||
-        !ReadSegment(aMsg, aIter, mPassword) ||
-        !ReadSegment(aMsg, aIter, mHost) ||
-        !ReadSegment(aMsg, aIter, mPath) ||
-        !ReadSegment(aMsg, aIter, mFilepath) ||
-        !ReadSegment(aMsg, aIter, mDirectory) ||
-        !ReadSegment(aMsg, aIter, mBasename) ||
-        !ReadSegment(aMsg, aIter, mExtension) ||
-        !ReadSegment(aMsg, aIter, mQuery) ||
-        !ReadSegment(aMsg, aIter, mRef) ||
-        !ReadParam(aMsg, aIter, &mOriginCharset) ||
-        !ReadParam(aMsg, aIter, &isMutable) ||
-        !ReadParam(aMsg, aIter, &supportsFileURL) ||
-        !ReadParam(aMsg, aIter, &hostEncoding))
-        return false;
-
-    if (hostEncoding != eEncoding_ASCII && hostEncoding != eEncoding_UTF8) {
+    if (params.hostEncoding() != eEncoding_ASCII &&
+        params.hostEncoding() != eEncoding_UTF8) {
         NS_WARNING("Unexpected host encoding");
         return false;
     }
-    mHostEncoding = hostEncoding;
-    mMutable = isMutable;
-    mSupportsFileURL = supportsFileURL;
+
+    mPort = params.port();
+    mDefaultPort = params.defaultPort();
+    mSpec = params.spec();
+    mScheme = FromIPCSegment(params.scheme());
+    mAuthority = FromIPCSegment(params.authority());
+    mUsername = FromIPCSegment(params.username());
+    mPassword = FromIPCSegment(params.password());
+    mHost = FromIPCSegment(params.host());
+    mPath = FromIPCSegment(params.path());
+    mFilepath = FromIPCSegment(params.filePath());
+    mDirectory = FromIPCSegment(params.directory());
+    mBasename = FromIPCSegment(params.baseName());
+    mExtension = FromIPCSegment(params.extension());
+    mQuery = FromIPCSegment(params.query());
+    mRef = FromIPCSegment(params.ref());
+    mOriginCharset = params.originCharset();
+    mMutable = params.isMutable();
+    mSupportsFileURL = params.supportsFileURL();
+    mHostEncoding = params.hostEncoding();
 
     // mSpecEncoding and mHostA are just caches that can be recovered as needed.
-
     return true;
 }
 
-void
-nsStandardURL::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-    
-    WriteParam(aMsg, mURLType);
-    WriteParam(aMsg, mPort);
-    WriteParam(aMsg, mDefaultPort);
-    WriteParam(aMsg, mSpec);
-    WriteSegment(aMsg, mScheme);
-    WriteSegment(aMsg, mAuthority);
-    WriteSegment(aMsg, mUsername);
-    WriteSegment(aMsg, mPassword);
-    WriteSegment(aMsg, mHost);
-    WriteSegment(aMsg, mPath);
-    WriteSegment(aMsg, mFilepath);
-    WriteSegment(aMsg, mDirectory);
-    WriteSegment(aMsg, mBasename);
-    WriteSegment(aMsg, mExtension);
-    WriteSegment(aMsg, mQuery);
-    WriteSegment(aMsg, mRef);
-    WriteParam(aMsg, mOriginCharset);
-    WriteParam(aMsg, bool(mMutable));
-    WriteParam(aMsg, bool(mSupportsFileURL));
-    WriteParam(aMsg, mHostEncoding);
-    // mSpecEncoding and mHostA are just caches that can be recovered as needed.
-}
-
 //----------------------------------------------------------------------------
 // nsStandardURL::nsIClassInfo
 //----------------------------------------------------------------------------
 
 NS_IMETHODIMP 
 nsStandardURL::GetInterfaces(uint32_t *count, nsIID * **array)
 {
     *count = 0;
@@ -3052,9 +3052,8 @@ nsStandardURL::SizeOfExcludingThis(nsMal
   // - mParser
   // - mFile
 }
 
 size_t
 nsStandardURL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
   return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
 }
-
--- a/netwerk/base/src/nsStandardURL.h
+++ b/netwerk/base/src/nsStandardURL.h
@@ -5,30 +5,30 @@
 
 #ifndef nsStandardURL_h__
 #define nsStandardURL_h__
 
 #include "nsString.h"
 #include "nsDependentString.h"
 #include "nsDependentSubstring.h"
 #include "nsISerializable.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "nsIFileURL.h"
 #include "nsIStandardURL.h"
 #include "nsIFile.h"
 #include "nsIURLParser.h"
 #include "nsIUnicodeEncoder.h"
 #include "nsIObserver.h"
 #include "nsIIOService.h"
 #include "nsCOMPtr.h"
 #include "nsURLHelper.h"
 #include "nsIClassInfo.h"
 #include "nsISizeOf.h"
 #include "prclist.h"
 #include "mozilla/Attributes.h"
+#include "nsIIPCSerializableURI.h"
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 #define DEBUG_DUMP_URLS_AT_SHUTDOWN
 #endif
 
 class nsIBinaryInputStream;
 class nsIBinaryOutputStream;
 class nsIIDNService;
@@ -37,30 +37,30 @@ class nsIPrefBranch;
 
 //-----------------------------------------------------------------------------
 // standard URL implementation
 //-----------------------------------------------------------------------------
 
 class nsStandardURL : public nsIFileURL
                     , public nsIStandardURL
                     , public nsISerializable
-                    , public nsIIPCSerializableObsolete
                     , public nsIClassInfo
                     , public nsISizeOf
+                    , public nsIIPCSerializableURI
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSIURL
     NS_DECL_NSIFILEURL
     NS_DECL_NSISTANDARDURL
     NS_DECL_NSISERIALIZABLE
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSIMUTABLE
+    NS_DECL_NSIIPCSERIALIZABLEURI
 
     // nsISizeOf
     virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
     virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
     nsStandardURL(bool aSupportsFileURL = false);
     virtual ~nsStandardURL();
 
@@ -222,20 +222,16 @@ private:
     void ShiftFromExtension(int32_t diff) { mExtension.mPos += diff; ShiftFromQuery(diff); }
     void ShiftFromQuery(int32_t diff)     { mQuery.mPos += diff; ShiftFromRef(diff); }
     void ShiftFromRef(int32_t diff)       { mRef.mPos += diff; }
 
     // fastload helper functions
     nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
     nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
 
-    // ipc helper functions
-    bool ReadSegment(const IPC::Message *, void **, URLSegment &);
-    void WriteSegment(IPC::Message *, const URLSegment &);
-
     static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
 
     // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
     nsCString mSpec;
     int32_t   mDefaultPort;
     int32_t   mPort;
 
     // url parts (relative to mSpec)
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -1,19 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/net/CookieServiceChild.h"
+
+#include "mozilla/ipc/URIUtils.h"
 #include "mozilla/net/NeckoChild.h"
 #include "nsIURI.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 
+using namespace mozilla::ipc;
+
 namespace mozilla {
 namespace net {
 
 // Behavior pref constants
 static const int32_t BEHAVIOR_ACCEPT = 0;
 static const int32_t BEHAVIOR_REJECTFOREIGN = 1;
 static const int32_t BEHAVIOR_REJECT = 2;
 
@@ -103,19 +107,22 @@ CookieServiceChild::GetCookieStringInter
 
   *aCookieString = NULL;
 
   // Determine whether the request is foreign. Failure is acceptable.
   bool isForeign = true;
   if (RequireThirdPartyCheck())
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
+  URIParams uriParams;
+  SerializeURI(aHostURI, uriParams);
+
   // Synchronously call the parent.
   nsCAutoString result;
-  SendGetCookieString(IPC::URI(aHostURI), !!isForeign, aFromHttp, &result);
+  SendGetCookieString(uriParams, !!isForeign, aFromHttp, &result);
   if (!result.IsEmpty())
     *aCookieString = ToNewCString(result);
 
   return NS_OK;
 }
 
 nsresult
 CookieServiceChild::SetCookieStringInternal(nsIURI *aHostURI,
@@ -132,19 +139,22 @@ CookieServiceChild::SetCookieStringInter
   if (RequireThirdPartyCheck())
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI, &isForeign);
 
   nsDependentCString cookieString(aCookieString);
   nsDependentCString serverTime;
   if (aServerTime)
     serverTime.Rebind(aServerTime);
 
+  URIParams uriParams;
+  SerializeURI(aHostURI, uriParams);
+
   // Synchronously call the parent.
-  SendSetCookieString(IPC::URI(aHostURI), !!isForeign,
-                      cookieString, serverTime, aFromHttp);
+  SendSetCookieString(uriParams, !!isForeign, cookieString, serverTime,
+                      aFromHttp);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CookieServiceChild::Observe(nsISupports     *aSubject,
                             const char      *aTopic,
                             const PRUnichar *aData)
 {
--- a/netwerk/cookie/CookieServiceParent.cpp
+++ b/netwerk/cookie/CookieServiceParent.cpp
@@ -1,17 +1,21 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/net/CookieServiceParent.h"
+
+#include "mozilla/ipc/URIUtils.h"
 #include "nsCookieService.h"
 #include "nsNetUtil.h"
 
+using namespace mozilla::ipc;
+
 namespace mozilla {
 namespace net {
 
 CookieServiceParent::CookieServiceParent()
 {
   // Instantiate the cookieservice via the service manager, so it sticks around
   // until shutdown.
   nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
@@ -22,48 +26,48 @@ CookieServiceParent::CookieServiceParent
   NS_ASSERTION(mCookieService, "couldn't get nsICookieService");
 }
 
 CookieServiceParent::~CookieServiceParent()
 {
 }
 
 bool
-CookieServiceParent::RecvGetCookieString(const IPC::URI& aHost,
+CookieServiceParent::RecvGetCookieString(const URIParams& aHost,
                                          const bool& aIsForeign,
                                          const bool& aFromHttp,
                                          nsCString* aResult)
 {
   if (!mCookieService)
     return true;
 
   // Deserialize URI. Having a host URI is mandatory and should always be
   // provided by the child; thus we consider failure fatal.
-  nsCOMPtr<nsIURI> hostURI(aHost);
+  nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost);
   if (!hostURI)
     return false;
 
   mCookieService->GetCookieStringInternal(hostURI, aIsForeign,
                                           aFromHttp, *aResult);
   return true;
 }
 
 bool
-CookieServiceParent::RecvSetCookieString(const IPC::URI& aHost,
+CookieServiceParent::RecvSetCookieString(const URIParams& aHost,
                                          const bool& aIsForeign,
                                          const nsCString& aCookieString,
                                          const nsCString& aServerTime,
                                          const bool& aFromHttp)
 {
   if (!mCookieService)
     return true;
 
   // Deserialize URI. Having a host URI is mandatory and should always be
   // provided by the child; thus we consider failure fatal.
-  nsCOMPtr<nsIURI> hostURI(aHost);
+  nsCOMPtr<nsIURI> hostURI = DeserializeURI(aHost);
   if (!hostURI)
     return false;
 
   nsDependentCString cookieString(aCookieString, 0);
   mCookieService->SetCookieStringInternal(hostURI, aIsForeign,
                                           cookieString, aServerTime,
                                           aFromHttp);
   return true;
--- a/netwerk/cookie/CookieServiceParent.h
+++ b/netwerk/cookie/CookieServiceParent.h
@@ -16,22 +16,22 @@ namespace net {
 
 class CookieServiceParent : public PCookieServiceParent
 {
 public:
   CookieServiceParent();
   virtual ~CookieServiceParent();
 
 protected:
-  virtual bool RecvGetCookieString(const IPC::URI& aHost,
+  virtual bool RecvGetCookieString(const URIParams& aHost,
                                    const bool& aIsForeign,
                                    const bool& aFromHttp,
                                    nsCString* aResult);
 
-  virtual bool RecvSetCookieString(const IPC::URI& aHost,
+  virtual bool RecvSetCookieString(const URIParams& aHost,
                                    const bool& aIsForeign,
                                    const nsCString& aCookieString,
                                    const nsCString& aServerTime,
                                    const bool& aFromHttp);
 
   nsRefPtr<nsCookieService> mCookieService;
 };
 
--- a/netwerk/cookie/PCookieService.ipdl
+++ b/netwerk/cookie/PCookieService.ipdl
@@ -1,20 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PNecko;
-
-include "mozilla/net/NeckoMessageUtils.h";
-
-using IPC::URI;
+include URIParams;
 
 namespace mozilla {
 namespace net {
 
 /**
  * PCookieService
  *
  * Provides IPDL methods for setting and getting cookies. These are stored on
@@ -52,17 +49,17 @@ parent:
    *        otherwise.
    *
    * @see nsICookieService.getCookieString
    * @see nsICookieService.getCookieStringFromHttp
    * @see mozIThirdPartyUtil.isThirdPartyChannel
    *
    * @return the resulting cookie string.
    */
-  sync GetCookieString(URI host,
+  sync GetCookieString(URIParams host,
                        bool isForeign,
                        bool fromHttp)
        returns (nsCString result);
 
   /*
    * Set a cookie string.
    *
    * @param host
@@ -83,17 +80,17 @@ parent:
    *        Whether the result is for an HTTP request header. This should be
    *        true for nsICookieService.setCookieStringFromHttp calls, false
    *        otherwise.
    *
    * @see nsICookieService.setCookieString
    * @see nsICookieService.setCookieStringFromHttp
    * @see mozIThirdPartyUtil.isThirdPartyChannel
    */
-  SetCookieString(URI host,
+  SetCookieString(URIParams host,
                   bool isForeign,
                   nsCString cookieString,
                   nsCString serverTime,
                   bool fromHttp);
 
   __delete__();
 };
 
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -3,151 +3,21 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_NeckoMessageUtils_h
 #define mozilla_net_NeckoMessageUtils_h
 
 #include "IPC/IPCMessageUtils.h"
 #include "nsStringGlue.h"
-#include "nsIURI.h"
-#include "nsIIPCSerializableObsolete.h"
-#include "nsIClassInfo.h"
-#include "nsComponentManagerUtils.h"
-#include "nsNetUtil.h"
-#include "nsStringStream.h"
 #include "prio.h"
 #include "mozilla/Util.h" // for DebugOnly
-#include "SerializedLoadContext.h"
 
 namespace IPC {
 
-// Since IPDL doesn't have any knowledge of pointers, there's no easy way to
-// pass around nsIURI pointers.  This is a very thin wrapper that IPDL can
-// easily work with, allowing for conversion to and from an nsIURI pointer.
-
-class URI {
- public:
-  URI() : mURI(nullptr) {}
-  URI(nsIURI* aURI) : mURI(aURI) {}
-  operator nsIURI*() const { return mURI.get(); }
-
-  friend struct ParamTraits<URI>;
-  
- private:
-  // Unimplemented
-  URI& operator=(URI&);
-
-  nsCOMPtr<nsIURI> mURI;
-};
-  
-template<>
-struct ParamTraits<URI>
-{
-  typedef URI paramType;
-  
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    bool isNull = !aParam.mURI;
-    WriteParam(aMsg, isNull);
-    if (isNull)
-      return;
-    
-    nsCOMPtr<nsIIPCSerializableObsolete> serializable =
-      do_QueryInterface(aParam.mURI);
-    if (!serializable) {
-      nsCString scheme;
-      aParam.mURI->GetScheme(scheme);
-      if (!scheme.EqualsASCII("about:") &&
-          !scheme.EqualsASCII("javascript:") &&
-          !scheme.EqualsASCII("javascript"))
-        NS_WARNING("All IPDL URIs must be serializable or an allowed scheme");
-    }
-    
-    bool isSerialized = !!serializable;
-    WriteParam(aMsg, isSerialized);
-    if (!isSerialized) {
-      nsCString spec, charset;
-      aParam.mURI->GetSpec(spec);
-      aParam.mURI->GetOriginCharset(charset);
-      WriteParam(aMsg, spec);
-      WriteParam(aMsg, charset);
-      return;
-    }
-    
-    nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aParam.mURI);
-    char cidStr[NSID_LENGTH];
-    nsCID cid;
-    mozilla::DebugOnly<nsresult> rv = classInfo->GetClassIDNoAlloc(&cid);
-    NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "All IPDL URIs must report a valid class ID");
-    
-    cid.ToProvidedString(cidStr);
-    WriteParam(aMsg, nsCAutoString(cidStr));
-    serializable->Write(aMsg);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    bool isNull;
-    if (!ReadParam(aMsg, aIter, &isNull))
-      return false;
-    if (isNull) {
-      aResult->mURI = nullptr;
-      return true;
-    }
-
-    bool isSerialized;
-    if (!ReadParam(aMsg, aIter, &isSerialized))
-      return false;
-    if (!isSerialized) {
-      nsCString spec, charset;
-      if (!ReadParam(aMsg, aIter, &spec) ||
-          !ReadParam(aMsg, aIter, &charset))
-        return false;
-      
-      nsCOMPtr<nsIURI> uri;
-      nsresult rv = NS_NewURI(getter_AddRefs(uri), spec, charset.get());
-      if (NS_FAILED(rv))
-        return false;
-      
-      uri.swap(aResult->mURI);
-      return true;
-    }
-    
-    nsCAutoString cidStr;
-    nsCID cid;
-    if (!ReadParam(aMsg, aIter, &cidStr) ||
-        !cid.Parse(cidStr.get()))
-      return false;
-
-    nsCOMPtr<nsIURI> uri = do_CreateInstance(cid);
-    if (!uri)
-      return false;
-    nsCOMPtr<nsIIPCSerializableObsolete> serializable = do_QueryInterface(uri);
-    if (!serializable || !serializable->Read(aMsg, aIter))
-      return false;
-
-    uri.swap(aResult->mURI);
-    return true;
-  }
-
-  static void Log(const paramType& aParam, std::wstring* aLog)
-  {
-    nsIURI* uri = aParam.mURI;
-    if (uri) {
-      nsCString spec;
-      uri->GetSpec(spec);
-      aLog->append(StringPrintf(L"[%s]", spec.get()));
-    }
-    else {
-      aLog->append(L"[]");
-    }
-  }
-};
-
 // nsIPermissionManager utilities
 
 struct Permission
 {
   nsCString host, type;
   uint32_t capability, expireType;
   int64_t expireTime;
 
@@ -248,9 +118,9 @@ struct ParamTraits<PRNetAddr>
 
     /* We've been tricked by some socket family we don't know about! */
     return false;
   }
 };
 
 }
 
-#endif // mozilla_net_NeckoMessageUtils_h
\ No newline at end of file
+#endif // mozilla_net_NeckoMessageUtils_h
--- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "IPCMessageUtils.h"
-#include "mozilla/net/NeckoMessageUtils.h"
+#include "base/basictypes.h"
 
 #include "nsAboutProtocolHandler.h"
 #include "nsIURI.h"
 #include "nsIIOService.h"
 #include "nsCRT.h"
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsIAboutModule.h"
@@ -287,41 +286,16 @@ nsNestedAboutURI::Write(nsIObjectOutputS
         rv = aStream->WriteCompoundObject(mBaseURI, NS_GET_IID(nsISupports),
                                           true);
         if (NS_FAILED(rv)) return rv;
     }
 
     return NS_OK;
 }
 
-// nsIIPCSerializableObsolete
-bool
-nsNestedAboutURI::Read(const IPC::Message *aMsg, void **aIter)
-{
-    if (!nsSimpleNestedURI::Read(aMsg, aIter))
-        return false;
-
-    IPC::URI uri;
-    if (!ReadParam(aMsg, aIter, &uri))
-        return false;
-
-    mBaseURI = uri;
-
-    return true;
-}
-
-void
-nsNestedAboutURI::Write(IPC::Message *aMsg)
-{
-    nsSimpleNestedURI::Write(aMsg);
-
-    IPC::URI uri(mBaseURI);
-    WriteParam(aMsg, uri);
-}
-
 // nsSimpleURI
 /* virtual */ nsSimpleURI*
 nsNestedAboutURI::StartClone(nsSimpleURI::RefHandlingEnum aRefHandlingMode)
 {
     // Sadly, we can't make use of nsSimpleNestedURI::StartClone here.
     // However, this function is expected to exactly match that function,
     // aside from the "new ns***URI()" call.
     NS_ENSURE_TRUE(mInnerURI, nullptr);
--- a/netwerk/protocol/about/nsAboutProtocolHandler.h
+++ b/netwerk/protocol/about/nsAboutProtocolHandler.h
@@ -7,16 +7,17 @@
 #define nsAboutProtocolHandler_h___
 
 #include "nsIProtocolHandler.h"
 #include "nsSimpleNestedURI.h"
 #include "mozilla/Attributes.h"
 
 class nsCString;
 class nsIAboutModule;
+class nsIURI;
 
 class nsAboutProtocolHandler : public nsIProtocolHandler
 {
 public:
     NS_DECL_ISUPPORTS
 
     // nsIProtocolHandler methods:
     NS_DECL_NSIPROTOCOLHANDLER
@@ -40,18 +41,16 @@ public:
 private:
     ~nsSafeAboutProtocolHandler() {}
 };
 
 
 // Class to allow us to propagate the base URI to about:blank correctly
 class nsNestedAboutURI : public nsSimpleNestedURI {
 public:
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
-
     nsNestedAboutURI(nsIURI* aInnerURI, nsIURI* aBaseURI)
         : nsSimpleNestedURI(aInnerURI)
         , mBaseURI(aBaseURI)
     {}
 
     // For use only from deserialization
     nsNestedAboutURI() : nsSimpleNestedURI() {}
 
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -12,16 +12,17 @@
 #include "nsStringStream.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsIURIFixup.h"
 #include "nsILoadContext.h"
 #include "nsCDefaultURIFixup.h"
 #include "base/compiler_specific.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
@@ -158,20 +159,23 @@ FTPChannelChild::AsyncOpen(::nsIStreamLi
   gNeckoChild->SendPFTPChannelConstructor(this);
   mListener = listener;
   mListenerContext = aContext;
 
   // add ourselves to the load group. 
   if (mLoadGroup)
     mLoadGroup->AddRequest(this, nullptr);
 
+  URIParams uri;
+  SerializeURI(nsBaseChannel::URI(), uri);
+
   OptionalInputStreamParams uploadStream;
   SerializeInputStream(mUploadStream, uploadStream);
 
-  SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID, uploadStream,
+  SendAsyncOpen(uri, mStartPos, mEntityID, uploadStream,
                 IPC::SerializedLoadContext(this));
 
   // The socket transport layer in the chrome process now has a logical ref to
   // us until OnStopRequest is called.
   AddIPDLReference();
 
   mIsPending = true;
   mWasOpened = true;
@@ -199,63 +203,63 @@ FTPChannelChild::OpenContentStream(bool 
 // FTPChannelChild::PFTPChannelChild
 //-----------------------------------------------------------------------------
 
 class FTPStartRequestEvent : public ChannelEvent
 {
  public:
   FTPStartRequestEvent(FTPChannelChild* aChild, const int32_t& aContentLength,
                        const nsCString& aContentType, const PRTime& aLastModified,
-                       const nsCString& aEntityID, const IPC::URI& aURI)
+                       const nsCString& aEntityID, const URIParams& aURI)
   : mChild(aChild), mContentLength(aContentLength), mContentType(aContentType),
     mLastModified(aLastModified), mEntityID(aEntityID), mURI(aURI) {}
   void Run() { mChild->DoOnStartRequest(mContentLength, mContentType,
                                        mLastModified, mEntityID, mURI); }
  private:
   FTPChannelChild* mChild;
   int32_t mContentLength;
   nsCString mContentType;
   PRTime mLastModified;
   nsCString mEntityID;
-  IPC::URI mURI;
+  URIParams mURI;
 };
 
 bool
 FTPChannelChild::RecvOnStartRequest(const int32_t& aContentLength,
                                     const nsCString& aContentType,
                                     const PRTime& aLastModified,
                                     const nsCString& aEntityID,
-                                    const IPC::URI& aURI)
+                                    const URIParams& aURI)
 {
   if (mEventQ.ShouldEnqueue()) {
     mEventQ.Enqueue(new FTPStartRequestEvent(this, aContentLength, aContentType,
                                              aLastModified, aEntityID, aURI));
   } else {
     DoOnStartRequest(aContentLength, aContentType, aLastModified,
                      aEntityID, aURI);
   }
   return true;
 }
 
 void
 FTPChannelChild::DoOnStartRequest(const int32_t& aContentLength,
                                   const nsCString& aContentType,
                                   const PRTime& aLastModified,
                                   const nsCString& aEntityID,
-                                  const IPC::URI& aURI)
+                                  const URIParams& aURI)
 {
   LOG(("FTPChannelChild::RecvOnStartRequest [this=%x]\n", this));
 
   SetContentLength(aContentLength);
   SetContentType(aContentType);
   mLastModifiedTime = aLastModified;
   mEntityID = aEntityID;
 
   nsCString spec;
-  nsCOMPtr<nsIURI> uri(aURI);
+  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   uri->GetSpec(spec);
   nsBaseChannel::URI()->SetSpec(spec);
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
   nsresult rv = mListener->OnStartRequest(this, mListenerContext);
   if (NS_FAILED(rv))
     Cancel(rv);
 }
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -67,29 +67,29 @@ public:
 
   bool IsSuspended();
 
 protected:
   bool RecvOnStartRequest(const int32_t& aContentLength,
                           const nsCString& aContentType,
                           const PRTime& aLastModified,
                           const nsCString& aEntityID,
-                          const IPC::URI& aURI) MOZ_OVERRIDE;
+                          const URIParams& aURI) MOZ_OVERRIDE;
   bool RecvOnDataAvailable(const nsCString& data,
                            const uint32_t& offset,
                            const uint32_t& count) MOZ_OVERRIDE;
   bool RecvOnStopRequest(const nsresult& statusCode) MOZ_OVERRIDE;
   bool RecvFailedAsyncOpen(const nsresult& statusCode) MOZ_OVERRIDE;
   bool RecvDeleteSelf() MOZ_OVERRIDE;
 
   void DoOnStartRequest(const int32_t& aContentLength,
                         const nsCString& aContentType,
                         const PRTime& aLastModified,
                         const nsCString& aEntityID,
-                        const IPC::URI& aURI);
+                        const URIParams& aURI);
   void DoOnDataAvailable(const nsCString& data,
                          const uint32_t& offset,
                          const uint32_t& count);
   void DoOnStopRequest(const nsresult& statusCode);
   void DoFailedAsyncOpen(const nsresult& statusCode);
   void DoDeleteSelf();
 
   friend class FTPStartRequestEvent;
--- a/netwerk/protocol/ftp/FTPChannelParent.cpp
+++ b/netwerk/protocol/ftp/FTPChannelParent.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/net/FTPChannelParent.h"
 #include "nsFTPChannel.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPriority.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "nsFtpProtocolHandler.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 
 namespace mozilla {
 namespace net {
@@ -53,23 +54,25 @@ NS_IMPL_ISUPPORTS4(FTPChannelParent,
                    nsIInterfaceRequestor,
                    nsIRequestObserver)
 
 //-----------------------------------------------------------------------------
 // FTPChannelParent::PFTPChannelParent
 //-----------------------------------------------------------------------------
 
 bool
-FTPChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
+FTPChannelParent::RecvAsyncOpen(const URIParams& aURI,
                                 const uint64_t& aStartPos,
                                 const nsCString& aEntityID,
                                 const OptionalInputStreamParams& aUploadStream,
                                 const IPC::SerializedLoadContext& loadContext)
 {
-  nsCOMPtr<nsIURI> uri(aURI);
+  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
+  if (!uri)
+      return false;
 
 #ifdef DEBUG
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
   LOG(("FTPChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
        this, uriSpec.get()));
 #endif
 
@@ -162,18 +165,21 @@ FTPChannelParent::OnStartRequest(nsIRequ
   chan->GetContentLength(&aContentLength);
   nsCString contentType;
   chan->GetContentType(contentType);
   nsCString entityID;
   chan->GetEntityID(entityID);
   PRTime lastModified;
   chan->GetLastModifiedTime(&lastModified);
 
+  URIParams uri;
+  SerializeURI(chan->URI(), uri);
+
   if (mIPCClosed || !SendOnStartRequest(aContentLength, contentType,
-                                       lastModified, entityID, chan->URI())) {
+                                       lastModified, entityID, uri)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelParent::OnStopRequest(nsIRequest* aRequest,
--- a/netwerk/protocol/ftp/FTPChannelParent.h
+++ b/netwerk/protocol/ftp/FTPChannelParent.h
@@ -29,17 +29,17 @@ public:
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIPARENTCHANNEL
   NS_DECL_NSIINTERFACEREQUESTOR
 
   FTPChannelParent();
   virtual ~FTPChannelParent();
 
 protected:
-  virtual bool RecvAsyncOpen(const IPC::URI& uri,
+  virtual bool RecvAsyncOpen(const URIParams& uri,
                              const uint64_t& startPos,
                              const nsCString& entityID,
                              const OptionalInputStreamParams& uploadStream,
                              const IPC::SerializedLoadContext& loadContext) MOZ_OVERRIDE;
   virtual bool RecvConnectChannel(const uint32_t& channelId) MOZ_OVERRIDE;
   virtual bool RecvCancel(const nsresult& status) MOZ_OVERRIDE;
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
--- a/netwerk/protocol/ftp/PFTPChannel.ipdl
+++ b/netwerk/protocol/ftp/PFTPChannel.ipdl
@@ -1,48 +1,48 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PNecko;
+include InputStreamParams;
+include URIParams;
 
-include "mozilla/net/NeckoMessageUtils.h";
-include IPCSerializableParams;
+include "SerializedLoadContext.h";
 
-using IPC::URI;
 using IPC::SerializedLoadContext;
 using PRTime;
 
 namespace mozilla {
 namespace net {
 
 async protocol PFTPChannel
 {
   manager PNecko;
 
 parent:
   __delete__();
 
-  AsyncOpen(URI uri,
+  AsyncOpen(URIParams uri,
             uint64_t startPos,
             nsCString entityID,
             OptionalInputStreamParams uploadStream,
             SerializedLoadContext loadContext);
 
   ConnectChannel(uint32_t channelId);
   Cancel(nsresult status);
   Suspend();
   Resume();
 
 child:
   OnStartRequest(int32_t aContentLength, nsCString aContentType,
-                 PRTime aLastModified, nsCString aEntityID, URI aURI);
+                 PRTime aLastModified, nsCString aEntityID, URIParams aURI);
   OnDataAvailable(nsCString data, uint32_t offset, uint32_t count);
   OnStopRequest(nsresult statusCode);
   FailedAsyncOpen(nsresult statusCode);
   DeleteSelf();
 };
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -12,17 +12,19 @@
 
 #include "nsStringStream.h"
 #include "nsHttpHandler.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsSerializationHelper.h"
 #include "base/compiler_specific.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
+using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild
 //-----------------------------------------------------------------------------
@@ -650,70 +652,70 @@ HttpChannelChild::DeleteSelf()
   Send__delete__(this);
 }
 
 class Redirect1Event : public ChannelEvent
 {
  public:
   Redirect1Event(HttpChannelChild* child,
                  const uint32_t& newChannelId,
-                 const IPC::URI& newURI,
+                 const URIParams& newURI,
                  const uint32_t& redirectFlags,
                  const nsHttpResponseHead& responseHead)
   : mChild(child)
   , mNewChannelId(newChannelId)
   , mNewURI(newURI)
   , mRedirectFlags(redirectFlags)
   , mResponseHead(responseHead) {}
 
   void Run() 
   { 
     mChild->Redirect1Begin(mNewChannelId, mNewURI, mRedirectFlags,
                            mResponseHead); 
   }
  private:
   HttpChannelChild*   mChild;
   uint32_t            mNewChannelId;
-  IPC::URI            mNewURI;
+  URIParams           mNewURI;
   uint32_t            mRedirectFlags;
   nsHttpResponseHead  mResponseHead;
 };
 
 bool
 HttpChannelChild::RecvRedirect1Begin(const uint32_t& newChannelId,
-                                     const URI& newUri,
+                                     const URIParams& newUri,
                                      const uint32_t& redirectFlags,
                                      const nsHttpResponseHead& responseHead)
 {
   if (mEventQ.ShouldEnqueue()) {
     mEventQ.Enqueue(new Redirect1Event(this, newChannelId, newUri,
                                        redirectFlags, responseHead));
   } else {
     Redirect1Begin(newChannelId, newUri, redirectFlags, responseHead);
   }
   return true;
 }
 
 void
 HttpChannelChild::Redirect1Begin(const uint32_t& newChannelId,
-                                 const IPC::URI& newURI,
+                                 const URIParams& newUri,
                                  const uint32_t& redirectFlags,
                                  const nsHttpResponseHead& responseHead)
 {
   nsresult rv;
 
   nsCOMPtr<nsIIOService> ioService;
   rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
   if (NS_FAILED(rv)) {
     // Veto redirect.  nsHttpChannel decides to cancel or continue.
     OnRedirectVerifyCallback(rv);
     return;
   }
 
-  nsCOMPtr<nsIURI> uri(newURI);
+  nsCOMPtr<nsIURI> uri = DeserializeURI(newUri);
 
   nsCOMPtr<nsIChannel> newChannel;
   rv = ioService->NewChannelFromURI(uri, getter_AddRefs(newChannel));
   if (NS_FAILED(rv)) {
     // Veto redirect.  nsHttpChannel decides to cancel or continue.
     OnRedirectVerifyCallback(rv);
     return;
   }
@@ -1032,21 +1034,28 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
   }
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
   gNeckoChild->SendPHttpChannelConstructor(this, tabChild);
 
+  URIParams uri;
+  SerializeURI(mURI, uri);
+
+  OptionalURIParams originalURI, documentURI, referrer;
+  SerializeURI(mOriginalURI, originalURI);
+  SerializeURI(mDocumentURI, documentURI);
+  SerializeURI(mReferrer, referrer);
+
   OptionalInputStreamParams uploadStream;
   SerializeInputStream(mUploadStream, uploadStream);
 
-  SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI),
-                IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags,
+  SendAsyncOpen(uri, originalURI, documentURI, referrer, mLoadFlags,
                 mClientSetRequestHeaders, mRequestHead.Method(), uploadStream,
                 mUploadStreamHasHeaders, mPriority, mRedirectionLimit,
                 mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt,
                 mStartPos, mEntityID, mChooseApplicationCache,
                 appCacheClientId, mAllowSpdy, IPC::SerializedLoadContext(this));
 
   return NS_OK;
 }
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -105,17 +105,17 @@ protected:
                               const nsCString& data,
                               const uint32_t& offset,
                               const uint32_t& count);
   bool RecvOnStopRequest(const nsresult& statusCode);
   bool RecvOnProgress(const uint64_t& progress, const uint64_t& progressMax);
   bool RecvOnStatus(const nsresult& status);
   bool RecvFailedAsyncOpen(const nsresult& status);
   bool RecvRedirect1Begin(const uint32_t& newChannel,
-                          const URI& newURI,
+                          const URIParams& newURI,
                           const uint32_t& redirectFlags,
                           const nsHttpResponseHead& responseHead);
   bool RecvRedirect3Complete();
   bool RecvAssociateApplicationCache(const nsCString& groupID,
                                      const nsCString& clientID);
   bool RecvDeleteSelf();
 
   bool GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nullptr);
@@ -160,17 +160,17 @@ private:
                           const uint32_t& offset,
                           const uint32_t& count);
   void OnStopRequest(const nsresult& statusCode);
   void OnProgress(const uint64_t& progress, const uint64_t& progressMax);
   void OnStatus(const nsresult& status);
   void FailedAsyncOpen(const nsresult& status);
   void HandleAsyncAbort();
   void Redirect1Begin(const uint32_t& newChannelId,
-                      const URI& newUri,
+                      const URIParams& newUri,
                       const uint32_t& redirectFlags,
                       const nsHttpResponseHead& responseHead);
   void Redirect3Complete();
   void DeleteSelf();
 
   // Called asynchronously from Resume: continues any pending calls into client.
   void CompleteResume();
 
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -20,17 +20,19 @@
 #include "nsISerializable.h"
 #include "nsIAssociatedContentSecurity.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIOfflineCacheUpdate.h"
 #include "nsIRedirectChannelRegistrar.h"
 #include "mozilla/LoadContext.h"
 #include "prinit.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
+using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 HttpChannelParent::HttpChannelParent(PBrowserParent* iframeEmbedding)
   : mIPCClosed(false)
   , mStoredStatus(NS_OK)
@@ -99,20 +101,20 @@ HttpChannelParent::GetInterface(const ns
   return QueryInterface(aIID, result);
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelParent::PHttpChannelParent
 //-----------------------------------------------------------------------------
 
 bool 
-HttpChannelParent::RecvAsyncOpen(const IPC::URI&            aURI,
-                                 const IPC::URI&            aOriginalURI,
-                                 const IPC::URI&            aDocURI,
-                                 const IPC::URI&            aReferrerURI,
+HttpChannelParent::RecvAsyncOpen(const URIParams&           aURI,
+                                 const OptionalURIParams&   aOriginalURI,
+                                 const OptionalURIParams&   aDocURI,
+                                 const OptionalURIParams&   aReferrerURI,
                                  const uint32_t&            loadFlags,
                                  const RequestHeaderTuples& requestHeaders,
                                  const nsHttpAtom&          requestMethod,
                                  const OptionalInputStreamParams& uploadStream,
                                  const bool&              uploadStreamHasHeaders,
                                  const uint16_t&            priority,
                                  const uint8_t&             redirectionLimit,
                                  const bool&              allowPipelining,
@@ -120,20 +122,20 @@ HttpChannelParent::RecvAsyncOpen(const I
                                  const bool&                doResumeAt,
                                  const uint64_t&            startPos,
                                  const nsCString&           entityID,
                                  const bool&                chooseApplicationCache,
                                  const nsCString&           appCacheClientID,
                                  const bool&                allowSpdy,
                                  const IPC::SerializedLoadContext& loadContext)
 {
-  nsCOMPtr<nsIURI> uri(aURI);
-  nsCOMPtr<nsIURI> originalUri(aOriginalURI);
-  nsCOMPtr<nsIURI> docUri(aDocURI);
-  nsCOMPtr<nsIURI> referrerUri(aReferrerURI);
+  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
+  nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
+  nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
+  nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
 
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
   LOG(("HttpChannelParent RecvAsyncOpen [this=%x uri=%s]\n", 
        this, uriSpec.get()));
 
   nsresult rv;
 
@@ -558,21 +560,22 @@ HttpChannelParent::StartRedirect(uint32_
                                  nsIAsyncVerifyRedirectCallback* callback)
 {
   if (mIPCClosed)
     return NS_BINDING_ABORTED;
 
   nsCOMPtr<nsIURI> newURI;
   newChannel->GetURI(getter_AddRefs(newURI));
 
+  URIParams uriParams;
+  SerializeURI(newURI, uriParams);
+
   nsHttpChannel *httpChan = static_cast<nsHttpChannel *>(mChannel.get());
   nsHttpResponseHead *responseHead = httpChan->GetResponseHead();
-  bool result = SendRedirect1Begin(newChannelId,
-                                   IPC::URI(newURI),
-                                   redirectFlags,
+  bool result = SendRedirect1Begin(newChannelId, uriParams, redirectFlags,
                                    responseHead ? *responseHead
                                                 : nsHttpResponseHead());
   if (!result) {
     // Bug 621446 investigation
     mSentRedirect1BeginFailed = true;
     return NS_BINDING_ABORTED;
   }
 
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -12,18 +12,16 @@
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/net/PHttpChannelParent.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsIParentRedirectingChannel.h"
 #include "nsIProgressEventSink.h"
 #include "nsITabParent.h"
 #include "nsHttpChannel.h"
 
-using namespace mozilla::dom;
-
 class nsICacheEntryDescriptor;
 class nsIAssociatedContentSecurity;
 
 namespace mozilla {
 namespace net {
 
 class HttpChannelParentListener;
 
@@ -36,24 +34,24 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIPARENTCHANNEL
   NS_DECL_NSIPARENTREDIRECTINGCHANNEL
   NS_DECL_NSIPROGRESSEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
 
-  HttpChannelParent(PBrowserParent* iframeEmbedding);
+  HttpChannelParent(mozilla::dom::PBrowserParent* iframeEmbedding);
   virtual ~HttpChannelParent();
 
 protected:
-  virtual bool RecvAsyncOpen(const IPC::URI&            uri,
-                             const IPC::URI&            originalUri,
-                             const IPC::URI&            docUri,
-                             const IPC::URI&            referrerUri,
+  virtual bool RecvAsyncOpen(const URIParams&           uri,
+                             const OptionalURIParams&   originalUri,
+                             const OptionalURIParams&   docUri,
+                             const OptionalURIParams&   referrerUri,
                              const uint32_t&            loadFlags,
                              const RequestHeaderTuples& requestHeaders,
                              const nsHttpAtom&          requestMethod,
                              const OptionalInputStreamParams& uploadStream,
                              const bool&              uploadStreamHasHeaders,
                              const uint16_t&            priority,
                              const uint8_t&             redirectionLimit,
                              const bool&              allowPipelining,
--- a/netwerk/protocol/http/HttpChannelParentListener.h
+++ b/netwerk/protocol/http/HttpChannelParentListener.h
@@ -12,18 +12,16 @@
 #include "mozilla/net/NeckoCommon.h"
 #include "PHttpChannelParams.h"
 #include "nsIParentChannel.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIChannelEventSink.h"
 #include "nsIRedirectResultListener.h"
 #include "nsIProgressEventSink.h"
 
-using namespace mozilla::dom;
-
 class nsICacheEntryDescriptor;
 
 namespace mozilla {
 namespace net {
 
 class HttpChannelParent;
 
 class HttpChannelParentListener : public nsIInterfaceRequestor
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -1,47 +1,47 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PNecko;
+include InputStreamParams;
+include URIParams;
 
 include "mozilla/net/PHttpChannelParams.h";
 include "mozilla/net/NeckoMessageUtils.h";
 include "prio.h";
-
-include IPCSerializableParams;
+include "SerializedLoadContext.h";
 
 using RequestHeaderTuples;
 using nsHttpHeaderArray;
 using nsHttpResponseHead;
 using nsHttpAtom;
-using IPC::URI;
 using IPC::SerializedLoadContext;
 using PRNetAddr;
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PHttpChannel
 {
   manager PNecko;
 
 parent:
-  AsyncOpen(URI                 uri,
+  AsyncOpen(URIParams           uri,
             // - TODO: bug 571161: unclear if any HTTP channel clients ever
             // set originalURI != uri (about:credits?); also not clear if
             // chrome channel would ever need to know.  Get rid of next arg?
-            URI                 original,
-            URI                 doc,
-            URI                 referrer,
+            OptionalURIParams   original,
+            OptionalURIParams   doc,
+            OptionalURIParams   referrer,
             uint32_t            loadFlags,
             RequestHeaderTuples requestHeaders,
             nsHttpAtom          requestMethod,
             OptionalInputStreamParams uploadStream,
             bool                uploadStreamHasHeaders,
             uint16_t            priority,
             uint8_t             redirectionLimit,
             bool                allowPipelining,
@@ -125,17 +125,17 @@ child:
 
   // Used to cancel child channel if we hit errors during creating and
   // AsyncOpen of nsHttpChannel on the parent.
   FailedAsyncOpen(nsresult status);
 
   // Called to initiate content channel redirect, starts talking to sinks
   // on the content process and reports result via Redirect2Verify above
   Redirect1Begin(uint32_t           newChannelId,
-                 URI                newUri,
+                 URIParams          newUri,
                  uint32_t           redirectFlags,
                  nsHttpResponseHead responseHead);
 
   // Called if redirect successful so that child can complete setup.
   Redirect3Complete();
 
   // Associte the child with an application ids
   AssociateApplicationCache(nsCString groupID,
--- a/netwerk/protocol/websocket/PWebSocket.ipdl
+++ b/netwerk/protocol/websocket/PWebSocket.ipdl
@@ -2,33 +2,32 @@
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PNecko;
 include protocol PBrowser;
+include InputStreamParams;
+include URIParams;
 
-include "mozilla/net/NeckoMessageUtils.h";
-include IPCSerializableParams;
-
-using IPC::URI;
+include "SerializedLoadContext.h";
 using IPC::SerializedLoadContext;
 
 namespace mozilla {
 namespace net {
 
 async protocol PWebSocket
 {
   manager PNecko;
 
 parent:
   // Forwarded methods corresponding to methods on nsIWebSocketChannel
-  AsyncOpen(URI aURI,
+  AsyncOpen(URIParams aURI,
             nsCString aOrigin,
             nsCString aProtocol,
             bool aSecure,
             SerializedLoadContext loadContext);
   Close(uint16_t code, nsCString reason);
   SendMsg(nsCString aMsg);
   SendBinaryMsg(nsCString aMsg);
   SendBinaryStream(InputStreamParams aStream, uint32_t aLength);
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -7,16 +7,17 @@
 #include "WebSocketLog.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "WebSocketChannelChild.h"
 #include "nsITabChild.h"
 #include "nsILoadContext.h"
 #include "nsNetUtil.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ADDREF(WebSocketChannelChild)
 
@@ -326,21 +327,24 @@ WebSocketChannelChild::AsyncOpen(nsIURI 
   nsCOMPtr<nsITabChild> iTabChild;
   NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
                                 NS_GET_IID(nsITabChild),
                                 getter_AddRefs(iTabChild));
   if (iTabChild) {
     tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
   }
 
+  URIParams uri;
+  SerializeURI(aURI, uri);
+
   // Corresponding release in DeallocPWebSocket
   AddIPDLReference();
 
   gNeckoChild->SendPWebSocketConstructor(this, tabChild);
-  if (!SendAsyncOpen(aURI, nsCString(aOrigin), mProtocol, mEncrypted,
+  if (!SendAsyncOpen(uri, nsCString(aOrigin), mProtocol, mEncrypted,
                      IPC::SerializedLoadContext(this)))
     return NS_ERROR_UNEXPECTED;
 
   mOriginalURI = aURI;
   mURI = mOriginalURI;
   mListener = aListener;
   mContext = aContext;
   mOrigin = aOrigin;
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebSocketLog.h"
 #include "WebSocketChannelParent.h"
 #include "nsIAuthPromptProvider.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(WebSocketChannelParent,
                               nsIWebSocketListener,
@@ -38,24 +39,27 @@ WebSocketChannelParent::RecvDeleteSelf()
 {
   LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
   mChannel = nullptr;
   mAuthProvider = nullptr;
   return mIPCOpen ? Send__delete__(this) : true;
 }
 
 bool
-WebSocketChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
+WebSocketChannelParent::RecvAsyncOpen(const URIParams& aURI,
                                       const nsCString& aOrigin,
                                       const nsCString& aProtocol,
                                       const bool& aSecure,
                                       const IPC::SerializedLoadContext& loadContext)
 {
   LOG(("WebSocketChannelParent::RecvAsyncOpen() %p\n", this));
+
   nsresult rv;
+  nsCOMPtr<nsIURI> uri;
+
   if (aSecure) {
     mChannel =
       do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
   } else {
     mChannel =
       do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
   }
   if (NS_FAILED(rv))
@@ -67,17 +71,23 @@ WebSocketChannelParent::RecvAsyncOpen(co
   rv = mChannel->SetNotificationCallbacks(this);
   if (NS_FAILED(rv))
     goto fail;
 
   rv = mChannel->SetProtocol(aProtocol);
   if (NS_FAILED(rv))
     goto fail;
 
-  rv = mChannel->AsyncOpen(aURI, aOrigin, this, nullptr);
+  uri = DeserializeURI(aURI);
+  if (!uri) {
+    rv = NS_ERROR_FAILURE;
+    goto fail;
+  }
+
+  rv = mChannel->AsyncOpen(uri, aOrigin, this, nullptr);
   if (NS_FAILED(rv))
     goto fail;
 
   return true;
 
 fail:
   mChannel = nullptr;
   return SendOnStop(rv);
--- a/netwerk/protocol/websocket/WebSocketChannelParent.h
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_net_WebSocketChannelParent_h
 #define mozilla_net_WebSocketChannelParent_h
 
 #include "mozilla/net/PWebSocketParent.h"
+#include "nsIInterfaceRequestor.h"
 #include "nsIWebSocketListener.h"
 #include "nsIWebSocketChannel.h"
 #include "nsILoadContext.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 class nsIAuthPromptProvider;
 
@@ -26,17 +27,17 @@ class WebSocketChannelParent : public PW
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIWEBSOCKETLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
 
   WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider);
 
  private:
-  bool RecvAsyncOpen(const IPC::URI& aURI,
+  bool RecvAsyncOpen(const URIParams& aURI,
                      const nsCString& aOrigin,
                      const nsCString& aProtocol,
                      const bool& aSecure,
                      const IPC::SerializedLoadContext& loadContext);
   bool RecvClose(const uint16_t & code, const nsCString & reason);
   bool RecvSendMsg(const nsCString& aMsg);
   bool RecvSendBinaryMsg(const nsCString& aMsg);
   bool RecvSendBinaryStream(const InputStreamParams& aStream,
--- a/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl
+++ b/netwerk/protocol/wyciwyg/PWyciwygChannel.ipdl
@@ -1,32 +1,32 @@
 /* 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 protocol PNecko;
+include URIParams;
 
-include "mozilla/net/NeckoMessageUtils.h";
+include "SerializedLoadContext.h";
 
-using IPC::URI;
 using IPC::SerializedLoadContext;
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PWyciwygChannel
 {
   manager PNecko;
 
 parent:
   __delete__();
 
-  Init(URI uri);
-  AsyncOpen(URI                   originalURI,
+  Init(URIParams uri);
+  AsyncOpen(URIParams             originalURI,
             uint32_t              loadFlags,
             SerializedLoadContext loadContext);
 
   // methods corresponding to those of nsIWyciwygChannel
   WriteToCacheEntry(nsString data);
   CloseCacheEntry(nsresult reason);
   SetCharsetAndSource(int32_t source, nsCString charset);
   SetSecurityInfo(nsCString securityInfo);
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -9,16 +9,19 @@
 
 #include "nsCharsetSource.h"
 #include "nsStringStream.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsISerializable.h"
 #include "nsSerializationHelper.h"
 #include "nsILoadContext.h"
+#include "mozilla/ipc/URIUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS3(WyciwygChannelChild,
                    nsIRequest,
                    nsIChannel,
                    nsIWyciwygChannel)
@@ -64,17 +67,20 @@ WyciwygChannelChild::Init(nsIURI* uri)
 {
   NS_ENSURE_ARG_POINTER(uri);
 
   mState = WCC_INIT;
 
   mURI = uri;
   mOriginalURI = uri;
 
-  SendInit(IPC::URI(mURI));
+  URIParams serializedUri;
+  SerializeURI(uri, serializedUri);
+
+  SendInit(serializedUri);
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelChild::PWyciwygChannelChild
 //-----------------------------------------------------------------------------
 
 class WyciwygStartRequestEvent : public ChannelEvent
@@ -557,18 +563,20 @@ WyciwygChannelChild::AsyncOpen(nsIStream
 
   mListener = aListener;
   mListenerContext = aContext;
   mIsPending = true;
 
   if (mLoadGroup)
     mLoadGroup->AddRequest(this, nullptr);
 
-  SendAsyncOpen(IPC::URI(mOriginalURI), mLoadFlags,
-                IPC::SerializedLoadContext(this));
+  URIParams originalURI;
+  SerializeURI(mOriginalURI, originalURI);
+
+  SendAsyncOpen(originalURI, mLoadFlags, IPC::SerializedLoadContext(this));
 
   mState = WCC_OPENED;
 
   return NS_OK;
 }
 
 
 //-----------------------------------------------------------------------------
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.cpp
@@ -7,16 +7,19 @@
 #include "mozilla/net/WyciwygChannelParent.h"
 #include "nsWyciwygChannel.h"
 #include "nsNetUtil.h"
 #include "nsISupportsPriority.h"
 #include "nsCharsetSource.h"
 #include "nsISerializable.h"
 #include "nsSerializationHelper.h"
 #include "mozilla/LoadContext.h"
+#include "mozilla/ipc/URIUtils.h"
+
+using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 WyciwygChannelParent::WyciwygChannelParent()
  : mIPCClosed(false)
 {
 #if defined(PR_LOGGING)
@@ -46,21 +49,23 @@ NS_IMPL_ISUPPORTS3(WyciwygChannelParent,
                    nsIInterfaceRequestor,
                    nsIRequestObserver)
 
 //-----------------------------------------------------------------------------
 // WyciwygChannelParent::PWyciwygChannelParent
 //-----------------------------------------------------------------------------
 
 bool
-WyciwygChannelParent::RecvInit(const IPC::URI& aURI)
+WyciwygChannelParent::RecvInit(const URIParams& aURI)
 {
   nsresult rv;
 
-  nsCOMPtr<nsIURI> uri(aURI);
+  nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
+  if (!uri)
+    return false;
 
   nsCString uriSpec;
   uri->GetSpec(uriSpec);
   LOG(("WyciwygChannelParent RecvInit [this=%x uri=%s]\n",
        this, uriSpec.get()));
 
   nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
   if (NS_FAILED(rv))
@@ -74,21 +79,23 @@ WyciwygChannelParent::RecvInit(const IPC
   mChannel = do_QueryInterface(chan, &rv);
   if (NS_FAILED(rv))
     return SendCancelEarly(rv);
 
   return true;
 }
 
 bool
-WyciwygChannelParent::RecvAsyncOpen(const IPC::URI& aOriginal,
+WyciwygChannelParent::RecvAsyncOpen(const URIParams& aOriginal,
                                     const uint32_t& aLoadFlags,
                                     const IPC::SerializedLoadContext& loadContext)
 {
-  nsCOMPtr<nsIURI> original(aOriginal);
+  nsCOMPtr<nsIURI> original = DeserializeURI(aOriginal);
+  if (!original)
+    return false;
 
   LOG(("WyciwygChannelParent RecvAsyncOpen [this=%x]\n", this));
 
   if (!mChannel)
     return true;
 
   nsresult rv;
 
--- a/netwerk/protocol/wyciwyg/WyciwygChannelParent.h
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelParent.h
@@ -25,18 +25,18 @@ public:
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
 
   WyciwygChannelParent();
   virtual ~WyciwygChannelParent();
 
 protected:
-  virtual bool RecvInit(const IPC::URI& uri);
-  virtual bool RecvAsyncOpen(const IPC::URI& original,
+  virtual bool RecvInit(const URIParams& uri);
+  virtual bool RecvAsyncOpen(const URIParams& original,
                              const uint32_t& loadFlags,
                              const IPC::SerializedLoadContext& loadContext);
   virtual bool RecvWriteToCacheEntry(const nsString& data);
   virtual bool RecvCloseCacheEntry(const nsresult& reason);
   virtual bool RecvSetCharsetAndSource(const int32_t& source,
                                        const nsCString& charset);
   virtual bool RecvSetSecurityInfo(const nsCString& securityInfo);
   virtual bool RecvCancel(const nsresult& statusCode);
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -23,21 +23,23 @@
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsIXPConnect.h"
 #include "mozilla/unused.h"
 #include "mozilla/Util.h"
 #include "nsContentUtils.h"
 #include "nsIMemoryReporter.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/ipc/URIUtils.h"
 
 // Initial size for the cache holding visited status observers.
 #define VISIT_OBSERVERS_INITIAL_CACHE_SIZE 128
 
 using namespace mozilla::dom;
+using namespace mozilla::ipc;
 using mozilla::unused;
 
 namespace mozilla {
 namespace places {
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Global Defines
 
@@ -303,20 +305,23 @@ public:
   static nsresult Start(nsIURI* aURI,
                         mozIVisitedStatusCallback* aCallback=nullptr)
   {
     NS_PRECONDITION(aURI, "Null URI");
 
   // If we are a content process, always remote the request to the
   // parent process.
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    URIParams uri;
+    SerializeURI(aURI, uri);
+
     mozilla::dom::ContentChild* cpc =
       mozilla::dom::ContentChild::GetSingleton();
     NS_ASSERTION(cpc, "Content Protocol is NULL!");
-    (void)cpc->SendStartVisitedQuery(aURI);
+    (void)cpc->SendStartVisitedQuery(uri);
     return NS_OK;
   }
 
     nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
     NS_ENSURE_STATE(navHistory);
     if (navHistory->hasEmbedVisit(aURI)) {
       nsRefPtr<VisitedQuery> callback = new VisitedQuery(aURI, aCallback, true);
       NS_ENSURE_TRUE(callback, NS_ERROR_OUT_OF_MEMORY);
@@ -1452,20 +1457,22 @@ History::~History()
 void
 History::NotifyVisited(nsIURI* aURI)
 {
   NS_ASSERTION(aURI, "Ruh-roh!  A NULL URI was passed to us!");
 
   nsAutoScriptBlocker scriptBlocker;
 
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
+    URIParams uri;
+    SerializeURI(aURI, uri);
     nsTArray<ContentParent*> cplist;
     ContentParent::GetAll(cplist);
     for (uint32_t i = 0; i < cplist.Length(); ++i) {
-      unused << cplist[i]->SendNotifyVisited(aURI);
+      unused << cplist[i]->SendNotifyVisited(uri);
     }
   }
 
   // If the hash table has not been initialized, then we have nothing to notify
   // about.
   if (!mObservers.IsInitialized()) {
     return;
   }
@@ -1787,20 +1794,26 @@ History::VisitURI(nsIURI* aURI,
                   uint32_t aFlags)
 {
   NS_PRECONDITION(aURI, "URI should not be NULL.");
   if (mShuttingDown) {
     return NS_OK;
   }
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    URIParams uri;
+    SerializeURI(aURI, uri);
+
+    OptionalURIParams lastVisitedURI;
+    SerializeURI(aLastVisitedURI, lastVisitedURI);
+
     mozilla::dom::ContentChild* cpc =
       mozilla::dom::ContentChild::GetSingleton();
     NS_ASSERTION(cpc, "Content Protocol is NULL!");
-    (void)cpc->SendVisitURI(aURI, aLastVisitedURI, aFlags);
+    (void)cpc->SendVisitURI(uri, lastVisitedURI, aFlags);
     return NS_OK;
   } 
 
   nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
   NS_ENSURE_TRUE(navHistory, NS_ERROR_OUT_OF_MEMORY);
 
   // Silently return if URI is something we shouldn't add to DB.
   bool canAdd;
@@ -1990,20 +2003,23 @@ NS_IMETHODIMP
 History::SetURITitle(nsIURI* aURI, const nsAString& aTitle)
 {
   NS_PRECONDITION(aURI, "Must pass a non-null URI!");
   if (mShuttingDown) {
     return NS_OK;
   }
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    URIParams uri;
+    SerializeURI(aURI, uri);
+
     mozilla::dom::ContentChild * cpc = 
       mozilla::dom::ContentChild::GetSingleton();
     NS_ASSERTION(cpc, "Content Protocol is NULL!");
-    (void)cpc->SendSetURITitle(aURI, nsString(aTitle));
+    (void)cpc->SendSetURITitle(uri, nsString(aTitle));
     return NS_OK;
   } 
 
   nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
 
   // At first, it seems like nav history should always be available here, no
   // matter what.
   //
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -6,57 +6,63 @@
 
 #include "ExternalHelperAppParent.h"
 #include "nsIContent.h"
 #include "nsCExternalHandlerService.h"
 #include "nsIExternalHelperAppService.h"
 #include "mozilla/dom/ContentParent.h"
 #include "nsIBrowserDOMWindow.h"
 #include "nsStringStream.h"
+#include "mozilla/ipc/URIUtils.h"
 
 #include "mozilla/unused.h"
 #include "mozilla/Util.h" // for DebugOnly
 
+using namespace mozilla::ipc;
+
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS_INHERITED4(ExternalHelperAppParent,
                              nsHashPropertyBag,
                              nsIRequest,
                              nsIChannel,
                              nsIMultiPartChannel,
                              nsIResumableChannel)
 
 ExternalHelperAppParent::ExternalHelperAppParent(
-    const IPC::URI& uri,
+    const OptionalURIParams& uri,
     const int64_t& aContentLength)
-  : mURI(uri)
+  : mURI(DeserializeURI(uri))
   , mPending(false)
   , mLoadFlags(0)
   , mStatus(NS_OK)
   , mContentLength(aContentLength)
 {
 }
 
 void
 ExternalHelperAppParent::Init(ContentParent *parent,
                               const nsCString& aMimeContentType,
                               const nsCString& aContentDispositionHeader,
                               const bool& aForceSave,
-                              const IPC::URI& aReferrer)
+                              const OptionalURIParams& aReferrer)
 {
   nsHashPropertyBag::Init();
 
   nsCOMPtr<nsIExternalHelperAppService> helperAppService =
     do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
   NS_ASSERTION(helperAppService, "No Helper App Service!");
 
   SetPropertyAsInt64(NS_CHANNEL_PROP_CONTENT_LENGTH, mContentLength);
-  if (aReferrer)
-    SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), aReferrer);
+
+  nsCOMPtr<nsIURI> referrer = DeserializeURI(aReferrer);
+  if (referrer)
+    SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), referrer);
+
   mContentDispositionHeader = aContentDispositionHeader;
   NS_GetFilenameFromDisposition(mContentDispositionFilename, mContentDispositionHeader, mURI);
   mContentDisposition = NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
   helperAppService->DoContent(aMimeContentType, this, nullptr,
                               aForceSave, getter_AddRefs(mListener));
 }
 
 bool
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -10,52 +10,59 @@
 #include "nsIResumableChannel.h"
 #include "nsHashPropertyBag.h"
 
 namespace IPC {
 class URI;
 }
 
 namespace mozilla {
+
+namespace ipc {
+class OptionalURIParams;
+} // namespace ipc
+
 namespace dom {
 
 class ContentParent;
 
 class ExternalHelperAppParent : public PExternalHelperAppParent
                               , public nsHashPropertyBag
                               , public nsIChannel
                               , public nsIMultiPartChannel
                               , public nsIResumableChannel
 {
+    typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
+
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIREQUEST
     NS_DECL_NSICHANNEL
     NS_DECL_NSIMULTIPARTCHANNEL
     NS_DECL_NSIRESUMABLECHANNEL
 
     bool RecvOnStartRequest(const nsCString& entityID);
     bool RecvOnDataAvailable(const nsCString& data, const uint32_t& offset, const uint32_t& count);
     bool RecvOnStopRequest(const nsresult& code);
-    
-    ExternalHelperAppParent(const IPC::URI& uri, const int64_t& contentLength);
+
+    ExternalHelperAppParent(const OptionalURIParams& uri, const int64_t& contentLength);
     void Init(ContentParent *parent,
               const nsCString& aMimeContentType,
               const nsCString& aContentDisposition,
               const bool& aForceSave,
-              const IPC::URI& aReferrer);
+              const OptionalURIParams& aReferrer);
     virtual ~ExternalHelperAppParent();
 
 private:
   nsCOMPtr<nsIStreamListener> mListener;
   nsCOMPtr<nsIURI> mURI;
   bool mPending;
   nsLoadFlags mLoadFlags;
   nsresult mStatus;
   int64_t mContentLength;
   uint32_t mContentDisposition;
   nsString mContentDispositionFilename;
   nsCString mContentDispositionHeader;
   nsCString mEntityID;
 };
 
 } // namespace dom
-} // namespace mozilla
+} // namespace mozilla
\ No newline at end of file
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -107,18 +107,20 @@
 #include "nsIDocShellTreeItem.h"
 #include "ExternalHelperAppChild.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 #include "mozilla/Preferences.h"
+#include "mozilla/ipc/URIUtils.h"
 
 using namespace mozilla;
+using namespace mozilla::ipc;
 
 // Buffer file writes in 32kb chunks
 #define BUFFERED_OUTPUT_SIZE (1024 * 32)
 
 // Download Folder location constants
 #define NS_PREF_DOWNLOAD_DIR        "browser.download.dir"
 #define NS_PREF_DOWNLOAD_FOLDERLIST "browser.download.folderList"
 enum {
@@ -581,26 +583,29 @@ NS_IMETHODIMP nsExternalHelperAppService
 
     nsCString disp;
     if (channel)
       channel->GetContentDispositionHeader(disp);
 
     nsCOMPtr<nsIURI> referrer;
     rv = NS_GetReferrerFromChannel(channel, getter_AddRefs(referrer));
 
+    OptionalURIParams uriParams, referrerParams;
+    SerializeURI(uri, uriParams);
+    SerializeURI(referrer, referrerParams);
+
     // Now we build a protocol for forwarding our data to the parent.  The
     // protocol will act as a listener on the child-side and create a "real"
     // helperAppService listener on the parent-side, via another call to
     // DoContent.
-    mozilla::dom::PExternalHelperAppChild *pc;
-    pc = child->SendPExternalHelperAppConstructor(IPC::URI(uri),
-                                                  nsCString(aMimeContentType),
-                                                  disp,
-                                                  aForceSave, contentLength,
-                                                  IPC::URI(referrer));
+    mozilla::dom::PExternalHelperAppChild *pc =
+      child->SendPExternalHelperAppConstructor(uriParams,
+                                               nsCString(aMimeContentType),
+                                               disp, aForceSave, contentLength,
+                                               referrerParams);
     ExternalHelperAppChild *childListener = static_cast<ExternalHelperAppChild *>(pc);
 
     NS_ADDREF(*aStreamListener = childListener);
 
     nsRefPtr<nsExternalAppHandler> handler =
       new nsExternalAppHandler(nullptr, EmptyCString(), aWindowContext, this,
                                fileName,
                                reason, aForceSave);
@@ -835,17 +840,20 @@ static const char kExternalProtocolDefau
 
 NS_IMETHODIMP 
 nsExternalHelperAppService::LoadURI(nsIURI *aURI,
                                     nsIInterfaceRequestor *aWindowContext)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    mozilla::dom::ContentChild::GetSingleton()->SendLoadURIExternal(aURI);
+    URIParams uri;
+    SerializeURI(aURI, uri);
+
+    mozilla::dom::ContentChild::GetSingleton()->SendLoadURIExternal(uri);
     return NS_OK;
   }
 
   nsCAutoString spec;
   aURI->GetSpec(spec);
 
   if (spec.Find("%00") != -1)
     return NS_ERROR_MALFORMED_URI;
--- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp
@@ -2,16 +2,17 @@
 /* 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 "OfflineCacheUpdateChild.h"
 #include "nsOfflineCacheUpdate.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabChild.h"
+#include "mozilla/ipc/URIUtils.h"
 
 #include "nsIApplicationCacheContainer.h"
 #include "nsIApplicationCacheChannel.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDOMWindow.h"
@@ -24,16 +25,18 @@
 #include "nsNetUtil.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsProxyRelease.h"
 #include "prlog.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 
+using namespace mozilla::ipc;
+
 #if defined(PR_LOGGING)
 //
 // To enable logging (see prlog.h for full details):
 //
 //    set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
 //    set NSPR_LOG_FILE=offlineupdate.log
 //
 // this enables PR_LOG_ALWAYS level information and places all output in
@@ -372,23 +375,27 @@ OfflineCacheUpdateChild::Schedule()
     nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(docshell);
     if (!item) {
       NS_WARNING("doc shell tree item is null");
       return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIDocShellTreeOwner> owner;
     item->GetTreeOwner(getter_AddRefs(owner));
-    
+
     nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
     if (!tabchild) {
       NS_WARNING("tab is null");
       return NS_ERROR_FAILURE;
     }
 
+    URIParams manifestURI, documentURI;
+    SerializeURI(mManifestURI, manifestURI);
+    SerializeURI(mDocumentURI, documentURI);
+
     // because owner implements nsITabChild, we can assume that it is
     // the one and only TabChild.
     mozilla::dom::TabChild* child = static_cast<mozilla::dom::TabChild*>(tabchild.get());
     
     nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
     if (observerService) {
       LOG(("Calling offline-cache-update-added"));
@@ -404,21 +411,18 @@ OfflineCacheUpdateChild::Schedule()
     // This tells the update to cache this document even in case the manifest
     // has not been changed since the last fetch.
     // See also nsOfflineCacheUpdate::ScheduleImplicit.
     bool stickDocument = mDocument != nullptr; 
 
     // Need to addref ourself here, because the IPC stack doesn't hold
     // a reference to us. Will be released in RecvFinish() that identifies 
     // the work has been done.
-    child->SendPOfflineCacheUpdateConstructor(this,
-                                              IPC::URI(mManifestURI),
-                                              IPC::URI(mDocumentURI),
-                                              mClientID,
-                                              stickDocument);
+    child->SendPOfflineCacheUpdateConstructor(this, manifestURI, documentURI,
+                                              mClientID, stickDocument);
 
     mIPCActivated = true;
     this->AddRef();
 
     return NS_OK;
 }
 
 bool
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -1,17 +1,21 @@
 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "OfflineCacheUpdateParent.h"
+
+#include "mozilla/ipc/URIUtils.h"
 #include "nsOfflineCacheUpdate.h"
 #include "nsIApplicationCache.h"
 
+using namespace mozilla::ipc;
+
 #if defined(PR_LOGGING)
 //
 // To enable logging (see prlog.h for full details):
 //
 //    set NSPR_LOG_MODULES=nsOfflineCacheUpdate:5
 //    set NSPR_LOG_FILE=offlineupdate.log
 //
 // this enables PR_LOG_ALWAYS level information and places all output in
@@ -55,26 +59,31 @@ OfflineCacheUpdateParent::~OfflineCacheU
 
 void
 OfflineCacheUpdateParent::ActorDestroy(ActorDestroyReason why)
 {
     mIPCClosed = true;
 }
 
 nsresult
-OfflineCacheUpdateParent::Schedule(const URI& aManifestURI,
-                                   const URI& aDocumentURI,
+OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI,
+                                   const URIParams& aDocumentURI,
                                    const nsCString& aClientID,
                                    const bool& stickDocument)
 {
     LOG(("OfflineCacheUpdateParent::RecvSchedule [%p]", this));
 
     nsRefPtr<nsOfflineCacheUpdate> update;
-    nsCOMPtr<nsIURI> manifestURI(aManifestURI);
-    nsCOMPtr<nsIURI> documentURI(aDocumentURI);
+    nsCOMPtr<nsIURI> manifestURI = DeserializeURI(aManifestURI);
+    if (!manifestURI)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsIURI> documentURI = DeserializeURI(aDocumentURI);
+    if (!documentURI)
+        return NS_ERROR_FAILURE;
 
     nsOfflineCacheUpdateService* service =
         nsOfflineCacheUpdateService::EnsureService();
     if (!service)
         return NS_ERROR_FAILURE;
 
     service->FindUpdate(manifestURI, documentURI, getter_AddRefs(update));
     if (!update) {
--- a/uriloader/prefetch/OfflineCacheUpdateParent.h
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.h
@@ -7,36 +7,44 @@
 #define nsOfflineCacheUpdateParent_h
 
 #include "mozilla/docshell/POfflineCacheUpdateParent.h"
 #include "nsIOfflineCacheUpdate.h"
 
 #include "nsString.h"
 
 namespace mozilla {
+
+namespace ipc {
+class URIParams;
+} // namespace ipc
+
 namespace docshell {
 
 class OfflineCacheUpdateParent : public POfflineCacheUpdateParent
                                , public nsIOfflineCacheUpdateObserver
 {
+    typedef mozilla::ipc::URIParams URIParams;
+
+public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER
 
     nsresult
-    Schedule(const URI& manifestURI,
-             const URI& documentURI,
+    Schedule(const URIParams& manifestURI,
+             const URIParams& documentURI,
              const nsCString& clientID,
              const bool& stickDocument);
 
     OfflineCacheUpdateParent();
     ~OfflineCacheUpdateParent();
 
     virtual void ActorDestroy(ActorDestroyReason why);
 
 private:
     void RefcountHitZero();
     bool mIPCClosed;
 };
 
-}
-}
+} // namespace docshell
+} // namespace mozilla
 
 #endif
--- a/uriloader/prefetch/POfflineCacheUpdate.ipdl
+++ b/uriloader/prefetch/POfflineCacheUpdate.ipdl
@@ -2,20 +2,16 @@
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* 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 protocol PBrowser;
 
-include "mozilla/net/NeckoMessageUtils.h";
-
-using IPC::URI;
-
 namespace mozilla {
 namespace docshell {
 
 //-------------------------------------------------------------------
 protocol POfflineCacheUpdate
 {
   manager PBrowser;
 
--- a/widget/xpwidgets/nsFilePickerProxy.cpp
+++ b/widget/xpwidgets/nsFilePickerProxy.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentChild.h"
 #include "nsFilePickerProxy.h"
+#include "nsNetUtil.h"
 
 
 NS_IMPL_ISUPPORTS1(nsFilePickerProxy, nsIFilePicker)
 
 nsFilePickerProxy::nsFilePickerProxy()
 { 
 }
 
--- a/xpcom/io/nsMultiplexInputStream.cpp
+++ b/xpcom/io/nsMultiplexInputStream.cpp
@@ -3,29 +3,27 @@
  * 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/. */
 
 /**
  * The multiplex stream concatenates a list of input streams into a single
  * stream.
  */
 
-#include "IPC/IPCMessageUtils.h"
-#include "mozilla/Attributes.h"
+#include "base/basictypes.h"
 
 #include "nsMultiplexInputStream.h"
+#include "mozilla/Attributes.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsISeekableStream.h"
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIIPCSerializableInputStream.h"
 #include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/IPCSerializableParams.h"
 
 using namespace mozilla::ipc;
 
 class nsMultiplexInputStream MOZ_FINAL : public nsIMultiplexInputStream,
                                          public nsISeekableStream,
                                          public nsIIPCSerializableInputStream
 {
 public:
--- a/xpcom/io/nsStringStream.cpp
+++ b/xpcom/io/nsStringStream.cpp
@@ -14,41 +14,38 @@
 #include "nsStreamUtils.h"
 #include "nsReadableUtils.h"
 #include "nsISeekableStream.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCRT.h"
 #include "prerror.h"
 #include "plstr.h"
 #include "nsIClassInfoImpl.h"
-#include "nsIIPCSerializableObsolete.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/ipc/IPCSerializableParams.h"
+#include "mozilla/ipc/InputStreamUtils.h"
 #include "nsIIPCSerializableInputStream.h"
 
 using namespace mozilla::ipc;
 
 //-----------------------------------------------------------------------------
 // nsIStringInputStream implementation
 //-----------------------------------------------------------------------------
 
 class nsStringInputStream MOZ_FINAL : public nsIStringInputStream
                                     , public nsISeekableStream
                                     , public nsISupportsCString
-                                    , public nsIIPCSerializableObsolete
                                     , public nsIIPCSerializableInputStream
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINPUTSTREAM
     NS_DECL_NSISTRINGINPUTSTREAM
     NS_DECL_NSISEEKABLESTREAM
     NS_DECL_NSISUPPORTSPRIMITIVE
     NS_DECL_NSISUPPORTSCSTRING
-    NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
 
     nsStringInputStream()
     {
         Clear();
     }
 
 private:
@@ -81,22 +78,21 @@ private:
 
 // This class needs to support threadsafe refcounting since people often
 // allocate a string stream, and then read it from a background thread.
 NS_IMPL_THREADSAFE_ADDREF(nsStringInputStream)
 NS_IMPL_THREADSAFE_RELEASE(nsStringInputStream)
 
 NS_IMPL_CLASSINFO(nsStringInputStream, NULL, nsIClassInfo::THREADSAFE,
                   NS_STRINGINPUTSTREAM_CID)
-NS_IMPL_QUERY_INTERFACE6_CI(nsStringInputStream,
+NS_IMPL_QUERY_INTERFACE5_CI(nsStringInputStream,
                             nsIStringInputStream,
                             nsIInputStream,
                             nsISupportsCString,
                             nsISeekableStream,
-                            nsIIPCSerializableObsolete,
                             nsIIPCSerializableInputStream)
 NS_IMPL_CI_INTERFACE_GETTER4(nsStringInputStream,
                              nsIStringInputStream,
                              nsIInputStream,
                              nsISupportsCString,
                              nsISeekableStream)
 
 /////////
@@ -288,45 +284,16 @@ nsStringInputStream::SetEOF()
 {
     if (Closed())
         return NS_BASE_STREAM_CLOSED;
 
     mOffset = Length();
     return NS_OK;
 }
 
-/////////
-// nsIIPCSerializableObsolete implementation
-/////////
-
-bool
-nsStringInputStream::Read(const IPC::Message *aMsg, void **aIter)
-{
-    using IPC::ReadParam;
-
-    nsCString value;
-
-    if (!ReadParam(aMsg, aIter, &value))
-        return false;
-
-    nsresult rv = SetData(value);
-    if (NS_FAILED(rv))
-        return false;
-
-    return true;
-}
-
-void
-nsStringInputStream::Write(IPC::Message *aMsg)
-{
-    using IPC::WriteParam;
-
-    WriteParam(aMsg, static_cast<const nsCString&>(PromiseFlatCString(mData)));
-}
-
 void
 nsStringInputStream::Serialize(InputStreamParams& aParams)
 {
     StringInputStreamParams params;
     params.data() = PromiseFlatCString(mData);
     aParams = params;
 }