Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 15 Nov 2012 20:21:35 -0500
changeset 113409 58ebb638a7ea6c3a4a19fa45c0bd8b9818c12542
parent 113378 a37525d304d933d39836a1639b73da440a715602 (current diff)
parent 113408 bbf5d4a4e73e4a7e136f0a9a8c7fbcf88d0cd1af (diff)
child 113410 a50a77da3cf90fa73b3cf00ad78ba18de36f3e89
child 113447 b7c7be527638eb90e30e46f757582cb77924afbc
child 117344 0b9c66c707ae2442b61e13fbec8c605fd3090c9f
push id23870
push userryanvm@gmail.com
push dateFri, 16 Nov 2012 01:21:36 +0000
treeherdermozilla-central@58ebb638a7ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone19.0a1
first release with
nightly linux32
58ebb638a7ea / 19.0a1 / 20121116030725 / files
nightly linux64
58ebb638a7ea / 19.0a1 / 20121116030725 / files
nightly mac
58ebb638a7ea / 19.0a1 / 20121116030725 / files
nightly win32
58ebb638a7ea / 19.0a1 / 20121116030725 / files
nightly win64
58ebb638a7ea / 19.0a1 / 20121116030725 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
accessible/src/xforms/Makefile.in
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xforms/nsXFormsAccessible.h
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.h
accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
accessible/src/xforms/nsXFormsWidgetsAccessible.h
b2g/installer/package-manifest.in
browser/themes/winstripe/downloads/download-glow-aero.png
content/base/public/nsIXFormsUtilityService.h
layout/reftests/svg/inline-in-xul-basic-01.xul
toolkit/toolkit-makefiles.sh
--- a/accessible/build/Makefile.in
+++ b/accessible/build/Makefile.in
@@ -24,17 +24,16 @@ CPPSRCS		= nsAccessibilityFactory.cpp
 LOCAL_INCLUDES	= -I$(srcdir)/../src
 
 SHARED_LIBRARY_LIBS = \
   ../src/base/$(LIB_PREFIX)accessibility_base_s.$(LIB_SUFFIX) \
   ../src/generic/$(LIB_PREFIX)accessibility_generic_s.$(LIB_SUFFIX) \
   ../src/html/$(LIB_PREFIX)accessibility_html_s.$(LIB_SUFFIX) \
   ../src/xpcom/$(LIB_PREFIX)accessibility_xpcom_s.$(LIB_SUFFIX) \
   ../src/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) \
-  ../src/xforms/$(LIB_PREFIX)accessibility_xforms_s.$(LIB_SUFFIX) \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 SHARED_LIBRARY_LIBS += \
   ../src/windows/ia2/$(LIB_PREFIX)accessibility_toolkit_ia2_s.$(LIB_SUFFIX) \
   ../src/windows/uia/$(LIB_PREFIX)accessibility_toolkit_uia_s.$(LIB_SUFFIX) \
   $(NULL)
 endif
--- a/accessible/public/nsIAccessibleProvider.idl
+++ b/accessible/public/nsIAccessibleProvider.idl
@@ -6,17 +6,17 @@
 
 #include "nsISupports.idl"
 
 /**
  * nsIAccessibleProvider interface is used to link element and accessible
    object. For that XBL binding of element should implement the interface.
  */
 
-[scriptable, uuid(ac0639d5-f95b-4e2b-970c-9eab281fb6a5)]
+[scriptable, uuid(f7e531b6-bc29-4d3d-8c91-60fc2b71eb40)]
 interface nsIAccessibleProvider : nsISupports
 {
   /**
    * Constants set of common use.
    */
 
   /** Do not create an accessible for this object
    * This is useful if an ancestor binding already implements nsIAccessibleProvider,
@@ -71,68 +71,13 @@ interface nsIAccessibleProvider : nsISup
   const long XULTree             = 0x0000101D;
   const long XULTreeColumns      = 0x0000101E;
   const long XULTreeColumnItem   = 0x0000101F;
   const long XULToolbar          = 0x00001020;
   const long XULToolbarSeparator = 0x00001021;
   const long XULTooltip          = 0x00001022;
   const long XULToolbarButton    = 0x00001023;
 
-
-  /**
-   * Constants set is used by XForms elements.
-   */
-
-  /** Used for xforms elements that provide accessible object for itself as
-   * well for anonymous content. This property are used for upload,
-   * input[type="xsd:gDay"] and input[type="xsd:gMonth"] */
-  const long XFormsContainer = 0x00002000;
-
-  /** Used for label element */
-  const long XFormsLabel = 0x00002001;
-  /** Used for output element */
-  const long XFormsOutput = 0x00002002;
-  /** Used for trigger and submit elements */
-  const long XFormsTrigger = 0x00002003;
-  /** Used for input and textarea elements */
-  const long XFormsInput = 0x00002004;
-  /** Used for input[xsd:boolean] element */
-  const long XFormsInputBoolean = 0x00002005;
-  /** Used for input[xsd:date] element */
-  const long XFormsInputDate = 0x00002006;
-  /** Used for secret element */
-  const long XFormsSecret = 0x00002007;
-  /** Used for range element represented by slider */
-  const long XFormsSliderRange = 0x00002008;
-
-  /** Used for select and select1 that are implemented using host document's
-   * native widget. For example, a select1 in a xhtml document may be
-   * represented by the native html control html:select */
-  const long XFormsSelect = 0x00002009;
-  /** Used for xforms choices element */
-  const long XFormsChoices = 0x00002010;
-  /** Used for xforms full select/select1 elements that may be represented by
-   * group of checkboxes and radiogroup */
-  const long XFormsSelectFull = 0x00002011;
-  /** Used for xforms item element that is used inside xforms select elements
-   * represented by group of checkboxes */
-  const long XFormsItemCheckgroup = 0x00002012;
-  /** Used for xforms item element that is used inside xforms select1 elements
-   * represented by radio group */
-  const long XFormsItemRadiogroup = 0x00002013;
-  /** Used for xforms select1 element that is represented by combobox */
-  const long XFormsSelectCombobox = 0x00002014;
-  /** Used for xforms item element that is used inside xforms select1
-   * elements represented by combobox */
-  const long XFormsItemCombobox = 0x00002015;
-
-  /** Used for dropmarker widget that is used by xforms elements */
-  const long XFormsDropmarkerWidget = 0x00002101;
-  /** Used for calendar widget that is used by xforms elements */
-  const long XFormsCalendarWidget = 0x00002102;
-  /** Used for popup widget that is used by xforms minimal select1 elements */
-  const long XFormsComboboxPopupWidget = 0x00002103;
-
   /**
    * Return one of constants declared above.
    */
   readonly attribute long accessibleType;
 };
--- a/accessible/public/nsIAccessibleRole.idl
+++ b/accessible/public/nsIAccessibleRole.idl
@@ -57,17 +57,17 @@ interface nsIAccessibleRole : nsISupport
    */
   const unsigned long ROLE_CARET = 7;
 
   /**
    * Represents an alert or a condition that a user should be notified about.
    * Assistive Technologies typically respond to the role by reading the entire
    * onscreen contents of containers advertising this role. Should be used for
    * warning dialogs, etc. The role is used by xul:browsermessage,
-   * role="alert", xforms:message.
+   * role="alert".
    */
   const unsigned long ROLE_ALERT = 8;
 
   /**
    * Represents the window frame, which contains child objects such as
    * a title bar, client, and other objects contained in a window. The role
    * is supported automatically by MS Windows.
    */
@@ -197,18 +197,17 @@ interface nsIAccessibleRole : nsISupport
    * Represents a cell within a table. It is used for html:td,
    * xul:tree cell and xul:listcell. Also, see ROLE_TABLE.
    */
   const unsigned long ROLE_CELL = 29;
 
   /**
    * Represents a link to something else. This object might look like text or
    * a graphic, but it acts like a button. It is used for
-   * xul:label@class="text-link", html:a, html:area,
-   * xforms:trigger@appearance="minimal".
+   * xul:label@class="text-link", html:a, html:area.
    */
   const unsigned long ROLE_LINK = 30;
 
   /**
    * Displays a Help topic in the form of a ToolTip or Help balloon.
    */
   const unsigned long ROLE_HELPBALLOON = 31;
 
@@ -264,35 +263,34 @@ interface nsIAccessibleRole : nsISupport
   /**
    * Represents a picture. Is is used for xul:image, html:img.
    */
   const unsigned long ROLE_GRAPHIC = 40;
 
   /**
    * Represents read-only text, such as labels for other controls or
    * instructions in a dialog box. Static text cannot be modified or selected.
-   * Is is used for xul:label, xul:description, html:label, role="label",
-   * or xforms:output.
+   * Is is used for xul:label, xul:description, html:label, role="label".
    */
   const unsigned long ROLE_STATICTEXT = 41;
 
   /**
    * Represents selectable text that allows edits or is designated read-only.
    */
   const unsigned long ROLE_TEXT_LEAF = 42;
 
   /**
    * Represents a push button control. It is used for xul:button, html:button,
-   * role="button", xforms:trigger, xforms:submit.
+   * role="button".
    */
   const unsigned long ROLE_PUSHBUTTON = 43;
 
   /**
    * Represents a check box control. It is used for xul:checkbox,
-   * html:input@type="checkbox", role="checkbox", boolean xforms:input.
+   * html:input@type="checkbox", role="checkbox".
    */
   const unsigned long ROLE_CHECKBUTTON = 44;
 
   /**
    * Represents an option button, also called a radio button. It is one of a
    * group of mutually exclusive options. All objects sharing a single parent
    * that have this attribute are assumed to be part of single mutually
    * exclusive group. It is used for xul:radio, html:input@type="radio",
@@ -303,17 +301,17 @@ interface nsIAccessibleRole : nsISupport
   /**
    * Represents a combo box; an edit control with an associated list box that
    * provides a set of predefined choices. It is used for html:select,
    * xul:menulist, role="combobox".
    */
   const unsigned long ROLE_COMBOBOX = 46;
 
   /**
-   * Represents the calendar control. It is used for date xforms:input.
+   * Represents the calendar control.
    */
   const unsigned long ROLE_DROPLIST = 47;
 
   /**
    * Represents a progress bar, dynamically showing the user the percent
    * complete of an operation in progress. It is used for xul:progressmeter,
    * role="progressbar".
    */
@@ -328,17 +326,17 @@ interface nsIAccessibleRole : nsISupport
    * Represents a hot-key field that allows the user to enter a combination or
    * sequence of keystrokes.
    */
   const unsigned long ROLE_HOTKEYFIELD = 50;
 
   /**
    * Represents a slider, which allows the user to adjust a setting in given
    * increments between minimum and maximum values. It is used by xul:scale,
-   * role="slider", xforms:range.
+   * role="slider".
    */
   const unsigned long ROLE_SLIDER = 51;
 
   /**
    * Represents a spin box, which is a control that allows the user to increment
    * or decrement the value displayed in a separate "buddy" control associated
    * with the spin box. It is used for xul:spinbuttons.
    */
--- a/accessible/src/Makefile.in
+++ b/accessible/src/Makefile.in
@@ -39,16 +39,15 @@ endif
 DIRS += $(PLATFORM_DIR)
 
 DIRS += \
   base \
   generic \
   html \
   jsat \
   xpcom \
-  xforms \
   $(null)
 
 ifdef MOZ_XUL
 DIRS +=   xul
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -74,17 +74,16 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../generic \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../xul \
-  -I$(srcdir)/../xforms \
   -I$(srcdir)/../../../layout/generic \
   -I$(srcdir)/../../../layout/style \
   -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
--- a/accessible/src/base/Role.h
+++ b/accessible/src/base/Role.h
@@ -64,17 +64,17 @@ enum Role {
    */
   CARET = 7,
 
   /**
    * Represents an alert or a condition that a user should be notified about.
    * Assistive Technologies typically respond to the role by reading the entire
    * onscreen contents of containers advertising this role. Should be used for
    * warning dialogs, etc. The role is used by xul:browsermessage,
-   * role="alert", xforms:message.
+   * role="alert".
    */
   ALERT = 8,
 
   /**
    * Represents the window frame, which contains child objects such as
    * a title bar, client, and other objects contained in a window. The role
    * is supported automatically by MS Windows.
    */
@@ -204,18 +204,17 @@ enum Role {
    * Represents a cell within a table. It is used for html:td,
    * xul:tree cell and xul:listcell. Also, see TABLE.
    */
   CELL = 29,
 
   /**
    * Represents a link to something else. This object might look like text or
    * a graphic, but it acts like a button. It is used for
-   * xul:label@class="text-link", html:a, html:area,
-   * xforms:trigger@appearance="minimal".
+   * xul:label@class="text-link", html:a, html:area.
    */
   LINK = 30,
 
   /**
    * Displays a Help topic in the form of a ToolTip or Help balloon.
    */
   HELPBALLOON = 31,
 
@@ -271,35 +270,34 @@ enum Role {
   /**
    * Represents a picture. Is is used for xul:image, html:img.
    */
   GRAPHIC = 40,
 
   /**
    * Represents read-only text, such as labels for other controls or
    * instructions in a dialog box. Static text cannot be modified or selected.
-   * Is is used for xul:label, xul:description, html:label, role="label",
-   * or xforms:output.
+   * Is is used for xul:label, xul:description, html:label, role="label".
    */
   STATICTEXT = 41,
 
   /**
    * Represents selectable text that allows edits or is designated read-only.
    */
   TEXT_LEAF = 42,
 
   /**
    * Represents a push button control. It is used for xul:button, html:button,
-   * role="button", xforms:trigger, xforms:submit.
+   * role="button".
    */
   PUSHBUTTON = 43,
 
   /**
    * Represents a check box control. It is used for xul:checkbox,
-   * html:input@type="checkbox", role="checkbox", boolean xforms:input.
+   * html:input@type="checkbox", role="checkbox".
    */
   CHECKBUTTON = 44,
   
   /**
    * Represents an option button, also called a radio button. It is one of a
    * group of mutually exclusive options. All objects sharing a single parent
    * that have this attribute are assumed to be part of single mutually
    * exclusive group. It is used for xul:radio, html:input@type="radio",
@@ -310,17 +308,17 @@ enum Role {
   /**
    * Represents a combo box; an edit control with an associated list box that
    * provides a set of predefined choices. It is used for html:select,
    * xul:menulist, role="combobox".
    */
   COMBOBOX = 46,
 
   /**
-   * Represents the calendar control. It is used for date xforms:input.
+   * Represents the calendar control.
    */
   DROPLIST = 47,
 
   /**
    * Represents a progress bar, dynamically showing the user the percent
    * complete of an operation in progress. It is used for xul:progressmeter,
    * role="progressbar".
    */
@@ -335,17 +333,17 @@ enum Role {
    * Represents a hot-key field that allows the user to enter a combination or
    * sequence of keystrokes.
    */
   HOTKEYFIELD = 50,
 
   /**
    * Represents a slider, which allows the user to adjust a setting in given
    * increments between minimum and maximum values. It is used by xul:scale,
-   * role="slider", xforms:range.
+   * role="slider".
    */
   SLIDER = 51,
 
   /**
    * Represents a spin box, which is a control that allows the user to increment
    * or decrement the value displayed in a separate "buddy" control associated
    * with the spin box. It is used for xul:spinbuttons.
    */
--- a/accessible/src/base/Statistics.h
+++ b/accessible/src/base/Statistics.h
@@ -26,20 +26,14 @@ namespace statistics {
     { Telemetry::Accumulate(Telemetry::A11Y_ISIMPLEDOM_USAGE_FLAG, true); }
 
   /**
    * Report that IAccessibleTable has been used.
    */
   inline void IAccessibleTableUsed()
     { Telemetry::Accumulate(Telemetry::A11Y_IATABLE_USAGE_FLAG, true); }
 
-  /**
-   * Report that XForms accessibility has been instantiated.
-   */
-  inline void XFormsAccessibleUsed()
-    { Telemetry::Accumulate(Telemetry::A11Y_XFORMS_USAGE_FLAG, true); }
-
 } // namespace statistics
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -19,18 +19,16 @@
 #include "HTMLSelectAccessible.h"
 #include "HTMLTableAccessibleWrap.h"
 #include "HyperTextAccessibleWrap.h"
 #include "nsAccessiblePivot.h"
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
 #include "nsEventShell.h"
 #include "nsIAccessibleProvider.h"
-#include "nsXFormsFormControlsAccessible.h"
-#include "nsXFormsWidgetsAccessible.h"
 #include "OuterDocAccessible.h"
 #include "Role.h"
 #include "RootAccessibleWrap.h"
 #include "States.h"
 #include "Statistics.h"
 #include "TextLeafAccessibleWrap.h"
 
 #ifdef MOZ_ACCESSIBILITY_ATK
@@ -1242,93 +1240,16 @@ nsAccessibilityService::CreateAccessible
       break;
 
     case nsIAccessibleProvider::XULToolbarButton:
       accessible = new XULToolbarButtonAccessible(aContent, aDoc);
       break;
 
 #endif // MOZ_XUL
 
-    // XForms elements
-    case nsIAccessibleProvider::XFormsContainer:
-      accessible = new nsXFormsContainerAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsLabel:
-      accessible = new nsXFormsLabelAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsOutput:
-      accessible = new nsXFormsOutputAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsTrigger:
-      accessible = new nsXFormsTriggerAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsInput:
-      accessible = new nsXFormsInputAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsInputBoolean:
-      accessible = new nsXFormsInputBooleanAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsInputDate:
-      accessible = new nsXFormsInputDateAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsSecret:
-      accessible = new nsXFormsSecretAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsSliderRange:
-      accessible = new nsXFormsRangeAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsSelect:
-      accessible = new nsXFormsSelectAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsChoices:
-      accessible = new nsXFormsChoicesAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsSelectFull:
-      accessible = new nsXFormsSelectFullAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsItemCheckgroup:
-      accessible = new nsXFormsItemCheckgroupAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsItemRadiogroup:
-      accessible = new nsXFormsItemRadiogroupAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsSelectCombobox:
-      accessible = new nsXFormsSelectComboboxAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsItemCombobox:
-      accessible = new nsXFormsItemComboboxAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsDropmarkerWidget:
-      accessible = new nsXFormsDropmarkerWidgetAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsCalendarWidget:
-      accessible = new nsXFormsCalendarWidgetAccessible(aContent, aDoc);
-      break;
-
-    case nsIAccessibleProvider::XFormsComboboxPopupWidget:
-      accessible = new nsXFormsComboboxPopupWidgetAccessible(aContent, aDoc);
-      break;
-
     default:
       return nullptr;
   }
 
   NS_IF_ADDREF(accessible);
   return accessible;
 }
 
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -111,16 +111,17 @@ this.AccessFu = {
 
     Logger.info('disable');
 
     this.chromeWin.document.removeChild(this.stylesheet);
     for each (let mm in Utils.getAllMessageManagers(this.chromeWin))
       mm.sendAsyncMessage('AccessFu:Stop');
 
     Input.detach();
+    this.touchAdapter.detach(this.chromeWin);
 
     this.chromeWin.removeEventListener('TabOpen', this);
     this.chromeWin.removeEventListener('TabSelect', this);
 
     Services.obs.removeObserver(this, 'remote-browser-frame-shown');
     Services.obs.removeObserver(this, 'Accessibility:NextObject');
     Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
     Services.obs.removeObserver(this, 'Accessibility:Focus');
deleted file mode 100644
--- a/accessible/src/xforms/Makefile.in
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# 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/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = accessibility
-LIBRARY_NAME = accessibility_xforms_s
-LIBXUL_LIBRARY = 1
-
-
-
-CPPSRCS = \
-  nsXFormsAccessible.cpp \
-  nsXFormsFormControlsAccessible.cpp \
-  nsXFormsWidgetsAccessible.cpp \
-  $(NULL)
-
-# we don't want the shared lib, but we want to force the creation of a static lib.
-FORCE_STATIC_LIB = 1
-
-include $(topsrcdir)/config/rules.mk
-
-LOCAL_INCLUDES = \
-  -I$(srcdir) \
-  -I$(srcdir)/../base \
-  -I$(srcdir)/../generic \
-  -I$(srcdir)/../html \
-  $(NULL)
-
-ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-LOCAL_INCLUDES += \
-  -I$(srcdir)/../atk \
-  $(NULL)
-else
-ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-LOCAL_INCLUDES += \
-  -I$(srcdir)/../msaa \
-  $(NULL)
-else
-ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
-LOCAL_INCLUDES += \
-  -I$(srcdir)/../mac \
-  $(NULL)
-else
-LOCAL_INCLUDES += \
-  -I$(srcdir)/../other \
-  $(NULL)
-endif
-endif
-endif
-
-ifneq ($(A11Y_LOG),0)
-  DEFINES += -DA11Y_LOG
-endif
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/* -*- 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 "nsXFormsAccessible.h"
-
-#include "nsAccessibilityService.h"
-#include "nsAccUtils.h"
-#include "DocAccessible.h"
-#include "nsTextEquivUtils.h"
-#include "Role.h"
-#include "States.h"
-#include "Statistics.h"
-
-#include "nscore.h"
-#include "nsServiceManagerUtils.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMNodeList.h"
-#include "nsIEditor.h"
-#include "nsIMutableArray.h"
-#include "nsIXFormsUtilityService.h"
-#include "nsIPlaintextEditor.h"
-#include "nsINodeList.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsAccessibleBase
-////////////////////////////////////////////////////////////////////////////////
-
-nsIXFormsUtilityService *nsXFormsAccessibleBase::sXFormsService = nullptr;
-
-nsXFormsAccessibleBase::nsXFormsAccessibleBase()
-{
-  if (!sXFormsService) {
-    nsresult rv = CallGetService("@mozilla.org/xforms-utility-service;1",
-                                 &sXFormsService);
-    if (NS_FAILED(rv))
-      NS_WARNING("No XForms utility service.");
-  }
-  statistics::XFormsAccessibleUsed();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsAccessible::
-  nsXFormsAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  HyperTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-nsresult
-nsXFormsAccessible::GetBoundChildElementValue(const nsAString& aTagName,
-                                              nsAString& aValue)
-{
-  NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsINodeList* nodes = mContent->ChildNodes();
-
-  uint32_t length;
-  nsresult rv = nodes->GetLength(&length);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (uint32_t index = 0; index < length; index++) {
-    nsIContent* content = nodes->Item(index);
-    if (content->NodeInfo()->Equals(aTagName) &&
-        content->NodeInfo()->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) {
-      nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(content));
-      return sXFormsService->GetValue(DOMNode, aValue);
-    }
-  }
-
-  aValue.Truncate();
-  return NS_OK;
-}
-
-void
-nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
-{
-  nsCOMPtr<nsIDOMNode> container(aContainerNode);
-  if (!container)
-    container = do_QueryInterface(mContent);
-
-  nsCOMPtr<nsIDOMNodeList> children;
-  sXFormsService->GetSelectChildrenFor(container, getter_AddRefs(children));
-
-  if (!children)
-    return;
-
-  uint32_t length = 0;
-  children->GetLength(&length);
-
-  for (uint32_t index = 0; index < length; index++) {
-    nsCOMPtr<nsIDOMNode> DOMChild;
-    children->Item(index, getter_AddRefs(DOMChild));
-    if (!DOMChild)
-      continue;
-
-    nsCOMPtr<nsIContent> child(do_QueryInterface(DOMChild));
-    Accessible* accessible =
-      GetAccService()->GetOrCreateAccessible(child, mDoc);
-    if (!accessible)
-      continue;
-
-    AppendChild(accessible);
-  }
-}
-
-uint64_t
-nsXFormsAccessible::NativeState()
-{
-  NS_ENSURE_TRUE(sXFormsService, 0);
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  bool isReadonly = false;
-  nsresult rv = sXFormsService->IsReadonly(DOMNode, &isReadonly);
-  NS_ENSURE_SUCCESS(rv, 0);
-
-  bool isRequired = false;
-  rv = sXFormsService->IsRequired(DOMNode, &isRequired);
-  NS_ENSURE_SUCCESS(rv, 0);
-
-  bool isValid = false;
-  rv = sXFormsService->IsValid(DOMNode, &isValid);
-  NS_ENSURE_SUCCESS(rv, 0);
-
-  uint64_t states = HyperTextAccessibleWrap::NativeState();
-
-  if (NativelyUnavailable())
-    states |= states::UNAVAILABLE;
-
-  if (isReadonly)
-    states |= states::READONLY;
-
-  if (isRequired)
-    states |= states::REQUIRED;
-
-  if (!isValid)
-    states |= states::INVALID;
-
-  return states;
-}
-
-bool
-nsXFormsAccessible::NativelyUnavailable() const
-{
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  bool isRelevant = false;
-  sXFormsService->IsRelevant(DOMNode, &isRelevant);
-  return !isRelevant;
-}
-
-ENameValueFlag
-nsXFormsAccessible::NativeName(nsString& aName)
-{
-  // search the xforms:label element
-  GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
-  return eNameOK;
-}
-
-void
-nsXFormsAccessible::Description(nsString& aDescription)
-{
-  nsTextEquivUtils::
-    GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
-                           aDescription);
-
-  if (aDescription.IsEmpty())
-    GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
-}
-
-void
-nsXFormsAccessible::Value(nsString& aValue)
-{
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  sXFormsService->GetValue(DOMNode, aValue);
-}
-
-bool
-nsXFormsAccessible::CanHaveAnonChildren()
-{
-  return false;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsContainerAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsContainerAccessible::
-  nsXFormsContainerAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsContainerAccessible::NativeRole()
-{
-  return roles::GROUPING;
-}
-
-bool
-nsXFormsContainerAccessible::CanHaveAnonChildren()
-{
-  return true;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsEditableAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsEditableAccessible::
-  nsXFormsEditableAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-uint64_t
-nsXFormsEditableAccessible::NativeState()
-{
-  uint64_t state = nsXFormsAccessible::NativeState();
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  bool isReadonly = false;
-  nsresult rv = sXFormsService->IsReadonly(DOMNode, &isReadonly);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (!isReadonly) {
-    bool isRelevant = false;
-    rv = sXFormsService->IsRelevant(DOMNode, &isRelevant);
-    NS_ENSURE_SUCCESS(rv, state);
-    if (isRelevant) {
-      state |= states::EDITABLE | states::SELECTABLE_TEXT;
-    }
-  }
-
-  nsCOMPtr<nsIEditor> editor = GetEditor();
-  NS_ENSURE_TRUE(editor, state);
-  uint32_t flags;
-  editor->GetFlags(&flags);
-  if (flags & nsIPlaintextEditor::eEditorSingleLineMask)
-    state |= states::SINGLE_LINE;
-  else
-    state |= states::MULTI_LINE;
-
-  return state;
-}
-
-already_AddRefed<nsIEditor>
-nsXFormsEditableAccessible::GetEditor() const
-{
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  nsCOMPtr<nsIEditor> editor;
-  sXFormsService->GetEditor(DOMNode, getter_AddRefs(editor));
-  return editor.forget();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSelectableAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSelectableAccessible::
-  nsXFormsSelectableAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsEditableAccessible(aContent, aDoc), mIsSelect1Element(false)
-{
-  mFlags |= eSelectAccessible;
-  mIsSelect1Element =
-    mContent->NodeInfo()->Equals(nsGkAtoms::select1);
-}
-
-already_AddRefed<nsIArray>
-nsXFormsSelectableAccessible::SelectedItems()
-{
-  nsCOMPtr<nsIMutableArray> selectedItems =
-    do_CreateInstance(NS_ARRAY_CONTRACTID);
-  if (!selectedItems)
-    return nullptr;
-
-  nsresult rv;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  if (mIsSelect1Element) {
-    nsCOMPtr<nsIDOMNode> itemDOMNode;
-    rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
-                                                   getter_AddRefs(itemDOMNode));
-    if (NS_FAILED(rv) || !itemDOMNode || !mDoc)
-      return nullptr;
-
-    nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
-    nsIAccessible* item = mDoc->GetAccessible(itemNode);
-    if (item)
-      selectedItems->AppendElement(item, false);
-
-    nsIMutableArray* items = nullptr;
-    selectedItems.forget(&items);
-    return items;
-  }
-
-  nsCOMPtr<nsIDOMNodeList> itemNodeList;
-  rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
-                                                 getter_AddRefs(itemNodeList));
-  if (NS_FAILED(rv) || !itemNodeList || !mDoc)
-    return nullptr;
-
-  uint32_t length = 0;
-  itemNodeList->GetLength(&length);
-
-  for (uint32_t index = 0; index < length; index++) {
-    nsCOMPtr<nsIDOMNode> itemDOMNode;
-    itemNodeList->Item(index, getter_AddRefs(itemDOMNode));
-    if (!itemDOMNode)
-      return nullptr;
-
-    nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
-    nsIAccessible* item = mDoc->GetAccessible(itemNode);
-    if (item)
-      selectedItems->AppendElement(item, false);
-  }
-
-  nsIMutableArray* items = nullptr;
-  selectedItems.forget(&items);
-  return items;
-}
-
-uint32_t
-nsXFormsSelectableAccessible::SelectedItemCount()
-{
-  nsresult rv;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-
-  if (mIsSelect1Element) {
-    nsCOMPtr<nsIDOMNode> item;
-    rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
-                                                   getter_AddRefs(item));
-    return NS_SUCCEEDED(rv) && item ? 1 : 0;
-  }
-
-  nsCOMPtr<nsIDOMNodeList> itemNodeList;
-  rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
-                                                 getter_AddRefs(itemNodeList));
-  if (NS_FAILED(rv) || !itemNodeList)
-    return 0;
-
-  uint32_t length = 0;
-  itemNodeList->GetLength(&length);
-  return length;
-}
-
-bool
-nsXFormsSelectableAccessible::AddItemToSelection(uint32_t aIndex)
-{
-  nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
-  if (!itemDOMNode)
-    return false;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  if (mIsSelect1Element)
-    sXFormsService->SetSelectedItemForSelect1(DOMNode, itemDOMNode);
-  else
-    sXFormsService->AddItemToSelectionForSelect(DOMNode, itemDOMNode);
-
-  return true;
-}
-
-bool
-nsXFormsSelectableAccessible::RemoveItemFromSelection(uint32_t aIndex)
-{
-  nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
-  if (!itemDOMNode)
-    return false;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  if (mIsSelect1Element) {
-    nsCOMPtr<nsIDOMNode> selItemDOMNode;
-    sXFormsService->GetSelectedItemForSelect1(DOMNode,
-                                              getter_AddRefs(selItemDOMNode));
-    if (selItemDOMNode == itemDOMNode)
-      sXFormsService->SetSelectedItemForSelect1(DOMNode, nullptr);
-
-    return true;
-  }
-
-  sXFormsService->RemoveItemFromSelectionForSelect(DOMNode, itemDOMNode);
-  return true;
-}
-
-Accessible*
-nsXFormsSelectableAccessible::GetSelectedItem(uint32_t aIndex)
-{
-  if (!mDoc)
-    return nullptr;
-
-  nsresult rv;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  if (mIsSelect1Element) {
-    if (aIndex != 0)
-      return nullptr;
-
-    nsCOMPtr<nsIDOMNode> itemDOMNode;
-    rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
-                                                   getter_AddRefs(itemDOMNode));
-    if (NS_SUCCEEDED(rv) && itemDOMNode) {
-      nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
-      return mDoc->GetAccessible(itemNode);
-    }
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIDOMNodeList> itemNodeList;
-  rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
-                                                 getter_AddRefs(itemNodeList));
-  if (NS_FAILED(rv) || !itemNodeList)
-    return nullptr;
-
-  nsCOMPtr<nsIDOMNode> itemDOMNode;
-  itemNodeList->Item(aIndex, getter_AddRefs(itemDOMNode));
-
-  nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
-  return mDoc->GetAccessible(itemNode);
-}
-
-bool
-nsXFormsSelectableAccessible::IsItemSelected(uint32_t aIndex)
-{
-  nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
-  if (!itemDOMNode)
-    return false;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  if (mIsSelect1Element) {
-    nsCOMPtr<nsIDOMNode> selItemDOMNode;
-    sXFormsService->GetSelectedItemForSelect1(DOMNode,
-                                              getter_AddRefs(selItemDOMNode));
-    return selItemDOMNode == itemDOMNode;
-  }
-
-  bool isSelected = false;
-  sXFormsService->IsSelectItemSelected(DOMNode, itemDOMNode, &isSelected);
-  return isSelected;
-}
-
-bool
-nsXFormsSelectableAccessible::UnselectAll()
-{
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  if (mIsSelect1Element)
-    sXFormsService->SetSelectedItemForSelect1(DOMNode, nullptr);
-
-  sXFormsService->ClearSelectionForSelect(DOMNode);
-  return true;
-}
-
-bool
-nsXFormsSelectableAccessible::SelectAll()
-{
-  if (mIsSelect1Element)
-    return false;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  sXFormsService->SelectAllItemsForSelect(DOMNode);
-  return true;
-}
-
-nsIContent*
-nsXFormsSelectableAccessible::GetItemByIndex(uint32_t* aIndex,
-                                             Accessible* aAccessible)
-{
-  Accessible* accessible = aAccessible ? aAccessible : this;
-  uint32_t childCount = accessible->ChildCount();
-  for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
-    Accessible* child = accessible->GetChildAt(childIdx);
-    nsIContent* childContent = child->GetContent();
-    nsINodeInfo *nodeInfo = childContent->NodeInfo();
-    if (nodeInfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) {
-      if (nodeInfo->Equals(nsGkAtoms::item)) {
-        if (!*aIndex)
-          return childContent;
-
-        --*aIndex;
-      } else if (nodeInfo->Equals(nsGkAtoms::choices)) {
-        nsIContent* itemContent = GetItemByIndex(aIndex, child);
-        if (itemContent)
-          return itemContent;
-      }
-    }
-  }
-
-  return nullptr;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSelectableItemAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSelectableItemAccessible::
-  nsXFormsSelectableItemAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-void
-nsXFormsSelectableItemAccessible::Value(nsString& aValue)
-{
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  sXFormsService->GetValue(DOMNode, aValue);
-}
-
-uint8_t
-nsXFormsSelectableItemAccessible::ActionCount()
-{
-  return 1;
-}
-
-NS_IMETHODIMP
-nsXFormsSelectableItemAccessible::DoAction(uint8_t aIndex)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  DoCommand();
-  return NS_OK;
-}
-
-bool
-nsXFormsSelectableItemAccessible::IsSelected()
-{
-  nsresult rv;
-
-  nsINode* parent = mContent;
-  while ((parent = parent->GetParentNode())) {
-    nsCOMPtr<nsIContent> content(do_QueryInterface(parent));
-    if (!content)
-      return false;
-
-    nsCOMPtr<nsINodeInfo> nodeinfo = content->NodeInfo();
-    if (!nodeinfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS)))
-      continue;
-
-    nsCOMPtr<nsIDOMNode> select(do_QueryInterface(parent));
-    if (!select)
-      continue;
-
-    nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-    if (nodeinfo->Equals(nsGkAtoms::select)) {
-      bool isSelected = false;
-      rv = sXFormsService->IsSelectItemSelected(select, DOMNode, &isSelected);
-      return NS_SUCCEEDED(rv) && isSelected;
-    }
-
-    if (nodeinfo->Equals(nsGkAtoms::select1)) {
-      nsCOMPtr<nsIDOMNode> selitem;
-      rv = sXFormsService->GetSelectedItemForSelect1(select,
-                                                     getter_AddRefs(selitem));
-      return NS_SUCCEEDED(rv) && (selitem == DOMNode);
-    }
-  }
-
-  return false;
-}
-
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _nsXFormsAccessible_H_
-#define _nsXFormsAccessible_H_
-
-#include "HyperTextAccessibleWrap.h"
-#include "nsIXFormsUtilityService.h"
-
-#define NS_NAMESPACE_XFORMS "http://www.w3.org/2002/xforms"
-
-/**
- * Utility class that provides access to nsIXFormsUtilityService.
- */
-class nsXFormsAccessibleBase
-{
-public:
-  nsXFormsAccessibleBase();
-
-protected:
-  // Used in GetActionName() methods.
-  enum { eAction_Click = 0 };
-
-  // Service allows to get some xforms functionality.
-  static nsIXFormsUtilityService *sXFormsService;
-};
-
-
-/**
- * Every XForms element that is bindable to XForms model or is able to contain
- * XForms hint and XForms label elements should have accessible object. This
- * class is base class for accessible objects for these XForms elements.
- */
-class nsXFormsAccessible : public HyperTextAccessibleWrap,
-                           public nsXFormsAccessibleBase
-{
-public:
-  nsXFormsAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  // Returns value of child xforms 'hint' element.
-  virtual void Description(nsString& aDescription);
-
-  // Returns value of instance node that xforms element is bound to.
-  virtual void Value(nsString& aValue);
-
-  // Returns state of xforms element taking into account state of instance node
-  // that it is bound to.
-  virtual uint64_t NativeState();
-  virtual bool NativelyUnavailable() const;
-
-  // Denies accessible nodes in anonymous content of xforms element by
-  // always returning false value.
-  virtual bool CanHaveAnonChildren();
-
-
-protected:
-  // Accessible
-  // Returns value of child xforms 'label' element.
-  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
-
-  // Returns value of first child xforms element by tagname that is bound to
-  // instance node.
-  nsresult GetBoundChildElementValue(const nsAString& aTagName,
-                                     nsAString& aValue);
-
-  // Cache accessible child item/choices elements. For example, the method is
-  // used for full appearance select/select1 elements or for their child choices
-  // element. Note, those select/select1 elements that use native widget
-  // for representation don't use the method since their item/choices elements
-  // are hidden and therefore aren't accessible.
-  //
-  // @param aContainerNode - node that contains item elements
-  void CacheSelectChildren(nsIDOMNode *aContainerNode = nullptr);
-};
-
-
-/**
- * This class is accessible object for XForms elements that provide accessible
- * object for itself as well for anonymous content. You should use this class
- * if accessible XForms element is complex, i.e. it is composed from elements
- * that should be accessible too. Especially for elements that have multiple
- * areas that a user can interact with or multiple visual areas. For example,
- * objects for XForms input[type="xsd:gMonth"] that contains combobox element
- * to choose month. It has an entryfield, a drop-down button and a drop-down
- * list, all of which need to be accessible. Another example would be
- * an XForms upload element since it is constructed from textfield and
- * 'pick up file' and 'clear file' buttons.
- */
-class nsXFormsContainerAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsContainerAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-
-  // Allows accessible nodes in anonymous content of xforms element by
-  // always returning true value.
-  virtual bool CanHaveAnonChildren();
-};
-
-
-/**
- * The class is base for accessible objects for XForms elements that have
- * editable area.
- */
-class nsXFormsEditableAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsEditableAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // HyperTextAccessible
-  virtual already_AddRefed<nsIEditor> GetEditor() const;
-
-  // Accessible
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * The class is base for accessible objects for XForms select and XForms
- * select1 elements.
- */
-class nsXFormsSelectableAccessible : public nsXFormsEditableAccessible
-{
-public:
-  nsXFormsSelectableAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // SelectAccessible
-  virtual already_AddRefed<nsIArray> SelectedItems();
-  virtual uint32_t SelectedItemCount();
-  virtual Accessible* GetSelectedItem(uint32_t aIndex);
-  virtual bool IsItemSelected(uint32_t aIndex);
-  virtual bool AddItemToSelection(uint32_t aIndex);
-  virtual bool RemoveItemFromSelection(uint32_t aIndex);
-  virtual bool SelectAll();
-  virtual bool UnselectAll();
-
-protected:
-  nsIContent* GetItemByIndex(uint32_t* aIndex,
-                             Accessible* aAccessible = nullptr);
-
-  bool mIsSelect1Element;
-};
-
-
-/**
- * The class is base for accessible objects for XForms item elements.
- */
-class nsXFormsSelectableItemAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsSelectableItemAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc);
-
-  NS_IMETHOD DoAction(uint8_t aIndex);
-
-  // Accessible
-  virtual void Value(nsString& aValue);
-
-  // ActionAccessible
-  virtual uint8_t ActionCount();
-
-protected:
-  bool IsSelected();
-};
-
-#endif
-
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-/* -*- 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 "nsXFormsFormControlsAccessible.h"
-
-#include "nsTextEquivUtils.h"
-#include "Role.h"
-#include "States.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsLabelAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsLabelAccessible::
-  nsXFormsLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsLabelAccessible::NativeRole()
-{
-  return roles::LABEL;
-}
-
-ENameValueFlag
-nsXFormsLabelAccessible::NativeName(nsString& aName)
-{
-  // XXX Correct name calculation for this, see bug 453594.
-  return eNameOK;
-}
-
-void
-nsXFormsLabelAccessible::Description(nsString& aDescription)
-{
-  nsTextEquivUtils::
-    GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
-                           aDescription);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsOutputAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsOutputAccessible::
-  nsXFormsOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsOutputAccessible::NativeRole()
-{
-  return roles::STATICTEXT;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsTriggerAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsTriggerAccessible::
-  nsXFormsTriggerAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsTriggerAccessible::NativeRole()
-{
-  return roles::PUSHBUTTON;
-}
-
-void
-nsXFormsTriggerAccessible::Value(nsString& aValue)
-{
-  aValue.Truncate();
-}
-
-uint8_t
-nsXFormsTriggerAccessible::ActionCount()
-{
-  return 1;
-}
-
-NS_IMETHODIMP
-nsXFormsTriggerAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex == eAction_Click) {
-    aName.AssignLiteral("press");
-    return NS_OK;
-  }
-  return NS_ERROR_INVALID_ARG;
-}
-
-NS_IMETHODIMP
-nsXFormsTriggerAccessible::DoAction(uint8_t aIndex)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  DoCommand();
-  return NS_OK;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsInputAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsInputAccessible::
-  nsXFormsInputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsEditableAccessible(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsInputAccessible,
-                             Accessible,
-                             nsIAccessibleText,
-                             nsIAccessibleEditableText)
-
-role
-nsXFormsInputAccessible::NativeRole()
-{
-  return roles::ENTRY;
-}
-
-uint8_t
-nsXFormsInputAccessible::ActionCount()
-{
-  return 1;
-}
-
-NS_IMETHODIMP
-nsXFormsInputAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  aName.AssignLiteral("activate");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXFormsInputAccessible::DoAction(uint8_t aIndex)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  return sXFormsService->Focus(DOMNode);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsInputBooleanAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsInputBooleanAccessible::
-  nsXFormsInputBooleanAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsInputBooleanAccessible::NativeRole()
-{
-  return roles::CHECKBUTTON;
-}
-
-uint64_t
-nsXFormsInputBooleanAccessible::NativeState()
-{
-  uint64_t state = nsXFormsAccessible::NativeState();
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetValue(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (value.EqualsLiteral("true"))
-    state |= states::CHECKED;
-
-  return state;
-}
-
-uint8_t
-nsXFormsInputBooleanAccessible::ActionCount()
-{
-  return 1;
-}
-
-NS_IMETHODIMP
-nsXFormsInputBooleanAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetValue(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (value.EqualsLiteral("true"))
-    aName.AssignLiteral("uncheck");
-  else
-    aName.AssignLiteral("check");
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXFormsInputBooleanAccessible::DoAction(uint8_t aIndex)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  DoCommand();
-  return NS_OK;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsInputDateAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsInputDateAccessible::
-  nsXFormsInputDateAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsContainerAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsInputDateAccessible::NativeRole()
-{
-  return roles::DROPLIST;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSecretAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSecretAccessible::
-  nsXFormsSecretAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsInputAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsSecretAccessible::NativeRole()
-{
-  return roles::PASSWORD_TEXT;
-}
-
-uint64_t
-nsXFormsSecretAccessible::NativeState()
-{
-  return nsXFormsInputAccessible::NativeState() | states::PROTECTED;
-}
-
-void
-nsXFormsSecretAccessible::Value(nsString& aValue)
-{
-  aValue.Truncate();
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsRangeAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsRangeAccessible::
-  nsXFormsRangeAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsRangeAccessible::NativeRole()
-{
-  return roles::SLIDER;
-}
-
-uint64_t
-nsXFormsRangeAccessible::NativeState()
-{
-  uint64_t state = nsXFormsAccessible::NativeState();
-
-  uint32_t isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsInRange(DOMNode, &isInRange);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
-    state |= states::INVALID;
-
-  return state;
-}
-
-NS_IMETHODIMP
-nsXFormsRangeAccessible::GetMaximumValue(double *aMaximumValue)
-{
-  NS_ENSURE_ARG_POINTER(aMaximumValue);
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetRangeEnd(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsresult error = NS_OK;
-  *aMaximumValue = value.ToDouble(&error);
-  return error;
-}
-
-NS_IMETHODIMP
-nsXFormsRangeAccessible::GetMinimumValue(double *aMinimumValue)
-{
-  NS_ENSURE_ARG_POINTER(aMinimumValue);
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetRangeStart(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsresult error = NS_OK;
-  *aMinimumValue = value.ToDouble(&error);
-  return error;
-}
-
-NS_IMETHODIMP
-nsXFormsRangeAccessible::GetMinimumIncrement(double *aMinimumIncrement)
-{
-  NS_ENSURE_ARG_POINTER(aMinimumIncrement);
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetRangeStep(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsresult error = NS_OK;
-  *aMinimumIncrement = value.ToDouble(&error);
-  return error;
-}
-
-NS_IMETHODIMP
-nsXFormsRangeAccessible::GetCurrentValue(double *aCurrentValue)
-{
-  NS_ENSURE_ARG_POINTER(aCurrentValue);
-
-  nsAutoString value;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->GetValue(DOMNode, value);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsresult error = NS_OK;
-  *aCurrentValue = value.ToDouble(&error);
-  return error;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSelectAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSelectAccessible::
-  nsXFormsSelectAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsContainerAccessible(aContent, aDoc)
-{
-}
-
-uint64_t
-nsXFormsSelectAccessible::NativeState()
-{
-  uint64_t state = nsXFormsContainerAccessible::NativeState();
-
-  uint32_t isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsInRange(DOMNode, &isInRange);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
-    state |= states::INVALID;
-
-  return state;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsChoicesAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsChoicesAccessible::
-  nsXFormsChoicesAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsChoicesAccessible::NativeRole()
-{
-  return roles::GROUPING;
-}
-
-void
-nsXFormsChoicesAccessible::Value(nsString& aValue)
-{
-  aValue.Truncate();
-}
-
-void
-nsXFormsChoicesAccessible::CacheChildren()
-{
-  CacheSelectChildren();
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSelectFullAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSelectFullAccessible::
-  nsXFormsSelectFullAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsSelectableAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsSelectFullAccessible::NativeRole()
-{
-  return roles::GROUPING;
-}
-
-void
-nsXFormsSelectFullAccessible::CacheChildren()
-{
-  CacheSelectChildren();
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsItemCheckgroupAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsItemCheckgroupAccessible::
-  nsXFormsItemCheckgroupAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsSelectableItemAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsItemCheckgroupAccessible::NativeRole()
-{
-  return roles::CHECKBUTTON;
-}
-
-uint64_t
-nsXFormsItemCheckgroupAccessible::NativeState()
-{
-  uint64_t state = nsXFormsSelectableItemAccessible::NativeState();
-
-  if (IsSelected())
-    state |= states::CHECKED;
-
-  return state;
-}
-
-NS_IMETHODIMP
-nsXFormsItemCheckgroupAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  if (IsSelected())
-    aName.AssignLiteral("uncheck");
-  else
-    aName.AssignLiteral("check");
-
-  return NS_OK;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsItemRadiogroupAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsItemRadiogroupAccessible::
-  nsXFormsItemRadiogroupAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsSelectableItemAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsItemRadiogroupAccessible::NativeRole()
-{
-  return roles::RADIOBUTTON;
-}
-
-uint64_t
-nsXFormsItemRadiogroupAccessible::NativeState()
-{
-  uint64_t state = nsXFormsSelectableItemAccessible::NativeState();
-
-  if (IsSelected())
-    state |= states::CHECKED;
-
-  return state;
-}
-
-NS_IMETHODIMP
-nsXFormsItemRadiogroupAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  aName.AssignLiteral("select");
-  return NS_OK;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsSelectComboboxAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsSelectComboboxAccessible::
-  nsXFormsSelectComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsSelectableAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsSelectComboboxAccessible::NativeRole()
-{
-  return roles::COMBOBOX;
-}
-
-uint64_t
-nsXFormsSelectComboboxAccessible::NativeState()
-{
-  uint64_t state = nsXFormsSelectableAccessible::NativeState();
-
-  bool isOpen = false;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (isOpen)
-    state |= states::EXPANDED;
-  else
-    state |= states::COLLAPSED;
-
-  return state | states::HASPOPUP;
-}
-
-uint64_t
-nsXFormsSelectComboboxAccessible::NativeInteractiveState() const
-{
-  return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE;
-}
-
-bool
-nsXFormsSelectComboboxAccessible::CanHaveAnonChildren()
-{
-  return true;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsItemComboboxAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsItemComboboxAccessible::
-  nsXFormsItemComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  nsXFormsSelectableItemAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsItemComboboxAccessible::NativeRole()
-{
-  return roles::LISTITEM;
-}
-
-uint64_t
-nsXFormsItemComboboxAccessible::NativeState()
-{
-  uint64_t state = nsXFormsSelectableItemAccessible::NativeState();
-  if (IsSelected())
-    state |= states::SELECTED;
-
-  return state;
-}
-
-uint64_t
-nsXFormsItemComboboxAccessible::NativeInteractiveState() const
-{
-  return NativelyUnavailable() ?
-    states::UNAVAILABLE : states::FOCUSABLE | states::SELECTABLE;
-}
-
-NS_IMETHODIMP
-nsXFormsItemComboboxAccessible::GetActionName(uint8_t aIndex, nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  aName.AssignLiteral("select");
-  return NS_OK;
-}
-
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _nsXFormsFormControlsAccessible_H_
-#define _nsXFormsFormControlsAccessible_H_
-
-#include "nsXFormsAccessible.h"
-
-/**
- * Accessible object for xforms:label.
- */
-
-class nsXFormsLabelAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual void Description(nsString& aDescription);
-  virtual mozilla::a11y::role NativeRole();
-
-protected:
-  // Accessible
-  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
-};
-
-/**
- * Accessible object for xforms:output.
- */
-
-class nsXFormsOutputAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsOutputAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-};
-
-/**
- * Accessible object for xforms:trigger and xforms:submit.
- */
-
-class nsXFormsTriggerAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsTriggerAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-  NS_IMETHOD DoAction(uint8_t aIndex);
-
-  // Accessible
-  virtual void Value(nsString& aValue);
-  virtual mozilla::a11y::role NativeRole();
-
-  // ActionAccessible
-  virtual uint8_t ActionCount();
-};
-
-/**
- * Accessible object for xforms:input and xforms:textarea.
- */
-
-class nsXFormsInputAccessible : public nsXFormsEditableAccessible
-{
-public:
-  nsXFormsInputAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-  NS_IMETHOD DoAction(uint8_t aIndex);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-
-  // ActionAccessible
-  virtual uint8_t ActionCount();
-};
-
-/**
- * Accessible object for xforms:input[type="xsd:boolean"].
- */
-
-class nsXFormsInputBooleanAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsInputBooleanAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-  NS_IMETHOD DoAction(uint8_t aIndex);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-
-  // ActionAccessible
-  virtual uint8_t ActionCount();
-};
-
-/**
- * Accessible object for xforms:input[type="xsd:date"].
- */
-
-class nsXFormsInputDateAccessible : public nsXFormsContainerAccessible
-{
-public:
-  nsXFormsInputDateAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-};
-
-/**
- * Accessible object for xforms:secret.
- */
-
-class nsXFormsSecretAccessible : public nsXFormsInputAccessible
-{
-public:
-  nsXFormsSecretAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual void Value(nsString& aValue);
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * Accessible object for xforms:range.
- */
-
-class nsXFormsRangeAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsRangeAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // nsIAccessibleValue
-  NS_IMETHOD GetMaximumValue(double *aMaximumValue);
-  NS_IMETHOD GetMinimumValue(double *aMinimumValue);
-  NS_IMETHOD GetMinimumIncrement(double *aMinimumIncrement);
-  NS_IMETHOD GetCurrentValue(double *aCurrentValue);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * Accessible object for xforms:select and xforms:select1 that are implemented
- * using host document's native widget.
- */
-
-class nsXFormsSelectAccessible : public nsXFormsContainerAccessible
-{
-public:
-  nsXFormsSelectAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * Accessible object for xforms:choices.
- */
-
-class nsXFormsChoicesAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsChoicesAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // nsIAccessible
-
-  // Accessible
-  virtual void Value(nsString& aValue);
-  virtual mozilla::a11y::role NativeRole();
-
-protected:
-  // Accessible
-  virtual void CacheChildren();
-};
-
-
-/**
- * Accessible object for xforms:select/xforms:select1 of full appearance that
- * may be represented by group of checkboxes or radiogroup.
- */
-
-class nsXFormsSelectFullAccessible : public nsXFormsSelectableAccessible
-{
-public:
-  nsXFormsSelectFullAccessible(nsIContent* aContent, DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-
-protected:
-  // Accessible
-  virtual void CacheChildren();
-};
-
-
-/**
- * Accessible object for a xforms:item when it is represented by a checkbox.
- * This occurs when the item is contained in a xforms:select with full
- * appearance. Such a xforms:select is represented by a checkgroup.
- */
-
-class nsXFormsItemCheckgroupAccessible : public nsXFormsSelectableItemAccessible
-{
-public:
-  nsXFormsItemCheckgroupAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * Accessible object for a xforms:item when it is represented by a radiobutton.
- * This occurs when the item is contained in a xforms:select1 with full
- * appearance. Such a xforms:select1 is represented as a radiogroup.
- */
-
-class nsXFormsItemRadiogroupAccessible : public nsXFormsSelectableItemAccessible
-{
-public:
-  nsXFormsItemRadiogroupAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-};
-
-
-/**
- * Accessible object for xforms:select1 of minimal appearance that is
- * represented by combobox.
- */
-
-class nsXFormsSelectComboboxAccessible : public nsXFormsSelectableAccessible
-{
-public:
-  nsXFormsSelectComboboxAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-  virtual uint64_t NativeInteractiveState() const;
-  virtual bool CanHaveAnonChildren();
-};
-
-
-/**
- * Accessible object for xforms:item element when it is represented by a
- * listitem. This occurs when the item is contained in a xforms:select with
- * minimal appearance. Such a xforms:select is represented by a combobox.
- */
-
-class nsXFormsItemComboboxAccessible : public nsXFormsSelectableItemAccessible
-{
-public:
-  nsXFormsItemComboboxAccessible(nsIContent* aContent,
-                                 DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-  virtual uint64_t NativeInteractiveState() const;
-};
-
-#endif
-
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- 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 "nsXFormsWidgetsAccessible.h"
-
-#include "Role.h"
-#include "States.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsDropmarkerWidgetAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsDropmarkerWidgetAccessible::
-  nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent,
-                                     DocAccessible* aDoc) :
-  LeafAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsDropmarkerWidgetAccessible::NativeRole()
-{
-  return roles::PUSHBUTTON;
-}
-
-uint64_t
-nsXFormsDropmarkerWidgetAccessible::NativeState()
-{
-  bool isOpen = false;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
-  NS_ENSURE_SUCCESS(rv, 0);
-
-  return isOpen ? states::PRESSED: 0;
-}
-
-uint8_t
-nsXFormsDropmarkerWidgetAccessible::ActionCount()
-{
-  return 1;
-}
-
-NS_IMETHODIMP
-nsXFormsDropmarkerWidgetAccessible::GetActionName(uint8_t aIndex,
-                                                  nsAString& aName)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  bool isOpen = false;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (isOpen)
-    aName.AssignLiteral("close");
-  else
-    aName.AssignLiteral("open");
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsXFormsDropmarkerWidgetAccessible::DoAction(uint8_t aIndex)
-{
-  if (aIndex != eAction_Click)
-    return NS_ERROR_INVALID_ARG;
-
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  return sXFormsService->ToggleDropmarkerState(DOMNode);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsCalendarWidgetAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsCalendarWidgetAccessible::
-  nsXFormsCalendarWidgetAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  AccessibleWrap(aContent, aDoc)
-{
-}
-
-role
-nsXFormsCalendarWidgetAccessible::NativeRole()
-{
-  return roles::CALENDAR;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXFormsComboboxPopupWidgetAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXFormsComboboxPopupWidgetAccessible::
-  nsXFormsComboboxPopupWidgetAccessible(nsIContent* aContent,
-                                        DocAccessible* aDoc) :
-  nsXFormsAccessible(aContent, aDoc)
-{
-}
-
-role
-nsXFormsComboboxPopupWidgetAccessible::NativeRole()
-{
-  return roles::LIST;
-}
-
-uint64_t
-nsXFormsComboboxPopupWidgetAccessible::NativeState()
-{
-  uint64_t state = nsXFormsAccessible::NativeState();
-
-  bool isOpen = false;
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
-  nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
-  NS_ENSURE_SUCCESS(rv, state);
-
-  if (isOpen)
-    state = states::FLOATING;
-  else
-    state = states::INVISIBLE;
-
-  return state;
-}
-
-uint64_t
-nsXFormsComboboxPopupWidgetAccessible::NativeInteractiveState() const
-{
-  return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE;
-}
-
-ENameValueFlag
-nsXFormsComboboxPopupWidgetAccessible::NativeName(nsString& aName)
-{
-  // Override nsXFormsAccessible::GetName() to prevent name calculation by
-  // XForms rules.
-  return eNameOK;
-}
-
-void
-nsXFormsComboboxPopupWidgetAccessible::Description(nsString& aDescription)
-{
-  aDescription.Truncate();
-}
-
-void
-nsXFormsComboboxPopupWidgetAccessible::Value(nsString& aValue)
-{
-  aValue.Truncate();
-}
-
-void
-nsXFormsComboboxPopupWidgetAccessible::CacheChildren()
-{
-  nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetParentNode());
-  // Parent node must be an xforms:select1 element.
-  CacheSelectChildren(parent);
-}
-
deleted file mode 100644
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _nsXFormsWidgetsAccessible_H_
-#define _nsXFormsWidgetsAccessible_H_
-
-#include "BaseAccessibles.h"
-#include "nsXFormsAccessible.h"
-
-/**
- * Accessible object for dropmarker widget that is used inside xforms elements
- * of combobox representation. For example, these are xforms:select1,
- * xforms:input[type="xsd:date"].
- */
-class nsXFormsDropmarkerWidgetAccessible : public mozilla::a11y::LeafAccessible,
-                                           public nsXFormsAccessibleBase
-{
-public:
-  nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent,
-                                     DocAccessible* aDoc);
-
-  // nsIAccessible
-  NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
-  NS_IMETHOD DoAction(uint8_t aIndex);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-
-  // ActionAccessible
-  virtual uint8_t ActionCount();
-};
-
-
-/**
- * Accessible object for calendar widget. It is used by xforms:input[xsd:date].
- */
-class nsXFormsCalendarWidgetAccessible : public AccessibleWrap
-{
-public:
-  nsXFormsCalendarWidgetAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc);
-
-  // Accessible
-  virtual mozilla::a11y::role NativeRole();
-};
-
-
-/**
- * Accessible object for popup menu of minimal xforms select1 element that is
- * represented by combobox.
- */
-class nsXFormsComboboxPopupWidgetAccessible : public nsXFormsAccessible
-{
-public:
-  nsXFormsComboboxPopupWidgetAccessible(nsIContent* aContent,
-                                        DocAccessible* aDoc);
-
-  // Accessible
-  virtual void Description(nsString& aDescription);
-  virtual void Value(nsString& aValue);
-  virtual mozilla::a11y::role NativeRole();
-  virtual uint64_t NativeState();
-  virtual uint64_t NativeInteractiveState() const;
-
-protected:
-  // Accessible
-  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
-  virtual void CacheChildren();
-};
-
-#endif
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -320,23 +320,23 @@ function getJSON(element) {
       case "time":
       case "datetime":
       case "datetime-local":
         type = typeLowerCase;
         break;
     }
   }
 
-  // Gecko supports the inputmode attribute on text fields (but not textareas).
-  // But it doesn't recognize "verbatim" and other modes that we're interested
-  // in in Gaia, and the inputmode property returns "auto" for any value
-  // that gecko does not support. So we must query the inputmode attribute
-  // with getAttribute() rather than just using the inputmode property here.
-  // See https://bugzilla.mozilla.org/show_bug.cgi?id=746142
-  let inputmode = element.getAttribute('inputmode');
+  // Gecko has some support for @inputmode but behind a preference and
+  // it is disabled by default.
+  // Gaia is then using @x-inputmode has its proprietary way to set
+  // inputmode for fields. This shouldn't be used outside of pre-installed
+  // apps because the attribute is going to disappear as soon as a definitive
+  // solution will be find.
+  let inputmode = element.getAttribute('x-inputmode');
   if (inputmode) {
     inputmode = inputmode.toLowerCase();
   } else {
     inputmode = '';
   }
 
   return {
     "type": type.toLowerCase(),
--- a/b2g/installer/Makefile.in
+++ b/b2g/installer/Makefile.in
@@ -33,16 +33,21 @@ JAREXT=.jar
 else
 JAREXT=
 endif
 DEFINES += -DJAREXT=$(JAREXT)
 
 include $(topsrcdir)/ipc/app/defs.mk
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
+# Set MSVC dlls version to package, if any.
+ifdef WIN32_REDIST_DIR
+DEFINES += -DMOZ_MSVC_REDIST=$(_MSC_VER)
+endif
+
 ifdef ENABLE_MARIONETTE
 DEFINES += -DENABLE_MARIONETTE=1
 endif
 
 ifdef MOZ_PKG_MANIFEST_P
 MOZ_PKG_MANIFEST = package-manifest
 endif
 
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -61,34 +61,34 @@
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
-#ifndef MOZ_MEMORY
-#if _MSC_VER == 1400
+#ifndef MOZ_DEBUG
+#if MOZ_MSVC_REDIST == 1400
 @BINPATH@/Microsoft.VC80.CRT.manifest
 @BINPATH@/msvcm80.dll
 @BINPATH@/msvcp80.dll
 @BINPATH@/msvcr80.dll
-#elif _MSC_VER == 1500
+#elif MOZ_MSVC_REDIST == 1500
 @BINPATH@/Microsoft.VC90.CRT.manifest
 @BINPATH@/msvcm90.dll
 @BINPATH@/msvcp90.dll
 @BINPATH@/msvcr90.dll
-#elif _MSC_VER == 1600
+#elif MOZ_MSVC_REDIST == 1600
 @BINPATH@/msvcp100.dll
 @BINPATH@/msvcr100.dll
+#elif MOZ_MSVC_REDIST == 1700
+@BINPATH@/msvcp110.dll
+@BINPATH@/msvcr110.dll
 #endif
-#else
-@BINPATH@/mozcrt19.dll
-@BINPATH@/mozcpp19.dll
 #endif
 #endif
 #ifdef MOZ_SHARED_MOZGLUE
 @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
 #endif
 #ifdef ANDROID
 @BINPATH@/AndroidManifest.xml
 @BINPATH@/resources.arsc
--- a/b2g/installer/removed-files.in
+++ b/b2g/installer/removed-files.in
@@ -1,6 +1,10 @@
 README.txt
 @DLL_PREFIX@mozutils@DLL_SUFFIX@
 jssubloader/
 #ifdef XP_MACOSX
 run-mozilla.sh
-#endif
\ No newline at end of file
+#endif
+#ifdef XP_WIN
+  mozcrt19.dll
+  mozcpp19.dll
+#endif
index 4e873d381e355127b8700a8395699b39ecba3665..4f9061a09ac8759d90dc1e6c848d2f72537a2295
GIT binary patch
literal 4172
zc$@)D5VP-zP)<h;3K|Lk000e1NJLTq003|R000mO1^@s6&J_C*0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU>?ny*JR9M5snF&;t<+{f$Tb;~o&~vNX
zx#!$Wt<>tQhI7y9tV&BOl}Xbk1R0bKq6jLp%AhiXm?+_ZIOG6nXoiF+$|Q)&JO~JE
z*uWkb_dI-i@Be+?57`Mqr_Q=--EXb``rh$lfA8;mp7(iPCQSH0zFu4sHFJhdOvKz3
zyNYMo#wwU*f0j`El67<h>l;1(zpWxZoM{tRPks2k`Ypf5&|^EpD6xCbBwf0Y-O;o3
zrQh>DoNU>vCYjx0PGV=zWRlq~La*Jd`^UsaMTL_vo}3&UzVh9;@yW5CU+ysBFO^OY
zpRI6w$UtTM7F9S-FjP7{be7G1;DJ+KnDCI`+@FgC=l_fmqBhp|E8rd`SiY|;jZ=HY
z{lxA0{wB^8wBTs&9RwXH#ERfE+)Ue8HNo{|V~6LxWF6D-KW;~mUsi{@#%eU)tw)Qn
z3GJP&=n{({?GdAIpa*irAk-Qa^aedlCeuBD829%;y8Jnl#O^br)FxbccY39=WmcV0
zYJ1oyvkPVI>JHmyehnP@7EdxsY?m0NcHyel*;Vr9xmu0z^%AO|;-4W~x)_*0@!s$k
zHu?A*Xl!VJUZ)$O=!gi!L`7q3@D{_i;4S;N1_h7!yOqupGrM-rGZ_j(V7$KbKJ9?9
zcssbFaBziT;PSVDyBZAcN&xiP-sp_^n~5N1js@@$x6J=Su{>#nSR3mb58j;55{f?Y
zOjTX4?Z)BkdaQ}PgpYhOc-imBhTp+bgdV?*w;jJ#&9aLt8ivR~{M8{D=Putwx3m{3
zjUFnk9%`-O7wHVp@ZxxB^&Agy?%c3P$6Wkwn?G_gTPIrV<Eqw|EA@lvX5HWkGnK2T
zErYeQeg<hgfCSl!#_i+8pPW|+ZOmq~4vN<IOq_Vh4@1weO)^RCK4oJgckX;NEF>i7
zQce!kYBdH12O*V8q19?ZeaOnnf>0<#eO(=PZr?8U_w`+Fu|UU%j9f_sxXdLm)f|Mm
zw+5!BGccAC#4LLlPW%IgV}FC;$Xn2-z5)HgxpaREy6g=ocbs4x3*e)x&;E&r7TfU-
zFIHx4tZ%HBWtR8x+Ei6VOE26AT+qIsk#j8{SMo3M%DI{kzoaZI-TET}j+Wz1hh!C5
zp6@Wg1s;d+p6h<h7aYPo!G0{-kcJfjCt)9w0mtw&aNh9))<m6yd&~u_Pq>K9doKMd
zKxR2=;hcQM-RbQE4O2BHP6`tz!@!+sYGw0_EgIn)*9k(JL2SF|<2CVBGi;(qxaN=7
zgy8I1D@f|!L{GzP=;Y@?1flIa3~Ak~=&pSoRV9m6Mu}}0`+GaWw;#&8k_V+yg|4n{
zh&sC<>**z!8c-khBqbsD@@0b9PGDu&y=#{-C?H_jJr@d7MIwwpE(TZn4Pa2?{>$8v
z2g8}gLlD#69D;aY4h*@Qcy~G$z(2TTyzl@(*2enA+Vhy(%)QkC*XSIa$|^)jX(770
zJD^Z1NOE*`b)fV{5l&plhjrk2xbG>(405MzE?cl=VHY8Y&W6L*Gx$3AB<U2s-f{{K
zA?a8ZmcavbjmWeB^xu~|0$@U7+|HP|NG>`y0(-s*N7+?tsAUl_8AQCyW+RECayyLr
zHfW@wkkq~3X_PMAJl!e^`+si2sls-P@+-11(EN9pO=_5oy>!>{0GSn<xE`u2Ag-MY
z`Uuj)LPOt8-j|F)xdLtN9rWH}w0DS5P*_Ost^)NVIyx2?vwucyeFMZ2Da2wa0s{j2
zw{F=ojR$x$7F@<WXrrb=y=5Y_yUEHjR>9buI|NbF2V<V^J$TfY@(K(&-s1ywI`#Ym
z09o5u0B2aoL<k~(<dQP0v1NY_Zda5+qtSrl3?vTTK3>r4bx^5PD6hN;zr7c+GA0iT
zy-#w}hXNZc-FX??)9=83`vrWo?hropPJ_+nW7zEZG6Drt;Iw7W2!Mg#Ua<fS3k!QB
zHa^P0+!g<_#ts+<c0t*`49xP(W<4#qoZ5SNnYb?M`wUIDzc5iy63?E)plwR4u;@f?
z8d_@>LM;uWIRwnu2Q$qx8$0PPruJZz7yX?9%m@w&POqt}N2gdqdv`l3tE#bW>ox@V
z2h`uLsN~D@=gklE^4ic_T~kMUd<&$qUi_Ss%f>`72yDM&F4A!1Z5R%|4*lMjpo@DB
z>X1J`f6fEYEBSZha@Iq)Zzgm}(_zT+7$2bHiDw@G$lAsNIA?i6am29_I7elp<aQ<f
zI0*~}1B^x^A8dU7<#MX)q0?z0k&01#s~lEA=kUe$Y`nZQzIZ%<_Fmpdj`}OAuLon3
z&j%v_ZrPuAKfuQbppm^G`$$ysdg%I+p%J@bpy^LT0Ccxt)|OCNiowReKqnQTsoc%1
z?_RohEPy8oV0mRQgw?d5iVHNq0w#S0{~TTaA#^s($AzC<d4PdIL1a+9sBdaUV{<D4
zgMwkda%Chf&1``{a3Cl+m@V=%@BZ_jD<UEz4b`>vXlQQ1-Buws`})=~2wYw;bjh>8
z-AIH<QVwI?DHyUn3Dir_?0gE^U9a#E%_<p<dkxz7=V3VKJU&4CWB>60K-M-EK#D9C
z2QN0@Lkd<J?$pyFDlGuhGfv+FXy5@V6mm2)*5m#4r{TVr+^9{AVl==t9t#oR`8)z#
zCPLDZL~gGQ+dLmfu;)|+dC!Gc%yEPqygDX8xm*tUKr=MGsZfhIK;0#P*-%f<xJzn=
zSziTJmn#gt{=)zx!zs)+8cpbzt1MCu<U`vViNU+G$>KT)ULAqVgh^LL&uN9C<xSL-
z4gvHF2tXGBEUT<WS$P%Q*RHLjW%=W9bn4{da`0aHu{Cajg4-2UxJBwDH|pmfpk)vY
z6jkz23S#IZQCRjrQ|lG7xYwYGcyh=R=`z;;0L_jm(5HVn1dyc$U!_iK`|9vC3@hT=
zq6Yx7w)@A>oCY?R0o<KggZbX+Xl-lZtw68W^DgvsI_+bt?2&r-5N+OKTHryn3R}hn
z=ooqo{;m^o=lXllN;Z<!6cB(0a*0vsxw8cELDS$9ydGhx`C|ec80be|pA?FoOsFLR
zP>EK8Q(whk^K8<q;8a(s?JIEop*%pPaM=pBZ?a3H)mWreH9|jd7z*JB(Dp<?-ue&7
z+uo!4LTIHS&~)0M?uHADvZY}gHg43lb&63`b{i!(%i-+mdUg2Y_TIQDltCP>3q00V
zmfosFX?Z0?;vQ`F^XDPxGuJ>9J{cO?|I|SfpoyIhV|Drvux5&ELm%V!#^F6tn>Yu$
zqc#?R6YX|AW%tE_XEaCa)>_hrH1QV}fUG>+ez-;eHr6)bsl{yWE6Wm!z4qkc^U$AA
z-`s}5!2#ad*uKX=_Vmh-b|e-4fqsxtxu&TVO9IDtp{vOPqy4ARVl8H0I4|0(kn!zI
z1b9uy`q*^rNGlitkOCMZ3o?3pdmxiZ(I+i~Qknuq$JbD_SwkiEhq7xkL9l|N{cHLl
zVo-X`$6S~rczP^=yyRC2UOZXydJ1|1Y2OQ{=lDU@y$+_q7~C#!gF#|9%gtkLV?}Kv
zL8&2#<p|yus&{f-J%<7F*}NH~5LWi`@mb?d^@`dClvUNDrK1}Jzn2G?zLEzwTEh@^
z-!0?oEU;mhKEn~ZBTFm*A0|Ei>GmnhmZv<eNv(DpVSV>o;i0NEpfRdX!lqc!oJnjh
zJ7KZ*OXt?@EkbDOHT3oOQV^r297tmks}Bs4b@caO+rewF{}(~bX3rTYzx0j;Acgzz
zUp)~X5y$vFF!E@j1z=oU+~i?^%*w^$E_8QyLe@=|Cr+V74~4ROSRuSPWd?bLcq74o
zVl03vwF-j@Iy~shg;MtI5Ijj3l#)<hX4OgTPua%rKVRCfOg?t{d(_g$d$sf?@`_5~
z=(1Y2*xJT*z0XGEUMm9KZ?SS-;dR`otU*=7T@;qyf~&wii$Tzx{(1;d)+U(cUHpC6
z68YfeMhahN(J5aq{sy|VMZfHU%#s+yg`tzJmL)%_VxUI5&;u2&pgzTdZIhR<v24z8
z8o^Fjd{RpJ6yb7N6O?Kte{#Z7h(Y-P!Rv!kr9keDMlAL}_dpsk8epL3a}ZU`N7==<
za4z*_47M!7j!jdsHvAhNV9fF2UjXikE>BKLYA_l(LwC2Ry|c4jDC!UjJKEcXUG29-
zJ)$$R{>}sa16_Lu`Z`nlB%&O#PN&wV9X-?(6CYJK7C;64)_(fUvR(<Kl3GZ+FGJS#
zJ;b8(5Oow#sA~Y5#|Lq*y*Agu#YJ(e<_=0L>u~<kRUA5g8eYDESnIU`Eg}iN`~C+4
zS4);xhXS(FCSe!0M@D0jmDO?{;P(zthfji8(LEGN)1B4Tp^x%=qN$@~s7_*eqN)8l
zbjPhn1~J1BKMH<)iCxkZ`TlYji`z`O?F`oTVbJ5B-Vg7-<1k;AoO`B}@qoh9iXf8q
zlMAKbh1{q}(uXi|d#sO*8J)<F2I%YY0z%e50pE4A;I&~Pg4`!jI`J4hx9{Tt#+|rs
z0Z0q^9i<R=Nv#C#WV^8Cy9d>LqNBa}#Bg1$R^8ER)OQmSV-Jr8s3vd0K0f9xBr-8N
zDW4UJC~9nLL{m!xFLn(Br0bD+3l?nh_6snTRW%^5<Q8@xNQ3((e+bsCM^k$@%Bt&;
zcb%-W<R<D{I&kC^olZG9pQE{x`5@*eH|P@ola9!Ihb)lptgcIVmJ;?57%qnm)#IP#
z%ZAILl-z&*U=%tGabCcrPplIs%ad=e0uz-7=lM@sFcv(^IVc^EF)+-!n2Til91B*M
zSedo4J~n3bQQByLRvVJ=g?A`E3p|N0x2D5s>$h+VOSYsDyH1td571quR2=UV3B5!e
zZR>uMM8frK4gp*}7QjIQ*h>J#(k_U)glKJV=E2oBRr4AJkX=u|`~C<1j;q~z&tJ;J
zmExO7Oi9J+wVt@s)<v%MHp<9CYn$6~;OGggbau&qX6n?L_fBGrhD)B%A9<4pq~7)j
zf7c&+m6vA66O>9k@k@Q@6pBipg5iP#132bU8V~V(zsKe;NqD@CiIvBLcRxgCRm?TA
z{fz}FEYf6RW!A>}*qG6W+3$OuCV&laj=abx@SoFZj1wK9xksOecVZTuyyQ^oa0L-Z
z3ds73u{*uga+pmEIafY7VEyli0M4fQW|s2&o{R12Y~H9PnDpX|8FOq`e12-V{Yv91
zfhU~ZJy6%$IYOD)m+_U8a}15=58^9VO~{lbzGLQcJiuLE2QJqW+$E2Da;N0ojkE^b
z&#Q-&?ZU&8#lK-@bH{{n4<ZXvp1P+=zXosg(HaX*ScJ*a1SVFV{{Qsvq<?iKev`0o
z_!#cDijCj3J8s_?k7H1#5Xk9oy#0<~m74&+q7ci!lU7YQTj4O_xBokd#<DqV?*9Vl
Wzh&#e7*Le}0000<MNUMnLSTZ`Aqr3c
index 973c4b0559d226df14824f4830c13c6ac057f0f5..b7365a9c6911301427ef88154a13b5ce92839301
GIT binary patch
literal 6530
zc$@)(8GYu7P)<h;3K|Lk000e1NJLTq005`}000;W1^@s6Zh^MJ000?DNkl<ZcwX(A
z36vGpz3#tVRc9RNd4{GNXqg%iP(T48UX53gK}8XyAu+jn$$h>IMn$h;yc$J}-X{r(
z(IAr=h$BV}2pDB(=!O>P24s-2=Xp4D4ST;`dsX9EXC0a;*Z1yP_qW!!_CC8#{kwOa
zul{?eBEDSwm(x|ta5?-B|AT@H@S}J8YzHs_iP^FI?&^uS0E7@EqTsd{iUCY=IqhbQ
zu~Aj)ZMWHK7-MC;z8%1qr$2rCATEOZDKGSM$ntM=O`9r7RDpnqf`LJlqKK(5#2hEz
z9w!86Ha<o0-yCLjsJ^})Z>?JO41h(r2<Fb8PY^>+PR{?o24$2@xM%odNW@<%Uz~tT
zMi|rWa@t;zWoho!gZfAV`ewL#=cFMe*^4uE?FA>QTMAB9H%&Wvx{(%5e`$@T=?`<G
zhR_3wB)y!HmNc!v*e7N9WH=lS*zI;9Ns=yj1KI61@!ifYKi=8aihl%J^BqGZgBDW4
zQo)fJX_F+JB$?~K{)fbGoIXq<=*K8hMK2`UP8m+vvOca%V7jN*tXzq_-n|#ydDmT#
zWf_TB_PgKVjn`iL3cv}c)47gE-TcVHg`Kzn`%1_p086;W;L0fHdNjX}{mZoHqfjpP
zF5KC<3bBk&nlFxBhB+s=9JY1iNA^qp$?S>lvcvT_R^5&Rr6*C}8bnsA8|f)t3?AIi
zHF?6-*!<=Gd8ba-Pvhs!;wIgJ^FS$^n&hF<f_qAkm7W5x*LzMjn++GsqUU}M-IdF5
z1+cce-BeY-$EYzj96mlnr_Mn(DO%}p7o9X1J7P3UFO&T0XQb$F+GWMBzS~Rf+CMR{
zu_6DF>6D}ll+kg}=^1!T0!|uD)A~y^=~Dnv#8C2sA3VKk#fpp%KKNk4UEHMMNCcs9
z7~Q0&rox~Uch8zNk`OYowWVcd#ooPLOI~>4WdN@{`uO7koS(J%H_gmW?q7^6q2t8C
zF=w~Dw-!LoMP*P*Sx?6<-JDL_#zp`7&z{_@R6M()6yu6Kn0%ET-eMo9VTU9;;8$fF
zt`1=9u6m3bImq3oPqus8_I(@q`Tu-glQJf!xl>Tx!jPH9z}UCC6at-X05WkU2y+rl
zVN}hb$QjzJ@KY&pX4*(bBQ->F4q^o9)Muvv{&rdM?L0nk8>7)oCifZS%l||Qp1o^0
zGs0&eyZV8VG#y<`0X_nUTGwFpn{N(tx!v<7O_~gYGDKAslu~p<8Net-dq)S-($X-r
zxEP~GkM4Ew(4l9xZr(g+@$=75U--lmN0FH9q})6hN8g9!_5uzUh@=37B+7bVR0nho
zOw)L&@-hlgiloBti&&R3#9zj-#KXFiXU-=cxW&^MHt^oNyYX+gWWeJf$jQ!u$Kyj~
z<pB&IQj9<_z<XPdvD~~%H=IUFS}Mkj8{sM6y?-5#Q*^%Je#qc_tk`%Mzh2!gE&>Gs
zK)Hzc3`W2t2EqUkB0fu!_y9u8I>Al(I<GT!CBu3&aBQwd9n%@pWLL)10PJw2K8RrR
zQ@0XGn%!pq%I56d!kVV-BbgsJfb+c{EdEVnm-N$6#8A)!MY&;oyt51whPFeN0C(n-
zBEBu<Ux~l*sc9gx;jq))4o7|qx(!MxR<Br*%}0`rbLN(K98M?N+S^5Y{AfwJy1Kf+
z0Fh0-9xnzI6(K)Af8g48-r4iQbI*-`{K+S)kO-=QINgx{>31L*SA%t)0Q4YO(>}1;
zFM&`4x*-f;AOPuZkN{8-<C5l})L@r&EFNyoSH_JfNX|%2!bj^X@UtnY$jQn?@4S2v
zB5?twyGk)({6zSCK4fKPp{}78kIkT1{81yaa&wWJmz7*s+w?Mk1&D)yAOHuR{9iL5
zQ5C8hMJN=8s%fB9Tx>1|%0%Xe5Hkg6x`C#)0RFt80w#%iwPeZjlN7t{_qwk4Ll1ns
zwOyJ#^0Yl=zz#4L0g*f~v3YNo6!&C1k?i)aQ`e8NIZ1;7n6ZRG>)NGX{NjNrBsVh|
zJ(20ELXq=tNG|*WU<M$$U}E>(0=s7-AlYUA$#EkcPSnMYbOxm_&zLqX*D~k1k;Ub5
z!O7dyXjGU}Hw?Jl9!Nxjrs)WVLZU4>DGB$L%=4{S{-;g9e)ic>|Nhid4M;%f^fz#K
zw7`}rfg~5fgrr{$4EZ5g>mjfsE5Vv8!3a3Qr4|hFd{;xfSgo52qWO1R?|yY%IetDh
z2YK0P$jj{mLWodnYb%;tn$gzQiqzCJv9QU_&I1AP@N_%=<1f`1arIz#Lw$1zkGCv-
zbuY;T&0Q*X9czcbvjc5BUQ25mbX^m%6j_EW^HLFYD3bhbU6zDd!Mg297~-(mZL8<Z
zF3C?%&p=PG=og5#A4jP13Ai$!0B8VUVJoD9NYjf5gj|x>Cz^W0BB~k0<MrTJogY0R
zWwaqn%7(q+r#$|1AT%oCn=mK{)jbATR*xZu70Z_o%+1T2)4O*cF?@5wiEEO=O=oiY
z)F~7e7K)6jMpcyW+0#@|P>?xn*f6*~9;m8{PM%d$Qc`fo%)4{md27ux03Jjl2tn7%
zsepNXb4Ebwl?&Td--l!PJs@dALB_uXc5*$8{mTIHzf((y;k(bElZF=MN)<;NFmZ4%
zBzbJe$?k2LQxfIb>a#F8bG903Y3X1LqCG1!2Z3M^H;qU}WrH7?S?N+ub^Rm&2jf@b
z5`iG1>Ig-31S1*@U4x>?uqg~SCWCe7TP}$bP>CUCcPSxDmo9Zg)L>pF&+5Tou*U_Z
ztVf|Zu0hnl2}WoKWJe(gh{&dT<Rq9@0e^IulEqrhB-Mo&I)W-%{899T->aj;I}B+1
z0y)0jP#gsykil3Nk6()uXUb7LVBm4YKq;L$?z-y{4o47)s^VIuB=tgPXBXD3TZ>R2
zP|<%t(denuring0^2>+&&Yw4bLgj%2Z_F(zDM(38MMq~R+PN|^GSIL8fFJ+r>0iD2
zt7m?7IL;7on@LBpiR(^{FpQS35IVjQp-oT0HR%z!#y<qoZ#raOUl?CJ3Pf4}UE|UL
zMn#NRr0*hw^5K1A-@FXh$+`{<@7D_%=~<A3n}{$)tU;@5&UCk%i0qe~l#EdWk`M|;
zxOtOZHk&dLafoOV0m1q4suk$h{!4g6e+Lo<5K$0MTU#56HDRnMrJ#lZ!xE)#h<2?7
zitAbcc4*<l0P(`+9uGrnw&H+LgH|I3RcDB5v`2M?oiHfiAg!>u#sY9c4QvNU3KaJk
zBsn_}k3s2_jI1mK!XaKaV0YLNjz;n3@;|}f)%C+U^X6Z3?AX!&`1r3Mo8JW|x@z^R
z&ueRH#;;zvvQASqIP4BYqbh>I5U#m)j6^9dK^)A`#bSr)DkMdL&Eti$cRqYWuYo<;
zhw$b_=zRSqut1ZTqsrfV1&k3;HENxwi5UMcGU(Xs%oJ?fe->%pR59-nfPpb#Mr_@>
z1uZQt*tBUArca%L7{vZ$W|AGDPzbr%X(ApH!T`q3JEO_f*5lzP-o}4EKNEGnn-Gga
zzBRXG1&Jr#q<~o>rp{m>4FuVcY`KWEE`t{Q9E7+KfexGJ1}OI4mTAagryThP7B>!J
z_}T462!$i)2|{~8)_F94e}r3p4I{V{k}VTz`x}rw6QR;9E1TmGEM%L#Kv8T6N220}
zaynetv3(mfU0=tyo>rQsoilHq*eB&I>b`t$u6VQI(MKO!%-04>C){uY{J{VMp%BtC
zGE5`i4B&CZAPg1>LAh-?q}(xJZAZZx_ko^R4@bHR#qB}p>^^k-{(2-W*aj)R81l8h
zg!b7Z0HfV8F4ds)l8?osYI^Tpy*y}a3&ExkIJn^$>s~#ZCZ)oh!-o$;Wn~pU+3;7~
zcI%Yx;Ynmsm&1mxfQo@W4|Lt=oxqv^Wnf5*gb2KL4H<b8knBrAgV6;jDX{3y=$64r
z4}CVkEMtN(tIn)CV6ZG+?F+?oE2v%#oBJj($pIJ<7<ve9-wg<#Ifb@><DI;LA4Xwu
zRW=hNi6Toq-xwr^mjj@9rvOF`l;jxz6fmYimMC;O7(iPylgS!bcs!mA)0mp3og0-7
zR#k$xt<htC!`UVCo_>4PO2ncY#;ybV_hZuJ8+o0=peg`j&P|6Q9$iPcxd~FRODwWT
z+F&8+s=HuRECs7t1$TBXLiM%quek?F4}K20cs7i^Z-6!&=#G)tpfi@H5CEsS@)5(}
z+-s2-ag3i=9`A``AN}w4frx<*$u%{N9R+DgPC&AYm9<k+EOSDrsOTzTPPf~QFSdOl
z=BBrN{}vdA4vouTGJIY;{Qe*mMXo^{mf<bqK#-*EMWOlzh~Wl_=(z2^$AwjA%>Fr6
zz4j0w*`P-{VdVZ0$h-$cVh|+sIqSY*;!GK1R_k+=4FY9=B6&d2XdV+LCCmXP_r+IV
ztF&fI&Z$dzWJwtnC8K6JSX?{VjL+)0s4%G{JJH<c#*l)JB}&GJXBdNkZyPlml;v=l
zF@(_=AuuRyHVgyZtbJ?E1NY7?d77)c!;H6ibX^zy<`U<d=eRvyJL1tbfEr?v1lbN-
z{y5l&-3jNlKY~2=5s<8Fp?)+UPPZH3nmq{bcvZ|xl}S${x@HOl=gXknRP5I0leUZ+
zIPU(5LvBYb$3oj7h-;fT_;#UgwjKT}_8lqvJi)$f*_qnbf|Mi=+JgqN#GJ<2ZBAj-
zd2{E9mArW|G+o8%GiOj%UWQ@Aip2$K^=t6(j&-zmfm4>qKQu1)rQ-lb6ldUjHx7X-
zc^s0`hl8mHP;^xx7A|@M!S<af+x0cd5AA_2af31<0wD3;vcRB5yfH;xlnhp#Ai_;b
zkOLX5kkAgw957fC-0son47>^;gbN`eo5o;PX_-_A1EC=o5@`j{#^r>~(~tLMB_`jx
z><nTEhJvRxUCSYan8P|E(FpntDB^uD9W#1(@m>I|Y+ofaC|&aQ>Qzaz?kjmIX8t;B
z@X%rAC@8k$%ovox+^g0Q2QxI-B??FYWl<Psw<CCJ8=`wwz&HORNClIjjC&aB#>b#Y
zKzQ3LaE^TdQsE?!^uZ#F@)+k|B<)!0e`Md$($97r-T;$>!Oz4a&Svc-;^A%L*x}$7
znDBGBId^@q<+-kfh(lGi?bUTHVXxPPisK!Ks$o!SSa&4lB?I5qz^GB9F=osdTz}no
z%$_wHBSs7tPdj8nu=iLy+#V-4aYtCw^zDg%Os*KiR?E{-e$<CQzFrDFTng%c9kk<V
zUj6|jx*aRtEXD4F9t1M}4U!bQX$*$Mh%6#xn56+BG4xTZZoshmrW;;FjeLak;Rx$j
zK{c`fV!QaPNkv>MrX|Ca4xN`8bs=KpAwr9}ia_LCP)ZX0&l_s%>fmrXMZ8XbfN$B2
zLLd-ac-!q$(*cmNBZm|7SY~$il6Tgudc=&+%R4~Gf^p-=i}|P7CMyb}nrbGK;|cx{
zVCX^;)nTJ597Kmvzh7ik7%G%8{932<hr%=<+=l3ZwJ?!~%n;{+((@bC-$2{SmWSr=
zJ+gCW>DQZ3?D;;tayrg~I5xy{6F29l;OBg~XGQ2IT9|br9^lLBnkH(#4D#uo26ToD
z1VUzqbt@xu4<DwOXpcn0h(;r#tuv_O6MkNLiVsbVE!2#cFoRNtSX3z;2c=)&tbPMF
zZ$5!o%F0fog%+bT_jxd9A7M~J&dou4FsKnDD%5kE=o18&IHY&SGGcCuIHL;bR(U@7
z`S0y2-3hnL0|ubIvje(rV8+aQ@)#kdlW)9nA^?Zkmpf<9LZAHnC2QYW{h1_5AKZEO
zEI1ravBkvWz~ywIy1LrzSAySw2}uPvz`0<zkWw%acIYq~4kA*%9AbZT^!*@=K?a3(
z>@%21eXi?1zvo3#>j|Ur=*CD1V_$qI5qZS8K~qrS{{Ru{M=VashY{W>*nMOR_8i{6
zuj>8C+?H>QCM3YzR39+yrMF6VA1oO<^eXqFRaIE_&=`cnAt;I>ChbI|EoNmN9lE9i
zgz)2bJh`d@{R{JOVE@-4O4*u3ui(Y5ZCKp6>>z%mrZ}PN6emx#Air-al2cr;(Po5W
zo<zk4OMnhAnQ|wHqp>S_QOCJ@&oD*A>H%@1(ipKA<6FkHOl*xB3_US(_I*eH^7fi_
zwRN?#Qc}`T*HDML#s)Z@ZrpQkN&oWl-G5KZ%BeOeC6Xj#+8r}dRe9j%frAE%?WMYg
zdNDOn6h)Y|Y<H<?*5!zUC^DF0gZ<uhkbGG%am-!|_EJ6+1Bh0=3+HtUAP>A1Wb;DE
z6wqqFvK~MT0<qadj0>&e*{SW?8O25JWpvBmxJe7f47?Mioom2AVImU+qkVVs;q&h(
zt=e+*^iFMd-G05+@<u{*UH?UGO~cf@-q~)u$Ah2zwhW7Zd=1ikGE`l)79XYn2?XMi
zTxS>ym+ywd?L{yUKwWKPhprnBBLV08nPe75lC~Rz23?26FMffrkpfBIkNbZx8cuo~
zfyha~TLf7mAPIKsm%P0ABW}t*Znx(vUDHQUN{@Uy=M*(jzgRR)ALw+tsx(d8$z!)Y
z`tZV=<IPDKv(#-!7HiIP_1Jl793=L)FwD%$=+EALckK;7`tgG~X{o6=efBJxJ6aG5
z22t350O86%dF*f(rA$2D96EHkcqgK<sagCDLI_fmQ*q|(8Ge(W*zkwnF0DX3b|<2S
z1Q#=6I|SnLKrtvH)q7w<dgX~WnK49zEifUTbkW9RT+}ubJ^q<`%;v%!+vvtm?TRz!
z`u-*7Ub!3B>ptxJW+%4o-&kL>SHJhzCiQqv=CrbC$b4n4eD{Hk=8GTcSy@=HbT?*P
z-y7qLvyhwSgU4w{D59daC4ik()mXo~#>||;ocz2XH|MPLyeJ~YuC-%p3^JD;uf1M|
zCg&UklKHenui|@r{|D62z+^8hUvd#xA6U$`Qr%A<`uSimewv}zQfgERLtG|?p?iNg
z|Nd0diA$HgS_uJcusF9n5G%`siHzE9(l}gPVJ>D3@wjW&eGTva`K?=4EPtbX&fIy<
z-nn_`-g@ft`^Do-!@41w+gimj3$bOCk)AGgU*3OjU6*NgB!D<wfJ6}Z;6Zrr`V&9^
z<L{4xc)U;;1A@(BNS7UU(MHTRe_Wf>b<z8v^zeGM%I3!G&FsVXZL&RWe8GH}96DWr
zEqm9uHXkwWIr52G1%Tp$2$PoP-~7~6{#Mf4=8GTv*}7}j2|u=0el6}=e?S#mNqn^~
z7DPh_^)-j}u$eidf%cN>&tE9F%t+(1g%bo+*L5j=V~7$54!IY@A%(ykdBO=1=hbM)
zc@;LB6S6J&+}<FF6^?+#WTAuHq&cmv%{wduQCtBn&5Z{MArc>IuLIC+&=lTgsA^Pp
zx!ky1I=ebx#sQGab&AWZcbkoybWRmF>6q7FTeg1kjW-t-7Y|2zS~{w0YQ!`8y0fQ5
z=C;iL?L(6E41~fVto!p@S|k#=<4?a|_6-t1>`pi{G7&kk6&*_oc|8M)+YRFKg2U@U
zg#I!MuI%jdwvnDPsJ|{|9c!ulk81g~57_VDK-aESB%84JhSIg+mgDsPJ#VNLYCxPL
zb1_Ts<%%*E*~${i+0D=H^W+R4OZA!0HPkoFG@q@frKLE{mq&a)kGan&wvwt(HAO0R
zw=g{#dcUD!?V?cA*M0zQF5QyKMJ>Z78EW9GvnS4u?w^-Q0Cw*AyiJi|cO=8%$bi$K
zz-hDbx&ntS2@bniD&jj)RR?20Ra1(t2iu>q;u>6s3~IOm9O#aD<v^m88ZicyT3g$e
zF8%F){=}fvaoIr$i8eL0yk=b!0t+K%@p$K~`>Nhs`_{;<TQ)5!-MM{1@vy618JU?#
zE9{5LiZbiXCnic0x62J#R`AKkAEBeYef68K{o!-OK?rf~nvGU}-PyEWL#M%k#CQuY
z+}2fn3Q+^C=`W~G_B<l-8I)M2mAgwd0D1TC)QVB}+aCJRSp6acw8n$<$*<njDhyQ^
z#;~Nvl<@{-v2DTn%J9kh%4d`MPukj1-FJdBDdTFJGr2z{O0vYXPA$}SCfw0*IMRBu
z++ST@ksy{4mqnHKuRmQwsFw0}bxk1%VcnbN=SFQIV%2c29Wg_@p;L0axouO;_TRpP
zZ#hIMZRnMhjDI9N=4k-!5TI?z;@>O*@CvRR$`$C&p0OEp`c0D*05<E`v)7Cp_s5o|
z#``o~pBz=ytgOt;T*iQcK7A3-%)95{owry1X#T%EaD3GpufG`YvrVV5SlYbdahrrx
zTmc$In;8p03RgYx<;G@Eh)fqJ*_331Q*j^#3`|$iK{Z5T%&EnS$28(HGvYF{#N`A;
zXVSScEhTeBtRJqKtHmliVvJ7{%s+c^6>=5GPG72|*zLGvh`EFfvT)$2riH!%(8)#d
zond9YD~EN9b1uUHBC**m*(@ohtTw6S$N%y<A;gOdpsMPkwX0UX#N$U|;-^?|!uxP#
z_^o$j+s*j#29*FIIj$rzGGQ^ITt;lkW70T-{#T=Lc`Vtv$YuVpnw5P*qW<3;VbJdY
o!T}(~m|e!@VQ{HdX)w<J1xd6IpFHVbs{jB107*qoM6N<$f-^LEZ2$lO
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0dbf602c732d74b1382a98fb8dddff8edf88a9dd
GIT binary patch
literal 556
zc%17D@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4(FKVEpXq;uvD#pX_m8<@klKCs_K@
z|CyVyC$Y=ikcrgw(09J&7AeBK?7vyjnLBFbk{bWyC7X{p6rIR&tdb16etLm~!N<vs
z#sP2sf6RaS-@itmEm=TXg>8~^826>q6ZV8j9c`EwUZv+?xZ&8p?OF*uNpQ_V;hqa6
zF8p;mFRIa&$l$@F(!NG)$#liKoh)sP4u(9;4oNTA8on4E(GxvvzyMKlmtjI&z!phG
zcTtbPD@uVNH42tnGOn__&aS=UH1WCM=a&D63tltwgJe!*EfVjvVR^Ncv2|C{v$C15
zHdr><PqX1_aKHPg->iVyA!o*qL+y3{9kVu<pPKf4@73_+2UC+0v@F*wo3_bsmsv&M
zfqqv0n!p_QvZH_4?fy4E=c@6K)sGD<4RaO-I<!Da{)E7@LwmJOoqWASiz)qM?fm-t
z{D--V-~al<KkMjs-PFA$mM5Gh$W4f2`+suJ0|8dfCpn?h{G*g3#SD7Czn*h@UqSl$
zeQ!U@t4!MywrWX2f0vMlt_Qz|e)D^lyoxOiDwnQnonqkC{5Jc@-_&DQ8~z)w`}v=J
zlRdMkcv^1Qq~=VvM4-{{?ewOUFa%B56BDPEIyXcv;9#);+eXKv6SEv8mP|jmx?PyL
qSwu~DsyI8_6mE{@8w!RwS&VyDJ<z$;>aPh*1q`09elF{r5}E+$VCT*N
index 507c627f765990037170bbb5244c7a3b686a59cb..7514317fedf29c162dea25a9e3fdcde262c9e30e
GIT binary patch
literal 723
zc$@*#0xbQBP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0007-Nkl<ZNQq<M
zm11DPg=hXZHUwe^0@x6r87Q2tM<ys3WI*vr`AY>yW&dNtAUTj4bbTaQkbhX_|M9O?
z|4)1`M!_I4kQ~Jp<Q<X*8`%F=1qFk|KynmYkaIu^rv)H6iY>_ACyCPnkQ~JpWbT&0
zX#q%%VhhrDisQ5ZBuB9YsoTVGS^$!x*n;FOqBt!8$x&=U;zkji7J%f4vH+-v3y5v7
z6$SC@gm78_lEYDafXw1Twt#KMKO@`t^+GRW*9iVc#vLczaasV9Lsy@$LFh5iJZm6k
zMF}FHfKdEek*!@9Z83_4#UE`jEC7k2tLp^nO;{(g5onem);LI7E~f=_#hKolW?&6-
zKbT<{jE?7jFbAsz>4{q_cqDC&q6XebPG2u?8MTuCO8-qOu*TW%jc^(cl7kp-{vW94
zQsyQFOM<B=xJQyHbF-XB#4^6S6K_F+VfuSL48uWUAUTj4pxWEn+Z5bDdWlM=S(}yE
zGB(SFhA!rLG5MAq*q{k-)!>FtdZ!K+n|#~uf7lY<$C+E@LTWE+vXYb!fEu{cH_Idh
z&*y$S^R6pON&>NG+;#pRyny>HNKL~vEpD<hTElfM!Q^$4xj}QeKF+=G2~RC^A9(%`
zn#c7qWrI|9;|(n#qH{73FhVgC5HkZYOa3lZh4|&-RsOR$ek`~X@_)hIkpKR(Ievh|
zKyn~8P_;}j{rD^ZDPjX+PLLE33jncj<P=%+uvx-g{?j==0P$N8J9>tkB}fjch8L;_
zq?ZYw1t6DjKs5*fu{aQeWMsqoWjrD#%VtJSmCXpBB<lqdgUX3R)$&61G86Iv$jj_d
z7x4fw9}x3%@-qvD_Q|LOcgZM&*dQ^e91m12J5(=<4*;PvQ?5y<BO?F+002ovPDHLk
FV1nGsHGu#C
--- a/browser/themes/gnomestripe/downloads/downloads.css
+++ b/browser/themes/gnomestripe/downloads/downloads.css
@@ -184,30 +184,32 @@ toolbar[iconsize="small"] #downloads-ind
                               0, 16, 16, 0) center no-repeat;
 }
 
 toolbar[iconsize="large"] #downloads-indicator-icon {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
                               0, 24, 24, 0) center no-repeat;
 }
 
-#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
-  background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                              16, 32, 32, 16) center no-repeat;
+toolbar[iconsize="small"] #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+  background-image: url("chrome://browser/skin/downloads/download-glow-small.png");
+}
+
+toolbar[iconsize="large"] #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
                               0, 16, 16, 0) center no-repeat;
   background-size: 12px;
 }
 
 #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
-  background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                                    16, 32, 32, 16);
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 /*** Event notification ***/
 
 #downloads-indicator-notification {
   opacity: 0;
   background: url("chrome://browser/skin/downloads/download-notification.png")
               center no-repeat;
--- a/browser/themes/gnomestripe/jar.mn
+++ b/browser/themes/gnomestripe/jar.mn
@@ -43,16 +43,17 @@ browser.jar:
   skin/classic/browser/click-to-play-warning-stripes.png
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-small.png
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/webRTC-shareDevice-16.png
   skin/classic/browser/webRTC-shareDevice-64.png
   skin/classic/browser/downloads/buttons.png          (downloads/buttons.png)
   skin/classic/browser/downloads/download-glow.png    (downloads/download-glow.png)
+  skin/classic/browser/downloads/download-glow-small.png (downloads/download-glow-small.png)
   skin/classic/browser/downloads/download-notification.png (downloads/download-notification.png)
   skin/classic/browser/downloads/downloads.css        (downloads/downloads.css)
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png           (feeds/feedIcon16.png)
   skin/classic/browser/feeds/videoFeedIcon.png        (feeds/feedIcon.png)
   skin/classic/browser/feeds/videoFeedIcon16.png      (feeds/feedIcon16.png)
   skin/classic/browser/feeds/audioFeedIcon.png        (feeds/feedIcon.png)
   skin/classic/browser/feeds/audioFeedIcon16.png      (feeds/feedIcon16.png)
index 8babe61f450c5a27c8a37ab04687b6aa3eb4ab61..54216081c78c8a719bbec7459ef4b8167f9ac57e
GIT binary patch
literal 570
zc%17D@N?(olHy`uVBq!ia0vp^LLkh+3?vf;>QaG}WQl7;NpOBzNqJ&XDuZK6ep0G}
zXKrG8YEWuoN@d~6R2!h8{{cQBu0WdAy6`^{VAA^2tB>AWdHC*<1GkqRyuD!W&4qh!
z&f9&XYvu7dyRJ{)er@uWD?CmWJkAwt_7!Xnm7*EDMKX5t=A079JI#}GTBzWRXyIA@
zyt5*y+XVB^3m2UiPTj#;^MS4A1E*Ifr&kwO{b#QFFWi3p+^zrkqnGnHe&%obBGCR%
zp#8r{K#xe-b&-}YBCTIU%WsHw{S)o_FBaS{UjJOO;J8%neW{M`(g};DbM{I1{+CHy
zDwnrUp<tiFg#XI<yOj%et4;o|Gxfhg>rI2UTZS|K8+AP}oBiKv&R^@f|M^%0c!5En
zRTAVE%)rPfAt@~@C$FfinwQ@@anh72)2GjzHEZtt{l_joeEaU(_a8rg{QUXr*Kh7S
zr|N;aW_!9ghDb<GJ$O{8DS(0XLUzO5yLV+9I-4}ME&B6+`;QWt=Q|4?S{{%WYSQ2;
zykI8oYrWpV`cCQJeeAi_%G(yK40mGnwG`yaIIX<#$ZW-{uf8pnRs6d9tO`f+4zt)3
z*-mjir}Atpldhi3@jG+u=mb&yZyBj4KH8XTu;^B7cJ-PYw|?&D%|AA<ed?{ccDmuv
kFQd$U$#{wBms{q`@fb-=(TQC&1?Wr$Pgg&ebxsLQ01f31vH$=8
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..054e4d1fad4f5f6dac69707664008d159b7c3145
GIT binary patch
literal 1165
zc$@)^1akX{P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000D3Nkl<Zc-rmQ
zTTI(k0LSr`LLqC}7!3Hg+?p|`GfW~71_OmaG@vm$6J<EvG&(Ud+R}}2b3nNXn7NB%
zK%6?~gRe@KIOoC!(zxLaBe1dQs4%Qtx(XXXSod##o_`^Pf70~8EQJRizJ2JqeUhGD
zQUQP!o$Y~T*_GHTaK!+Hj`B)S3LLbgz$jAm0*i7rF!Ifkud>&r9vqRT6hNA4KW>c7
z8Rh13Yg`G8-jH5m2+TN%pxvhtyyuMFxG`>yU)mu9x5lMFCbQvTL`f&2YW0Y!>$e{n
z<L1aS8zx){6q2G9A2uVt@n0l<X(hpaWGt@!KEkuVpL97eTzvrvr>sc$0uGCBdVtO9
zb2gwS0r6T&;6`-|;!c5DY?B$AR6n{Ns35@D&p|Dw(TwnA0jgRM(*$Z!C(YQXTn1pM
zvIS2!f?8y~8H$`4pm@7dz;6kG!8t96Yyh>bC(H=jw+z6beJzNn2el`Un-P+|3_uwH
zZaD#JPaHENcoyhEK)jp;6xu18A;8U_f!bq7&5+Lm?d|obz{ef^I_d5kN?_E#Ap98U
z9eIc#Rhtb+DP*BQ(WvQO?E2Ka9&u8>MVwp!eua?ks0UMc6N;mtcZ3CVup5$>kI$~>
z=b4nxGU-K^IOIZs!l~&8G3(N_ebQGO;hpg{ymy|N*EjHe|2*W{VT67PdWWr$l^U>q
z?>TNgzl_t6yi$+Am&$c?Ais!jFWz{M$vSJ?aG(bPMSmioxPPv|vSG+;rxA1*^axO1
zGljs?A>JMVMSA${??On{cly?@fednH7zN1BVzIo?+;JyMuIU&Fs2B%RX9e>KoKu|z
z{#p|h`*r%Oe;9X@vyvD6E(YL17QT4)>fm0PrsHov?HK%P$;Nf~f7P<^D>ETXqq}`g
zZ+eTIkqSUW13E&cpTA~!m&v{ImrvOkd}}Q5t;M5N!@{TZE<!cBTi5T5?IL@p%;6|N
zM@V<FQQD=R;dhwa%Y$o6{((=m1wJ2RaaFTe`;id}O?z+8fDM<-!%=~B<ny}Tk+;d`
zU%&K_3Eou}cvoX#Rk4s18xg8*zkbUw{s!4A34oj1c8y?hKsxfd%fB1<FlwECO|c1*
zN(&@aa9kyeHASNY*VdySzMo0<c!t9X2~HU2<nLktBJNUmlFJ>a(%tqfx(lxg7G9OG
zUpWiULJs$H*TCq+PO>&}9?r=?J~D;7M>19WO^-q&!~`O)06#4YkAe||sarc|aS1cH
zTn^?0ARU?9J2<{erfk3AUSNbf0lAlBrZN_yd=A(4o53{sI++^>Kq!p2;hY4dBi+cs
z&-RgfCC_Q?7Uc~=R5Cr&0Rt4Oiyg*$Q?HRZ+c=zn-~<H3%PBxQGO?e$giq!D^n*v%
zuan{ru1v(_Uud4i#m?cjDedGGARTG7TDKC+j`@-2woq`c0dfEiLJA;lB88Lu={Q@f
fe_*ZxS3K}P+f2UjENuW*00000NkvXXu0mjf=ousw
--- a/browser/themes/pinstripe/downloads/downloads.css
+++ b/browser/themes/pinstripe/downloads/downloads.css
@@ -170,42 +170,50 @@ richlistitem[type="download"][state="1"]
 
 #downloads-indicator-icon {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
                               0, 140, 20, 120) center no-repeat;
 }
 
 #downloads-indicator[attention]
 #downloads-indicator-icon {
-  background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                              14, 34, 34, 14) center no-repeat;
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 #downloads-indicator:not([counter])
 #downloads-indicator-counter {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
                               0, 140, 20, 120) center no-repeat;
   background-size: 12px;
 }
 
 #downloads-indicator:not([counter])[attention]
 #downloads-indicator-counter {
-  background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                                    14, 34, 34, 14);
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 @media (min-resolution: 2dppx) {
   #downloads-indicator-icon:not(:-moz-lwtheme-brighttext) {
     background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar@2x.png"), 0, 280, 40, 240);
     background-size: 20px;
   }
 
   #downloads-indicator:not([counter]) #downloads-indicator-counter {
     background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar@2x.png"), 0, 280, 40, 240);
   }
+
+  #downloads-indicator[attention]
+  #downloads-indicator-icon {
+    background-image: url("chrome://browser/skin/downloads/download-glow@2x.png");
+  }
+
+  #downloads-indicator:not([counter])[attention]
+  #downloads-indicator-counter {
+    background-image: url("chrome://browser/skin/downloads/download-glow@2x.png");
+  }
 }
 
 /*** Event notification ***/
 
 #downloads-indicator-notification {
   opacity: 0;
   background: url("chrome://browser/skin/downloads/download-notification.png")
               center no-repeat;
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -66,16 +66,17 @@ browser.jar:
   skin/classic/browser/urlbar-arrow.png
   skin/classic/browser/urlbar-arrow@2x.png
   skin/classic/browser/urlbar-popup-blocked.png
   skin/classic/browser/urlbar-popup-blocked@2x.png
   skin/classic/browser/webRTC-shareDevice-16.png
   skin/classic/browser/webRTC-shareDevice-64.png
   skin/classic/browser/downloads/buttons.png                (downloads/buttons.png)
   skin/classic/browser/downloads/download-glow.png          (downloads/download-glow.png)
+  skin/classic/browser/downloads/download-glow@2x.png       (downloads/download-glow@2x.png)
   skin/classic/browser/downloads/download-notification.png  (downloads/download-notification.png)
   skin/classic/browser/downloads/downloads.css              (downloads/downloads.css)
   skin/classic/browser/feeds/subscribe.css                  (feeds/subscribe.css)
   skin/classic/browser/feeds/subscribe-ui.css               (feeds/subscribe-ui.css)
   skin/classic/browser/feeds/feedIcon.png                   (feeds/feedIcon.png)
   skin/classic/browser/feeds/feedIcon16.png                 (feeds/feedIcon16.png)
   skin/classic/browser/feeds/videoFeedIcon.png              (feeds/feedIcon.png)
   skin/classic/browser/feeds/videoFeedIcon16.png            (feeds/feedIcon16.png)
deleted file mode 100644
index c70b5b0370796782dc0cf99b0a3f87ee9256e490..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
index c8b3dc02ff1a1bb3c053996039fae83ac3eed6a6..53182d7a407316db4ad925641c44d5d1b35d194e
GIT binary patch
literal 546
zc$@(u0^R+IP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B0005$Nkl<Zc-pm&
zO-~b16o&821*IUA=}du!Dc>-33W47wAGVU<4t2qbkg$P(H1;EH2!=>0X$fcy3lahg
zK&`c)2rm5rx`YCY!?~A)n;Qt&7#B}+=6%n3<`VMQ^-ll*=Rb@3kU@QijMM;mS<7KF
zW}Ddkt%ysAGVTFor5Tj9mMbzik9nA^2vGn<ArsVH3)DRhpOsk?uq#3oG>H1z1p3L6
zU>SC|i<CasO`aNrM!Zm(?UY~{cGB*>qLN4hJk0qdFe^@^4jJUZd=ohGwgk(tyF)af
zD{4^xMPJkc9j$}XDHF=p+oAlxmcWd4e1|@-0X3lSUyIa!oej#w#&oPA+H&Fe&<5q(
z7F6VHc=X*bff?@{@7tg<+<G>>6`hns>Ju(&pWTVgIa3|ym026A4!fZ0hXl`9rzNdI
z;`2fjZyIIMfKF(@U_op6<6J^ZS?A82AF7YKq57D^XXh6`xRSoYd@dQr-G-|hAri76
zFPanCg_xe|Jk#=c__Ld%ef5K}<U4(vPls^FixPGtMED^Pvc@;~SNF27pyA6je2II>
zK1qFBeT7{;4RVPrqWB>pWZuR7bjXbN{PD(ne`gNg&0yxiPVC()60&;a88VF2(Eyhe
kDMHv`$&i~PB)5w$0hfopsI#dlSpWb407*qoM6N<$g1XiG=>Px#
--- a/browser/themes/winstripe/downloads/downloads.css
+++ b/browser/themes/winstripe/downloads/downloads.css
@@ -176,29 +176,27 @@ richlistitem[type="download"][state="1"]
 }
 
 #downloads-indicator-icon:-moz-lwtheme-brighttext {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
                               0, 108, 18, 90) center no-repeat;
 }
 
 #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
-  background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                              15, 33, 33, 15) center no-repeat;
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
   background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
                               0, 108, 18, 90) center no-repeat;
   background-size: 12px;
 }
 
 #downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
-  background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
-                                    16, 32, 32, 16);
+  background-image: url("chrome://browser/skin/downloads/download-glow.png");
 }
 
 /*** Event notification ***/
 
 #downloads-indicator-notification {
   opacity: 0;
   background: url("chrome://browser/skin/downloads/download-notification.png")
               center no-repeat;
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -264,17 +264,17 @@ browser.jar:
         skin/classic/aero/browser/urlbar-arrow.png
         skin/classic/aero/browser/urlbar-popup-blocked.png
         skin/classic/aero/browser/urlbar-history-dropmarker.png
         skin/classic/aero/browser/webapps-16.png
         skin/classic/aero/browser/webapps-64.png
         skin/classic/aero/browser/webRTC-shareDevice-16.png
         skin/classic/aero/browser/webRTC-shareDevice-64.png
         skin/classic/aero/browser/downloads/buttons.png              (downloads/buttons-aero.png)
-        skin/classic/aero/browser/downloads/download-glow.png        (downloads/download-glow-aero.png)
+        skin/classic/aero/browser/downloads/download-glow.png        (downloads/download-glow.png)
         skin/classic/aero/browser/downloads/download-notification.png (downloads/download-notification.png)
 *       skin/classic/aero/browser/downloads/downloads.css            (downloads/downloads-aero.css)
         skin/classic/aero/browser/feeds/feedIcon.png                 (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/feedIcon16.png               (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/feeds/audioFeedIcon.png            (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/audioFeedIcon16.png          (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/feeds/videoFeedIcon.png            (feeds/feedIcon-aero.png)
         skin/classic/aero/browser/feeds/videoFeedIcon16.png          (feeds/feedIcon16-aero.png)
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -36,17 +36,16 @@ nsCaseTreatment.h \
 nsContentCID.h \
 nsCopySupport.h \
 nsContentCreatorFunctions.h \
 nsDOMFile.h \
 nsLineBreaker.h \
 nsReferencedElement.h \
 nsTreeSanitizer.h \
 nsXMLNameSpaceMap.h \
-nsIXFormsUtilityService.h \
 nsHostObjectProtocolHandler.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom mozilla
 
 EXPORTS_mozilla/dom = \
 		DirectionalityUtils.h \
 		Element.h \
--- a/content/base/public/nsIDOMDataChannel.idl
+++ b/content/base/public/nsIDOMDataChannel.idl
@@ -1,15 +1,15 @@
 #include "domstubs.idl"
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIVariant;
 
-[scriptable, builtinclass, uuid(fb7a8ec4-c1eb-4d9f-b927-fbb8b4493e6d)]
+[scriptable, builtinclass, uuid(7363aa5c-f4b2-4b86-8d15-e0f714c9216b)]
 interface nsIDOMDataChannel : nsIDOMEventTarget
 {
   readonly attribute DOMString label;
   readonly attribute boolean reliable;
   readonly attribute boolean ordered;
 
   readonly attribute DOMString readyState;
   readonly attribute unsigned long bufferedAmount;
@@ -26,10 +26,10 @@ interface nsIDOMDataChannel : nsIDOMEven
   /**
    * Transmits data to other end of the connection.
    * @param data The data to be transmitted.  Arraybuffers and Blobs are sent as
    * binary data.  Strings are sent as UTF-8 text data.  Other types are
    * converted to a String and sent as a String.
    * @return if the connection is still established and the data was queued or
    *         sent successfully.
    */
-  [implicit_jscontext] void send(in nsIVariant data);
+  void send(in nsIVariant data);
 };
deleted file mode 100644
--- a/content/base/public/nsIXFormsUtilityService.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- 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/. */
-
-#ifndef nsIXFormsUtilityService_h
-#define nsIXFormsUtilityService_h
-
-#include "nsISupports.h"
-
-class nsIDOMNode;
-class nsIDOMNodeList;
-class nsIEditor;
-
-/* For IDL files that don't want to include root IDL files. */
-#ifndef NS_NO_VTABLE
-#define NS_NO_VTABLE
-#endif
-
-/* nsIXFormsUtilityService */
-#define NS_IXFORMSUTILITYSERVICE_IID_STR "cd3457b6-cb6a-496c-bdfa-6cfecb2bd5fb"
-#define NS_IXFORMSUTILITYSERVICE_IID \
-{ 0xcd3457b6, 0xcb6a, 0x496c, \
-  { 0xbd, 0xfa, 0x6c, 0xfe, 0xcb, 0x2b, 0xd5, 0xfb } }
-
-
-/**
- * Private interface implemented by the nsXFormsUtilityService in XForms
- * extension.
- */
-class NS_NO_VTABLE nsIXFormsUtilityService : public nsISupports {
-public:
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXFORMSUTILITYSERVICE_IID)
-
-  enum {
-    STATE_OUT_OF_RANGE,
-    STATE_IN_RANGE,
-    STATE_NOT_A_RANGE
-  };
-
-  /**
-   * Returns the name of the builtin type of the instance node that aElement is
-   * bound to. Fails if aElement doesn't have a bound node.
-   */
-  NS_IMETHOD GetBuiltinTypeName(nsIDOMNode *aElement, nsAString& aName) = 0;
-
-  /**
-   * Return true if instance node that element is bound to is readonly.
-   */
-  NS_IMETHOD IsReadonly(nsIDOMNode *aElement, bool *aState) = 0;
-
-  /**
-   * Return true if instance node that element is bound to is relevant.
-   */
-  NS_IMETHOD IsRelevant(nsIDOMNode *aElement, bool *aState) = 0;
-
-  /**
-   * Return true if instance node that element is bound to is required.
-   */
-  NS_IMETHOD IsRequired(nsIDOMNode *aElement, bool *aState) = 0;
-
-  /**
-   * Return true if instance node that element is bound to is valid.
-   */
-  NS_IMETHOD IsValid(nsIDOMNode *aElement, bool *aState) = 0;
-
-  /**
-   * Return constant declared above that indicates whether instance node that
-   * element is bound to is out of range, is in range or neither. The last value
-   * is used if element can't have in-range or out-of-range state, for exmple,
-   * xforms:input.
-   */
-  NS_IMETHOD IsInRange(nsIDOMNode *aElement, uint32_t *aState) = 0;
-
-  /**
-   * Return value of instance node that given node is bound to. If given node is
-   * xforms:item element then the method returns item value.
-   */
-  NS_IMETHOD GetValue(nsIDOMNode *aElement, nsAString& aValue) = 0;
-
-  /**
-   * Set the focus to xforms element.
-   */
-  NS_IMETHOD Focus(nsIDOMNode *aElement) = 0;
-
-  /**
-   * Return @start attribute value of xforms:range element. Failure if
-   * given element is not xforms:range.
-   */
-  NS_IMETHOD GetRangeStart(nsIDOMNode *aElement, nsAString& aValue) = 0;
-
-  /**
-   * Return @end attribute value of xforms:range element. Failure if
-   * given element is not xforms:range.
-   */
-  NS_IMETHOD GetRangeEnd(nsIDOMNode *aElement, nsAString& aValue) = 0;
-
-  /**
-   * Return @step attribute value of xforms:range element. Failure if
-   * given element is not xforms:range.
-   */
-  NS_IMETHOD GetRangeStep(nsIDOMNode *aElement, nsAString& aValue) = 0;
-
-  /**
-   * Return nsIEditor for xforms element if element is editable, null if it is
-   * not editable. Failure if given element doesn't support editing.
-   */
-  NS_IMETHOD GetEditor(nsIDOMNode *aElement, nsIEditor **aEditor) = 0;
-
-  /**
-   * Return true if dropmarker is in open state (combobox popup is open),
-   * otherwise false. Failure if given 'aElement' node is not direct child of
-   * combobox element or is not combobox itself.
-   */
-  NS_IMETHOD IsDropmarkerOpen(nsIDOMNode *aElement, bool* aIsOpen) = 0;
-
-  /**
-   * Toggles dropmarker state (close/open combobox popup). Failure if given
-   * 'aElement' node is not direct child of combobox element or is not combobox
-   * itself.
-   */
-  NS_IMETHOD ToggleDropmarkerState(nsIDOMNode *aElement) = 0;
-
-  /**
-   * Get selected xforms:item element for xforms:select1. Failure if
-   * given 'aElement' node is not xforms:select1.
-   */
-  NS_IMETHOD GetSelectedItemForSelect1(nsIDOMNode *aElement,
-                                       nsIDOMNode ** aItem) = 0;
-
-  /**
-   * Set selected xforms:item element for xforms:select1. Failure if
-   * given 'aElement' node is not xforms:select1.
-   */
-  NS_IMETHOD SetSelectedItemForSelect1(nsIDOMNode *aElement,
-                                       nsIDOMNode *aItem) = 0;
-
-  /**
-   * Get the list of selected xforms:item elements from the xforms:select.
-   * Failure if given 'aElement' node is not xforms:select.
-   */
-  NS_IMETHOD GetSelectedItemsForSelect(nsIDOMNode *aElement,
-                                       nsIDOMNodeList **aItems) = 0;
-
-  /**
-   * Add xforms:item element to selection of xforms:select. Failure if
-   * given 'aElement' node is not xforms:select.
-   */
-  NS_IMETHOD AddItemToSelectionForSelect(nsIDOMNode *aElement,
-                                         nsIDOMNode *Item) = 0;
-
-  /**
-   * Remove xforms:item element from selection of xforms:select. Failure if
-   * given 'aElement' node is not xforms:select.
-   */
-  NS_IMETHOD RemoveItemFromSelectionForSelect(nsIDOMNode *aElement,
-                                              nsIDOMNode *Item) = 0;
-
-  /**
-   * Deslect all xforms:item elements contained in the given xforms:select.
-   * Failure if given 'aElement' node is not xforms:select.
-   */
-  NS_IMETHOD ClearSelectionForSelect(nsIDOMNode *aElement) = 0;
-
-  /**
-   * Select all xforms:item elements of xforms:select. Failure if
-   * given 'aElement' node is not xforms:select.
-   */
-  NS_IMETHOD SelectAllItemsForSelect(nsIDOMNode *aElement) = 0;
-
-  /**
-   * Return true if given xforms:item element of xforms:select is selected,
-   * otherwise return false. Failure if given 'aElement' node is not
-   * xforms:select.
-   */
-  NS_IMETHOD IsSelectItemSelected(nsIDOMNode *aElement, nsIDOMNode *aItem,
-                                  bool *aIsSelected) = 0;
-
-  /**
-   * Return the list of xforms:item or xforms:choices elements that are children
-   * of the given 'aElement' node. 'aElement' node may be a xforms:select,
-   * xforms:select1, xforms:choices or xforms:itemset element. Otherwise
-   * failure.
-   */
-  NS_IMETHOD GetSelectChildrenFor(nsIDOMNode *aElement,
-                                  nsIDOMNodeList **aNodeList) = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIXFormsUtilityService,
-                              NS_IXFORMSUTILITYSERVICE_IID)
-
-#endif /* nsIXFormsUtilityService_h */
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -235,17 +235,17 @@ nsDOMMultipartFile::InitInternal(JSConte
           continue;
         }
         if (JS_IsArrayBufferViewObject(&obj)) {
           blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj),
                                 JS_GetArrayBufferViewByteLength(&obj));
           continue;
         }
         if (JS_IsArrayBufferObject(&obj)) {
-          blobSet.AppendArrayBuffer(&obj, aCx);
+          blobSet.AppendArrayBuffer(&obj);
           continue;
         }
         // neither Blob nor ArrayBuffer(View)
       } else if (element.isString()) {
         blobSet.AppendString(element.toString(), nativeEOL, aCx);
         continue;
       }
       // coerce it to a string
@@ -314,13 +314,13 @@ BlobSet::AppendBlobs(const nsTArray<nsCO
 {
   Flush();
   mBlobs.AppendElements(aBlob);
 
   return NS_OK;
 }
 
 nsresult
-BlobSet::AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx)
+BlobSet::AppendArrayBuffer(JSObject* aBuffer)
 {
   return AppendVoidPtr(JS_GetArrayBufferData(aBuffer),
                        JS_GetArrayBufferByteLength(aBuffer));
 }
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -83,17 +83,17 @@ class BlobSet {
 public:
   BlobSet()
     : mData(nullptr), mDataLen(0), mDataBufferLen(0)
   {}
 
   nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
   nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
   nsresult AppendBlob(nsIDOMBlob* aBlob);
-  nsresult AppendArrayBuffer(JSObject* aBuffer, JSContext *aCx);
+  nsresult AppendArrayBuffer(JSObject* aBuffer);
   nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob);
 
   nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; }
 
   already_AddRefed<nsIDOMBlob>
   GetBlobInternal(const nsACString& aContentType)
   {
     nsCOMPtr<nsIDOMBlob> blob =
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -83,18 +83,17 @@ public:
 
   virtual void
   AppReady();
 
 private:
   // Get msg info out of JS variable being sent (string, arraybuffer, blob)
   nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
                          nsCOMPtr<nsIInputStream> &aStreamOut,
-                         bool &aIsBinary, uint32_t &aOutgoingLength,
-                         JSContext *aCx);
+                         bool &aIsBinary, uint32_t &aOutgoingLength);
 
   // Owning reference
   nsRefPtr<mozilla::DataChannel> mDataChannel;
   nsString  mOrigin;
   enum
   {
     DC_BINARY_TYPE_ARRAYBUFFER,
     DC_BINARY_TYPE_BLOB,
@@ -246,32 +245,32 @@ NS_IMETHODIMP
 nsDOMDataChannel::Close()
 {
   mDataChannel->Close();
   return NS_OK;
 }
 
 // Almost a clone of nsWebSocketChannel::Send()
 NS_IMETHODIMP
-nsDOMDataChannel::Send(nsIVariant* aData, JSContext* aCx)
+nsDOMDataChannel::Send(nsIVariant* aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
   uint16_t state = mDataChannel->GetReadyState();
 
   // In reality, the DataChannel protocol allows this, but we want it to
   // look like WebSockets
   if (state == mozilla::DataChannel::CONNECTING) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   nsCString msgString;
   nsCOMPtr<nsIInputStream> msgStream;
   bool isBinary;
   uint32_t msgLen;
-  nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen, aCx);
+  nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (state == mozilla::DataChannel::CLOSING ||
       state == mozilla::DataChannel::CLOSED) {
     return NS_OK;
   }
 
   MOZ_ASSERT(state == mozilla::DataChannel::OPEN,
@@ -289,18 +288,17 @@ nsDOMDataChannel::Send(nsIVariant* aData
   }
   return sent >= 0 ? NS_OK : NS_ERROR_FAILURE;
 }
 
 // XXX Exact clone of nsWebSocketChannel::GetSendParams() - find a way to share!
 nsresult
 nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
                                 nsCOMPtr<nsIInputStream>& aStreamOut,
-                                bool& aIsBinary, uint32_t& aOutgoingLength,
-                                JSContext* aCx)
+                                bool& aIsBinary, uint32_t& aOutgoingLength)
 {
   // Get type of data (arraybuffer, blob, or string)
   uint16_t dataType;
   nsresult rv = aData->GetDataType(&dataType);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (dataType == nsIDataType::VTYPE_INTERFACE ||
       dataType == nsIDataType::VTYPE_INTERFACE_IS) {
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2645,34 +2645,20 @@ GetRequestBody(nsIVariant* aBody, nsIInp
     // nsIXHRSendable?
     nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
     if (sendable) {
       return GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
     }
 
     // ArrayBuffer?
     jsval realVal;
-    nsCxPusher pusher;
-    Maybe<JSAutoCompartment> ac;
-
-    // If there's a context on the stack, we can just use it. Otherwise, we need
-    // to use the safe js context (and push it into the stack, so that it's
-    // visible to cx-less functions that we might call here).
-    JSContext* cx = nsContentUtils::GetCurrentJSContext();
-    if (!cx) {
-      cx = nsContentUtils::GetSafeJSContext();
-      if (!pusher.Push(cx)) {
-        return NS_ERROR_FAILURE;
-      }
-    }
 
     nsresult rv = aBody->GetAsJSVal(&realVal);
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
       JSObject *obj = JSVAL_TO_OBJECT(realVal);
-      ac.construct(cx, obj);
       if (JS_IsArrayBufferObject(obj)) {
           ArrayBuffer buf(obj);
           return GetRequestBody(&buf, aResult, aContentLength, aContentType, aCharset);
       }
     }
   }
   else if (dataType == nsIDataType::VTYPE_VOID ||
            dataType == nsIDataType::VTYPE_EMPTY) {
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3586,35 +3586,33 @@ CanvasRenderingContext2D::FillRuleChange
 {
   if (mPath) {
     mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule);
     mPath = nullptr;
   }
 }
 
 void
-CanvasRenderingContext2D::PutImageData(JSContext* cx,
-                                       ImageData& imageData, double dx,
+CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
                                        double dy, ErrorResult& error)
 {
   if (!FloatValidate(dx, dy)) {
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
   }
 
   dom::Uint8ClampedArray arr(imageData.GetDataObject());
 
   error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
                                 imageData.Width(), imageData.Height(),
                                 arr.Data(), arr.Length(), false, 0, 0, 0, 0);
 }
 
 void
-CanvasRenderingContext2D::PutImageData(JSContext* cx,
-                                       ImageData& imageData, double dx,
+CanvasRenderingContext2D::PutImageData(ImageData& imageData, double dx,
                                        double dy, double dirtyX,
                                        double dirtyY, double dirtyWidth,
                                        double dirtyHeight,
                                        ErrorResult& error)
 {
   if (!FloatValidate(dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)) {
     error.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -290,19 +290,19 @@ public:
     CreateImageData(JSContext* cx, double sw, double sh,
                     mozilla::ErrorResult& error);
   already_AddRefed<mozilla::dom::ImageData>
     CreateImageData(JSContext* cx, mozilla::dom::ImageData& imagedata,
                     mozilla::ErrorResult& error);
   already_AddRefed<mozilla::dom::ImageData>
     GetImageData(JSContext* cx, double sx, double sy, double sw, double sh,
                  mozilla::ErrorResult& error);
-  void PutImageData(JSContext* cx, mozilla::dom::ImageData& imageData,
+  void PutImageData(mozilla::dom::ImageData& imageData,
                     double dx, double dy, mozilla::ErrorResult& error);
-  void PutImageData(JSContext* cx, mozilla::dom::ImageData& imageData,
+  void PutImageData(mozilla::dom::ImageData& imageData,
                     double dx, double dy, double dirtyX, double dirtyY,
                     double dirtyWidth, double dirtyHeight,
                     mozilla::ErrorResult& error);
 
   double LineWidth()
   {
     return CurrentState().lineWidth;
   }
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -837,28 +837,28 @@ public:
     void StencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask);
     void StencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref,
                              WebGLuint mask);
     void StencilMask(WebGLuint mask);
     void StencilMaskSeparate(WebGLenum face, WebGLuint mask);
     void StencilOp(WebGLenum sfail, WebGLenum dpfail, WebGLenum dppass);
     void StencilOpSeparate(WebGLenum face, WebGLenum sfail, WebGLenum dpfail,
                            WebGLenum dppass);
-    void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+    void TexImage2D(WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLsizei width,
                     WebGLsizei height, WebGLint border, WebGLenum format,
                     WebGLenum type, dom::ArrayBufferView *pixels,
                     ErrorResult& rv);
-    void TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+    void TexImage2D(WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
                     dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexImage2D
     template<class ElementType>
-    void TexImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level,
+    void TexImage2D(WebGLenum target, WebGLint level,
                     WebGLenum internalformat, WebGLenum format, WebGLenum type,
                     ElementType* elt, ErrorResult& rv) {
         if (!IsContextStable())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
@@ -874,28 +874,28 @@ public:
     }
     void TexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) {
         TexParameter_base(target, pname, nullptr, &param);
     }
     void TexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) {
         TexParameter_base(target, pname, &param, nullptr);
     }
     
-    void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+    void TexSubImage2D(WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset,
                        WebGLsizei width, WebGLsizei height, WebGLenum format,
                        WebGLenum type, dom::ArrayBufferView* pixels,
                        ErrorResult& rv);
-    void TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+    void TexSubImage2D(WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
                        WebGLenum type, dom::ImageData* pixels, ErrorResult& rv);
     // Allow whatever element types the bindings are willing to pass
     // us in TexSubImage2D
     template<class ElementType>
-    void TexSubImage2D(JSContext* /* unused */, WebGLenum target, WebGLint level,
+    void TexSubImage2D(WebGLenum target, WebGLint level,
                        WebGLint xoffset, WebGLint yoffset, WebGLenum format,
                        WebGLenum type, ElementType* elt, ErrorResult& rv) {
         if (!IsContextStable())
             return;
         nsRefPtr<gfxImageSurface> isurf;
         WebGLTexelFormat srcFormat;
         nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
         rv = SurfaceFromElementResultToImageSurface(res, getter_AddRefs(isurf),
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -4857,33 +4857,33 @@ WebGLContext::TexImage2D_base(WebGLenum 
         GenerateWarning("texImage2D generated error %s", ErrorName(error));
         return;
     }
 
     tex->SetImageInfo(target, level, width, height, format, type);
 }
 
 void
-WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
                          WebGLenum internalformat, WebGLsizei width,
                          WebGLsizei height, WebGLint border, WebGLenum format,
                          WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
                            pixels ? pixels->Data() : 0,
                            pixels ? pixels->Length() : 0,
                            pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1,
                            WebGLTexelConversions::Auto, false);
 }
 
 void
-WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
                          WebGLenum internalformat, WebGLenum format,
                          WebGLenum type, ImageData* pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     if (!pixels) {
         // Spec says to generate an INVALID_VALUE error
@@ -5006,17 +5006,17 @@ WebGLContext::TexSubImage2D_base(WebGLen
                     actualSrcFormat, srcPremultiplied,
                     dstFormat, mPixelStorePremultiplyAlpha, dstTexelSize);
 
         gl->fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, convertedData);
     }
 }
 
 void
-WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
                             WebGLint xoffset, WebGLint yoffset,
                             WebGLsizei width, WebGLsizei height,
                             WebGLenum format, WebGLenum type,
                             ArrayBufferView* pixels,
                             ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
@@ -5027,17 +5027,17 @@ WebGLContext::TexSubImage2D(JSContext* c
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               width, height, 0, format, type,
                               pixels->Data(), pixels->Length(),
                               JS_GetTypedArrayType(pixels->Obj()),
                               WebGLTexelConversions::Auto, false);
 }
 
 void
-WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
+WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
                             WebGLint xoffset, WebGLint yoffset,
                             WebGLenum format, WebGLenum type, ImageData* pixels,
                             ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     if (!pixels)
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1102,25 +1102,16 @@ private:
 
 MappedAttrParser::MappedAttrParser(css::Loader* aLoader,
                                    nsIURI* aDocURI,
                                    already_AddRefed<nsIURI> aBaseURI,
                                    nsIPrincipal* aNodePrincipal)
   : mParser(aLoader), mDocURI(aDocURI), mBaseURI(aBaseURI),
     mNodePrincipal(aNodePrincipal), mDecl(nullptr)
 {
-  // SVG and CSS differ slightly in their interpretation of some of
-  // the attributes.  SVG allows attributes of the form: font-size="5"
-  // (style="font-size: 5" if using a style attribute)
-  // where CSS requires units: font-size="5pt" (style="font-size: 5pt")
-  // Set a flag to pass information to the parser so that we can use
-  // the CSS parser to parse the font-size attribute.  Note that this
-  // does *not* affect the use of CSS stylesheets, which will still
-  // require units.
-  mParser.SetSVGMode(true);
 }
 
 MappedAttrParser::~MappedAttrParser()
 {
   NS_ABORT_IF_FALSE(!mDecl,
                     "If mDecl was initialized, it should have been converted "
                     "into a style rule (and had its pointer cleared)");
 }
@@ -1136,17 +1127,17 @@ MappedAttrParser::ParseMappedAttrValue(n
 
   // Get the nsCSSProperty ID for our mapped attribute.
   nsCSSProperty propertyID =
     nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName),
                                nsCSSProps::eEnabled);
   if (propertyID != eCSSProperty_UNKNOWN) {
     bool changed; // outparam for ParseProperty. (ignored)
     mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
-                          mNodePrincipal, mDecl, &changed, false);
+                          mNodePrincipal, mDecl, &changed, false, true);
     return;
   }
   NS_ABORT_IF_FALSE(aMappedAttrName == nsGkAtoms::lang,
                     "Only 'lang' should be unrecognized!");
   // nsCSSParser doesn't know about 'lang', so we need to handle it specially.
   if (aMappedAttrName == nsGkAtoms::lang) {
     propertyID = eCSSProperty__x_lang;
     nsCSSExpandedDataBlock block;
--- a/dom/activities/src/Activity.cpp
+++ b/dom/activities/src/Activity.cpp
@@ -1,16 +1,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 "Activity.h"
 #include "nsDOMClassInfo.h"
 #include "nsContentUtils.h"
 #include "nsIDOMActivityOptions.h"
+#include "nsEventStateManager.h"
 
 using namespace mozilla::dom;
 
 #ifdef MOZ_SYS_MSG
 DOMCI_DATA(MozActivity, Activity)
 #endif
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Activity)
@@ -46,16 +47,24 @@ Activity::Initialize(nsISupports* aOwner
                      uint32_t aArgc,
                      JS::Value* aArgv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner);
   NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED);
 
   Init(window);
 
+  if (!nsEventStateManager::IsHandlingUserInput()) {
+    nsCOMPtr<nsIDOMRequestService> rs =
+      do_GetService("@mozilla.org/dom/dom-request-service;1");
+    rs->FireErrorAsync(static_cast<DOMRequest*>(this),
+                       NS_LITERAL_STRING("NotUserInput"));
+    return NS_OK;
+  }
+
   // We expect a single argument, which is a nsIDOMMozActivityOptions.
   if (aArgc != 1 || !aArgv[0].isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   nsCOMPtr<nsISupports> tmp;
   nsContentUtils::XPConnect()->WrapJS(aContext, aArgv[0].toObjectOrNull(),
                                       NS_GET_IID(nsIDOMMozActivityOptions),
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -123,17 +123,17 @@ DOMInterfaces = {
     'headerFile': 'nsIDOMFile.h',
 },
 {
     'workers': True,
 }],
 
 'CanvasRenderingContext2D': {
     'implicitJSContext': [
-        'createImageData', 'getImageData', 'putImageData', 'strokeStyle',
+        'createImageData', 'getImageData', 'strokeStyle',
         'fillStyle', 'mozDash'
     ],
     'resultNotAddRefed': [ 'canvas' ],
     'binaryNames': {
         'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
         'mozFillRule': 'fillRule'
     }
 },
@@ -444,17 +444,17 @@ DOMInterfaces = {
    'headerFile': 'WebGLContext.h'
 },
 
 'WebGLRenderingContext': {
   'nativeType': 'mozilla::WebGLContext',
   'headerFile': 'WebGLContext.h',
   'resultNotAddRefed': [ 'canvas', 'getContextAttributes', 'getExtension',
                          'getAttachedShaders' ],
-  'implicitJSContext': [ 'texImage2D', 'texSubImage2D', 'getSupportedExtensions' ],
+  'implicitJSContext': [ 'getSupportedExtensions' ],
 },
 
 'WebGLShader': {
    'nativeType': 'mozilla::WebGLShader',
    'headerFile': 'WebGLContext.h'
 },
 
 'WebGLShaderPrecisionFormat': {
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/crashtests/801227.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html class="reftest-wait">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=801227
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Abort due to page reload</title>
+  <script type="application/javascript">
+    var pc = new mozRTCPeerConnection();
+
+    var index = localStorage.index || 0;
+    if (index < 3) {
+      localStorage.index = index + 1;
+      window.location.reload();
+    }
+
+    function finish() {
+      delete localStorage["index"];
+
+      pc.close();
+      document.documentElement.removeAttribute("class");
+    }
+
+    navigator.mozGetUserMedia({ audio: true, fake: true }, function (aStream) {
+      pc.addStream(aStream);
+      finish();
+    }, finish);
+  </script>
+</head>
+
+<body>
+</body>
+</html>
+
--- a/dom/media/tests/crashtests/crashtests.list
+++ b/dom/media/tests/crashtests/crashtests.list
@@ -1,4 +1,5 @@
 pref(media.peerconnection.enabled,true) load 780790.html
 pref(media.peerconnection.enabled,true) load 791270.html
 pref(media.peerconnection.enabled,true) load 791278.html
 pref(media.peerconnection.enabled,true) load 791330.html
+pref(media.peerconnection.enabled,true) load 801227.html
--- a/dom/system/OSFileConstants.cpp
+++ b/dom/system/OSFileConstants.cpp
@@ -402,16 +402,21 @@ static dom::ConstantSpec gLibcProperties
   { "OSFILE_OFFSETOF_STAT_ST_MTIME", INT_TO_JSVAL(offsetof (struct stat, st_mtimespec)) },
   { "OSFILE_OFFSETOF_STAT_ST_CTIME", INT_TO_JSVAL(offsetof (struct stat, st_ctimespec)) },
 #else
   { "OSFILE_OFFSETOF_STAT_ST_ATIME", INT_TO_JSVAL(offsetof (struct stat, st_atime)) },
   { "OSFILE_OFFSETOF_STAT_ST_MTIME", INT_TO_JSVAL(offsetof (struct stat, st_mtime)) },
   { "OSFILE_OFFSETOF_STAT_ST_CTIME", INT_TO_JSVAL(offsetof (struct stat, st_ctime)) },
 #endif // defined(HAVE_ST_ATIME)
 
+  // Several OSes have a birthtime field. For the moment, supporting only Darwin.
+#if defined(_DARWIN_FEATURE_64_BIT_INODE)
+  { "OSFILE_OFFSETOF_STAT_ST_BIRTHTIME", INT_TO_JSVAL(offsetof (struct stat, st_birthtime)) },
+#endif // defined(_DARWIN_FEATURE_64_BIT_INODE)
+
 #endif // defined(XP_UNIX)
 
 
 
   // System configuration
 
   // Under MacOSX, to avoid using deprecated functions that do not
   // match the constants we define in this object (including
--- a/dom/telephony/CallEvent.cpp
+++ b/dom/telephony/CallEvent.cpp
@@ -21,31 +21,19 @@ CallEvent::Create(TelephonyCall* aCall)
 
   nsRefPtr<CallEvent> event = new CallEvent();
 
   event->mCall = aCall;
 
   return event.forget();
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(CallEvent)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CallEvent,
-                                                  nsDOMEvent)
-  // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mCall->ToISupports(),
-  //                                              TelephonyCall, "mCall")
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCall");
-  cb.NoteNativeChild(tmp->mCall->ToISupports(), NS_CYCLE_COLLECTION_PARTICIPANT(TelephonyCall));
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CallEvent,
-                                                nsDOMEvent)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCall)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_INHERITED_1(CallEvent,
+                                     nsDOMEvent,
+                                     mCall)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CallEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCallEvent)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CallEvent)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
 
 NS_IMPL_ADDREF_INHERITED(CallEvent, nsDOMEvent)
 NS_IMPL_RELEASE_INHERITED(CallEvent, nsDOMEvent)
--- a/dom/telephony/TelephonyCall.cpp
+++ b/dom/telephony/TelephonyCall.cpp
@@ -135,30 +135,19 @@ TelephonyCall::NotifyError(const nsAStri
   NS_ASSERTION(event, "This should never fail!");
 
   if (NS_FAILED(event->Dispatch(ToIDOMEventTarget(),
                                 NS_LITERAL_STRING("error")))) {
     NS_WARNING("Failed to dispatch error event!");
   }
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(TelephonyCall)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCall,
-                                                  nsDOMEventTargetHelper)
-  // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mTelephony->ToISupports(),
-  //                                              Telephony, "mTelephony")
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mTelephony");
-  cb.NoteNativeChild(tmp->mTelephony->ToISupports(), NS_CYCLE_COLLECTION_PARTICIPANT(Telephony));
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCall,
-                                                nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTelephony)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_INHERITED_1(TelephonyCall,
+                                     nsDOMEventTargetHelper,
+                                     mTelephony)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
   NS_INTERFACE_MAP_ENTRY(nsIDOMTelephonyCall)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TelephonyCall)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(TelephonyCall, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(TelephonyCall, nsDOMEventTargetHelper)
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -206,17 +206,17 @@ public:
   static const gfx::Rect CalculatePendingDisplayPort(
     const FrameMetrics& aFrameMetrics,
     const gfx::Point& aVelocity,
     const gfx::Point& aAcceleration,
     double aEstimatedPaintDuration);
 
   /**
    * Return the scale factor needed to fit the viewport in |aMetrics|
-   * into its compositiong bounds.
+   * into its composition bounds.
    */
   static gfxSize CalculateIntrinsicScale(const FrameMetrics& aMetrics);
 
   /**
    * Return the resolution that content should be rendered at given
    * the configuration in aFrameMetrics: viewport dimensions, zoom
    * factor, etc.  (The mResolution member of aFrameMetrics is
    * ignored.)
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -25,17 +25,17 @@ using mozilla::DebugOnly;
 namespace js {
 namespace ion {
 
 StringObject *
 MNewStringObject::templateObj() const {
     return &templateObj_->asString();
 }
 
-CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph &graph)
+CodeGenerator::CodeGenerator(MIRGenerator *gen, LIRGraph *graph)
   : CodeGeneratorSpecific(gen, graph)
 {
 }
 
 bool
 CodeGenerator::visitValueToInt32(LValueToInt32 *lir)
 {
     ValueOperand operand = ToValue(lir, LValueToInt32::Input);
@@ -2978,49 +2978,50 @@ CodeGenerator::visitGetArgument(LGetArgu
         masm.loadValue(argPtr, result);
     }
     return true;
 }
 
 bool
 CodeGenerator::generate()
 {
-    AssertCanGC();
-    JSContext *cx = GetIonContext()->cx;
-
-    unsigned slots = graph.localSlotCount() +
-                     (graph.argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE);
-    if (!safepoints_.init(slots))
+    if (!safepoints_.init(graph.totalSlotCount()))
         return false;
 
     // Before generating any code, we generate type checks for all parameters.
     // This comes before deoptTable_, because we can't use deopt tables without
     // creating the actual frame.
     if (!generateArgumentsChecks())
         return false;
 
     if (frameClass_ != FrameSizeClass::None()) {
-        deoptTable_ = cx->compartment->ionCompartment()->getBailoutTable(frameClass_);
+        deoptTable_ = GetIonContext()->compartment->ionCompartment()->getBailoutTable(frameClass_);
         if (!deoptTable_)
             return false;
     }
 
     if (!generatePrologue())
         return false;
     if (!generateBody())
         return false;
     if (!generateEpilogue())
         return false;
     if (!generateInvalidateEpilogue())
         return false;
     if (!generateOutOfLineCode())
         return false;
 
-    if (masm.oom())
-        return false;
+    return !masm.oom();
+}
+
+bool
+CodeGenerator::link()
+{
+    AssertCanGC();
+    JSContext *cx = GetIonContext()->cx;
 
     Linker linker(masm);
     IonCode *code = linker.newCode(cx);
     if (!code)
         return false;
 
     // We encode safepoints after the OSI-point offsets have been determined.
     encodeSafepoints();
@@ -3034,17 +3035,17 @@ CodeGenerator::generate()
                            : FrameSizeClass::FromDepth(frameDepth_).frameSize();
 
     // Check to make sure we didn't have a mid-build invalidation. If so, we
     // will trickle to ion::Compile() and return Method_Skipped.
     if (cx->compartment->types.compiledInfo.compilerOutput(cx)->isInvalidated())
         return true;
 
     IonScript *ionScript =
-      IonScript::New(cx, slots, scriptFrameSize, snapshots_.size(),
+      IonScript::New(cx, graph.totalSlotCount(), scriptFrameSize, snapshots_.size(),
                      bailouts_.length(), graph.numConstants(),
                      safepointIndices_.length(), osiIndices_.length(),
                      cacheList_.length(), barrierOffsets_.length(),
                      safepoints_.size(), graph.mir().numScripts());
     SetIonScript(script, executionMode, ionScript);
 
     if (!ionScript)
         return false;
--- a/js/src/ion/CodeGenerator.h
+++ b/js/src/ion/CodeGenerator.h
@@ -31,20 +31,21 @@ class OutOfLineTypeOfV;
 class OutOfLineLoadTypedArray;
 
 class CodeGenerator : public CodeGeneratorSpecific
 {
     bool generateArgumentsChecks();
     bool generateBody();
 
   public:
-    CodeGenerator(MIRGenerator *gen, LIRGraph &graph);
+    CodeGenerator(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     bool generate();
+    bool link();
 
     bool visitLabel(LLabel *lir);
     bool visitNop(LNop *lir);
     bool visitOsiPoint(LOsiPoint *lir);
     bool visitGoto(LGoto *lir);
     bool visitTableSwitch(LTableSwitch *ins);
     bool visitTableSwitchV(LTableSwitchV *ins);
     bool visitParameter(LParameter *lir);
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -202,21 +202,28 @@ IonCompartment::IonCompartment(IonRuntim
   : rt(rt),
     flusher_(NULL)
 {
 }
 
 void
 ion::FinishOffThreadBuilder(IonBuilder *builder)
 {
+    // Clean up if compilation did not succeed.
     if (builder->script()->isIonCompilingOffThread()) {
         types::TypeCompartment &types = builder->script()->compartment()->types;
         builder->recompileInfo.compilerOutput(types)->invalidate();
         builder->script()->ion = NULL;
     }
+
+    // The builder is allocated into its LifoAlloc, so destroying that will
+    // destroy the builder and all other data accumulated during compilation,
+    // except any final codegen (which includes an assembler and needs to be
+    // explicitly destroyed).
+    js_delete(builder->backgroundCodegen());
     js_delete(builder->temp().lifoAlloc());
 }
 
 static inline void
 FinishAllOffThreadCompilations(IonCompartment *ion)
 {
     OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations();
 
@@ -755,17 +762,17 @@ ion::ToggleBarriers(JSCompartment *comp,
         if (script->hasIonScript())
             script->ion->toggleBarriers(needs);
     }
 }
 
 namespace js {
 namespace ion {
 
-LIRGraph *
+CodeGenerator *
 CompileBackEnd(MIRGenerator *mir)
 {
     IonSpewPass("BuildSSA");
     // Note: don't call AssertGraphCoherency before SplitCriticalEdges,
     // the graph is not in RPO at this point.
 
     MIRGraph &graph = mir->graph();
 
@@ -941,17 +948,23 @@ CompileBackEnd(MIRGenerator *mir)
         if (!regalloc.go())
             return NULL;
         IonSpewPass("Allocate Registers", &regalloc);
 
         if (mir->shouldCancel("Allocate Registers"))
             return NULL;
     }
 
-    return lir;
+    CodeGenerator *codegen = js_new<CodeGenerator>(mir, lir);
+    if (!codegen || !codegen->generate()) {
+        js_delete(codegen);
+        return NULL;
+    }
+
+    return codegen;
 }
 
 class AutoDestroyAllocator
 {
     LifoAlloc *alloc;
 
   public:
     AutoDestroyAllocator(LifoAlloc *alloc) : alloc(alloc) {}
@@ -992,34 +1005,37 @@ AttachFinishedCompilations(JSContext *cx
     OffThreadCompilationVector &compilations = ion->finishedOffThreadCompilations();
 
     // Incorporate any off thread compilations which have finished, failed or
     // have been cancelled, and destroy JM jitcode for any compilations which
     // succeeded, to allow entering the Ion code from the interpreter.
     while (!compilations.empty()) {
         IonBuilder *builder = compilations.popCopy();
 
-        if (builder->backgroundCompiledLir) {
+        if (CodeGenerator *codegen = builder->backgroundCodegen()) {
             RootedScript script(cx, builder->script());
             IonContext ictx(cx, cx->compartment, &builder->temp());
 
-            CodeGenerator codegen(builder, *builder->backgroundCompiledLir);
+            // Root the assembler until the builder is finished below. As it
+            // was constructed off thread, the assembler has not been rooted
+            // previously, though any GC activity would discard the builder.
+            codegen->masm.constructRoot(cx);
 
             types::AutoEnterTypeInference enterTypes(cx);
 
             ExecutionMode executionMode = builder->info().executionMode();
             types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
             enterCompiler.initExisting(builder->recompileInfo);
 
             bool success;
             {
                 // Release the worker thread lock and root the compiler for GC.
                 AutoTempAllocatorRooter root(cx, &builder->temp());
                 AutoUnlockWorkerThreadState unlock(cx->runtime);
-                success = codegen.generate();
+                success = codegen->link();
             }
 
             if (success) {
                 if (script->hasIonScript())
                     mjit::ReleaseScriptCodeFromVM(cx, script);
             } else {
                 // Silently ignore OOM during code generation, we're at an
                 // operation callback and can't propagate failures.
@@ -1118,31 +1134,28 @@ SequentialCompileContext::compile(IonBui
 
         // The allocator and associated data will be destroyed after being
         // processed in the finishedOffThreadCompilations list.
         autoDestroy.cancel();
 
         return true;
     }
 
-    LIRGraph *lir = CompileBackEnd(builder);
-    if (!lir) {
+    CodeGenerator *codegen = CompileBackEnd(builder);
+    if (!codegen) {
         IonSpew(IonSpew_Abort, "Failed during back-end compilation.");
         return false;
     }
 
-    CodeGenerator codegen(builder, *lir);
-    if (!codegen.generate()) {
-        IonSpew(IonSpew_Abort, "Failed during code generation.");
-        return false;
-    }
+    bool success = codegen->link();
+    js_delete(codegen);
 
     IonSpewEndFunction();
 
-    return true;
+    return success;
 }
 
 bool
 TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
 {
     SequentialCompileContext compileContext;
     if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) {
         if (!cx->isExceptionPending())
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -248,19 +248,19 @@ void Invalidate(JSContext *cx, const Vec
 bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true);
 
 void MarkFromIon(JSCompartment *comp, Value *vp);
 
 void ToggleBarriers(JSCompartment *comp, bool needs);
 
 class IonBuilder;
 class MIRGenerator;
-class LIRGraph;
+class CodeGenerator;
 
-LIRGraph *CompileBackEnd(MIRGenerator *mir);
+CodeGenerator *CompileBackEnd(MIRGenerator *mir);
 void AttachFinishedCompilations(JSContext *cx);
 void FinishOffThreadBuilder(IonBuilder *builder);
 bool TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing);
 
 static inline bool IsEnabled(JSContext *cx)
 {
     return cx->hasRunOption(JSOPTION_ION) && cx->typeInferenceEnabled();
 }
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -25,17 +25,17 @@ using namespace js;
 using namespace js::ion;
 
 using mozilla::DebugOnly;
 
 IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
                        TypeOracle *oracle, CompileInfo *info, size_t inliningDepth, uint32 loopDepth)
   : MIRGenerator(cx->compartment, temp, graph, info),
     recompileInfo(cx->compartment->types.compiledInfo),
-    backgroundCompiledLir(NULL),
+    backgroundCodegen_(NULL),
     cx(cx),
     loopDepth_(loopDepth),
     callerResumePoint_(NULL),
     callerBuilder_(NULL),
     oracle(oracle),
     inliningDepth(inliningDepth),
     failedBoundsCheck_(info->script()->failedBoundsCheck),
     failedShapeGuard_(info->script()->failedShapeGuard),
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -12,17 +12,17 @@
 // JSScript.
 
 #include "MIR.h"
 #include "MIRGraph.h"
 
 namespace js {
 namespace ion {
 
-class LIRGraph;
+class CodeGenerator;
 
 class IonBuilder : public MIRGenerator
 {
     enum ControlStatus {
         ControlStatus_Error,
         ControlStatus_Ended,        // There is no continuation/join point.
         ControlStatus_Joined,       // Created a join node.
         ControlStatus_Jumped,       // Parsing another branch at the same level.
@@ -434,27 +434,32 @@ class IonBuilder : public MIRGenerator
                            MGetPropertyCache *getPropCache,
                            types::StackTypeSet *types, types::StackTypeSet *barrier,
                            MBasicBlock *bottom,
                            Vector<MDefinition *, 8, IonAllocPolicy> &retvalDefns);
 
     // A builder is inextricably tied to a particular script.
     HeapPtrScript script_;
 
+    // If off thread compilation is successful, the final code generator is
+    // attached here. Code has been generated, but not linked (there is not yet
+    // an IonScript). This is heap allocated, and must be explicitly destroyed.
+    CodeGenerator *backgroundCodegen_;
+
   public:
     // Compilation index for this attempt.
     types::RecompileInfo const recompileInfo;
 
-    // If off thread compilation is successful, final LIR is attached here.
-    LIRGraph *backgroundCompiledLir;
-
     void clearForBackEnd();
 
     Return<JSScript*> script() const { return script_; }
 
+    CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
+    void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }
+
   private:
     JSContext *cx;
 
     jsbytecode *pc;
     MBasicBlock *current;
     uint32 loopDepth_;
 
     /* Information used for inline-call builders. */
--- a/js/src/ion/IonMacroAssembler.h
+++ b/js/src/ion/IonMacroAssembler.h
@@ -46,17 +46,17 @@ class MacroAssembler : public MacroAssem
             masm_(masm)
         { }
 
         MacroAssembler *masm() const {
             return masm_;
         }
     };
 
-    AutoRooter autoRooter_;
+    mozilla::Maybe<AutoRooter> autoRooter_;
     mozilla::Maybe<IonContext> ionContext_;
     mozilla::Maybe<AutoIonContextAlloc> alloc_;
     bool enoughMemory_;
 
   private:
     // This field is used to manage profiling instrumentation output. If
     // provided and enabled, then instrumentation will be emitted around call
     // sites. The IonInstrumentation instance is hosted inside of
@@ -64,41 +64,48 @@ class MacroAssembler : public MacroAssem
     // actually emitted or not. If NULL, then no instrumentation is emitted.
     IonInstrumentation *sps_;
 
   public:
     // If instrumentation should be emitted, then the sps parameter should be
     // provided, but otherwise it can be safely omitted to prevent all
     // instrumentation from being emitted.
     MacroAssembler(IonInstrumentation *sps = NULL)
-      : autoRooter_(GetIonContext()->cx, thisFromCtor()),
-        enoughMemory_(true),
+      : enoughMemory_(true),
         sps_(sps)
     {
+        JSContext *cx = GetIonContext()->cx;
+        if (cx)
+            constructRoot(cx);
+
         if (!GetIonContext()->temp)
-            alloc_.construct(GetIonContext()->cx);
+            alloc_.construct(cx);
 #ifdef JS_CPU_ARM
         m_buffer.id = GetIonContext()->getNextAssemblerId();
 #endif
     }
 
     // This constructor should only be used when there is no IonContext active
     // (for example, Trampoline-$(ARCH).cpp).
     MacroAssembler(JSContext *cx)
-      : autoRooter_(cx, thisFromCtor()),
-        enoughMemory_(true),
+      : enoughMemory_(true),
         sps_(NULL) // no need for instrumentation in trampolines and such
     {
+        constructRoot(cx);
         ionContext_.construct(cx, cx->compartment, (js::ion::TempAllocator *)NULL);
         alloc_.construct(cx);
 #ifdef JS_CPU_ARM
         m_buffer.id = GetIonContext()->getNextAssemblerId();
 #endif
     }
 
+    void constructRoot(JSContext *cx) {
+        autoRooter_.construct(cx, this);
+    }
+
     MoveResolver &moveResolver() {
         return moveResolver_;
     }
 
     size_t instructionsSize() const {
         return size();
     }
 
@@ -150,21 +157,21 @@ class MacroAssembler : public MacroAssem
     }
 
     void loadStringLength(Register str, Register dest) {
         loadPtr(Address(str, JSString::offsetOfLengthAndFlags()), dest);
         rshiftPtr(Imm32(JSString::LENGTH_SHIFT), dest);
     }
 
     void loadJSContext(const Register &dest) {
-        movePtr(ImmWord(GetIonContext()->cx->runtime), dest);
+        movePtr(ImmWord(GetIonContext()->compartment->rt), dest);
         loadPtr(Address(dest, offsetof(JSRuntime, ionJSContext)), dest);
     }
     void loadIonActivation(const Register &dest) {
-        movePtr(ImmWord(GetIonContext()->cx->runtime), dest);
+        movePtr(ImmWord(GetIonContext()->compartment->rt), dest);
         loadPtr(Address(dest, offsetof(JSRuntime, ionActivation)), dest);
     }
 
     template<typename T>
     void loadTypedOrValue(const T &src, TypedOrValueRegister dest) {
         if (dest.hasValue())
             loadValue(src, dest.valueReg());
         else
@@ -365,17 +372,17 @@ class MacroAssembler : public MacroAssem
         if (key.isRegister())
             branch32(cond, length, key.reg(), label);
         else
             branch32(cond, length, Imm32(key.constant()), label);
     }
 
     void branchTestNeedsBarrier(Condition cond, const Register &scratch, Label *label) {
         JS_ASSERT(cond == Zero || cond == NonZero);
-        JSCompartment *comp = GetIonContext()->cx->compartment;
+        JSCompartment *comp = GetIonContext()->compartment;
         movePtr(ImmWord(comp), scratch);
         Address needsBarrierAddr(scratch, JSCompartment::OffsetOfNeedsBarrier());
         branchTest32(cond, needsBarrierAddr, Imm32(0x1), label);
     }
 
     template <typename T>
     void callPreBarrier(const T &address, MIRType type) {
         JS_ASSERT(type == MIRType_Value || type == MIRType_String || type == MIRType_Object);
--- a/js/src/ion/LIR.h
+++ b/js/src/ion/LIR.h
@@ -1139,16 +1139,19 @@ class LIRGraph
         return localSlotCount_;
     }
     void setArgumentSlotCount(uint32 argumentSlotCount) {
         argumentSlotCount_ = argumentSlotCount;
     }
     uint32 argumentSlotCount() const {
         return argumentSlotCount_;
     }
+    uint32 totalSlotCount() const {
+        return localSlotCount() + (argumentSlotCount() * sizeof(Value) / STACK_SLOT_SIZE);
+    }
     bool addConstantToPool(const Value &v, uint32 *index);
     size_t numConstants() const {
         return constantPool_.length();
     }
     HeapValue *constantPool() {
         return &constantPool_[0];
     }
     const HeapValue &getConstant(size_t index) const {
--- a/js/src/ion/arm/CodeGenerator-arm.cpp
+++ b/js/src/ion/arm/CodeGenerator-arm.cpp
@@ -46,17 +46,17 @@ class DeferredJumpTable : public Deferre
             *jumpData = (void *)(code->raw() + masm->actualOffset(offset));
             jumpData++;
         }
     }
 };
 
 
 // shared
-CodeGeneratorARM::CodeGeneratorARM(MIRGenerator *gen, LIRGraph &graph)
+CodeGeneratorARM::CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph)
   : CodeGeneratorShared(gen, graph),
     deoptLabel_(NULL)
 {
 }
 
 bool
 CodeGeneratorARM::generatePrologue()
 {
--- a/js/src/ion/arm/CodeGenerator-arm.h
+++ b/js/src/ion/arm/CodeGenerator-arm.h
@@ -117,17 +117,17 @@ class CodeGeneratorARM : public CodeGene
 
     void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType,
                            const Register &elements, const LAllocation *index);
 
   protected:
     void linkAbsoluteLabels();
 
   public:
-    CodeGeneratorARM(MIRGenerator *gen, LIRGraph &graph);
+    CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     bool visitBox(LBox *box);
     bool visitBoxDouble(LBoxDouble *box);
     bool visitUnbox(LUnbox *unbox);
     bool visitValue(LValue *value);
     bool visitOsrValue(LOsrValue *value);
     bool visitDouble(LDouble *ins);
--- a/js/src/ion/shared/CodeGenerator-shared.cpp
+++ b/js/src/ion/shared/CodeGenerator-shared.cpp
@@ -16,31 +16,31 @@
 using namespace js;
 using namespace js::ion;
 
 using mozilla::DebugOnly;
 
 namespace js {
 namespace ion {
 
-CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph &graph)
+CodeGeneratorShared::CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph)
   : oolIns(NULL),
     masm(&sps_),
     gen(gen),
-    graph(graph),
+    graph(*graph),
     current(NULL),
     deoptTable_(NULL),
 #ifdef DEBUG
     pushedArgs_(0),
 #endif
     lastOsiPointOffset_(0),
     sps_(&gen->compartment->rt->spsProfiler, &lastPC_),
     osrEntryOffset_(0),
-    frameDepth_(graph.localSlotCount() * sizeof(STACK_SLOT_SIZE) +
-                graph.argumentSlotCount() * sizeof(Value))
+    frameDepth_(graph->localSlotCount() * sizeof(STACK_SLOT_SIZE) +
+                graph->argumentSlotCount() * sizeof(Value))
 {
     frameClass_ = FrameSizeClass::FromDepth(frameDepth_);
 }
 
 bool
 CodeGeneratorShared::generateOutOfLineCode()
 {
     for (size_t i = 0; i < outOfLineCode_.length(); i++) {
--- a/js/src/ion/shared/CodeGenerator-shared.h
+++ b/js/src/ion/shared/CodeGenerator-shared.h
@@ -30,18 +30,20 @@ template <class ArgSeq, class StoreOutpu
 class OutOfLineCallVM;
 class OutOfLineTruncateSlow;
 
 class CodeGeneratorShared : public LInstructionVisitor
 {
     js::Vector<OutOfLineCode *, 0, SystemAllocPolicy> outOfLineCode_;
     OutOfLineCode *oolIns;
 
+  public:
+    MacroAssembler masm;
+
   protected:
-    MacroAssembler masm;
     MIRGenerator *gen;
     LIRGraph &graph;
     LBlock *current;
     SnapshotWriter snapshots_;
     IonCode *deoptTable_;
 #ifdef DEBUG
     uint32 pushedArgs_;
 #endif
@@ -277,17 +279,17 @@ class CodeGeneratorShared : public LInst
 
     void linkAbsoluteLabels() {
     }
 
   private:
     void generateInvalidateEpilogue();
 
   public:
-    CodeGeneratorShared(MIRGenerator *gen, LIRGraph &graph);
+    CodeGeneratorShared(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     template <class ArgSeq, class StoreOutputTo>
     bool visitOutOfLineCallVM(OutOfLineCallVM<ArgSeq, StoreOutputTo> *ool);
 
     bool visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool);
 };
 
--- a/js/src/ion/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/ion/shared/CodeGenerator-x86-shared.cpp
@@ -39,17 +39,17 @@ class DeferredJumpTable : public Deferre
 
             uint32 offset = caseheader->offset();
             *jumpData = (void *)(code->raw() + offset);
             jumpData++;
         }
     }
 };
 
-CodeGeneratorX86Shared::CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph &graph)
+CodeGeneratorX86Shared::CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph)
   : CodeGeneratorShared(gen, graph),
     deoptLabel_(NULL)
 {
 }
 
 double
 test(double x, double y)
 {
--- a/js/src/ion/shared/CodeGenerator-x86-shared.h
+++ b/js/src/ion/shared/CodeGenerator-x86-shared.h
@@ -78,17 +78,17 @@ class CodeGeneratorX86Shared : public Co
     // true, and the false block if |cond| is false.
     void emitBranch(Assembler::Condition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse,
                     NaNCond ifNaN = NaN_Unexpected);
     void emitBranch(Assembler::DoubleCondition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse);
 
     bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base);
 
   public:
-    CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph &graph);
+    CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     // Instruction visitors.
     virtual bool visitMinMaxD(LMinMaxD *ins);
     virtual bool visitNegD(LNegD *ins);
     virtual bool visitAbsD(LAbsD *ins);
     virtual bool visitSqrtD(LSqrtD *ins);
     virtual bool visitPowHalfD(LPowHalfD *ins);
--- a/js/src/ion/x64/CodeGenerator-x64.cpp
+++ b/js/src/ion/x64/CodeGenerator-x64.cpp
@@ -11,17 +11,17 @@
 #include "ion/MIRGraph.h"
 #include "jsnum.h"
 #include "jsscope.h"
 #include "jsscopeinlines.h"
 
 using namespace js;
 using namespace js::ion;
 
-CodeGeneratorX64::CodeGeneratorX64(MIRGenerator *gen, LIRGraph &graph)
+CodeGeneratorX64::CodeGeneratorX64(MIRGenerator *gen, LIRGraph *graph)
   : CodeGeneratorX86Shared(gen, graph)
 {
 }
 
 ValueOperand
 CodeGeneratorX64::ToValue(LInstruction *ins, size_t pos)
 {
     return ValueOperand(ToRegister(ins->getOperand(pos)));
--- a/js/src/ion/x64/CodeGenerator-x64.h
+++ b/js/src/ion/x64/CodeGenerator-x64.h
@@ -29,17 +29,17 @@ class CodeGeneratorX64 : public CodeGene
     void loadUnboxedValue(Operand source, MIRType type, const LDefinition *dest);
     void storeUnboxedValue(const LAllocation *value, MIRType valueType,
                            Operand dest, MIRType slotType);
 
     void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType,
                            const Register &elements, const LAllocation *index);
 
   public:
-    CodeGeneratorX64(MIRGenerator *gen, LIRGraph &graph);
+    CodeGeneratorX64(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     bool visitValue(LValue *value);
     bool visitOsrValue(LOsrValue *value);
     bool visitBox(LBox *box);
     bool visitUnbox(LUnbox *unbox);
     bool visitDouble(LDouble *ins);
     bool visitLoadSlotV(LLoadSlotV *ins);
--- a/js/src/ion/x86/CodeGenerator-x86.cpp
+++ b/js/src/ion/x86/CodeGenerator-x86.cpp
@@ -13,17 +13,17 @@
 #include "jsscope.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
 using namespace js::ion;
 
 using mozilla::DebugOnly;
 
-CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph &graph)
+CodeGeneratorX86::CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph)
   : CodeGeneratorX86Shared(gen, graph)
 {
 }
 
 static const uint32 FrameSizes[] = { 128, 256, 512, 1024 };
 
 FrameSizeClass
 FrameSizeClass::FromDepth(uint32 frameDepth)
--- a/js/src/ion/x86/CodeGenerator-x86.h
+++ b/js/src/ion/x86/CodeGenerator-x86.h
@@ -47,17 +47,17 @@ class CodeGeneratorX86 : public CodeGene
 
     void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType,
                            const Register &elements, const LAllocation *index);
 
   protected:
     void linkAbsoluteLabels();
 
   public:
-    CodeGeneratorX86(MIRGenerator *gen, LIRGraph &graph);
+    CodeGeneratorX86(MIRGenerator *gen, LIRGraph *graph);
 
   public:
     bool visitBox(LBox *box);
     bool visitBoxDouble(LBoxDouble *box);
     bool visitUnbox(LUnbox *unbox);
     bool visitValue(LValue *value);
     bool visitOsrValue(LOsrValue *value);
     bool visitDouble(LDouble *ins);
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -278,16 +278,19 @@ WorkerThread::ThreadMain(void *arg)
 }
 
 void
 WorkerThread::threadLoop()
 {
     WorkerThreadState &state = *runtime->workerThreadState;
     state.lock();
 
+    threadData.construct(runtime);
+    js::TlsPerThreadData.set(threadData.addr());
+
     while (true) {
         JS_ASSERT(!ionBuilder);
 
         while (state.ionWorklist.empty()) {
             if (terminate) {
                 state.unlock();
                 return;
             }
@@ -298,17 +301,17 @@ WorkerThread::threadLoop()
 
         ion::ExecutionMode executionMode = ionBuilder->info().executionMode();
         JS_ASSERT(GetIonScript(ionBuilder->script().unsafeGet(), executionMode) == ION_COMPILING_SCRIPT);
 
         state.unlock();
 
         {
             ion::IonContext ictx(NULL, ionBuilder->script()->compartment(), &ionBuilder->temp());
-            ionBuilder->backgroundCompiledLir = ion::CompileBackEnd(ionBuilder);
+            ionBuilder->setBackgroundCodegen(ion::CompileBackEnd(ionBuilder));
         }
 
         state.lock();
 
         FinishOffThreadIonCompile(ionBuilder);
         ionBuilder = NULL;
 
         /*
--- a/js/src/jsworkers.h
+++ b/js/src/jsworkers.h
@@ -77,16 +77,18 @@ class WorkerThreadState
     /* Condvar to notify helper threads that they may be able to make progress. */
     PRCondVar *helperWakeup;
 };
 
 /* Individual helper thread, one allocated per core. */
 struct WorkerThread
 {
     JSRuntime *runtime;
+
+    mozilla::Maybe<PerThreadData> threadData;
     PRThread *thread;
 
     /* Indicate to an idle thread that it should finish executing. */
     bool terminate;
 
     /* Any builder currently being compiled by Ion on this thread. */
     ion::IonBuilder *ionBuilder;
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1108,27 +1108,28 @@ nsXPCWrappedJSClass::CheckForException(X
             return pending_result;
         }
     }
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
-                                const XPTMethodDescriptor* info,
+                                const XPTMethodDescriptor* info_,
                                 nsXPTCMiniVariant* nativeParams)
 {
     jsval* sp = nullptr;
     jsval* argv = nullptr;
     uint8_t i;
     nsresult retval = NS_ERROR_FAILURE;
     nsresult pending_result = NS_OK;
     JSBool success;
     JSBool readyToDoTheCall = false;
     nsID  param_iid;
+    const nsXPTMethodInfo* info = static_cast<const nsXPTMethodInfo*>(info_);
     const char* name = info->name;
     jsval fval;
     JSBool foundDependentParam;
 
     // Make sure not to set the callee on ccx until after we've gone through
     // the whole nsIXPCFunctionThisTranslator bit.  That code uses ccx to
     // convert natives to JSObjects, but we do NOT plan to pass those JSObjects
     // to our real callee.
@@ -1138,16 +1139,27 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
         return retval;
 
     XPCContext *xpcc = ccx.GetXPCContext();
     JSContext *cx = xpc_UnmarkGrayContext(ccx.GetJSContext());
 
     if (!cx || !xpcc || !IsReflectable(methodIndex))
         return NS_ERROR_FAILURE;
 
+    // [implicit_jscontext] and [optional_argc] have a different calling
+    // convention, which we don't support for JS-implemented components.
+    if (info->WantsOptArgc() || info->WantsContext()) {
+        const char *str = "IDL methods marked with [implicit_jscontext] "
+                          "or [optional_argc] may not be implemented in JS";
+        // Throw and warn for good measure.
+        JS_ReportError(cx, str);
+        NS_WARNING(str);
+        return NS_ERROR_FAILURE;
+    }
+
     JSObject *obj = wrapper->GetJSObject();
     JSObject *thisObj = obj;
 
     JSAutoCompartment ac(cx, obj);
     ccx.SetScopeForNewJSObjects(obj);
 
     JS::AutoValueVector args(cx);
     AutoScriptEvaluate scriptEval(cx);
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -9,23 +9,23 @@
 
 #include "nsAttrValue.h"
 #include "nsAutoCopyListener.h"
 #include "nsColorNames.h"
 #include "nsComputedDOMStyle.h"
 #include "nsContentDLF.h"
 #include "nsContentUtils.h"
 #include "nsCSSAnonBoxes.h"
+#include "mozilla/css/ErrorReporter.h"
 #include "nsCSSKeywords.h"
 #include "nsCSSParser.h"
 #include "nsCSSProps.h"
 #include "nsCSSPseudoClasses.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSRendering.h"
-#include "nsCSSScanner.h"
 #include "nsDOMAttribute.h"
 #include "nsDOMClassInfo.h"
 #include "nsEventListenerManager.h"
 #include "nsFrame.h"
 #include "nsGlobalWindow.h"
 #include "nsGkAtoms.h"
 #include "nsImageFrame.h"
 #include "nsLayoutStylesheetCache.h"
@@ -307,17 +307,17 @@ nsLayoutStatics::Shutdown()
   nsSprocketLayout::Shutdown();
 #endif
 
   nsMathMLOperators::ReleaseTable();
 
   nsFloatManager::Shutdown();
   nsImageFrame::ReleaseGlobals();
 
-  nsCSSScanner::ReleaseGlobals();
+  mozilla::css::ErrorReporter::ReleaseGlobals();
 
   nsTextFragment::Shutdown();
 
   nsAttrValue::Shutdown();
   nsContentUtils::Shutdown();
   nsNodeInfo::ClearCache();
   nsLayoutStylesheetCache::Shutdown();
   NS_NameSpaceManagerShutdown();
deleted file mode 100644
--- a/layout/reftests/svg/inline-in-xul-basic-01.xul
+++ /dev/null
@@ -1,12 +0,0 @@
-<!--
-     Any copyright is dedicated to the Public Domain.
-     http://creativecommons.org/publicdomain/zero/1.0/
--->
-
-<!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=364732 -->
-
-<box xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1">
-  <svg xmlns="http://www.w3.org/2000/svg">
-    <rect fill="lime" width="100%" height="100%"/>
-  </svg>
-</box>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -157,17 +157,16 @@ fails-if(Android) == filter-extref-diffe
 == foreignObject-dynamic-abspos-01.html foreignObject-dynamic-abspos-01-ref.html
 == foreignObject-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html
 == foreignObject-dynamic-fixedpos-01.html foreignObject-dynamic-abspos-01-ref.html
 == getElementById-a-element-01.svg pass.svg
 fuzzy-if(Android,9,980) == gradient-live-01a.svg gradient-live-01-ref.svg
 fuzzy-if(Android,9,980) == gradient-live-01b.svg gradient-live-01-ref.svg
 fuzzy-if(Android,9,980) == gradient-live-01c.svg gradient-live-01-ref.svg
 fuzzy-if(Android,9,980) == gradient-live-01d.svg gradient-live-01-ref.svg
-fails == inline-in-xul-basic-01.xul pass.svg
 == invalid-text-01.svg pass.svg
 == lang-attribute-01.svg pass.svg
 == lang-attribute-02.svg pass.svg
 == lang-attribute-03.svg pass.svg
 == linearGradient-basic-01.svg pass.svg
 == linearGradient-basic-02.svg pass.svg
 == markers-and-group-opacity-01.svg markers-and-group-opacity-01-ref.svg
 == marker-attribute-01.svg pass.svg
new file mode 100644
--- /dev/null
+++ b/layout/style/ErrorReporter.cpp
@@ -0,0 +1,336 @@
+/* -*- 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/. */
+
+/* diagnostic reporting for CSS style sheet parser */
+
+#include "mozilla/css/ErrorReporter.h"
+#include "mozilla/css/Loader.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Services.h"
+#include "nsCSSScanner.h"
+#include "nsCSSStyleSheet.h"
+#include "nsIConsoleService.h"
+#include "nsIDocument.h"
+#include "nsIFactory.h"
+#include "nsIScriptError.h"
+#include "nsIServiceManager.h"
+#include "nsIStringBundle.h"
+#include "nsThreadUtils.h"
+
+#ifdef CSS_REPORT_PARSE_ERRORS
+
+using mozilla::Preferences;
+namespace services = mozilla::services;
+
+namespace {
+class ShortTermURISpecCache : public nsRunnable {
+public:
+  ShortTermURISpecCache() : mPending(false) {}
+
+  nsString const& GetSpec(nsIURI* aURI) {
+    if (mURI != aURI) {
+      mURI = aURI;
+
+      nsAutoCString cSpec;
+      mURI->GetSpec(cSpec);
+      CopyUTF8toUTF16(cSpec, mSpec);
+    }
+    return mSpec;
+  }
+
+  bool IsInUse() const { return mURI != nullptr; }
+  bool IsPending() const { return mPending; }
+  void SetPending() { mPending = true; }
+
+  // When invoked as a runnable, zap the cache.
+  NS_IMETHOD Run() {
+    mURI = nullptr;
+    mSpec.Truncate();
+    mPending = false;
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIURI> mURI;
+  nsString mSpec;
+  bool mPending;
+};
+}
+
+static bool sReportErrors;
+static nsIConsoleService *sConsoleService;
+static nsIFactory *sScriptErrorFactory;
+static nsIStringBundle *sStringBundle;
+static ShortTermURISpecCache *sSpecCache;
+
+#define CSS_ERRORS_PREF "layout.css.report_errors"
+
+static bool
+InitGlobals()
+{
+  NS_ABORT_IF_FALSE(!sConsoleService && !sScriptErrorFactory && !sStringBundle,
+                    "should not have been called");
+
+  if (NS_FAILED(Preferences::AddBoolVarCache(&sReportErrors, CSS_ERRORS_PREF,
+                                             true))) {
+    return false;
+  }
+
+  nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+  if (!cs) {
+    return false;
+  }
+
+  nsCOMPtr<nsIFactory> sf = do_GetClassObject(NS_SCRIPTERROR_CONTRACTID);
+  if (!sf) {
+    return false;
+  }
+
+  nsCOMPtr<nsIStringBundleService> sbs = services::GetStringBundleService();
+  if (!sbs) {
+    return false;
+  }
+
+  nsCOMPtr<nsIStringBundle> sb;
+  nsresult rv = sbs->CreateBundle("chrome://global/locale/css.properties",
+                                  getter_AddRefs(sb));
+  if (NS_FAILED(rv) || !sb) {
+    return false;
+  }
+
+  sConsoleService = cs.forget().get();
+  sScriptErrorFactory = sf.forget().get();
+  sStringBundle = sb.forget().get();
+
+  return true;
+}
+
+static inline bool
+ShouldReportErrors()
+{
+  if (!sConsoleService) {
+    if (!InitGlobals()) {
+      return false;
+    }
+  }
+  return sReportErrors;
+}
+
+namespace mozilla {
+namespace css {
+
+/* static */ void
+ErrorReporter::ReleaseGlobals()
+{
+  NS_IF_RELEASE(sConsoleService);
+  NS_IF_RELEASE(sScriptErrorFactory);
+  NS_IF_RELEASE(sStringBundle);
+  NS_IF_RELEASE(sSpecCache);
+}
+
+ErrorReporter::ErrorReporter(const nsCSSScanner& aScanner,
+                             const nsCSSStyleSheet* aSheet,
+                             const Loader* aLoader,
+                             nsIURI* aURI)
+  : mScanner(&aScanner), mSheet(aSheet), mLoader(aLoader), mURI(aURI),
+    mInnerWindowID(0), mErrorLineNumber(0), mErrorColNumber(0)
+{
+}
+
+ErrorReporter::~ErrorReporter()
+{
+  // Schedule deferred cleanup for cached data. We want to strike a
+  // balance between performance and memory usage, so we only allow
+  // short-term caching.
+  if (sSpecCache && sSpecCache->IsInUse() && !sSpecCache->IsPending()) {
+    if (NS_FAILED(NS_DispatchToCurrentThread(sSpecCache))) {
+      // Peform the "deferred" cleanup immediately if the dispatch fails.
+      sSpecCache->Run();
+    } else {
+      sSpecCache->SetPending();
+    }
+  }
+}
+
+void
+ErrorReporter::OutputError()
+{
+  if (mError.IsEmpty()) {
+    return;
+  }
+  if (!ShouldReportErrors()) {
+    ClearError();
+    return;
+  }
+
+  if (mInnerWindowID == 0 && (mSheet || mLoader)) {
+    if (mSheet) {
+      mInnerWindowID = mSheet->FindOwningWindowInnerID();
+    }
+    if (mInnerWindowID == 0 && mLoader) {
+      nsIDocument* doc = mLoader->GetDocument();
+      if (doc) {
+        mInnerWindowID = doc->InnerWindowID();
+      }
+    }
+    // don't attempt this again, even if we failed
+    mSheet = nullptr;
+    mLoader = nullptr;
+  }
+
+  if (mFileName.IsEmpty()) {
+    if (mURI) {
+      if (!sSpecCache) {
+        sSpecCache = new ShortTermURISpecCache;
+        NS_ADDREF(sSpecCache);
+      }
+      mFileName = sSpecCache->GetSpec(mURI);
+      mURI = nullptr;
+    } else {
+      mFileName.AssignLiteral("from DOM");
+    }
+  }
+
+  nsresult rv;
+  nsCOMPtr<nsIScriptError> errorObject =
+    do_CreateInstance(sScriptErrorFactory, &rv);
+
+  if (NS_SUCCEEDED(rv)) {
+    rv = errorObject->InitWithWindowID(mError,
+                                       mFileName,
+                                       EmptyString(),
+                                       mErrorLineNumber,
+                                       mErrorColNumber,
+                                       nsIScriptError::warningFlag,
+                                       "CSS Parser",
+                                       mInnerWindowID);
+    if (NS_SUCCEEDED(rv)) {
+      sConsoleService->LogMessage(errorObject);
+    }
+  }
+
+  ClearError();
+}
+
+void
+ErrorReporter::ClearError()
+{
+  mError.Truncate();
+}
+
+void
+ErrorReporter::AddToError(const nsString &aErrorText)
+{
+  if (!ShouldReportErrors()) return;
+
+  if (mError.IsEmpty()) {
+    mErrorLineNumber = mScanner->GetLineNumber();
+    mErrorColNumber = mScanner->GetColumnNumber();
+    mError = aErrorText;
+  } else {
+    mError.AppendLiteral("  ");
+    mError.Append(aErrorText);
+  }
+}
+
+void
+ErrorReporter::ReportUnexpected(const char *aMessage)
+{
+  if (!ShouldReportErrors()) return;
+
+  nsAutoString str;
+  sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
+                                   getter_Copies(str));
+  AddToError(str);
+}
+
+void
+ErrorReporter::ReportUnexpected(const char *aMessage,
+                                const nsString &aParam)
+{
+  if (!ShouldReportErrors()) return;
+
+  const PRUnichar *params[1] = { aParam.get() };
+  nsAutoString str;
+  sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
+                                      params, ArrayLength(params),
+                                      getter_Copies(str));
+  AddToError(str);
+}
+
+void
+ErrorReporter::ReportUnexpected(const char *aMessage,
+                                const nsCSSToken &aToken)
+{
+  if (!ShouldReportErrors()) return;
+
+  nsAutoString tokenString;
+  aToken.AppendToString(tokenString);
+  const PRUnichar *params[1] = { tokenString.get() };
+
+  nsAutoString str;
+  sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
+                                      params, ArrayLength(params),
+                                      getter_Copies(str));
+  AddToError(str);
+}
+
+void
+ErrorReporter::ReportUnexpected(const char *aMessage,
+                                const nsCSSToken &aToken,
+                                PRUnichar aChar)
+{
+  if (!ShouldReportErrors()) return;
+
+  nsAutoString tokenString;
+  aToken.AppendToString(tokenString);
+  const PRUnichar charStr[2] = { aChar, 0 };
+  const PRUnichar *params[2] = { tokenString.get(), charStr };
+
+  nsAutoString str;
+  sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
+                                      params, ArrayLength(params),
+                                      getter_Copies(str));
+  AddToError(str);
+}
+
+void
+ErrorReporter::ReportUnexpectedEOF(const char *aMessage)
+{
+  if (!ShouldReportErrors()) return;
+
+  nsAutoString innerStr;
+  sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
+                                   getter_Copies(innerStr));
+  const PRUnichar *params[1] = { innerStr.get() };
+
+  nsAutoString str;
+  sStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(),
+                                      params, ArrayLength(params),
+                                      getter_Copies(str));
+  AddToError(str);
+}
+
+void
+ErrorReporter::ReportUnexpectedEOF(PRUnichar aExpected)
+{
+  if (!ShouldReportErrors()) return;
+
+  const PRUnichar expectedStr[] = {
+    PRUnichar('\''), aExpected, PRUnichar('\''), PRUnichar(0)
+  };
+  const PRUnichar *params[1] = { expectedStr };
+
+  nsAutoString str;
+  sStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(),
+                                      params, ArrayLength(params),
+                                      getter_Copies(str));
+  AddToError(str);
+}
+
+} // namespace css
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/layout/style/ErrorReporter.h
@@ -0,0 +1,104 @@
+/* -*- 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/. */
+
+/* diagnostic reporting for CSS style sheet parser */
+
+#ifndef mozilla_css_ErrorReporter_h_
+#define mozilla_css_ErrorReporter_h_
+
+// XXX turn this off for minimo builds
+#define CSS_REPORT_PARSE_ERRORS
+
+#include "nsString.h"
+
+struct nsCSSToken;
+class nsCSSStyleSheet;
+class nsCSSScanner;
+class nsIURI;
+
+namespace mozilla {
+namespace css {
+
+class Loader;
+
+// If CSS_REPORT_PARSE_ERRORS is not defined, all of this class's
+// methods become inline stubs.
+class NS_STACK_CLASS ErrorReporter {
+public:
+  ErrorReporter(const nsCSSScanner &aScanner,
+                const nsCSSStyleSheet *aSheet,
+                const Loader *aLoader,
+                nsIURI *aURI);
+  ~ErrorReporter();
+
+  static void ReleaseGlobals();
+
+  void OutputError();
+  void ClearError();
+
+  // In all overloads of ReportUnexpected, aMessage is a stringbundle
+  // name, which will be processed as a format string with the
+  // indicated number of parameters.
+
+  // no parameters
+  void ReportUnexpected(const char *aMessage);
+  // one parameter, a string
+  void ReportUnexpected(const char *aMessage, const nsString& aParam);
+  // one parameter, a token
+  void ReportUnexpected(const char *aMessage, const nsCSSToken& aToken);
+  // two parameters, a token and a character, in that order
+  void ReportUnexpected(const char *aMessage, const nsCSSToken& aToken,
+                        PRUnichar aChar);
+
+  // for ReportUnexpectedEOF, aExpected can be either a stringbundle
+  // name or a single character.  In the former case there may not be
+  // any format parameters.
+  void ReportUnexpectedEOF(const char *aExpected);
+  void ReportUnexpectedEOF(PRUnichar aExpected);
+
+private:
+  void AddToError(const nsString &aErrorText);
+
+#ifdef CSS_REPORT_PARSE_ERRORS
+  nsAutoString mError;
+  nsString mFileName;
+  const nsCSSScanner *mScanner;
+  const nsCSSStyleSheet *mSheet;
+  const Loader *mLoader;
+  nsIURI *mURI;
+  uint64_t mInnerWindowID;
+  uint32_t mErrorLineNumber;
+  uint32_t mErrorColNumber;
+#endif
+};
+
+#ifndef CSS_REPORT_PARSE_ERRORS
+inline ErrorReporter::ErrorReporter(const nsCSSScanner&,
+                                    const nsCSSStyleSheet*,
+                                    const Loader*,
+                                    nsIURI*) {}
+inline ErrorReporter::~ErrorReporter() {}
+
+inline void ErrorReporter::ReleaseGlobals() {}
+
+inline void ErrorReporter::OutputError() {}
+inline void ErrorReporter::ClearError() {}
+
+inline void ErrorReporter::ReportUnexpected(const char *) {}
+inline void ErrorReporter::ReportUnexpected(const char *, const nsString &) {}
+inline void ErrorReporter::ReportUnexpected(const char *, const nsCSSToken &) {}
+inline void ErrorReporter::ReportUnexpected(const char *, const nsCSSToken &,
+                                            PRUnichar) {}
+
+inline void ErrorReporter::ReportUnexpectedEOF(const char *) {}
+inline void ErrorReporter::ReportUnexpectedEOF(PRUnichar) {}
+
+inline void ErrorReporter::AddToError(const nsString &) {}
+#endif
+
+} // namespace css
+} // namespace mozilla
+
+#endif // mozilla_css_ErrorReporter_h_
--- a/layout/style/Makefile.in
+++ b/layout/style/Makefile.in
@@ -66,30 +66,32 @@ EXPORTS		= \
 		nsStyleStructInlines.h \
 		nsStyleStructList.h \
 		nsStyleTransformMatrix.h \
 		nsStyleUtil.h \
 		$(NULL)
 
 EXPORTS_mozilla/css = \
 		Declaration.h \
+		ErrorReporter.h \
 		GroupRule.h \
 		ImageLoader.h \
 		ImportRule.h \
 		Loader.h \
 		NameSpaceRule.h \
 		Rule.h \
 		StyleRule.h \
 		$(NULL)
 
 CPPSRCS		= \
 		AnimationCommon.cpp \
 		nsCSSAnonBoxes.cpp \
 		nsCSSDataBlock.cpp \
 		Declaration.cpp \
+		ErrorReporter.cpp \
 		nsCSSKeywords.cpp \
 		ImageLoader.cpp \
 		Loader.cpp \
 		nsAnimationManager.cpp \
 		nsCSSParser.cpp \
 		nsCSSProps.cpp \
 		nsCSSPseudoClasses.cpp \
 		nsCSSPseudoElements.cpp \
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* parsing of CSS stylesheets, based on a token stream from the CSS scanner */
 
 #include "nsCSSParser.h"
 #include "nsCSSProps.h"
 #include "nsCSSKeywords.h"
 #include "nsCSSScanner.h"
+#include "mozilla/css/ErrorReporter.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/ImportRule.h"
 #include "nsCSSRules.h"
 #include "mozilla/css/NameSpaceRule.h"
 #include "nsTArray.h"
 #include "nsCSSStyleSheet.h"
 #include "mozilla/css/Declaration.h"
@@ -156,18 +157,16 @@ class CSSParserImpl {
 public:
   CSSParserImpl();
   ~CSSParserImpl();
 
   nsresult SetStyleSheet(nsCSSStyleSheet* aSheet);
 
   nsresult SetQuirkMode(bool aQuirkMode);
 
-  nsresult SetSVGMode(bool aSVGMode);
-
   nsresult SetChildLoader(mozilla::css::Loader* aChildLoader);
 
   // Clears everything set by the above Set*() functions.
   void Reset();
 
   nsresult ParseSheet(const nsAString& aInput,
                       nsIURI*          aSheetURI,
                       nsIURI*          aBaseURI,
@@ -196,17 +195,18 @@ public:
 
   nsresult ParseProperty(const nsCSSProperty aPropID,
                          const nsAString& aPropValue,
                          nsIURI* aSheetURL,
                          nsIURI* aBaseURL,
                          nsIPrincipal* aSheetPrincipal,
                          css::Declaration* aDeclaration,
                          bool* aChanged,
-                         bool aIsImportant);
+                         bool aIsImportant,
+                         bool aIsSVGMode);
 
   nsresult ParseMediaList(const nsSubstring& aBuffer,
                           nsIURI* aURL, // for error reporting
                           uint32_t aLineNumber, // for error reporting
                           nsMediaList* aMediaList,
                           bool aHTMLMode);
 
   bool ParseColorString(const nsSubstring& aBuffer,
@@ -254,41 +254,37 @@ protected:
       {
         mParser->SetParsingCompoundProperty(false);
       }
     private:
       CSSParserImpl* mParser;
   };
 
   // the caller must hold on to aString until parsing is done
-  void InitScanner(const nsSubstring& aString, nsIURI* aSheetURI,
-                   uint32_t aLineNumber, nsIURI* aBaseURI,
+  void InitScanner(nsCSSScanner& aScanner,
+                   css::ErrorReporter& aReporter,
+                   nsIURI* aSheetURI, nsIURI* aBaseURI,
                    nsIPrincipal* aSheetPrincipal);
   void ReleaseScanner(void);
   bool IsSVGMode() const {
-    return mScanner.IsSVGMode();
+    return mScanner->IsSVGMode();
   }
 
   bool GetToken(bool aSkipWS);
   void UngetToken();
 
   // get the part in paretheses of the url() function, which is really a
   // part of a token in the CSS grammar, but we're using a combination
   // of the parser and the scanner to do it to handle the backtracking
   // required by the error handling of the tokenization (since if we
   // fail to scan the full token, we should fall back to tokenizing as
   // FUNCTION ... ')').
   // Note that this function WILL WRITE TO aURL IN SOME FAILURE CASES.
   bool GetURLInParens(nsString& aURL);
 
-  void AssertInitialState() {
-    NS_PRECONDITION(!mHTMLMediaMode, "Bad initial state");
-    NS_PRECONDITION(!mParsingCompoundProperty, "Bad initial state");
-  }
-
   bool ExpectSymbol(PRUnichar aSymbol, bool aSkipWS);
   bool ExpectEndProperty();
   bool CheckEndProperty();
   nsSubstring* NextIdent();
   void SkipUntil(PRUnichar aStopSymbol);
   void SkipUntilOneOf(const PRUnichar* aStopSymbolChars);
   void SkipRuleSet(bool aInsideBraces);
   bool SkipAtRule(bool aInsideBlock);
@@ -630,17 +626,20 @@ protected:
   /* Find the correct default namespace, and set it on aSelector. */
   void SetDefaultNamespaceOnSelector(nsCSSSelector& aSelector);
 
   // Current token. The value is valid after calling GetToken and invalidated
   // by UngetToken.
   nsCSSToken mToken;
 
   // Our scanner.
-  nsCSSScanner mScanner;
+  nsCSSScanner* mScanner;
+
+  // Our error reporter.
+  css::ErrorReporter* mReporter;
 
   // The URI to be used as a base for relative URIs.
   nsCOMPtr<nsIURI> mBaseURI;
 
   // The URI to be used as an HTTP "Referer" and for error reporting.
   nsCOMPtr<nsIURI> mSheetURI;
 
   // The principal of the sheet involved
@@ -685,20 +684,16 @@ protected:
   // True for parsing media lists for HTML attributes, where we have to
   // ignore CSS comments.
   bool mHTMLMediaMode : 1;
 
   // This flag is set when parsing a non-box shorthand; it's used to not apply
   // some quirks during shorthand parsing
   bool          mParsingCompoundProperty : 1;
 
-#ifdef DEBUG
-  bool mScannerInited : 1;
-#endif
-
   // Stack of rule groups; used for @media and such.
   InfallibleTArray<nsRefPtr<css::GroupRule> > mGroupStack;
 
   // During the parsing of a property (which may be a shorthand), the data
   // are stored in |mTempData|.  (It is needed to ensure that parser
   // errors cause the data to be ignored, and to ensure that a
   // non-'!important' declaration does not override an '!important'
   // one.)
@@ -718,73 +713,54 @@ static void AppendRuleToArray(css::Rule*
 }
 
 static void AppendRuleToSheet(css::Rule* aRule, void* aParser)
 {
   CSSParserImpl* parser = (CSSParserImpl*) aParser;
   parser->AppendRule(aRule);
 }
 
-#ifdef CSS_REPORT_PARSE_ERRORS
-
 #define REPORT_UNEXPECTED(msg_) \
-  mScanner.ReportUnexpected(#msg_)
-
-#define REPORT_UNEXPECTED_P(msg_, params_) \
-  mScanner.ReportUnexpectedParams(#msg_, params_)
-
-#define REPORT_UNEXPECTED_EOF(lf_) \
-  mScanner.ReportUnexpectedEOF(#lf_)
-
-#define REPORT_UNEXPECTED_EOF_CHAR(ch_) \
-  mScanner.ReportUnexpectedEOF(ch_)
+  mReporter->ReportUnexpected(#msg_)
+
+#define REPORT_UNEXPECTED_P(msg_, param_) \
+  mReporter->ReportUnexpected(#msg_, param_)
 
 #define REPORT_UNEXPECTED_TOKEN(msg_) \
-  mScanner.ReportUnexpectedToken(mToken, #msg_)
-
-#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_) \
-  mScanner.ReportUnexpectedTokenParams(mToken, #msg_, \
-                                       params_, ArrayLength(params_))
-
+  mReporter->ReportUnexpected(#msg_, mToken)
+
+#define REPORT_UNEXPECTED_TOKEN_CHAR(msg_, ch_) \
+  mReporter->ReportUnexpected(#msg_, mToken, ch_)
+
+#define REPORT_UNEXPECTED_EOF(lf_) \
+  mReporter->ReportUnexpectedEOF(#lf_)
+
+#define REPORT_UNEXPECTED_EOF_CHAR(ch_) \
+  mReporter->ReportUnexpectedEOF(ch_)
 
 #define OUTPUT_ERROR() \
-  mScanner.OutputError()
+  mReporter->OutputError()
 
 #define CLEAR_ERROR() \
-  mScanner.ClearError()
-
-#else
-
-#define REPORT_UNEXPECTED(msg_)
-#define REPORT_UNEXPECTED_P(msg_, params_)
-#define REPORT_UNEXPECTED_EOF(lf_)
-#define REPORT_UNEXPECTED_EOF_CHAR(ch_)
-#define REPORT_UNEXPECTED_TOKEN(msg_)
-#define REPORT_UNEXPECTED_TOKEN_P(msg_, params_)
-#define OUTPUT_ERROR()
-#define CLEAR_ERROR()
-
-#endif
+  mReporter->ClearError()
 
 CSSParserImpl::CSSParserImpl()
   : mToken(),
-    mScanner(),
+    mScanner(nullptr),
+    mReporter(nullptr),
     mChildLoader(nullptr),
     mSection(eCSSSection_Charset),
     mNameSpaceMap(nullptr),
     mHavePushBack(false),
     mNavQuirkMode(false),
     mHashlessColorQuirk(false),
     mUnitlessLengthQuirk(false),
     mUnsafeRulesEnabled(false),
     mHTMLMediaMode(false),
     mParsingCompoundProperty(false),
-#ifdef DEBUG
-    mScannerInited(false),
-#endif
     mNextFree(nullptr)
 {
 }
 
 CSSParserImpl::~CSSParserImpl()
 {
   mData.AssertInitialState();
   mTempData.AssertInitialState();
@@ -812,101 +788,89 @@ CSSParserImpl::SetStyleSheet(nsCSSStyleS
 nsresult
 CSSParserImpl::SetQuirkMode(bool aQuirkMode)
 {
   mNavQuirkMode = aQuirkMode;
   return NS_OK;
 }
 
 nsresult
-CSSParserImpl::SetSVGMode(bool aSVGMode)
-{
-  mScanner.SetSVGMode(aSVGMode);
-  return NS_OK;
-}
-
-nsresult
 CSSParserImpl::SetChildLoader(mozilla::css::Loader* aChildLoader)
 {
   mChildLoader = aChildLoader;  // not ref counted, it owns us
   return NS_OK;
 }
 
 void
 CSSParserImpl::Reset()
 {
-  NS_ASSERTION(! mScannerInited, "resetting with scanner active");
+  NS_ASSERTION(!mScanner, "resetting with scanner active");
   SetStyleSheet(nullptr);
   SetQuirkMode(false);
-  SetSVGMode(false);
   SetChildLoader(nullptr);
 }
 
 void
-CSSParserImpl::InitScanner(const nsSubstring& aString, nsIURI* aSheetURI,
-                           uint32_t aLineNumber, nsIURI* aBaseURI,
+CSSParserImpl::InitScanner(nsCSSScanner& aScanner,
+                           css::ErrorReporter& aReporter,
+                           nsIURI* aSheetURI, nsIURI* aBaseURI,
                            nsIPrincipal* aSheetPrincipal)
 {
-  // Having it not own the string is OK since the caller will hold on to
-  // the stream until we're done parsing.
-  NS_ASSERTION(! mScannerInited, "already have scanner");
-
-  mScanner.Init(aString, aSheetURI, aLineNumber, mSheet, mChildLoader);
-
-#ifdef DEBUG
-  mScannerInited = true;
-#endif
+  NS_PRECONDITION(!mHTMLMediaMode, "Bad initial state");
+  NS_PRECONDITION(!mParsingCompoundProperty, "Bad initial state");
+  NS_PRECONDITION(!mScanner, "already have scanner");
+
+  mScanner = &aScanner;
+  mReporter = &aReporter;
+  mScanner->SetErrorReporter(mReporter);
+
   mBaseURI = aBaseURI;
   mSheetURI = aSheetURI;
   mSheetPrincipal = aSheetPrincipal;
-
   mHavePushBack = false;
 }
 
 void
-CSSParserImpl::ReleaseScanner(void)
-{
-  mScanner.Close();
-#ifdef DEBUG
-  mScannerInited = false;
-#endif
+CSSParserImpl::ReleaseScanner()
+{
+  mScanner = nullptr;
+  mReporter = nullptr;
   mBaseURI = nullptr;
   mSheetURI = nullptr;
   mSheetPrincipal = nullptr;
 }
 
 nsresult
 CSSParserImpl::ParseSheet(const nsAString& aInput,
                           nsIURI*          aSheetURI,
                           nsIURI*          aBaseURI,
                           nsIPrincipal*    aSheetPrincipal,
                           uint32_t         aLineNumber,
                           bool             aAllowUnsafeRules)
 {
   NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
-
-  NS_ASSERTION(nullptr != aBaseURI, "need base URI");
-  NS_ASSERTION(nullptr != aSheetURI, "need sheet URI");
-  AssertInitialState();
-
+  NS_PRECONDITION(aBaseURI, "need base URI");
+  NS_PRECONDITION(aSheetURI, "need sheet URI");
   NS_PRECONDITION(mSheet, "Must have sheet to parse into");
   NS_ENSURE_STATE(mSheet);
 
 #ifdef DEBUG
   nsIURI* uri = mSheet->GetSheetURI();
   bool equal;
   NS_ASSERTION(NS_SUCCEEDED(aSheetURI->Equals(uri, &equal)) && equal,
                "Sheet URI does not match passed URI");
   NS_ASSERTION(NS_SUCCEEDED(mSheet->Principal()->Equals(aSheetPrincipal,
                                                         &equal)) &&
                equal,
                "Sheet principal does not match passed principal");
 #endif
 
-  InitScanner(aInput, aSheetURI, aLineNumber, aBaseURI, aSheetPrincipal);
+  nsCSSScanner scanner(aInput, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI);
+  InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal);
 
   int32_t ruleCount = mSheet->StyleRuleCount();
   if (0 < ruleCount) {
     css::Rule* lastRule = nullptr;
     mSheet->GetStyleRuleAt(ruleCount - 1, lastRule);
     if (lastRule) {
       switch (lastRule->GetType()) {
         case css::Rule::CHARSET_RULE:
@@ -972,22 +936,22 @@ NonMozillaVendorIdentifier(const nsAStri
 nsresult
 CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
                                    nsIURI*          aDocURI,
                                    nsIURI*          aBaseURI,
                                    nsIPrincipal*    aNodePrincipal,
                                    css::StyleRule** aResult)
 {
   NS_PRECONDITION(aNodePrincipal, "Must have principal here!");
-  AssertInitialState();
-
-  NS_ASSERTION(nullptr != aBaseURI, "need base URI");
+  NS_PRECONDITION(aBaseURI, "need base URI");
 
   // XXX line number?
-  InitScanner(aAttributeValue, aDocURI, 0, aBaseURI, aNodePrincipal);
+  nsCSSScanner scanner(aAttributeValue, 0);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aDocURI);
+  InitScanner(scanner, reporter, aDocURI, aBaseURI, aNodePrincipal);
 
   mSection = eCSSSection_General;
 
   // In quirks mode, allow style declarations to have braces or not
   // (bug 99554).
   bool haveBraces;
   if (mNavQuirkMode && GetToken(true)) {
     haveBraces = eCSSToken_Symbol == mToken.mType &&
@@ -1020,22 +984,23 @@ CSSParserImpl::ParseStyleAttribute(const
 nsresult
 CSSParserImpl::ParseDeclarations(const nsAString&  aBuffer,
                                  nsIURI*           aSheetURI,
                                  nsIURI*           aBaseURI,
                                  nsIPrincipal*     aSheetPrincipal,
                                  css::Declaration* aDeclaration,
                                  bool*           aChanged)
 {
+  *aChanged = false;
+
   NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
-  AssertInitialState();
-
-  *aChanged = false;
-
-  InitScanner(aBuffer, aSheetURI, 0, aBaseURI, aSheetPrincipal);
+
+  nsCSSScanner scanner(aBuffer, 0);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI);
+  InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal);
 
   mSection = eCSSSection_General;
 
   mData.AssertInitialState();
   aDeclaration->ClearData();
   // We could check if it was already empty, but...
   *aChanged = true;
 
@@ -1058,21 +1023,21 @@ CSSParserImpl::ParseDeclarations(const n
 nsresult
 CSSParserImpl::ParseRule(const nsAString&        aRule,
                          nsIURI*                 aSheetURI,
                          nsIURI*                 aBaseURI,
                          nsIPrincipal*           aSheetPrincipal,
                          nsCOMArray<css::Rule>&  aResult)
 {
   NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
-  AssertInitialState();
-
-  NS_ASSERTION(nullptr != aBaseURI, "need base URI");
-
-  InitScanner(aRule, aSheetURI, 0, aBaseURI, aSheetPrincipal);
+  NS_PRECONDITION(aBaseURI, "need base URI");
+
+  nsCSSScanner scanner(aRule, 0);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI);
+  InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal);
 
   mSection = eCSSSection_Charset; // callers are responsible for rejecting invalid rules.
 
   nsCSSToken* tk = &mToken;
   // Get first non-whitespace token
   if (!GetToken(true)) {
     REPORT_UNEXPECTED(PEParseRuleWSOnly);
     OUTPUT_ERROR();
@@ -1096,57 +1061,55 @@ CSSParserImpl::ParseRule(const nsAString
 nsresult
 CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
                              const nsAString& aPropValue,
                              nsIURI* aSheetURI,
                              nsIURI* aBaseURI,
                              nsIPrincipal* aSheetPrincipal,
                              css::Declaration* aDeclaration,
                              bool* aChanged,
-                             bool aIsImportant)
+                             bool aIsImportant,
+                             bool aIsSVGMode)
 {
   NS_PRECONDITION(aSheetPrincipal, "Must have principal here!");
   NS_PRECONDITION(aBaseURI, "need base URI");
   NS_PRECONDITION(aDeclaration, "Need declaration to parse into!");
-  AssertInitialState();
+
   mData.AssertInitialState();
   mTempData.AssertInitialState();
   aDeclaration->AssertMutable();
 
-  InitScanner(aPropValue, aSheetURI, 0, aBaseURI, aSheetPrincipal);
+  nsCSSScanner scanner(aPropValue, 0);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aSheetURI);
+  InitScanner(scanner, reporter, aSheetURI, aBaseURI, aSheetPrincipal);
   mSection = eCSSSection_General;
+  scanner.SetSVGMode(aIsSVGMode);
 
   *aChanged = false;
 
   // Check for unknown or preffed off properties
   if (eCSSProperty_UNKNOWN == aPropID || !nsCSSProps::IsEnabled(aPropID)) {
     NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
-    const PRUnichar *params[] = {
-      propName.get()
-    };
-    REPORT_UNEXPECTED_P(PEUnknownProperty, params);
+    REPORT_UNEXPECTED_P(PEUnknownProperty, propName);
     REPORT_UNEXPECTED(PEDeclDropped);
     OUTPUT_ERROR();
     ReleaseScanner();
     return NS_OK;
   }
 
   bool parsedOK = ParseProperty(aPropID);
   // We should now be at EOF
   if (parsedOK && GetToken(true)) {
     REPORT_UNEXPECTED_TOKEN(PEExpectEndValue);
     parsedOK = false;
   }
 
   if (!parsedOK) {
     NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
-    const PRUnichar *params[] = {
-      propName.get()
-    };
-    REPORT_UNEXPECTED_P(PEValueParsingError, params);
+    REPORT_UNEXPECTED_P(PEValueParsingError, propName);
     REPORT_UNEXPECTED(PEDeclDropped);
     OUTPUT_ERROR();
     mTempData.ClearProperty(aPropID);
   } else {
 
     // We know we don't need to force a ValueAppended call for the new
     // value.  So if we are not processing a shorthand, and there's
     // already a value for this property in the declaration at the
@@ -1180,19 +1143,20 @@ CSSParserImpl::ParseMediaList(const nsSu
                               nsMediaList* aMediaList,
                               bool aHTMLMode)
 {
   // XXX Are there cases where the caller wants to keep what it already
   // has in case of parser error?
   aMediaList->Clear();
 
   // fake base URI since media lists don't have URIs in them
-  InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr);
-
-  AssertInitialState();
+  nsCSSScanner scanner(aBuffer, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr);
+
   mHTMLMediaMode = aHTMLMode;
 
     // XXXldb We need to make the scanner not skip CSS comments!  (Or
     // should we?)
 
   // For aHTMLMode, we used to follow the parsing rules in
   // http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-media-descriptors
   // which wouldn't work for media queries since they remove all but the
@@ -1212,35 +1176,36 @@ CSSParserImpl::ParseMediaList(const nsSu
 }
 
 bool
 CSSParserImpl::ParseColorString(const nsSubstring& aBuffer,
                                 nsIURI* aURI, // for error reporting
                                 uint32_t aLineNumber, // for error reporting
                                 nsCSSValue& aValue)
 {
-  AssertInitialState();
-  InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr);
+  nsCSSScanner scanner(aBuffer, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr);
 
   // Parse a color, and check that there's nothing else after it.
   bool colorParsed = ParseColor(aValue) && !GetToken(true);
   OUTPUT_ERROR();
   ReleaseScanner();
   return colorParsed;
 }
 
 nsresult
 CSSParserImpl::ParseSelectorString(const nsSubstring& aSelectorString,
                                    nsIURI* aURI, // for error reporting
                                    uint32_t aLineNumber, // for error reporting
                                    nsCSSSelectorList **aSelectorList)
 {
-  InitScanner(aSelectorString, aURI, aLineNumber, aURI, nullptr);
-
-  AssertInitialState();
+  nsCSSScanner scanner(aSelectorString, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr);
 
   bool success = ParseSelectorList(*aSelectorList, PRUnichar(0));
 
   // We deliberately do not call OUTPUT_ERROR here, because all our
   // callers map a failure return to a JS exception, and if that JS
   // exception is caught, people don't want to see parser diagnostics;
   // see e.g. http://bugs.jquery.com/ticket/7535
   // It would be nice to be able to save the parser diagnostics into
@@ -1261,19 +1226,19 @@ CSSParserImpl::ParseSelectorString(const
 }
 
 
 already_AddRefed<nsCSSKeyframeRule>
 CSSParserImpl::ParseKeyframeRule(const nsSubstring&  aBuffer,
                                  nsIURI*             aURI,
                                  uint32_t            aLineNumber)
 {
-  InitScanner(aBuffer, aURI, aLineNumber, aURI, nullptr);
-
-  AssertInitialState();
+  nsCSSScanner scanner(aBuffer, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr);
 
   nsRefPtr<nsCSSKeyframeRule> result = ParseKeyframeRule();
   if (GetToken(true)) {
     // extra garbage at the end
     result = nullptr;
   }
 
   OUTPUT_ERROR();
@@ -1285,19 +1250,19 @@ CSSParserImpl::ParseKeyframeRule(const n
 bool
 CSSParserImpl::ParseKeyframeSelectorString(const nsSubstring& aSelectorString,
                                            nsIURI* aURI, // for error reporting
                                            uint32_t aLineNumber, // for error reporting
                                            InfallibleTArray<float>& aSelectorList)
 {
   NS_ABORT_IF_FALSE(aSelectorList.IsEmpty(), "given list should start empty");
 
-  InitScanner(aSelectorString, aURI, aLineNumber, aURI, nullptr);
-
-  AssertInitialState();
+  nsCSSScanner scanner(aSelectorString, aLineNumber);
+  css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr);
 
   bool success = ParseKeyframeSelectorList(aSelectorList) &&
                  // must consume entire input string
                  !GetToken(true);
 
   OUTPUT_ERROR();
   ReleaseScanner();
 
@@ -1312,34 +1277,34 @@ CSSParserImpl::ParseKeyframeSelectorStri
 
 //----------------------------------------------------------------------
 
 bool
 CSSParserImpl::GetToken(bool aSkipWS)
 {
   for (;;) {
     if (!mHavePushBack) {
-      if (!mScanner.Next(mToken)) {
+      if (!mScanner->Next(mToken)) {
         break;
       }
     }
     mHavePushBack = false;
     if (aSkipWS && (eCSSToken_WhiteSpace == mToken.mType)) {
       continue;
     }
     return true;
   }
   return false;
 }
 
 bool
 CSSParserImpl::GetURLInParens(nsString& aURL)
 {
   NS_ASSERTION(!mHavePushBack, "mustn't have pushback at this point");
-  if (! mScanner.NextURL(mToken)) {
+  if (! mScanner->NextURL(mToken)) {
     // EOF
     return false;
   }
 
   aURL = mToken.mIdent;
 
   if (eCSSToken_URL != mToken.mType) {
     // In the failure case (which gives a token of type
@@ -1953,20 +1918,17 @@ CSSParserImpl::ProcessImport(const nsStr
   // Diagnose bad URIs even if we don't have a child loader.
   nsCOMPtr<nsIURI> url;
   // Charset will be deduced from mBaseURI, which is more or less correct.
   nsresult rv = NS_NewURI(getter_AddRefs(url), aURLSpec, nullptr, mBaseURI);
 
   if (NS_FAILED(rv)) {
     if (rv == NS_ERROR_MALFORMED_URI) {
       // import url is bad
-      const PRUnichar *params[] = {
-        aURLSpec.get()
-      };
-      REPORT_UNEXPECTED_P(PEImportBadURI, params);
+      REPORT_UNEXPECTED_P(PEImportBadURI, aURLSpec);
       OUTPUT_ERROR();
     }
     return;
   }
 
   if (mChildLoader) {
     mChildLoader->LoadChildSheet(mSheet, url, aMedia, rule);
   }
@@ -2237,29 +2199,23 @@ CSSParserImpl::ParseFontDescriptor(nsCSS
   nsCSSValue value;
 
   if (descID == eCSSFontDesc_UNKNOWN) {
     if (NonMozillaVendorIdentifier(descName)) {
       // silently skip other vendors' extensions
       SkipDeclaration(true);
       return true;
     } else {
-      const PRUnichar *params[] = {
-        descName.get()
-      };
-      REPORT_UNEXPECTED_P(PEUnknownFontDesc, params);
+      REPORT_UNEXPECTED_P(PEUnknownFontDesc, descName);
       return false;
     }
   }
 
   if (!ParseFontDescriptorValue(descID, value)) {
-    const PRUnichar *params[] = {
-      descName.get()
-    };
-    REPORT_UNEXPECTED_P(PEValueParsingError, params);
+    REPORT_UNEXPECTED_P(PEValueParsingError, descName);
     return false;
   }
 
   if (!ExpectEndProperty())
     return false;
 
   aRule->SetDesc(descID, value);
   return true;
@@ -2386,32 +2342,32 @@ CSSParserImpl::ParseKeyframeSelectorList
 //   : "@supports" supports_condition group_rule_body
 //   ;
 bool
 CSSParserImpl::ParseSupportsRule(RuleAppendFunc aAppendFunc, void* aProcessData)
 {
   bool conditionMet = false;
   nsString condition;
 
-  mScanner.StartRecording();
+  mScanner->StartRecording();
   bool parsed = ParseSupportsCondition(conditionMet);
 
   if (!parsed) {
-    mScanner.StopRecording();
+    mScanner->StopRecording();
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PESupportsGroupRuleStart);
-    mScanner.StopRecording();
+    mScanner->StopRecording();
     return false;
   }
 
   UngetToken();
-  mScanner.StopRecording(condition);
+  mScanner->StopRecording(condition);
 
   // Remove the "{" that would follow the condition.
   if (condition.Length() != 0) {
     condition.Truncate(condition.Length() - 1);
   }
 
   // Remove spaces from the start and end of the recorded supports condition.
   condition.Trim(" ", true, true, false);
@@ -2515,20 +2471,17 @@ CSSParserImpl::ParseSupportsConditionInP
     if (!mToken.mIdent.LowerCaseEqualsLiteral("not")) {
       nsAutoString propertyName = mToken.mIdent;
       if (!ExpectSymbol(':', true)) {
         REPORT_UNEXPECTED_TOKEN(PEParseDeclarationNoColon);
         return false;
       }
 
       if (ExpectSymbol(')', true)) {
-        const PRUnichar *params[] = {
-          propertyName.get()
-        };
-        REPORT_UNEXPECTED_P(PEValueParsingError, params);
+        REPORT_UNEXPECTED_P(PEValueParsingError, propertyName);
         UngetToken();
         return false;
       }
 
       nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName,
                                                         nsCSSProps::eEnabled);
       if (propID == eCSSProperty_UNKNOWN) {
         aConditionMet = false;
@@ -2772,17 +2725,17 @@ CSSParserImpl::AppendRule(css::Rule* aRu
 }
 
 bool
 CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
                             bool aInsideBraces)
 {
   // First get the list of selectors for the rule
   nsCSSSelectorList* slist = nullptr;
-  uint32_t linenum = mScanner.GetLineNumber();
+  uint32_t linenum = mScanner->GetLineNumber();
   if (! ParseSelectorList(slist, PRUnichar('{'))) {
     REPORT_UNEXPECTED(PEBadSelectorRSIgnored);
     OUTPUT_ERROR();
     SkipRuleSet(aInsideBraces);
     return false;
   }
   NS_ASSERTION(nullptr != slist, "null selector list");
   CLEAR_ERROR();
@@ -3677,17 +3630,17 @@ CSSParserImpl::ParsePseudoClassWithNthPa
     uint32_t truncAt = 0;
     if (StringBeginsWith(mToken.mIdent, NS_LITERAL_STRING("n-"))) {
       truncAt = 1;
     } else if (StringBeginsWith(mToken.mIdent, NS_LITERAL_STRING("-n-"))) {
       truncAt = 2;
     }
     if (truncAt != 0) {
       for (uint32_t i = mToken.mIdent.Length() - 1; i >= truncAt; --i) {
-        mScanner.Pushback(mToken.mIdent[i]);
+        mScanner->Pushback(mToken.mIdent[i]);
       }
       mToken.mIdent.Truncate(truncAt);
     }
   }
 
   if (eCSSToken_Ident == mToken.mType) {
     if (mToken.mIdent.LowerCaseEqualsLiteral("odd")) {
       numbers[0] = 2;
@@ -4158,22 +4111,17 @@ CSSParserImpl::ParseColorComponent(uint8
     return false;
   }
   if (ExpectSymbol(aStop, true)) {
     if (value < 0.0f) value = 0.0f;
     if (value > 255.0f) value = 255.0f;
     aComponent = NSToIntRound(value);
     return true;
   }
-  const PRUnichar stopString[] = { PRUnichar(aStop), PRUnichar(0) };
-  const PRUnichar *params[] = {
-    nullptr,
-    stopString
-  };
-  REPORT_UNEXPECTED_TOKEN_P(PEColorComponentBadTerm, params);
+  REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, aStop);
   return false;
 }
 
 
 bool
 CSSParserImpl::ParseHSLColor(nscolor& aColor,
                              char aStop)
 {
@@ -4232,22 +4180,17 @@ CSSParserImpl::ParseHSLColor(nscolor& aC
   if (l < 0.0f) l = 0.0f;
   if (l > 1.0f) l = 1.0f;
 
   if (ExpectSymbol(aStop, true)) {
     aColor = NS_HSL2RGB(h, s, l);
     return true;
   }
 
-  const PRUnichar stopString[] = { PRUnichar(aStop), PRUnichar(0) };
-  const PRUnichar *params[] = {
-    nullptr,
-    stopString
-  };
-  REPORT_UNEXPECTED_TOKEN_P(PEColorComponentBadTerm, params);
+  REPORT_UNEXPECTED_TOKEN_CHAR(PEColorComponentBadTerm, aStop);
   return false;
 }
 
 
 bool
 CSSParserImpl::ParseColorOpacity(uint8_t& aOpacity)
 {
   if (!GetToken(true)) {
@@ -4365,32 +4308,26 @@ CSSParserImpl::ParseDeclaration(css::Dec
 
   // Map property name to its ID and then parse the property
   nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName,
                                                     nsCSSProps::eEnabled);
   if (eCSSProperty_UNKNOWN == propID ||
      (aContext == nsCSSContextType::eCSSContext_Page &&
       !nsCSSProps::PropHasFlags(propID, CSS_PROPERTY_APPLIES_TO_PAGE_RULE))) { // unknown property
     if (!NonMozillaVendorIdentifier(propertyName)) {
-      const PRUnichar *params[] = {
-        propertyName.get()
-      };
-      REPORT_UNEXPECTED_P(PEUnknownProperty, params);
+      REPORT_UNEXPECTED_P(PEUnknownProperty, propertyName);
       REPORT_UNEXPECTED(PEDeclDropped);
       OUTPUT_ERROR();
     }
 
     return false;
   }
   if (! ParseProperty(propID)) {
     // XXX Much better to put stuff in the value parsers instead...
-    const PRUnichar *params[] = {
-      propertyName.get()
-    };
-    REPORT_UNEXPECTED_P(PEValueParsingError, params);
+    REPORT_UNEXPECTED_P(PEValueParsingError, propertyName);
     REPORT_UNEXPECTED(PEDeclDropped);
     OUTPUT_ERROR();
     mTempData.ClearProperty(propID);
     mTempData.AssertInitialState();
     return false;
   }
   CLEAR_ERROR();
 
@@ -9885,20 +9822,17 @@ CSSParserImpl::GetNamespaceIdForPrefix(c
     if (!prefix) {
       NS_RUNTIMEABORT("do_GetAtom failed - out of memory?");
     }
     nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix);
   }
   // else no declared namespaces
 
   if (nameSpaceID == kNameSpaceID_Unknown) {   // unknown prefix, dump it
-    const PRUnichar *params[] = {
-      aPrefix.get()
-    };
-    REPORT_UNEXPECTED_P(PEUnknownNamespacePrefix, params);
+    REPORT_UNEXPECTED_P(PEUnknownNamespacePrefix, aPrefix);
   }
 
   return nameSpaceID;
 }
 
 void
 CSSParserImpl::SetDefaultNamespaceOnSelector(nsCSSSelector& aSelector)
 {
@@ -10044,23 +9978,16 @@ nsCSSParser::SetStyleSheet(nsCSSStyleShe
 nsresult
 nsCSSParser::SetQuirkMode(bool aQuirkMode)
 {
   return static_cast<CSSParserImpl*>(mImpl)->
     SetQuirkMode(aQuirkMode);
 }
 
 nsresult
-nsCSSParser::SetSVGMode(bool aSVGMode)
-{
-  return static_cast<CSSParserImpl*>(mImpl)->
-    SetSVGMode(aSVGMode);
-}
-
-nsresult
 nsCSSParser::SetChildLoader(mozilla::css::Loader* aChildLoader)
 {
   return static_cast<CSSParserImpl*>(mImpl)->
     SetChildLoader(aChildLoader);
 }
 
 nsresult
 nsCSSParser::ParseSheet(const nsAString& aInput,
@@ -10113,22 +10040,24 @@ nsCSSParser::ParseRule(const nsAString& 
 
 nsresult
 nsCSSParser::ParseProperty(const nsCSSProperty aPropID,
                            const nsAString&    aPropValue,
                            nsIURI*             aSheetURI,
                            nsIURI*             aBaseURI,
                            nsIPrincipal*       aSheetPrincipal,
                            css::Declaration*   aDeclaration,
-                           bool*             aChanged,
-                           bool                aIsImportant)
+                           bool*               aChanged,
+                           bool                aIsImportant,
+                           bool                aIsSVGMode)
 {
   return static_cast<CSSParserImpl*>(mImpl)->
     ParseProperty(aPropID, aPropValue, aSheetURI, aBaseURI,
-                  aSheetPrincipal, aDeclaration, aChanged, aIsImportant);
+                  aSheetPrincipal, aDeclaration, aChanged,
+                  aIsImportant, aIsSVGMode);
 }
 
 nsresult
 nsCSSParser::ParseMediaList(const nsSubstring& aBuffer,
                             nsIURI*            aURI,
                             uint32_t           aLineNumber,
                             nsMediaList*       aMediaList,
                             bool               aHTMLMode)
--- a/layout/style/nsCSSParser.h
+++ b/layout/style/nsCSSParser.h
@@ -52,19 +52,16 @@ public:
   // Set a style sheet for the parser to fill in. The style sheet must
   // implement the nsCSSStyleSheet interface.  Null can be passed in to clear
   // out an existing stylesheet reference.
   nsresult SetStyleSheet(nsCSSStyleSheet* aSheet);
 
   // Set whether or not to emulate Nav quirks
   nsresult SetQuirkMode(bool aQuirkMode);
 
-  // Set whether or not we are in an SVG element
-  nsresult SetSVGMode(bool aSVGMode);
-
   // Set loader to use for child sheets
   nsresult SetChildLoader(mozilla::css::Loader* aChildLoader);
 
   /**
    * Parse aInput into the stylesheet that was previously set by calling
    * SetStyleSheet.  Calling this method without calling SetStyleSheet first is
    * an error.
    *
@@ -108,24 +105,33 @@ public:
                              bool*           aChanged);
 
   nsresult ParseRule(const nsAString&        aRule,
                      nsIURI*                 aSheetURL,
                      nsIURI*                 aBaseURL,
                      nsIPrincipal*           aSheetPrincipal,
                      nsCOMArray<mozilla::css::Rule>& aResult);
 
+  // Parse the value of a single CSS property, and add or replace that
+  // property in aDeclaration.
+  //
+  // SVG "mapped attributes" (which correspond directly to CSS
+  // properties) are parsed slightly differently from regular CSS; in
+  // particular, units may be omitted from <length>.  The 'aIsSVGMode'
+  // argument controls this quirk.  Note that this *only* applies to
+  // mapped attributes, not inline styles or full style sheets in SVG.
   nsresult ParseProperty(const nsCSSProperty aPropID,
                          const nsAString&    aPropValue,
                          nsIURI*             aSheetURL,
                          nsIURI*             aBaseURL,
                          nsIPrincipal*       aSheetPrincipal,
                          mozilla::css::Declaration* aDeclaration,
-                         bool*             aChanged,
-                         bool                aIsImportant);
+                         bool*               aChanged,
+                         bool                aIsImportant,
+                         bool                aIsSVGMode = false);
 
   /**
    * Parse aBuffer into a media list |aMediaList|, which must be
    * non-null, replacing its current contents.  If aHTMLMode is true,
    * parse according to HTML rules, with commas as the most important
    * delimiter.  Otherwise, parse according to CSS rules, with
    * parentheses and strings more important than commas.  |aURL| and
    * |aLineNumber| are used for error reporting.
--- a/layout/style/nsCSSScanner.cpp
+++ b/layout/style/nsCSSScanner.cpp
@@ -4,44 +4,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 /* tokenization of CSS style sheets */
 
 #include <math.h> // must be first due to symbol conflicts
 
 #include "nsCSSScanner.h"
-#include "nsString.h"
-#include "nsCRT.h"
+#include "mozilla/css/ErrorReporter.h"
+#include "mozilla/Likely.h"
 #include "mozilla/Util.h"
 
-// for #ifdef CSS_REPORT_PARSE_ERRORS
-#include "nsCOMPtr.h"
-#include "nsIServiceManager.h"
-#include "nsIComponentManager.h"
-#include "nsReadableUtils.h"
-#include "nsIURI.h"
-#include "nsIConsoleService.h"
-#include "nsIScriptError.h"
-#include "nsIStringBundle.h"
-#include "nsIDocument.h"
-#include "mozilla/Services.h"
-#include "mozilla/css/Loader.h"
-#include "nsCSSStyleSheet.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Likely.h"
-
-using namespace mozilla;
-
-#ifdef CSS_REPORT_PARSE_ERRORS
-static bool gReportErrors = true;
-static nsIConsoleService *gConsoleService;
-static nsIFactory *gScriptErrorFactory;
-static nsIStringBundle *gStringBundle;
-#endif
+using mozilla::ArrayLength;
 
 static const uint8_t IS_HEX_DIGIT  = 0x01;
 static const uint8_t START_IDENT   = 0x02;
 static const uint8_t IS_IDENT      = 0x04;
 static const uint8_t IS_WHITESPACE = 0x08;
 static const uint8_t IS_URL_CHAR   = 0x10;
 
 #define W    IS_WHITESPACE
@@ -159,17 +136,17 @@ HexDigitValue(int32_t ch)
 }
 
 nsCSSToken::nsCSSToken()
 {
   mType = eCSSToken_Symbol;
 }
 
 void
-nsCSSToken::AppendToString(nsString& aBuffer)
+nsCSSToken::AppendToString(nsString& aBuffer) const
 {
   switch (mType) {
     case eCSSToken_AtKeyword:
       aBuffer.Append(PRUnichar('@')); // fall through intentional
     case eCSSToken_Ident:
     case eCSSToken_WhiteSpace:
     case eCSSToken_Function:
     case eCSSToken_HTMLComment:
@@ -245,400 +222,41 @@ nsCSSToken::AppendToString(nsString& aBu
       aBuffer.Append(mIdent);
       break;
     default:
       NS_ERROR("invalid token type");
       break;
   }
 }
 
-class DeferredCleanupRunnable : public nsRunnable
-{
-public:
-  DeferredCleanupRunnable(nsCSSScanner* aToClean)
-    : mToClean(aToClean)
-  {}
-
-  NS_IMETHOD Run() {
-    if (mToClean) {
-      mToClean->PerformDeferredCleanup();
-    }
-
-    return NS_OK;
-  }
-
-  void Revoke() {
-    mToClean = nullptr;
-  }
-
-private:
-  nsCSSScanner* mToClean;
-};
-
-nsCSSScanner::nsCSSScanner()
-  : mReadPointer(nullptr)
+nsCSSScanner::nsCSSScanner(const nsAString& aBuffer, uint32_t aLineNumber)
+  : mReadPointer(aBuffer.BeginReading())
+  , mOffset(0)
+  , mCount(aBuffer.Length())
+  , mPushback(mLocalPushback)
+  , mPushbackCount(0)
+  , mPushbackSize(ArrayLength(mLocalPushback))
+  , mLineNumber(aLineNumber)
+  , mLineOffset(0)
+  , mRecordStartOffset(0)
+  , mReporter(nullptr)
   , mSVGMode(false)
-#ifdef CSS_REPORT_PARSE_ERRORS
-  , mError(mErrorBuf, ArrayLength(mErrorBuf), 0)
-  , mInnerWindowID(0)
-  , mWindowIDCached(false)
-  , mSheet(nullptr)
-  , mLoader(nullptr)
-#endif
+  , mRecording(false)
 {
   MOZ_COUNT_CTOR(nsCSSScanner);
-  mPushback = mLocalPushback;
-  mPushbackSize = ArrayLength(mLocalPushback);
-  // No need to init the other members, since they represent state
-  // which can get cleared.  We'll init them every time Init() is
-  // called.
 }
 
 nsCSSScanner::~nsCSSScanner()
 {
   MOZ_COUNT_DTOR(nsCSSScanner);
-  Reset();
   if (mLocalPushback != mPushback) {
     delete [] mPushback;
   }
 }
 
-#ifdef CSS_REPORT_PARSE_ERRORS
-void
-nsCSSScanner::PerformDeferredCleanup()
-{
-  // Clean up all short term caches.
-  mCachedURI = nullptr;
-  mCachedFileName.Truncate();
-
-  // Release our DeferredCleanupRunnable.
-  mDeferredCleaner.Forget();
-}
-
-#define CSS_ERRORS_PREF "layout.css.report_errors"
-
-static int
-CSSErrorsPrefChanged(const char *aPref, void *aClosure)
-{
-  gReportErrors = Preferences::GetBool(CSS_ERRORS_PREF, true);
-  return 0;
-}
-#endif
-
-/* static */ bool
-nsCSSScanner::InitGlobals()
-{
-#ifdef CSS_REPORT_PARSE_ERRORS
-  if (gConsoleService && gScriptErrorFactory)
-    return true;
-  
-  nsresult rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &gConsoleService);
-  NS_ENSURE_SUCCESS(rv, false);
-
-  rv = CallGetClassObject(NS_SCRIPTERROR_CONTRACTID, &gScriptErrorFactory);
-  NS_ENSURE_SUCCESS(rv, false);
-  NS_ASSERTION(gConsoleService && gScriptErrorFactory,
-               "unexpected null pointer without failure");
-
-  Preferences::RegisterCallback(CSSErrorsPrefChanged, CSS_ERRORS_PREF);
-  CSSErrorsPrefChanged(CSS_ERRORS_PREF, nullptr);
-#endif
-  return true;
-}
-
-/* static */ void
-nsCSSScanner::ReleaseGlobals()
-{
-#ifdef CSS_REPORT_PARSE_ERRORS
-  Preferences::UnregisterCallback(CSSErrorsPrefChanged, CSS_ERRORS_PREF);
-  NS_IF_RELEASE(gConsoleService);
-  NS_IF_RELEASE(gScriptErrorFactory);
-  NS_IF_RELEASE(gStringBundle);
-#endif
-}
-
-void
-nsCSSScanner::Init(const nsAString& aBuffer,
-                   nsIURI* aURI, uint32_t aLineNumber,
-                   nsCSSStyleSheet* aSheet, mozilla::css::Loader* aLoader)
-{
-  NS_PRECONDITION(!mReadPointer, "Should not have an existing input buffer!");
-
-  mReadPointer = aBuffer.BeginReading();
-  mCount = aBuffer.Length();
-
-#ifdef CSS_REPORT_PARSE_ERRORS
-  // If aURI is different from mCachedURI, invalidate the filename cache.
-  if (aURI != mCachedURI) {
-    mCachedURI = aURI;
-    mCachedFileName.Truncate();
-  }
-#endif // CSS_REPORT_PARSE_ERRORS
-
-  mLineNumber = aLineNumber;
-
-  // Reset variables that we use to keep track of our progress through the input
-  mOffset = 0;
-  mPushbackCount = 0;
-  mRecording = false;
-
-#ifdef CSS_REPORT_PARSE_ERRORS
-  mColNumber = 0;
-  mSheet = aSheet;
-  mLoader = aLoader;
-#endif
-}
-
-#ifdef CSS_REPORT_PARSE_ERRORS
-
-// @see REPORT_UNEXPECTED_EOF in nsCSSParser.cpp
-#define REPORT_UNEXPECTED_EOF(lf_) \
-  ReportUnexpectedEOF(#lf_)
-
-void
-nsCSSScanner::AddToError(const nsSubstring& aErrorText)
-{
-  if (mError.IsEmpty()) {
-    mErrorLineNumber = mLineNumber;
-    mErrorColNumber = mColNumber;
-    mError = aErrorText;
-  } else {
-    mError.Append(NS_LITERAL_STRING("  ") + aErrorText);
-  }
-}
-
-void
-nsCSSScanner::ClearError()
-{
-  mError.Truncate();
-}
-
-void
-nsCSSScanner::OutputError()
-{
-  if (mError.IsEmpty()) return;
- 
-  // Log it to the Error console
-
-  if (InitGlobals() && gReportErrors) {
-    if (!mWindowIDCached) {
-      if (mSheet) {
-        mInnerWindowID = mSheet->FindOwningWindowInnerID();
-      }
-      if (mInnerWindowID == 0 && mLoader) {
-        nsIDocument* doc = mLoader->GetDocument();
-        if (doc) {
-          mInnerWindowID = doc->InnerWindowID();
-        }
-      }
-      mWindowIDCached = true;
-    }
-
-    nsresult rv;
-    nsCOMPtr<nsIScriptError> errorObject =
-      do_CreateInstance(gScriptErrorFactory, &rv);
-
-    if (NS_SUCCEEDED(rv)) {
-      // Update the cached filename if needed.
-      if (mCachedFileName.IsEmpty()) {
-        if (mCachedURI) {
-          nsAutoCString cFileName;
-          mCachedURI->GetSpec(cFileName);
-          CopyUTF8toUTF16(cFileName, mCachedFileName);
-        } else {
-          mCachedFileName.AssignLiteral("from DOM");
-        }
-      }
-
-      rv = errorObject->InitWithWindowID(mError,
-                                         mCachedFileName,
-                                         EmptyString(),
-                                         mErrorLineNumber,
-                                         mErrorColNumber,
-                                         nsIScriptError::warningFlag,
-                                         "CSS Parser",
-                                         mInnerWindowID);
-      if (NS_SUCCEEDED(rv)) {
-        gConsoleService->LogMessage(errorObject);
-      }
-    }
-  }
-  ClearError();
-}
-
-static bool
-InitStringBundle()
-{
-  if (gStringBundle)
-    return true;
-
-  nsCOMPtr<nsIStringBundleService> sbs =
-    mozilla::services::GetStringBundleService();
-  if (!sbs)
-    return false;
-
-  nsresult rv = 
-    sbs->CreateBundle("chrome://global/locale/css.properties", &gStringBundle);
-  if (NS_FAILED(rv)) {
-    gStringBundle = nullptr;
-    return false;
-  }
-
-  return true;
-}
-
-#define ENSURE_STRINGBUNDLE \
-  PR_BEGIN_MACRO if (!InitStringBundle()) return; PR_END_MACRO
-
-// aMessage must take no parameters
-void nsCSSScanner::ReportUnexpected(const char* aMessage)
-{
-  ENSURE_STRINGBUNDLE;
-
-  nsXPIDLString str;
-  gStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
-                                   getter_Copies(str));
-  AddToError(str);
-}
-  
-void
-nsCSSScanner::ReportUnexpectedParams(const char* aMessage,
-                                     const PRUnichar **aParams,
-                                     uint32_t aParamsLength)
-{
-  NS_PRECONDITION(aParamsLength > 0, "use the non-params version");
-  ENSURE_STRINGBUNDLE;
-
-  nsXPIDLString str;
-  gStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
-                                      aParams, aParamsLength,
-                                      getter_Copies(str));
-  AddToError(str);
-}
-
-// aLookingFor is a plain string, not a format string
-void
-nsCSSScanner::ReportUnexpectedEOF(const char* aLookingFor)
-{
-  ENSURE_STRINGBUNDLE;
-
-  nsXPIDLString innerStr;
-  gStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aLookingFor).get(),
-                                   getter_Copies(innerStr));
-
-  const PRUnichar *params[] = {
-    innerStr.get()
-  };
-  nsXPIDLString str;
-  gStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(),
-                                      params, ArrayLength(params),
-                                      getter_Copies(str));
-  AddToError(str);
-}
-
-// aLookingFor is a single character
-void
-nsCSSScanner::ReportUnexpectedEOF(PRUnichar aLookingFor)
-{
-  ENSURE_STRINGBUNDLE;
-
-  const PRUnichar lookingForStr[] = {
-    PRUnichar('\''), aLookingFor, PRUnichar('\''), PRUnichar(0)
-  };
-  const PRUnichar *params[] = { lookingForStr };
-  nsXPIDLString str;
-  gStringBundle->FormatStringFromName(NS_LITERAL_STRING("PEUnexpEOF2").get(),
-                                      params, ArrayLength(params),
-                                      getter_Copies(str));
-  AddToError(str);
-}
-
-// aMessage must take 1 parameter (for the string representation of the
-// unexpected token)
-void
-nsCSSScanner::ReportUnexpectedToken(nsCSSToken& tok,
-                                    const char *aMessage)
-{
-  ENSURE_STRINGBUNDLE;
-  
-  nsAutoString tokenString;
-  tok.AppendToString(tokenString);
-
-  const PRUnichar *params[] = {
-    tokenString.get()
-  };
-
-  ReportUnexpectedParams(aMessage, params);
-}
-
-// aParams's first entry must be null, and we'll fill in the token
-void
-nsCSSScanner::ReportUnexpectedTokenParams(nsCSSToken& tok,
-                                          const char* aMessage,
-                                          const PRUnichar **aParams,
-                                          uint32_t aParamsLength)
-{
-  NS_PRECONDITION(aParamsLength > 1, "use the non-params version");
-  NS_PRECONDITION(aParams[0] == nullptr, "first param should be empty");
-
-  ENSURE_STRINGBUNDLE;
-  
-  nsAutoString tokenString;
-  tok.AppendToString(tokenString);
-  aParams[0] = tokenString.get();
-
-  ReportUnexpectedParams(aMessage, aParams, aParamsLength);
-}
-
-#else
-
-#define REPORT_UNEXPECTED_EOF(lf_)
-
-#endif // CSS_REPORT_PARSE_ERRORS
-
-void
-nsCSSScanner::Close()
-{
-  Reset();
-
-  // Schedule deferred cleanup for cached data. We want to strike a balance
-  // between performance and memory usage, so we only allow short-term caching.
-#ifdef CSS_REPORT_PARSE_ERRORS
-  if (!mDeferredCleaner.IsPending()) {
-    mDeferredCleaner = new DeferredCleanupRunnable(this);
-    if (NS_FAILED(NS_DispatchToCurrentThread(mDeferredCleaner.get()))) {
-      // Peform the "deferred" cleanup immediately if the dispatch fails.
-      // This will also have the effect of clearing mDeferredCleaner.
-      nsCSSScanner::PerformDeferredCleanup();
-    }
-  }
-#endif
-}
-
-void
-nsCSSScanner::Reset()
-{
-  mReadPointer = nullptr;
-
-  // Clean things up so we don't hold on to memory if our parser gets recycled.
-#ifdef CSS_REPORT_PARSE_ERRORS
-  mError.Truncate();
-  mInnerWindowID = 0;
-  mWindowIDCached = false;
-  mSheet = nullptr;
-  mLoader = nullptr;
-#endif
-
-  if (mPushback != mLocalPushback) {
-    delete [] mPushback;
-    mPushback = mLocalPushback;
-    mPushbackSize = ArrayLength(mLocalPushback);
-  }
-}
-
 // Returns -1 on error or eof
 int32_t
 nsCSSScanner::Read()
 {
   int32_t rv;
   if (0 < mPushbackCount) {
     rv = int32_t(mPushback[--mPushbackCount]);
   } else {
@@ -655,21 +273,17 @@ nsCSSScanner::Read()
       rv = '\n';
     } else if (rv == '\f') {
       rv = '\n';
     }
     if (rv == '\n') {
       // 0 is a magical line number meaning that we don't know (i.e., script)
       if (mLineNumber != 0)
         ++mLineNumber;
-#ifdef CSS_REPORT_PARSE_ERRORS
-      mColNumber = 0;
-    } else {
-      mColNumber++;
-#endif
+      mLineOffset = 0;
     }
   }
   return rv;
 }
 
 int32_t
 nsCSSScanner::Peek()
 {
@@ -1038,18 +652,18 @@ nsCSSScanner::ParseAndAppendEscape(nsStr
       AppendUCS4ToUTF16(ENSURE_VALID_CHAR(rv), aOutput);
     } else {
       while (i--)
         aOutput.Append('0');
       if (IsWhitespace(ch))
         Pushback(ch);
     }
     return true;
-  } 
-  // "Any character except a hexidecimal digit can be escaped to
+  }
+  // "Any character except a hexadecimal digit can be escaped to
   // remove its special meaning by putting a backslash in front"
   // -- CSS1 spec section 7.1
   if (ch == '\n') {
     if (!aInString) {
       // Outside of strings (which includes url() that contains a
       // string), escaped newlines aren't special, and just tokenize as
       // eCSSToken_Symbol (DELIM).
       Pushback(ch);
@@ -1092,19 +706,16 @@ nsCSSScanner::GatherIdent(int32_t aChar,
       // See how much we can consume and append in one go
       uint32_t n = mOffset;
       // Count number of Ident characters that can be processed
       while (n < mCount && IsIdent(mReadPointer[n])) {
         ++n;
       }
       // Add to the token what we have so far
       if (n > mOffset) {
-#ifdef CSS_REPORT_PARSE_ERRORS
-        mColNumber += n - mOffset;
-#endif
         aIdent.Append(&mReadPointer[mOffset], n - mOffset);
         mOffset = n;
       }
     }
 
     aChar = Read();
     if (aChar < 0) break;
     if (aChar == '\\') {
@@ -1339,17 +950,17 @@ nsCSSScanner::SkipCComment()
     if (ch < 0) break;
     if (ch == '*') {
       if (LookAhead('/')) {
         return true;
       }
     }
   }
 
-  REPORT_UNEXPECTED_EOF(PECommentEOF);
+  mReporter->ReportUnexpectedEOF("PECommentEOF");
   return false;
 }
 
 bool
 nsCSSScanner::ParseString(int32_t aStop, nsCSSToken& aToken)
 {
   aToken.mIdent.SetLength(0);
   aToken.mType = eCSSToken_String;
@@ -1361,51 +972,44 @@ nsCSSScanner::ParseString(int32_t aStop,
       uint32_t n = mOffset;
       // Count number of characters that can be processed
       for (;n < mCount; ++n) {
         PRUnichar nextChar = mReadPointer[n];
         if ((nextChar == aStop) || (nextChar == '\\') ||
             (nextChar == '\n') || (nextChar == '\r') || (nextChar == '\f')) {
           break;
         }
-#ifdef CSS_REPORT_PARSE_ERRORS
-        ++mColNumber;
-#endif
       }
       // Add to the token what we have so far
       if (n > mOffset) {
         aToken.mIdent.Append(&mReadPointer[mOffset], n - mOffset);
         mOffset = n;
       }
     }
     int32_t ch = Read();
     if (ch < 0 || ch == aStop) {
       break;
     }
     if (ch == '\n') {
       aToken.mType = eCSSToken_Bad_String;
-#ifdef CSS_REPORT_PARSE_ERRORS
-      ReportUnexpectedToken(aToken, "SEUnterminatedString");
-#endif
+      mReporter->ReportUnexpected("SEUnterminatedString", aToken);
       break;
     }
     if (ch == '\\') {
       if (!ParseAndAppendEscape(aToken.mIdent, true)) {
         aToken.mType = eCSSToken_Bad_String;
         Pushback(ch);
-#ifdef CSS_REPORT_PARSE_ERRORS
         // For strings, the only case where ParseAndAppendEscape will
         // return false is when there's a backslash to start an escape
         // immediately followed by end-of-stream.  In that case, the
         // correct tokenization is badstring *followed* by a DELIM for
         // the backslash, but as far as the author is concerned, it
         // works pretty much the same as an unterminated string, so we
         // use the same error message.
-        ReportUnexpectedToken(aToken, "SEUnterminatedString");
-#endif
+        mReporter->ReportUnexpected("SEUnterminatedString", aToken);
         break;
       }
     } else {
       aToken.mIdent.Append(ch);
     }
   }
   return true;
 }
--- a/layout/style/nsCSSScanner.h
+++ b/layout/style/nsCSSScanner.h
@@ -4,27 +4,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* tokenization of CSS style sheets */
 
 #ifndef nsCSSScanner_h___
 #define nsCSSScanner_h___
 
 #include "nsString.h"
-#include "nsCOMPtr.h"
-#include "mozilla/css/Loader.h"
-#include "nsCSSStyleSheet.h"
 
-// XXX turn this off for minimo builds
-#define CSS_REPORT_PARSE_ERRORS
-
-// for #ifdef CSS_REPORT_PARSE_ERRORS
-#include "nsXPIDLString.h"
-#include "nsThreadUtils.h"
-class nsIURI;
+namespace mozilla {
+namespace css {
+class ErrorReporter;
+}
+}
 
 // Token types
 enum nsCSSTokenType {
   // A css identifier (e.g. foo)
   eCSSToken_Ident,          // mIdent
 
   // A css at keyword (e.g. @foo)
   eCSSToken_AtKeyword,      // mIdent
@@ -84,89 +79,43 @@ struct nsCSSToken {
   bool            mHasSign; // for number, percentage, and dimension
 
   nsCSSToken();
 
   bool IsSymbol(PRUnichar aSymbol) {
     return bool((eCSSToken_Symbol == mType) && (mSymbol == aSymbol));
   }
 
-  void AppendToString(nsString& aBuffer);
+  void AppendToString(nsString& aBuffer) const;
 };
 
-class DeferredCleanupRunnable; 
-
 // CSS Scanner API. Used to tokenize an input stream using the CSS
 // forward compatible tokenization rules. This implementation is
 // private to this package and is only used internally by the css
 // parser.
 class nsCSSScanner {
   public:
-  nsCSSScanner();
-  ~nsCSSScanner();
-
-  // Init the scanner.
   // |aLineNumber == 1| is the beginning of a file, use |aLineNumber == 0|
   // when the line number is unknown.
-  void Init(const nsAString& aBuffer,
-            nsIURI* aURI, uint32_t aLineNumber,
-            nsCSSStyleSheet* aSheet, mozilla::css::Loader* aLoader);
-  void Close();
+  nsCSSScanner(const nsAString& aBuffer, uint32_t aLineNumber);
+  ~nsCSSScanner();
 
-  static bool InitGlobals();
-  static void ReleaseGlobals();
-
+  void SetErrorReporter(mozilla::css::ErrorReporter* aReporter) {
+    mReporter = aReporter;
+  }
   // Set whether or not we are processing SVG
   void SetSVGMode(bool aSVGMode) {
     mSVGMode = aSVGMode;
   }
   bool IsSVGMode() const {
     return mSVGMode;
   }
 
-#ifdef CSS_REPORT_PARSE_ERRORS
-  // Clean up any reclaimable cached resources.
-  void PerformDeferredCleanup();
-
-  void AddToError(const nsSubstring& aErrorText);
-  void OutputError();
-  void ClearError();
-
-  // aMessage must take no parameters
-  void ReportUnexpected(const char* aMessage);
-  
-private:
-  void Reset();
-
-  void ReportUnexpectedParams(const char* aMessage,
-                              const PRUnichar** aParams,
-                              uint32_t aParamsLength);
-
-public:
-  template<uint32_t N>                           
-  void ReportUnexpectedParams(const char* aMessage,
-                              const PRUnichar* (&aParams)[N])
-    {
-      return ReportUnexpectedParams(aMessage, aParams, N);
-    }
-  // aLookingFor is a plain string, not a format string
-  void ReportUnexpectedEOF(const char* aLookingFor);
-  // aLookingFor is a single character
-  void ReportUnexpectedEOF(PRUnichar aLookingFor);
-  // aMessage must take 1 parameter (for the string representation of the
-  // unexpected token)
-  void ReportUnexpectedToken(nsCSSToken& tok, const char *aMessage);
-  // aParams's first entry must be null, and we'll fill in the token
-  void ReportUnexpectedTokenParams(nsCSSToken& tok,
-                                   const char* aMessage,
-                                   const PRUnichar **aParams,
-                                   uint32_t aParamsLength);
-#endif
-
-  uint32_t GetLineNumber() { return mLineNumber; }
+  uint32_t GetLineNumber() const { return mLineNumber; }
+  uint32_t GetColumnNumber() const { return mOffset - mLineOffset + 1; }
 
   // Get the next token. Return false on EOF. aTokenResult
   // is filled in with the data for the token.
   bool Next(nsCSSToken& aTokenResult);
 
   // Get the next token that may be a string or unquoted URL
   bool NextURL(nsCSSToken& aTokenResult);
 
@@ -202,34 +151,25 @@ protected:
   bool ParseURange(int32_t aChar, nsCSSToken& aResult);
   bool SkipCComment();
 
   bool GatherIdent(int32_t aChar, nsString& aIdent);
 
   const PRUnichar *mReadPointer;
   uint32_t mOffset;
   uint32_t mCount;
+
   PRUnichar* mPushback;
   int32_t mPushbackCount;
   int32_t mPushbackSize;
   PRUnichar mLocalPushback[4];
 
   uint32_t mLineNumber;
+  uint32_t mLineOffset;
+  uint32_t mRecordStartOffset;
+
+  mozilla::css::ErrorReporter *mReporter;
   // True if we are in SVG mode; false in "normal" CSS
   bool mSVGMode;
   bool mRecording;
-  uint32_t mRecordStartOffset;
-
-#ifdef CSS_REPORT_PARSE_ERRORS
-  nsRevocableEventPtr<DeferredCleanupRunnable> mDeferredCleaner;
-  nsCOMPtr<nsIURI> mCachedURI;  // Used to invalidate the cached filename.
-  nsString mCachedFileName;
-  uint32_t mErrorLineNumber, mColNumber, mErrorColNumber;
-  nsFixedString mError;
-  PRUnichar mErrorBuf[200];
-  uint64_t mInnerWindowID;
-  bool mWindowIDCached;
-  nsCSSStyleSheet* mSheet;
-  mozilla::css::Loader* mLoader;
-#endif
 };
 
 #endif /* nsCSSScanner_h___ */
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -2212,29 +2212,26 @@ BuildStyleRule(nsCSSProperty aProperty,
   nsAutoPtr<css::Declaration> declaration(new css::Declaration());
   declaration->InitializeEmpty();
 
   bool changed; // ignored, but needed as outparam for ParseProperty
   nsIDocument* doc = aTargetElement->OwnerDoc();
   nsCOMPtr<nsIURI> baseURI = aTargetElement->GetBaseURI();
   nsCSSParser parser(doc->CSSLoader());
 
-  if (aUseSVGMode) {
-    parser.SetSVGMode(true);
-  }
-
   nsCSSProperty propertyToCheck = nsCSSProps::IsShorthand(aProperty) ?
     nsCSSProps::SubpropertyEntryFor(aProperty)[0] : aProperty;
 
   // Get a parser, parse the property, and check for CSS parsing errors.
   // If any of these steps fails, we bail out and delete the declaration.
   if (NS_FAILED(parser.ParseProperty(aProperty, aSpecifiedValue,
                                      doc->GetDocumentURI(), baseURI,
                                      aTargetElement->NodePrincipal(),
-                                     declaration, &changed, false)) ||
+                                     declaration, &changed, false,
+                                     aUseSVGMode)) ||
       // check whether property parsed without CSS parsing errors
       !declaration->HasNonImportantValueFor(propertyToCheck)) {
     NS_WARNING("failure in BuildStyleRule");
     return nullptr;
   }
 
   nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration.forget());
   return rule.forget();
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/768087-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html>
+<body onload="setTimeout(function() { document.body.innerHTML = '<span>x<svg viewbox=\'0 0 30 40\' ></svg></span>'; }, 0);"></body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/778492-1.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<svg width="1cm" viewBox="0 0 1 1" xmlns="http://www.w3.org/2000/svg">
+<line x2="100" y2="100"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/780764-1.svg
@@ -0,0 +1,18 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait">
+
+<marker id="marker"><path d="M100,0 l100,100 200,200" filter="url(#filter)"/></marker>
+
+<filter id="filter"/>
+
+<path d="M100,0 l100,100 200,200" marker-mid="url(#marker)"/>
+
+<script>
+window.addEventListener("load", function() {
+    setTimeout(function() {
+        document.getElementById("filter").style.fontWeight = "bold";
+        document.documentElement.removeAttribute("class");
+    }, 200);
+}, false);
+</script>
+
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -131,13 +131,16 @@ load 732836-1.svg
 load 740627-1.svg
 load 740627-2.svg
 load 757704-1.svg
 load 757718-1.svg
 load 767056-1.svg
 load 768351.svg
 load 780963-1.html
 load 757751-1.svg
+load 768087-1.html
+load 778492-1.svg
 load 779971-1.svg
+load 780764-1.svg
 load 782141-1.svg
 load 784061-1.svg
 load 790072.svg
 load 791826-1.svg
--- a/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/fsmdef.c
@@ -163,522 +163,522 @@ static void fsmdef_update_calltype (fsm_
 /*
  * TODO <emannion> Update events for correct JSEP transitions
  *                 Instead of providing events for all states
  */
 static sm_function_t fsmdef_function_table[FSMDEF_S_MAX][CC_MSG_MAX] =
 {
 /* FSMDEF_S_IDLE ------------------------------------------------------------ */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_idle_setup,       // New incoming
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_release_complete,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_idle_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_idle_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_default,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_idle_offhook,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_idle_dialstring,  // new outgoing
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_idle_setup,       // New incoming
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_idle_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_idle_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_default,
+    /* CC_MSG_LINE             */ fsmdef_ev_idle_offhook,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_idle_dialstring,  // new outgoing
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_COLLECT_INFO ---------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_collectinginfo_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_collectinginfo_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_digit_begin,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_dialstring,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_collectinginfo_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_collectinginfo_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_digit_begin,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_dialstring,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_CALL_SENT ------------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_proceeding,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_out_alerting,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_connected,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_callsent_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_callsent_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_proceeding,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_out_alerting,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_connected,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_callsent_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_callsent_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_OUTGOING_PROCEEDING --------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_out_alerting,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_connected,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_callsent_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_callsent_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_out_alerting,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_connected,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_callsent_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_callsent_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_KPML_COLLECT_INFO ----------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_out_alerting,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_connected,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_callsent_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_collectinginfo_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_digit_begin,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_out_alerting,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_connected,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_callsent_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_collectinginfo_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_digit_begin,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_OUTGOING_ALERTING ----------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_out_alerting,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_connected,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_callsent_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_callsent_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_out_alerting,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_connected,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_callsent_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_callsent_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_INCOMING_ALERTING ----------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_inalerting_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_inalerting_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_inalerting_offhook,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_inalerting_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_inalerting_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_inalerting_offhook,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_CONNECTING ------------------------------------------------------ */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_connected_ack,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_connecting_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_connected_line,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_connected_ack,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_connecting_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_connected_line,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_JOINING --------------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_joining_connected_ack,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_connecting_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_joining_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_connected_line,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_joining_connected_ack,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_connecting_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_joining_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_connected_line,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_CONNECTED ------------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_connected_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_connected_line,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_connected_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_connected_line,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_CONNECTED_MEDIA_PEND  ------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_connected_media_pend_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_connected_media_pend_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_connected_line,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_connected_media_pend_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_connected_media_pend_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_connected_line,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_RELEASING ------------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_releasing_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_release_complete,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_releasing_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_releasing_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_connected_line,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_releasing_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_release_complete,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_releasing_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_releasing_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_connected_line,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_HOLD_PENDING ---------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_holding_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_hold_pending_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_hold_pending_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_holding_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_hold_pending_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_hold_pending_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_HOLDING --------------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_holding_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_holding_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_holding_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_holding_offhook,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_holding_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_holding_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_holding_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_holding_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_holding_offhook,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_holding_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_RESUME_PENDING -------------------------------------------------- */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_resume_pending_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_resume_pending_feature_ack,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_resume_pending_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_resume_pending_feature_ack,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     },
 
 /* FSMDEF_S_PRESERVED  ------------------------------------------------------ */
     {
-    /* FSMDEF_E_SETUP            */ fsmdef_ev_default,
-    /* FSMDEF_E_SETUP_ACK        */ fsmdef_ev_default,
-    /* FSMDEF_E_PROCEEDING       */ fsmdef_ev_default,
-    /* FSMDEF_E_ALERTING         */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED        */ fsmdef_ev_default,
-    /* FSMDEF_E_CONNECTED_ACK    */ fsmdef_ev_default,
-    /* FSMDEF_E_RELEASE          */ fsmdef_ev_release,
-    /* FSMDEF_E_RELEASE_COMPLETE */ fsmdef_ev_default,
-    /* FSMDEF_E_FEATURE          */ fsmdef_ev_preserved_feature,
-    /* FSMDEF_E_FEATURE_ACK      */ fsmdef_ev_default,
-    /* FSMDEF_E_OFFHOOK          */ fsmdef_ev_default,
-    /* FSMDEF_E_ONHOOK           */ fsmdef_ev_onhook,
-    /* FSMDEF_E_LINE             */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_BEGIN      */ fsmdef_ev_default,
-    /* FSMDEF_E_DIGIT_END        */ fsmdef_ev_default,
-    /* FSMDEF_E_DIALSTRING       */ fsmdef_ev_default,
-    /* FSMDEF_E_MWI              */ fsmdef_ev_default,
-    /* FSMDEF_E_SESSION_AUDIT    */ fsmdef_ev_session_audit,
-    /* FSMDEF_E_CREATEOFFER      */ fsmdef_ev_createoffer,
-    /* FSMDEF_E_CREATEANSWER     */ fsmdef_ev_createanswer,
-    /* FSMDEF_E_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
-    /* FSMDEF_E_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
-    /* FSMDEF_E_LOCALDESC        */ fsmdef_ev_localdesc,
-    /* FSMDEF_E_REMOTEDESC       */ fsmdef_ev_remotedesc,
-    /* FSMDEF_E_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
-    /* FSMDEF_E_ADDSTREAM        */ fsmdef_ev_addstream,
-    /* FSMDEF_E_REMOVESTREAM     */ fsmdef_ev_removestream,
-    /* FAMDEF_E_ADDCANDIDATE     */ fsmdef_ev_addcandidate
+    /* CC_MSG_SETUP            */ fsmdef_ev_default,
+    /* CC_MSG_SETUP_ACK        */ fsmdef_ev_default,
+    /* CC_MSG_PROCEEDING       */ fsmdef_ev_default,
+    /* CC_MSG_ALERTING         */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED        */ fsmdef_ev_default,
+    /* CC_MSG_CONNECTED_ACK    */ fsmdef_ev_default,
+    /* CC_MSG_RELEASE          */ fsmdef_ev_release,
+    /* CC_MSG_RELEASE_COMPLETE */ fsmdef_ev_default,
+    /* CC_MSG_FEATURE          */ fsmdef_ev_preserved_feature,
+    /* CC_MSG_FEATURE_ACK      */ fsmdef_ev_default,
+    /* CC_MSG_OFFHOOK          */ fsmdef_ev_default,
+    /* CC_MSG_ONHOOK           */ fsmdef_ev_onhook,
+    /* CC_MSG_LINE             */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_BEGIN      */ fsmdef_ev_default,
+    /* CC_MSG_DIGIT_END        */ fsmdef_ev_default,
+    /* CC_MSG_DIALSTRING       */ fsmdef_ev_default,
+    /* CC_MSG_MWI              */ fsmdef_ev_default,
+    /* CC_MSG_SESSION_AUDIT    */ fsmdef_ev_session_audit,
+    /* CC_MSG_CREATEOFFER      */ fsmdef_ev_createoffer,
+    /* CC_MSG_CREATEANSWER     */ fsmdef_ev_createanswer,
+    /* CC_MSG_SETLOCALDESC     */ fsmdef_ev_setlocaldesc,
+    /* CC_MSG_SETREMOTEDESC    */ fsmdef_ev_setremotedesc,
+    /* CC_MSG_LOCALDESC        */ fsmdef_ev_localdesc,
+    /* CC_MSG_REMOTEDESC       */ fsmdef_ev_remotedesc,
+    /* CC_MSG_SETPEERCONNECTION */fsmdef_ev_setpeerconnection,
+    /* CC_MSG_ADDSTREAM        */ fsmdef_ev_addstream,
+    /* CC_MSG_REMOVESTREAM     */ fsmdef_ev_removestream,
+    /* CC_MSG_ADDCANDIDATE     */ fsmdef_ev_addcandidate
     }
 };
 
 static sm_table_t fsmdef_sm_table;
 sm_table_t *pfsmdef_sm_table = &fsmdef_sm_table;
 
 /*--------------------------------------------------------------------------
  * Global data
@@ -2764,17 +2764,17 @@ fsmdef_dialstring (fsm_fcb_t *fcb, const
     default:
         if (dialstring) {
             dcb->caller_id.called_number =
                 strlib_update(dcb->caller_id.called_number, dialstring);
         }
         break;
     }
 
-    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE);
+    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE);
     if (cause != CC_CAUSE_OK) {
         FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
         /* Force clean up call without sending release */
         return (fsmdef_release(fcb, cause, FALSE));
     }
 
     /* Build SDP for sending out */
     cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body);
@@ -2927,17 +2927,17 @@ fsmdef_ev_createoffer (sm_event_t *event
                     dcb->digest_alg, FSMDEF_MAX_DIGEST_ALG_LEN,
                     dcb->digest, FSMDEF_MAX_DIGEST_LEN);
 
     if (vcm_res) {
     	FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
         return SM_RC_END;
     }
 
-    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE);
+    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE);
     if (cause != CC_CAUSE_OK) {
         ui_create_offer(evCreateOfferError, line, call_id, dcb->caller_id.call_instance_id, NULL);
         FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
         return (fsmdef_release(fcb, cause, FALSE));
     }
 
     cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body);
     if (cause != CC_CAUSE_OK) {
@@ -2974,16 +2974,19 @@ fsmdef_ev_createanswer (sm_event_t *even
     const char          *called_number = "1234";
     cc_causes_t         lsm_rc;
     cc_msgbody_t        *part;
     uint32_t            body_length;
     char                *ufrag = NULL;
     char                *ice_pwd = NULL;
     short               vcm_res;
     session_data_t      *sess_data_p;
+    boolean             has_audio;
+    boolean             has_video;
+    boolean             has_data;
 
     FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
 
     config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
     if (!sdpmode) {
         return (fsmdef_release(fcb, cause, FALSE));
     }
 
@@ -3031,31 +3034,37 @@ fsmdef_ev_createanswer (sm_event_t *even
                     dcb->digest, FSMDEF_MAX_DIGEST_LEN);
 
     if (vcm_res) {
         FSM_DEBUG_SM(DEB_F_PREFIX"vcmGetDtlsIdentity returned an error\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
         return SM_RC_END;
     }
 
     /*
+     * Determine what media types are offered, used to create matching local SDP
+     * for negotiation.
+     */
+    gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data);
+
+    /*
      * The sdp member of the dcb has local and remote sdp
      * this next function fills in the local part
      */
-    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE);
+    cause = gsmsdp_create_local_sdp(dcb, FALSE, has_audio, has_video, has_data, FALSE);
     if (cause != CC_CAUSE_OK) {
         ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL);
         FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
         // Force clean up call without sending release
         return (fsmdef_release(fcb, cause, FALSE));
     }
 
     /* TODO(ekr@rtfm.com): The second true is because we are acting as if we are
        processing an offer. The first, however, is for an initial offer and we may
        want to set that conditionally. */
-    cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, FALSE);
+    cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, FALSE, TRUE);
 
     if (cause != CC_CAUSE_OK) {
         ui_create_answer(evCreateAnswerError, line, call_id, dcb->caller_id.call_instance_id, NULL);
         return (fsmdef_release(fcb, cause, FALSE));
     }
 
     cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body);
     if (cause != CC_CAUSE_OK) {
@@ -3242,26 +3251,26 @@ fsmdef_ev_setremotedesc(sm_event_t *even
          * for negotiation.
          */
         gsmsdp_get_offered_media_types(fcb, dcb->sdp, &has_audio, &has_video, &has_data);
 
         /*
          * The sdp member of the dcb has local and remote sdp
          * this next function fills in the local part
          */
-        cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data);
+        cause = gsmsdp_create_local_sdp(dcb, TRUE, has_audio, has_video, has_data, FALSE);
         if (cause != CC_CAUSE_OK) {
             ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id,
                 NULL, PC_SETREMOTEDESCERROR);
             FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
             // Force clean up call without sending release
             return (fsmdef_release(fcb, cause, FALSE));
         }
 
-        cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, TRUE);
+        cause = gsmsdp_negotiate_media_lines(fcb, dcb->sdp, TRUE, TRUE, TRUE, FALSE);
         if (cause != CC_CAUSE_OK) {
             ui_set_remote_description(evSetRemoteDescError, line, call_id, dcb->caller_id.call_instance_id,
                 NULL, PC_SETREMOTEDESCERROR);
             return (fsmdef_release(fcb, cause, FALSE));
         }
 
         gsmsdp_clean_media_list(dcb);
 
@@ -3436,17 +3445,16 @@ fsmdef_ev_addstream(sm_event_t *event) {
      * default streams. When multiple streams > 2 are supported this
      * will be re-implemented.
      */
     if (msg->data.track.media_type == VIDEO) {
         dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
         dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV;
         dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_stream = msg->data.track.stream_id;
         dcb->media_cap_tbl->cap[CC_VIDEO_1].pc_track = msg->data.track.track_id;
-        dcb->video_pref = SDP_DIRECTION_SENDRECV;
     } else if (msg->data.track.media_type == AUDIO) {
         dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
         dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV;
         dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_stream = msg->data.track.stream_id;
         dcb->media_cap_tbl->cap[CC_AUDIO_1].pc_track = msg->data.track.track_id;
     } else {
         return (SM_RC_END);
     }
@@ -3479,23 +3487,23 @@ fsmdef_ev_removestream(sm_event_t *event
         return SM_RC_CLEANUP;
     }
 
     /*
      * This is temporary code to allow configuration of the two
      * default streams. When multiple streams > 2 are supported this
      * will be re-implemented.
      */
-    if (msg->data.track.media_type == VIDEO) {
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE;
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_INACTIVE;
+    if (msg->data.track.media_type == AUDIO) {
+        dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
+        dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY;
         dcb->video_pref = SDP_DIRECTION_SENDRECV;
-    } else if (msg->data.track.media_type == AUDIO) {
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
+    } else if (msg->data.track.media_type == VIDEO) {
+        dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
+        dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY;
     } else {
         return (SM_RC_END);
     }
 
 	return (SM_RC_END);
 }
 
 static sm_rcs_t
@@ -7746,17 +7754,17 @@ fsmdef_cfwd_clear_ccm (fsm_fcb_t *fcb)
     FSM_DEBUG_SM(DEB_F_PREFIX"Entered.\n", DEB_F_PREFIX_ARGS(FSM, __FUNCTION__));
 
     // to clear CFA in CCM mode... only put service uri... no dialstring.
     fsmdef_append_dialstring_to_feature_uri(dcb, NULL);
 
     // From here on all we need to do is send INVITE out.
     // Since, its not a real call there is no need to update UI etc.
     // Response to this call will be 5xx so it will be released by the SIP stack.
-    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE);
+    cause = gsmsdp_create_local_sdp(dcb, FALSE, TRUE, TRUE, TRUE, TRUE);
     if (cause != CC_CAUSE_OK) {
         FSM_DEBUG_SM(get_debug_string(FSM_DBG_SDP_BUILD_ERR));
         return (fsmdef_release(fcb, cause, dcb->send_release));
     }
 
     /* Build SDP for sending out */
     cause = gsmsdp_encode_sdp_and_update_version(dcb, &msg_body);
     if (cause != CC_CAUSE_OK) {
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp.c
@@ -77,17 +77,17 @@ static cc_causes_t
 gsmsdp_init_local_sdp (const char *peerconnection, cc_sdp_t **sdp_pp);
 
 static void
 gsmsdp_set_media_capability(fsmdef_media_t *media,
                             const cc_media_cap_t *media_cap);
 static fsmdef_media_t *
 gsmsdp_add_media_line(fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
                       uint8_t cap_index, uint16_t level,
-                      cpr_ip_type addr_type);
+                      cpr_ip_type addr_type, boolean offer);
 
 
 extern cc_media_cap_table_t g_media_table;
 extern vcm_media_payload_type_t vcmRtpToMediaPayload (int32_t ptype,
                                             int32_t dynamic_ptype_value,
                                             uint16_t mode);
 extern boolean g_disable_mass_reg_debug_print;
 /**
@@ -119,91 +119,98 @@ static const cc_media_cap_table_t *gsmsd
              GSM_ERR_MSG(GSM_L_C_F_PREFIX"media table malloc failed.\n",
                     dcb_p->line, dcb_p->call_id, fname);
              return NULL;
          }
     }
 
     *(dcb_p->media_cap_tbl) = g_media_table;
 
-    if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) {
-     // do not enable video
-       dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
-    }
-
-    if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) {
-       if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
-           dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
-       }
-
-       if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) {
-           dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
-            DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n",
-                dcb_p->line, dcb_p->call_id, fname);
-       }
-    } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) {
-       if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
-           dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
-       }
-
-       if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) {
-           dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
-            DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n",
-                dcb_p->line, dcb_p->call_id, fname);
-       }
-    } // else if requested is SENDRECV just go by capability
-
     /*
      * Turn off two default streams, this is temporary
      * until we can handle multiple streams properly
      */
     if (sdpmode) {
-    	dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
-    	dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE;
-    	dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE;
+        dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
+        dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
+        dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY;
+        dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY;
+        dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE;
     } else {
         dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE;
+
+        if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) {
+            // do not enable video
+            dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
+        }
+
+        if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) {
+            if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
+                dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
+            }
+
+            if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) {
+                dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
+                DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n",
+                dcb_p->line, dcb_p->call_id, fname);
+            }
+        } else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) {
+            if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
+                dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
+            }
+
+            if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) {
+               dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
+                DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n",
+                    dcb_p->line, dcb_p->call_id, fname);
+            }
+        } // else if requested is SENDRECV just go by capability
     }
 
     return (dcb_p->media_cap_tbl);
 }
 
 /*
- * Process constraints only related to media capabilities. i.e OfferToReceiveAudio, OfferToReceiveVideo
+ * Process a single constraint for one media capablity
  */
-void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints) {
+void gsmsdp_process_cap_constraint(cc_media_cap_t *cap,
+                                   const char *constraint) {
+  /* Check constraint string for values "TRUE" or "FALSE"
+     (currently set in PeerConnectionImpl.cpp, with only
+     two possible hardcoded values).
+     TODO -- The values that constraints can take are
+     fairly narrow and enumerated; they should probably
+     use an enumeration rather than a string. See bug 811360.
+  */
+  if (constraint[0] == 'F') {
+    cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV;
+  } else if (constraint[0] == 'T') {
+    cap->support_direction |= SDP_DIRECTION_FLAG_RECV;
+  }
+}
+
+/*
+ * Process constraints only related to media capabilities., i.e
+ * OfferToReceiveAudio, OfferToReceiveVideo
+ */
+void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb,
+                                    const cc_media_constraints_t* constraints) {
   int i = 0;
 
   for (i=0; i<constraints->constraint_count; i++) {
-
-    if (strcmp(constraints_table[OfferToReceiveAudio].name, constraints->constraints[i]->name) == 0) {
-      if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) {
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDONLY;
-      } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 &&
-                                 TRUE == dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled) {
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV;
-      } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) {
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
-        dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY;
-      }
-    }
-
-    if (strcmp("OfferToReceiveVideo", constraints->constraints[i]->name) == 0) {
-      if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) {
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDONLY;
-      } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 &&
-                                 TRUE == dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled) {
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV;
-      } else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) {
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
-        dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY;
-      }
+    if (strcmp(constraints_table[OfferToReceiveAudio].name,
+               constraints->constraints[i]->name) == 0) {
+      gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1],
+                                    constraints->constraints[i]->value);
+    } else if (strcmp(constraints_table[OfferToReceiveVideo].name,
+               constraints->constraints[i]->name) == 0) {
+      gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1],
+                                    constraints->constraints[i]->value);
     }
   }
-
 }
 
 /**
  * Sets up the media track table
  *
  * @param[in]dcb     - pointer to the fsmdef_dcb_t
  *
  * @return           - pointer to the the media track table for session
@@ -1961,35 +1968,39 @@ gsmsdp_add_default_audio_formats_to_loca
 
         if (sdp_add_media_payload_type(local_sdp_p, level,
                                        (uint16_t)local_media_types[type_cnt],
                                        SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) {
             GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding media payload type failed\n",
                         DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
         }
 
-        gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p,
+        if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+            gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p,
                                     level, (uint16_t)local_media_types[type_cnt]);
+        }
     }
 
     /*
      * add the avt media type
      */
     if (local_avt_payload_type > RTP_NONE) {
         if (sdp_add_media_payload_type(local_sdp_p, level,
                                        local_avt_payload_type,
                                        SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) {
             GSM_ERR_MSG(GSM_L_C_F_PREFIX"Adding AVT payload type failed\n",
                         dcb_p->line, dcb_p->call_id, fname);
         }
 
-        gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level,
-                                    local_avt_payload_type);
-        if (media) {
-            media->avt_payload_type = local_avt_payload_type;
+        if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+            gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level,
+                                        local_avt_payload_type);
+            if (media) {
+                media->avt_payload_type = local_avt_payload_type;
+            }
         }
     }
 }
 
 /*
  * gsmsdp_add_default_video_formats_to_local_sdp
  *
  * Description:
@@ -2070,18 +2081,20 @@ gsmsdp_add_default_video_formats_to_loca
 
         if (sdp_add_media_payload_type(local_sdp_p, level,
                                        (uint16_t)video_media_types[type_cnt],
                                        SDP_PAYLOAD_NUMERIC) != SDP_SUCCESS) {
             GSM_ERR_MSG(GSM_L_C_F_PREFIX"SDP ERROR(1)\n",
                         line, call_id, fname);
         }
 
-        gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p,
-                           level, (uint16_t)video_media_types[type_cnt]);
+        if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+            gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p,
+                               level, (uint16_t)video_media_types[type_cnt]);
+        }
     }
 }
 
 /**
  * This function sets the mid attr at the media level
  * and labels the relevant media streams when phone is
  * operating in a dual stack mode
  *
@@ -2263,17 +2276,20 @@ gsmsdp_update_local_sdp_media (fsmdef_dc
 
     result = sdp_insert_media_line(sdp_p, level);
     if (result != SDP_SUCCESS) {
         GSM_ERR_MSG(GSM_L_C_F_PREFIX"Inserting media line to Sdp failed\n",
                     dcb_p->line, dcb_p->call_id, fname);
         return;
     }
 
-    gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr);
+    if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+        gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr);
+    }
+
     (void) sdp_set_media_type(sdp_p, level, media->type);
 
 
     (void) sdp_set_media_portnum(sdp_p, level, port, media->sctp_port);
 
     /* Set media transport and crypto attributes if it is for SRTP */
     gsmsdp_update_local_sdp_media_transport(dcb_p, sdp_p, media, transport,
                                             all_formats);
@@ -2616,17 +2632,17 @@ gsmsdp_get_remote_avt_payload_type (uint
  *
  *  Returns:
  *
  *  payload  >  0: negotiated payload
  *           <= 0: negotiation failed
  */
 static int
 gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
-                        fsmdef_media_t *media, boolean offer, boolean initial_offer)
+                        fsmdef_media_t *media, boolean offer, boolean initial_offer, uint16 media_level)
 {
     static const char fname[] = "gsmsdp_negotiate_codec";
     rtp_ptype       pref_codec = RTP_NONE;
     uint16_t        i;
     uint16_t        j;
     int            *master_list_p = NULL;
     int            *slave_list_p = NULL;
     DtmfOutOfBandTransport_t transport = DTMF_OUTOFBAND_NONE;
@@ -2654,17 +2670,17 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dc
     int             remote_dynamic_payload_type_value = RTP_NONE;
     int32_t         payload_types_count = 0; // count for allocating right amout
                                              // of memory for media->paylaods
 
     if (!dcb_p || !sdp_p || !media) {
         return (RTP_NONE);
     }
 
-    level = media->level;
+    level = media_level;
     attr_label = sdp_attr_get_simple_string(sdp_p->dest_sdp,
                                             SDP_ATTR_LABEL, level, 0, 1);
 
     if (attr_label != NULL) {
         if (strcmp(attr_label, MIX_NEAREND_STRING) == 0) {
             dcb_p->session = WHISPER_COACHING;
         }
     }
@@ -3875,41 +3891,59 @@ gsmsdp_negotiate_remove_media_line (fsmd
 
     /*
      * This media line is to be removed.
      */
     return (TRUE);
 }
 
 /*
+ * Find a media line based on the media type.
+ */
+fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e media_type) {
+
+    fsmdef_media_t *media = NULL;
+
+    /*
+     * search the all entries that has a valid media and matches the media type
+     */
+    GSMSDP_FOR_ALL_MEDIA(media, dcb_p) {
+        if (media->type == media_type) {
+            /* found a match */
+            return (media);
+        }
+    }
+    return (NULL);
+}
+
+/*
  * gsmsdp_negotiate_media_lines
  *
  * Description:
  *
  * Walk down the media lines provided in the remote sdp. Compare each
  * media line to the corresponding media line in the local sdp. If
  * the media line does not exist in the local sdp, add it. If the media
  * line exists in the local sdp but is different from the remote sdp,
  * change the local sdp to match the remote sdp. If the media line
  * is an AUDIO format, negotiate the codec and update the local sdp
- * as needed. We will reject all media lines that are not AUDIO and we
- * will only accept the first AUDIO media line located.
+ * as needed.
  *
  * Parameters:
  *
  * fcb_p - Pointer to the FCB containing thhe DCB whose media lines are being negotiated
  * sdp_p - Pointer to the local and remote SDP
  * initial_offer - Boolean indicating if the remote SDP came in the first OFFER of this session
  * offer - Boolean indicating if the remote SDP came in an OFFER.
  * notify_stream_added - Boolean indicating the UI should be notified of streams added
  *
  */
 cc_causes_t
-gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
-                             boolean initial_offer, boolean offer, boolean notify_stream_added)
+gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer,
+                              boolean offer, boolean notify_stream_added, boolean create_answer)
 {
     static const char fname[] = "gsmsdp_negotiate_media_lines";
     cc_causes_t     cause = CC_CAUSE_OK;
     uint16_t        num_m_lines = 0;
     uint16_t        num_local_m_lines = 0;
     uint16_t        i = 0;
     sdp_media_e     media_type;
     fsmdef_dcb_t   *dcb_p = fcb_p->dcb;
@@ -3952,22 +3986,49 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
                   DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
         return (CC_CAUSE_NO_MEDIA);
     }
 
     /*
      * Process each media line in the remote SDP
      */
     for (i = 1; i <= num_m_lines; i++) {
-
         unsupported_line = FALSE; /* assume line will be supported */
         new_media        = FALSE;
         media            = NULL;
         media_type = sdp_get_media_type(sdp_p->dest_sdp, i);
 
+        /*
+         * Only perform these checks when called from createanswer
+         * because at this point we are concerned as to which m= lines
+         * have been created in the answer.
+         */
+        if (create_answer) {
+
+            /* Since the incoming SDP might not be in the same order as
+               our media, we find them by type rather than location
+               for this check. Note that we're not checking for the
+               value of any _particular_ m= section; we're just checking
+               whether (at least) one of the specified type exists.  */
+            media = gsmsdp_find_media_by_media_type(dcb_p, media_type);
+
+            if (media_type == SDP_MEDIA_AUDIO && !media) {
+                /* continue if answer will not add this m= line */
+                continue;
+            }
+
+            if (media_type == SDP_MEDIA_VIDEO && !media) {
+                continue;
+            }
+
+            if (media_type == SDP_MEDIA_APPLICATION && !media) {
+                continue;
+            }
+        }
+
         port = (uint16_t) sdp_get_media_portnum(sdp_p->dest_sdp, i);
         GSM_DEBUG(DEB_L_C_F_PREFIX"Port is %d at %d %d\n",
                   DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),
                   port, i, initial_offer);
 
         switch (media_type) {
         case SDP_MEDIA_AUDIO:
         case SDP_MEDIA_VIDEO:
@@ -3986,17 +4047,19 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
                 break;
             }
 
             /*
              * Find the corresponding media entry in the dcb to see
              * this has been negiotiated previously (from the
              * last offer/answer session).
              */
-            media = gsmsdp_find_media_by_level(dcb_p, i);
+            if(!create_answer)
+              media = gsmsdp_find_media_by_level(dcb_p, i);
+
             if (media == NULL) {
                 /* No previous media, negotiate adding new media line. */
                 media = gsmsdp_negotiate_add_media_line(dcb_p, media_type, i,
                                                         port, offer);
                 if (media == NULL) {
                     /* new one can not be added */
                     unsupported_line = TRUE;
                     break;
@@ -4024,16 +4087,21 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
             } else {
                 /* The media at the same level but not the expected type */
                 GSM_ERR_MSG(GSM_L_C_F_PREFIX"mismatch media type at %d\n",
                             dcb_p->line, dcb_p->call_id, fname, i);
                 unsupported_line = TRUE;
                 break;
             }
 
+            /* Do not negotiate if media is set to inactive */
+            if (SDP_DIRECTION_INACTIVE == media->direction) {
+                break;
+            }
+
             /* Reset multicast flag and port */
             media->is_multicast = FALSE;
             media->multicast_port = 0;
 
             /* Update remote address */
             media->previous_sdp.dest_addr = media->dest_addr;
             media->dest_addr = remote_addr;
 
@@ -4085,32 +4153,32 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
             }
 
             /*
              * Negotiate RTP/SRTP. The result is the media transport
              * which could be RTP/SRTP or fail.
              */
             transport = gsmsdp_negotiate_media_transport(dcb_p, sdp_p,
                                                          offer, media,
-                                                         &crypto_inst);
+                                                         &crypto_inst, i);
             if (transport == SDP_TRANSPORT_INVALID) {
                 /* unable to negotiate transport */
                 unsupported_line = TRUE;
                 GSM_DEBUG(DEB_L_C_F_PREFIX"transport mismatch at %d\n",
                           DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i);
                 break;
             }
 
             /* Don't need to negotiate a codec for an m= applicaton line */
             if (SDP_MEDIA_APPLICATION != media_type) {
 
                 /*
                  * Negotiate to a single codec
                  */
-                if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer) ==
+                if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer, i) ==
                     RTP_NONE) {
                     /* unable to negotiate codec */
                     unsupported_line = TRUE;
                     /* Failed codec negotiation */
                     cause = CC_CAUSE_PAYLOAD_MISMATCH;
                     GSM_DEBUG(DEB_L_C_F_PREFIX"codec mismatch at %d\n",
                               DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), i);
                     break;
@@ -4120,17 +4188,17 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
             }
 
             /*
              * Both media transport (RTP/SRTP) and codec are
              * now negotiated to common ones, update transport
              * parameters to be used for SRTP, if there is any.
              */
             gsmsdp_update_negotiated_transport(dcb_p, sdp_p, media,
-                                               crypto_inst, transport);
+                                               crypto_inst, transport, i);
             GSM_DEBUG(DEB_F_PREFIX"local transport after updating negotiated: %d\n",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1));
             /*
              * Add to or update media line to the local SDP as needed.
              */
             if (gsmsdp_is_multicast_address(media->dest_addr)) {
                 /*
                  * Multicast, if the address is multicast
                  * then change the local sdp and do the necessary
@@ -4173,17 +4241,17 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t 
                 unsupported_line = TRUE;
                 update_local_ret_value = TRUE;
             }
 
             /*
              * Negotiate rtcp-mux
              */
 
-            sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, media->level,
+            sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, i,
                                               0, SDP_ATTR_RTCP_MUX, 1, &rtcp_mux);
 
             if (SDP_SUCCESS == sdp_res) {
             	media->rtcp_mux = TRUE;
             }
 
             if (!unsupported_line) {
 
@@ -4545,17 +4613,17 @@ gsmsdp_set_media_capability (fsmdef_medi
  *                   add a new line otherwise return NULL.
  *
  * @pre              (dcb_p not_eq NULL)
  * @pre              (media_cap not_eq NULL)
  */
 static fsmdef_media_t *
 gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
                        uint8_t cap_index, uint16_t level,
-                       cpr_ip_type addr_type)
+                       cpr_ip_type addr_type, boolean offer)
 {
     static const char fname[] = "gsmsdp_add_media_line";
     cc_action_data_t  data;
     fsmdef_media_t   *media = NULL;
     int               i=0;
     int               rtcpmux = 0;
     int               sctp_port = 0;
 
@@ -4577,105 +4645,119 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb
         /* associate this media line to the capability entry */
         media->cap_index = cap_index; /* keep the media cap entry index */
 
         /* override the direction for special feature */
         gsmsdp_feature_overide_direction(dcb_p, media);
         if (media->support_direction == SDP_DIRECTION_INACTIVE) {
             GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive"
                       " no media added\n",
-					  DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
-            gsmsdp_remove_media(dcb_p, media);
-            return (NULL);
+                      DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
+
+            /*
+             * For an answer, SDP_DIRECTION_INACTIVE will now add an m=
+             * line but it is disabled.
+             */
+            if (!offer) {
+                media->src_port = 0;
+            } else {
+              gsmsdp_remove_media(dcb_p, media);
+              return (NULL);
+            }
         }
 
-        /*
-         * Get the local RTP port. The src port will be set in the dcb
-         * within the call to cc_call_action(CC_ACTION_OPEN_RCV)
-         */
-        data.open_rcv.is_multicast = FALSE;
-        data.open_rcv.listen_ip = ip_addr_invalid;
-        data.open_rcv.port = 0;
-        data.open_rcv.keep = FALSE;
-        /*
-         * Indicate type of media (audio/video etc) becase some for
-         * supporting video over vieo, the port is obtained from other
-         * entity.
-         */
-        data.open_rcv.media_type = media->type;
-        data.open_rcv.media_refid = media->refid;
-        if (cc_call_action(dcb_p->call_id, dcb_p->line,
-                           CC_ACTION_OPEN_RCV,
-                           &data) != CC_RC_SUCCESS) {
-            GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n",
-                        dcb_p->line, dcb_p->call_id, fname);
-            gsmsdp_remove_media(dcb_p, media);
-            return (NULL);
-        }
-
-        /* allocate port successful, save the port */
-
-        media->src_port = data.open_rcv.port;
-
-        if(media_cap->type == SDP_MEDIA_APPLICATION) {
+        if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+          /*
+           * Get the local RTP port. The src port will be set in the dcb
+           * within the call to cc_call_action(CC_ACTION_OPEN_RCV)
+           */
+          data.open_rcv.is_multicast = FALSE;
+          data.open_rcv.listen_ip = ip_addr_invalid;
+          data.open_rcv.port = 0;
+          data.open_rcv.keep = FALSE;
+          /*
+           * Indicate type of media (audio/video etc) becase some for
+           * supporting video over vieo, the port is obtained from other
+           * entity.
+           */
+          data.open_rcv.media_type = media->type;
+          data.open_rcv.media_refid = media->refid;
+          if (cc_call_action(dcb_p->call_id, dcb_p->line,
+                             CC_ACTION_OPEN_RCV,
+                             &data) != CC_RC_SUCCESS) {
+              GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n",
+                          dcb_p->line, dcb_p->call_id, fname);
+              gsmsdp_remove_media(dcb_p, media);
+              return (NULL);
+          }
+
+          /* allocate port successful, save the port */
+
+          media->src_port = data.open_rcv.port;
+
+          if(media_cap->type == SDP_MEDIA_APPLICATION) {
             config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port));
             media->sctp_port = sctp_port;
-        }
-
-        /*
-         * Setup the local soruce address.
-         */
-        if (addr_type == CPR_IP_ADDR_IPV6) {
-            gsmsdp_get_local_source_v6_address(media);
-        } else if (addr_type == CPR_IP_ADDR_IPV4) {
-            gsmsdp_get_local_source_v4_address(media);
-        } else {
-            GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n",
-                        dcb_p->line, dcb_p->call_id, fname);
-            gsmsdp_remove_media(dcb_p, media);
-            return (NULL);
+          }
+
+          /*
+           * Setup the local soruce address.
+           */
+          if (addr_type == CPR_IP_ADDR_IPV6) {
+              gsmsdp_get_local_source_v6_address(media);
+          } else if (addr_type == CPR_IP_ADDR_IPV4) {
+              gsmsdp_get_local_source_v4_address(media);
+          } else {
+              GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n",
+                          dcb_p->line, dcb_p->call_id, fname);
+              gsmsdp_remove_media(dcb_p, media);
+              return (NULL);
+          }
+
         }
 
         /*
          * Initialize the media transport for RTP or SRTP (or do not thing
          * and leave to the gsmsdp_update_local_sdp_media to set default)
          */
         gsmsdp_init_sdp_media_transport(dcb_p, dcb_p->sdp->src_sdp, media);
 
 
         gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media,
                                           media->transport);
 
-
-        gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction);
-
-        /*
-         * wait until here to set ICE candidates as SDP is now initialized
-         */
-        for (i=0; i<media->candidate_ct; i++) {
-        	gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]);
+        if (media->support_direction != SDP_DIRECTION_INACTIVE) {
+
+          gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction);
+
+          /*
+           * wait until here to set ICE candidates as SDP is now initialized
+           */
+          for (i=0; i<media->candidate_ct; i++) {
+            gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]);
+          }
+
+          config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux));
+          if (rtcpmux) {
+            gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE);
+          }
+
+
+          /*
+           * Since we are initiating an initial offer and opening a
+           * receive port, store initial media settings.
+           */
+          media->previous_sdp.avt_payload_type = media->avt_payload_type;
+          media->previous_sdp.direction = media->direction;
+          media->previous_sdp.packetization_period = media->packetization_period;
+          media->previous_sdp.payload_type = media->payload;
+          media->previous_sdp.local_payload_type = media->payload;
+          break;
         }
 
-        config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux));
-        if (rtcpmux) {
-          gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE);
-        }
-
-
-        /*
-         * Since we are initiating an initial offer and opening a
-         * receive port, store initial media settings.
-         */
-        media->previous_sdp.avt_payload_type = media->avt_payload_type;
-        media->previous_sdp.direction = media->direction;
-        media->previous_sdp.packetization_period = media->packetization_period;
-        media->previous_sdp.payload_type = media->payload;
-        media->previous_sdp.local_payload_type = media->payload;
-        break;
-
     default:
         /* Unsupported media type, not added */
         GSM_DEBUG(DEB_L_C_F_PREFIX"media type %d is not supported\n",
                   DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), media_cap->type);
         break;
     }
     return (media);
 }
@@ -4692,17 +4774,17 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb
  *                         streams are added
  *
  * returns    cc_causes_t
  *            CC_CAUSE_OK - indicates success
  *            CC_CAUSE_ERROR - indicates failure
  */
 cc_causes_t
 gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
-                         boolean audio, boolean video, boolean data)
+                         boolean audio, boolean video, boolean data, boolean offer)
 {
     static const char fname[] = "gsmsdp_create_local_sdp";
     uint16_t        level;
     const cc_media_cap_table_t *media_cap_tbl;
     const cc_media_cap_t       *media_cap;
     cpr_ip_mode_e   ip_mode;
     uint8_t         cap_index;
     fsmdef_media_t  *media;
@@ -4724,17 +4806,17 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *d
         /* should not happen */
         GSM_ERR_MSG(GSM_L_C_F_PREFIX"no media capbility available\n",
                     dcb_p->line, dcb_p->call_id, fname);
         return (CC_CAUSE_ERROR);
     }
 
     media_cap = &media_cap_tbl->cap[0];
     level = 0;
-    for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) {
+    for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP-1; cap_index++) {
 
         /* Build local m lines based on m lines that were in the offered SDP */
         media_enabled = TRUE;
         if (FALSE == audio && SDP_MEDIA_AUDIO == media_cap->type) {
             media_enabled = FALSE;
         } else if (FALSE == video && SDP_MEDIA_VIDEO == media_cap->type) {
             media_enabled = FALSE;
         } else if (FALSE == data && SDP_MEDIA_APPLICATION == media_cap->type) {
@@ -4744,34 +4826,34 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *d
         /*
          * Add each enabled media line to the SDP
          */
         if (media_enabled && ( media_cap->enabled || force_streams_enabled)) {
             level = level + 1;  /* next level */
             ip_mode = platform_get_ip_address_mode();
             if (ip_mode >= CPR_IP_MODE_IPV6) {
                 if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
-                                          level, CPR_IP_ADDR_IPV6)
+                                          level, CPR_IP_ADDR_IPV6, offer)
                     == NULL) {
                     /* fail to add a media line, go back one level */
                     level = level - 1;
                 }
 
                 if (ip_mode == CPR_IP_MODE_DUAL) {
                     level = level + 1;  /* next level */
                     if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
-                                              level, CPR_IP_ADDR_IPV4) ==
+                                              level, CPR_IP_ADDR_IPV4, offer) ==
                         NULL) {
                         /* fail to add a media line, go back one level */
                         level = level - 1;
                     }
                 }
             } else {
                 if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, level,
-                                          CPR_IP_ADDR_IPV4) == NULL) {
+                                          CPR_IP_ADDR_IPV4, offer) == NULL) {
                     /* fail to add a media line, go back one level */
                     level = level - 1;
                 }
             }
         }
         /* next capability */
         media_cap++;
     }
@@ -5039,17 +5121,17 @@ gsmsdp_check_add_local_sdp_media (fsmdef
                 num_m_lines  = sdp_get_num_media_lines(src_sdp);
                 level_to_use = num_m_lines + 1;
             }
             GSM_DEBUG(DEB_L_C_F_PREFIX"add media at level %d\n",
                       DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), level_to_use);
 
             /* add a new media */
             media = gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
-                                          level_to_use, ip_addr_type[i]);
+                                          level_to_use, ip_addr_type[i], FALSE);
             if (media != NULL) {
                 /* successfully add a new media line */
                 if (hold) {
                     /* this new media needs to be sent out with hold */
                     gsmsdp_set_local_hold_sdp(dcb_p, media);
                 }
                 added = TRUE;
             } else {
@@ -5765,17 +5847,17 @@ gsmsdp_negotiate_answer_sdp (fsm_fcb_t *
     }
     if (status != CC_CAUSE_OK) {
         /* Error parsing SDP */
         return status;
     }
 
     gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp);
 
-    status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE);
+    status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE, TRUE);
     GSM_DEBUG(DEB_F_PREFIX"returns with %d\n",DEB_F_PREFIX_ARGS(GSM, fname), status);
     return (status);
 }
 
 
 
 
 /*
@@ -5803,17 +5885,17 @@ gsmsdp_negotiate_offer_sdp (fsm_fcb_t *f
     status = gsmsdp_process_offer_sdp(fcb_p, msg_body, init);
     if (status != CC_CAUSE_OK)
        return status;
 
     /*
      * If a new error code has been added to sdp processing please make sure
      * the sip side is aware of it
      */
-    status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE);
+    status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE, FALSE);
     return (status);
 }
 
 
 /*
  * gsmsdp_process_offer_sdp
  *
  * Description:
@@ -5847,17 +5929,17 @@ gsmsdp_process_offer_sdp (fsm_fcb_t *fcb
         DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname), init);
     if (num_sdp_bodies == 0) {
         /*
          * No remote SDP. So we will offer in our response and receive far end
          * answer in the ack. Only need to create local sdp if this is first offer
          * of a session. Otherwise, we will send what we have.
          */
         if (init) {
-            if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE)) {
+            if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE, TRUE)) {
                 return CC_CAUSE_ERROR;
             }
         } else {
             /*
              * Reset all media entries that we have to offer all capabilities
              */
            (void)gsmsdp_update_local_sdp_media_capability(dcb_p, TRUE, FALSE);
         }
--- a/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/gsm_sdp_crypto.c
@@ -944,43 +944,41 @@ gsmsdp_check_answer_crypto_param (fsmdef
  *     crypto_inst - pointer to crypto attribute instance number of the
  *                   selected crypto line
  *
  *  Returns:
  *      transport - sdp_transport_e for RTP or SRTP or invalid
  */
 static sdp_transport_e
 gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
-                               fsmdef_media_t *media, uint16_t *crypto_inst)
+                               fsmdef_media_t *media, uint16_t *crypto_inst, uint16 dest_level)
 {
     sdp_transport_e remote_transport;
     sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID;
     void           *sdp_p = cc_sdp_p->dest_sdp;
-    uint16_t       level;
     int            sdpmode = 0;
 
     config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
-    level = media->level;
     *crypto_inst     = 0;
-    remote_transport = sdp_get_media_transport(sdp_p, level);
+    remote_transport = sdp_get_media_transport(sdp_p, dest_level);
 
     /* negotiate media transport */
     switch (remote_transport) {
     case SDP_TRANSPORT_RTPAVP:
         /* Remote offers RTP for media transport, negotiated transport to RTP */
         negotiated_transport = SDP_TRANSPORT_RTPAVP;
         break;
 
     case SDP_TRANSPORT_RTPSAVP:
 
         /* Remote offer SRTP for media transport */
         if (((sip_regmgr_get_sec_level(dcb_p->line) == ENCRYPTED) &&
             FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) || sdpmode) {
             /* The signalling with this line is encrypted, try to use SRTP */
-            if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, level, crypto_inst)) {
+            if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, dest_level, crypto_inst)) {
                 /* Found a suitable crypto line from the remote offer */
                 negotiated_transport = SDP_TRANSPORT_RTPSAVP;
             }
         }
 
         if (negotiated_transport == SDP_TRANSPORT_INVALID) {
             /*
              * Unable to find a suitable crypto or the signaling is
@@ -1108,24 +1106,24 @@ gsmsdp_negotiate_answer_crypto (fsmdef_d
  *                   selected crypto line.
  *
  *  Returns:
  *      transport - sdp_transport_e for RTP or SRTP or invalid
  */
 sdp_transport_e
 gsmsdp_negotiate_media_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
                                   boolean offer, fsmdef_media_t *media,
-                                  uint16_t *crypto_inst)
+                                  uint16_t *crypto_inst, uint16 level)
 {
     sdp_transport_e transport;
 
     /* negotiate media transport based on offer or answer from the remote */
     if (offer) {
         transport = gsmsdp_negotiate_offer_crypto(dcb_p, cc_sdp_p, media,
-                                                  crypto_inst);
+                                                  crypto_inst, level);
     } else {
         transport = gsmsdp_negotiate_answer_crypto(dcb_p, cc_sdp_p, media,
                                                    crypto_inst);
     }
     return (transport);
 }
 
 /*
@@ -1688,26 +1686,27 @@ gsmsdp_update_crypto_transmit_key (fsmde
  *  Returns:
  *      none
  */
 void
 gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p,
                                     cc_sdp_t *cc_sdp_p,
                                     fsmdef_media_t *media,
                                     uint16_t crypto_inst,
-                                    sdp_transport_e transport)
+                                    sdp_transport_e transport,
+                                    uint16 dest_level)
 {
     const char *fname = "gsmsdp_update_negotiated_transport";
     sdp_srtp_crypto_suite_t crypto_suite;
     void                   *dest_sdp = cc_sdp_p->dest_sdp;
     vcm_crypto_algorithmID  algorithmID;
     vcm_crypto_key_t        key;
     uint16_t                level;
 
-    level = media->level;
+    level = dest_level;
     /*
      * Also detect changes of the crypto parameters for Tx and Rx.
      * It is done here to avoid adding last crypto parameters for Tx and
      * Rx into the dcb structure since the parameters include key which
      * are rather long. This minimize the dcb's increasing.
      */
     /* reset changes flags */
     media->negotiated_crypto.flags &= ~(FSMDEF_CRYPTO_TX_CHANGE |
--- a/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/h/gsm_sdp.h
@@ -45,35 +45,35 @@ typedef enum constraints_ {
 
 static const gsmsdp_key_table_entry_t constraints_table[] = {
     {"OfferToReceiveAudio",         OfferToReceiveAudio},
     {"OfferToReceiveVideo",         OfferToReceiveVideo},
     {"VoiceActivityDetection",      VoiceActivityDetection}
 };
 
 cc_causes_t gsmsdp_create_local_sdp(fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
-                                    boolean audio, boolean video, boolean data);
+                                    boolean audio, boolean video, boolean data, boolean offer);
 void gsmsdp_create_options_sdp(cc_sdp_t **sdp_pp);
 void gsmsdp_reset_local_sdp_media(fsmdef_dcb_t *dcb, fsmdef_media_t *media,
                                   boolean hold);
 void gsmsdp_set_local_sdp_direction(fsmdef_dcb_t *dcb_p, fsmdef_media_t *media,
                                     sdp_direction_e direction);
 void gsmsdp_set_local_hold_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media);
 void gsmsdp_set_local_resume_sdp(fsmdef_dcb_t *dcb, fsmdef_media_t *media);
 cc_causes_t gsmsdp_negotiate_answer_sdp(fsm_fcb_t *fcb,
                                         cc_msgbody_info_t *msg_body);
 cc_causes_t gsmsdp_negotiate_offer_sdp(fsm_fcb_t *fcb,
                                        cc_msgbody_info_t *msg_body,
                                        boolean init);
 cc_causes_t gsmsdp_process_offer_sdp(fsm_fcb_t *fcb,
                                      cc_msgbody_info_t *msg_body,
                                      boolean init);
 cc_causes_t
-gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
-                              boolean initial_offer, boolean offer, boolean notify_stream_added);
+gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer,
+                              boolean offer, boolean notify_stream_added, boolean create_answer);
 
 boolean gsmsdp_sdp_differs_from_previous_sdp(boolean rcv_only,
                                              fsmdef_media_t *media);
 cc_causes_t gsmsdp_encode_sdp(cc_sdp_t *sdp_p, cc_msgbody_info_t *msg_body);
 cc_causes_t gsmsdp_encode_sdp_and_update_version(fsmdef_dcb_t *dcb_p,
                                                  cc_msgbody_info_t *msg_body);
 void gsmsdp_free(fsmdef_dcb_t *dcb_p);
 fsmdef_media_t *gsmsdp_find_audio_media(fsmdef_dcb_t *dcb_p);
@@ -85,27 +85,29 @@ extern void gsmsdp_init_sdp_media_transp
 extern void gsmsdp_reset_sdp_media_transport(fsmdef_dcb_t *dcb,
                                              void *sdp,
                                              fsmdef_media_t *media,
                                              boolean hold);
 extern sdp_transport_e gsmsdp_negotiate_media_transport(fsmdef_dcb_t *dcb_p,
                                                         cc_sdp_t *cc_sdp_p,
                                                         boolean offer,
                                                         fsmdef_media_t *media,
-                                                        uint16_t *inst_num);
+                                                        uint16_t *inst_num,
+                                                        uint16 level);
 extern void gsmsdp_update_local_sdp_media_transport(fsmdef_dcb_t *dcb_p,
                                                     void *sdp_p,
                                                     fsmdef_media_t *media,
                                                     sdp_transport_e transport,
                                                     boolean all);
 extern void gsmsdp_update_negotiated_transport(fsmdef_dcb_t *dcb_p,
                                                cc_sdp_t *cc_sdp_p,
                                                fsmdef_media_t *media,
                                                uint16_t crypto_inst,
-                                               sdp_transport_e transport);
+                                               sdp_transport_e transport,
+                                               uint16 level);
 extern void gsmsdp_update_crypto_transmit_key(fsmdef_dcb_t *dcb_p,
                                               fsmdef_media_t *media,
                                               boolean offer,
                                               boolean initial_offer,
                                               sdp_direction_e direction);
 extern void gsmsdp_set_media_transport_for_option(void *sdp, uint16 level);
 extern boolean gsmsdp_is_crypto_ready(fsmdef_media_t *media, boolean rx);
 extern boolean gsmsdp_is_media_encrypted(fsmdef_dcb_t *dcb_p);
@@ -127,11 +129,11 @@ boolean is_gsmsdp_media_ip_updated_to_la
 
 void gsmsdp_add_remote_stream(uint16_t idx, int pc_stream_id, fsmdef_dcb_t * dcb, fsmdef_media_t *media);
 cc_causes_t gsmsdp_install_peer_ice_attributes(fsm_fcb_t *fcb_p);
 cc_causes_t gsmsdp_configure_dtls_data_attributes(fsm_fcb_t *fcb_p);
 cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uint16_t *level);
 void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints);
 cc_causes_t
 gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data);
-
+fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e 	media_type);
 #endif
 
--- a/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c
+++ b/media/webrtc/signaling/src/sipcc/core/gsm/media_cap_tbl.c
@@ -13,18 +13,18 @@
  * global media cap table for interaction between what platform
  * can do and the GSM-SDP module
  * AUDIO_1 is used for audio cannot be turned off
  * VIDEO_1 is used for video
  */
 cc_media_cap_table_t g_media_table = {
       1,
       {
-        {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_SENDRECV},
-        {CC_VIDEO_1,SDP_MEDIA_VIDEO,FALSE,TRUE,SDP_DIRECTION_SENDRECV},
+        {CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_RECVONLY},
+        {CC_VIDEO_1,SDP_MEDIA_VIDEO,TRUE,TRUE,SDP_DIRECTION_RECVONLY},
         {CC_DATACHANNEL_1,SDP_MEDIA_APPLICATION,FALSE,TRUE,SDP_DIRECTION_SENDRECV},
       }
 };
 
 static boolean g_nativeVidSupported = FALSE;
 static boolean g_vidCapEnabled = FALSE;
 static boolean g_natve_txCap_enabled = FALSE;
 
--- a/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h
+++ b/media/webrtc/signaling/src/sipcc/core/sdp/sdp.h
@@ -253,23 +253,28 @@ typedef enum {
 /* T.38 udp EC Types */
 typedef enum {
     SDP_T38_UDP_REDUNDANCY,
     SDP_T38_UDP_FEC,
     SDP_T38_UDPEC_UNKNOWN,
     SDP_T38_MAX_UDPEC
 } sdp_t38_udpec_e;
 
+/* Bitmaps for manipulating sdp_direction_e */
+typedef enum {
+    SDP_DIRECTION_FLAG_SEND=0x01,
+    SDP_DIRECTION_FLAG_RECV=0x02
+} sdp_direction_flag_e;
 
 /* Media flow direction */
 typedef enum {
-    SDP_DIRECTION_INACTIVE,
-    SDP_DIRECTION_SENDONLY,
-    SDP_DIRECTION_RECVONLY,
-    SDP_DIRECTION_SENDRECV,
+    SDP_DIRECTION_INACTIVE = 0,
+    SDP_DIRECTION_SENDONLY = SDP_DIRECTION_FLAG_SEND,
+    SDP_DIRECTION_RECVONLY = SDP_DIRECTION_FLAG_RECV,
+    SDP_DIRECTION_SENDRECV = SDP_DIRECTION_FLAG_SEND | SDP_DIRECTION_FLAG_RECV,
     SDP_MAX_QOS_DIRECTIONS
 } sdp_direction_e;
 
 #define SDP_DIRECTION_PRINT(arg) \
     (((sdp_direction_e)(arg)) == SDP_DIRECTION_INACTIVE ? "SDP_DIRECTION_INACTIVE " : \
      ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDONLY ? "SDP_DIRECTION_SENDONLY": \
      ((sdp_direction_e)(arg)) == SDP_DIRECTION_RECVONLY ? "SDP_DIRECTION_RECVONLY ": \
      ((sdp_direction_e)(arg)) == SDP_DIRECTION_SENDRECV ? " SDP_DIRECTION_SENDRECV": "SDP_MAX_QOS_DIRECTIONS")
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -66,16 +66,51 @@ static const std::string strSampleSdpAud
 
 static const std::string strSampleCandidate =
   "a=candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host\r\n";
 
 static const std::string strSampleMid = "";
 
 static const unsigned short nSamplelevel = 2;
 
+enum sdpTestFlags
+{
+  SHOULD_SEND_AUDIO     = (1<<0),
+  SHOULD_RECV_AUDIO     = (1<<1),
+  SHOULD_INACTIVE_AUDIO = (1<<2),
+  SHOULD_REJECT_AUDIO   = (1<<3),
+  SHOULD_SEND_VIDEO     = (1<<4),
+  SHOULD_RECV_VIDEO     = (1<<5),
+  SHOULD_INACTIVE_VIDEO = (1<<6),
+  SHOULD_REJECT_VIDEO   = (1<<7),
+
+  SHOULD_SENDRECV_AUDIO = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO,
+  SHOULD_SENDRECV_VIDEO = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO,
+  SHOULD_SENDRECV_AV = SHOULD_SENDRECV_AUDIO | SHOULD_SENDRECV_VIDEO,
+  AUDIO_FLAGS = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO
+                | SHOULD_INACTIVE_AUDIO | SHOULD_REJECT_AUDIO,
+  VIDEO_FLAGS = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO
+                | SHOULD_INACTIVE_VIDEO | SHOULD_REJECT_VIDEO
+};
+
+enum offerAnswerFlags
+{
+  OFFER_NONE  = 0, // Sugar to make function calls clearer.
+  OFFER_AUDIO = (1<<0),
+  OFFER_VIDEO = (1<<1),
+  // Leaving some room here for other media types
+  ANSWER_NONE  = 0, // Sugar to make function calls clearer.
+  ANSWER_AUDIO = (1<<8),
+  ANSWER_VIDEO = (1<<9),
+
+  OFFER_AV = OFFER_AUDIO | OFFER_VIDEO,
+  ANSWER_AV = ANSWER_AUDIO | ANSWER_VIDEO
+};
+
+
 class TestObserver : public IPeerConnectionObserver
 {
 public:
   enum Action {
     OFFER,
     ANSWER
   };
 
@@ -475,17 +510,18 @@ class SignalingAgent {
     // Shutdown is synchronous evidently.
     // ASSERT_TRUE(pObserver->WaitForObserverCall());
     // ASSERT_EQ(pc->sipcc_state(), sipcc::PeerConnectionInterface::kIdle);
   }
 
   char* offer() const { return offer_; }
   char* answer() const { return answer_; }
 
-  void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
+  void CreateOffer(sipcc::MediaConstraints& constraints,
+                   uint32_t offerFlags, uint32_t sdpCheck) {
 
     // Create a media stream as if it came from GUM
     Fake_AudioStreamSource *audio_stream =
       new Fake_AudioStreamSource();
 
     nsresult ret;
     test_utils->sts_target()->Dispatch(
       WrapRunnableRet(audio_stream, &Fake_MediaStream::Start, &ret),
@@ -494,91 +530,91 @@ class SignalingAgent {
     ASSERT_TRUE(NS_SUCCEEDED(ret));
 
     // store in object to be used by RemoveStream
     nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream(audio_stream);
     domMediaStream_ = domMediaStream;
 
     uint32_t aHintContents = 0;
 
-    if (audio) {
+    if (offerFlags & OFFER_AUDIO) {
       aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
     }
-    if (video) {
+    if (offerFlags & OFFER_VIDEO) {
       aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
     }
 
-    PR_ASSERT(aHintContents);
-
     domMediaStream->SetHintContents(aHintContents);
 
     pc->AddStream(domMediaStream);
     domMediaStream_ = domMediaStream;
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
-    SDPSanityCheck(pObserver->lastString, audio, video, true);
+    SDPSanityCheck(pObserver->lastString, sdpCheck, true);
     offer_ = pObserver->lastString;
   }
 
   void CreateOfferExpectError(sipcc::MediaConstraints& constraints) {
     ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateError, kDefaultTimeout);
   }
 
-  void CreateAnswer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
+void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
+                    uint32_t offerAnswerFlags, uint32_t sdpCheck) {
     // Create a media stream as if it came from GUM
     nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream();
 
     uint32_t aHintContents = 0;
 
-    if (audio) {
+    if (offerAnswerFlags & ANSWER_AUDIO) {
       aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
     }
-    if (video) {
+    if (offerAnswerFlags & ANSWER_VIDEO) {
       aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
     }
 
-    PR_ASSERT(aHintContents);
-
     domMediaStream->SetHintContents(aHintContents);
 
     pc->AddStream(domMediaStream);
 
+    // Decide if streams are disabled for offer or answer
+    // then perform SDP checking based on which stream disabled
+
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateAnswer(constraints), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
-    SDPSanityCheck(pObserver->lastString, audio, video, false);
+    SDPSanityCheck(pObserver->lastString, sdpCheck, false);
+
     answer_ = pObserver->lastString;
   }
 
-  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) {
-
-    uint32_t aHintContents = 0;
+  // At present, we use the hints field in a stream to find and
+  // remove it. This only works if the specified hints flags are
+  // unique among all streams in the PeerConnection. This is not
+  // generally true, and will need significant revision once
+  // multiple streams are supported.
+  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
+                               uint32_t hints, uint32_t sdpCheck) {
 
-    if (!audio) {
-      aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
-    }
-    if (!video) {
-      aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
-    }
+    domMediaStream_->SetHintContents(hints);
 
-    domMediaStream_->SetHintContents(aHintContents);
-
+    // This currently "removes" a stream that has the same audio/video
+    // hints as were passed in.
     // When complete RemoveStream will remove and entire stream and its tracks
     // not just disable a track as this is currently doing
     pc->RemoveStream(domMediaStream_);
 
     // Now call CreateOffer as JS would
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
-    SDPSanityCheck(pObserver->lastString, audio, video, true);
+    SDPSanityCheck(pObserver->lastString, sdpCheck, true);
     offer_ = pObserver->lastString;
   }
 
   void SetRemote(TestObserver::Action action, std::string remote) {
     pObserver->state = TestObserver::stateNoResponse;
     ASSERT_EQ(pc->SetRemoteDescription(action, remote.c_str()), NS_OK);
     ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
   }
@@ -629,319 +665,538 @@ class SignalingAgent {
 
 public:
   mozilla::RefPtr<sipcc::PeerConnectionImpl> pc;
   nsRefPtr<TestObserver> pObserver;
   char* offer_;
   char* answer_;
   nsRefPtr<nsDOMMediaStream> domMediaStream_;
 
-
 private:
-  void SDPSanityCheck(std::string sdp, bool shouldHaveAudio, bool shouldHaveVideo, bool offer)
+  void SDPSanityCheck(std::string sdp, uint32_t flags, bool offer)
   {
     ASSERT_NE(sdp.find("v=0"), std::string::npos);
     ASSERT_NE(sdp.find("c=IN IP4"), std::string::npos);
     ASSERT_NE(sdp.find("a=fingerprint:sha-256"), std::string::npos);
 
-    if (shouldHaveAudio)
-    {
-    	if (offer)
-    		ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
+    cout << "SDPSanityCheck flags = " << std::hex << std::showbase
+         << flags << std::dec
+         << ((flags & SHOULD_SEND_AUDIO)?" SHOULD_SEND_AUDIO":"")
+         << ((flags & SHOULD_RECV_AUDIO)?" SHOULD_RECV_AUDIO":"")
+         << ((flags & SHOULD_INACTIVE_AUDIO)?" SHOULD_INACTIVE_AUDIO":"")
+         << ((flags & SHOULD_REJECT_AUDIO)?" SHOULD_REJECT_AUDIO":"")
+         << ((flags & SHOULD_SEND_VIDEO)?" SHOULD_SEND_VIDEO":"")
+         << ((flags & SHOULD_RECV_VIDEO)?" SHOULD_RECV_VIDEO":"")
+         << ((flags & SHOULD_INACTIVE_VIDEO)?" SHOULD_INACTIVE_VIDEO":"")
+         << ((flags & SHOULD_REJECT_VIDEO)?" SHOULD_REJECT_VIDEO":"")
+         << endl;
 
-
-    	// after negotiation we are left with one codec
-    	ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+    if ((flags & AUDIO_FLAGS) && offer) {
+      ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
     }
 
-    if (shouldHaveVideo)
-    {
-      ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
+    switch(flags & AUDIO_FLAGS) {
+      case 0:
+            ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+        break;
+      case SHOULD_SEND_AUDIO:
+        ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+            ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendonly"), std::string::npos);
+        break;
+      case SHOULD_RECV_AUDIO:
+        ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+            ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=recvonly"), std::string::npos);
+        break;
+      case SHOULD_SENDRECV_AUDIO:
+        ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+            ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendrecv"), std::string::npos);
+        break;
+      case SHOULD_INACTIVE_AUDIO:
+        ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+            ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=inactive"), std::string::npos);
+        break;
+      case SHOULD_REJECT_AUDIO:
+        ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
+        ASSERT_NE(sdp.find("m=audio 0 "), std::string::npos);
+        break;
+      default:
+        ASSERT_FALSE("Missing case in switch statement");
+    }
+
+    switch(flags & VIDEO_FLAGS) {
+      case 0:
+        ASSERT_EQ(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
+        break;
+      case SHOULD_SEND_VIDEO:
+        ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendonly"),
+                  std::string::npos);
+        break;
+      case SHOULD_RECV_VIDEO:
+        ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=recvonly"),
+                  std::string::npos);
+        break;
+      case SHOULD_SENDRECV_VIDEO:
+        ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendrecv"),
+                  std::string::npos);
+        break;
+      case SHOULD_INACTIVE_VIDEO:
+        ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=inactive"),
+                  std::string::npos);
+        break;
+      case SHOULD_REJECT_VIDEO:
+        ASSERT_NE(sdp.find("m=video 0 "), std::string::npos);
+        break;
+      default:
+        ASSERT_FALSE("Missing case in switch statement");
     }
   }
 };
 
 class SignalingEnvironment : public ::testing::Environment {
  public:
   void TearDown() {
     sipcc::PeerConnectionImpl::Shutdown();
   }
 };
 
 class SignalingTest : public ::testing::Test {
 public:
-  void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
-    a1_.CreateOffer(constraints, audio, video);
+  void CreateOffer(sipcc::MediaConstraints& constraints,
+                   uint32_t offerFlags, uint32_t sdpCheck) {
+    a1_.CreateOffer(constraints, offerFlags, sdpCheck);
   }
 
-  void CreateSetOffer(sipcc::MediaConstraints& constraints) {
-    a1_.CreateOffer(constraints, true, true);
+  void CreateSetOffer(sipcc::MediaConstraints& constraints, uint32_t sdpCheck) {
+    a1_.CreateOffer(constraints, OFFER_AV, sdpCheck);
     a1_.SetLocal(TestObserver::OFFER, a1_.offer());
   }
 
-  void OfferAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints,
-                       bool audio, bool video, bool finishAfterAnswer) {
-    a1_.CreateOffer(aconstraints, audio, video);
+  void OfferAnswer(sipcc::MediaConstraints& aconstraints,
+                   sipcc::MediaConstraints& bconstraints,
+                   uint32_t offerAnswerFlags,
+                   bool finishAfterAnswer, uint32_t offerSdpCheck,
+                   uint32_t answerSdpCheck) {
+    a1_.CreateOffer(aconstraints, offerAnswerFlags, offerSdpCheck);
     a1_.SetLocal(TestObserver::OFFER, a1_.offer());
     a2_.SetRemote(TestObserver::OFFER, a1_.offer());
-    a2_.CreateAnswer(bconstraints, audio, video);
+    a2_.CreateAnswer(bconstraints, a1_.offer(),
+                     offerAnswerFlags, answerSdpCheck);
     if(true == finishAfterAnswer) {
         a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
         a1_.SetRemote(TestObserver::ANSWER, a2_.answer());
 
         ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
         ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
     }
   }
 
-  void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) {
-    a1_.CreateOffer(aconstraints, true, true);
+  void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints,
+                           sipcc::MediaConstraints& bconstraints,
+                           uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
+    a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
     a1_.SetLocal(TestObserver::OFFER, a1_.offer());
     a2_.SetRemote(TestObserver::OFFER, a1_.offer());
-    a2_.CreateAnswer(bconstraints, true, true);
+    a2_.CreateAnswer(bconstraints, a1_.offer(), OFFER_AV | ANSWER_AV,
+                     answerSdpCheck);
     a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
     ParsedSDP sdpWrapper(a2_.answer());
     sdpWrapper.ReplaceLine("m=audio", "m=audio 65375 RTP/SAVPF 109 8 101\r\n");
     sdpWrapper.AddLine("a=rtpmap:8 PCMA/8000\r\n");
     cout << "Modified SDP " << sdpWrapper.getSdp() << endl;
     a1_.SetRemote(TestObserver::ANSWER, sdpWrapper.getSdp());
     ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
   }
 
-  void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) {
-    a1_.CreateOffer(aconstraints, true, true);
+  void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints,
+                          sipcc::MediaConstraints& bconstraints,
+                          uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
+    a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
     a1_.SetLocal(TestObserver::OFFER, a1_.offer());
     ParsedSDP a1_offer(a1_.offer());
     a2_.SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
-    a2_.CreateAnswer(bconstraints, true, true);
+    a2_.CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
+                     OFFER_AV|ANSWER_AV, answerSdpCheck);
     a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
     ParsedSDP a2_answer(a2_.answer());
     a1_.SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
     // Now set the trickle ICE candidates
     a1_.DoTrickleIce(a2_answer);
     a2_.DoTrickleIce(a1_offer);
     ASSERT_TRUE_WAIT(a1_.IceCompleted() == true, kDefaultTimeout);
     ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
   }
 
-  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) {
+  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
+                               uint32_t hints, uint32_t sdpCheck) {
     sipcc::MediaConstraints aconstraints;
     aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
     aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-    a1_.CreateOffer(aconstraints, true, true);
-    a1_.CreateOfferRemoveStream(constraints, audio, video);
-  }
-
-  void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints) {
-    a1_.CreateOffer(constraints, true, false);
+    a1_.CreateOffer(aconstraints, OFFER_AV, SHOULD_SENDRECV_AV );
+    a1_.CreateOfferRemoveStream(constraints, hints, sdpCheck);
   }
 
-  void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints) {
-	a1_.CreateOffer(constraints, true, true);
-    a1_.CreateOfferRemoveStream(constraints, false, true);
+  void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints,
+                            uint32_t sdpCheck) {
+    a1_.CreateOffer(constraints, OFFER_AUDIO, sdpCheck);
   }
 
-  void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints, const char * candidate, const char * mid, unsigned short level) {
-    a1_.CreateOffer(constraints, true, true);
+  void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints,
+                               const char * candidate, const char * mid,
+                               unsigned short level, uint32_t sdpCheck) {
+    a1_.CreateOffer(constraints, OFFER_AV, sdpCheck);
     a1_.AddIceCandidate(candidate, mid, level);
   }
 
  protected:
   SignalingAgent a1_;  // Canonically "caller"
   SignalingAgent a2_;  // Canonically "callee"
 };
 
 
 TEST_F(SignalingTest, JustInit)
 {
 }
 
 TEST_F(SignalingTest, CreateSetOffer)
 {
   sipcc::MediaConstraints constraints;
-  CreateSetOffer(constraints);
+  CreateSetOffer(constraints, SHOULD_SENDRECV_AV);
 }
 
 TEST_F(SignalingTest, CreateOfferAudioVideoConstraintUndefined)
 {
   sipcc::MediaConstraints constraints;
-  CreateOffer(constraints, true, true);
+  CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
 }
 
 TEST_F(SignalingTest, CreateOfferNoVideoStream)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, true, false);
+  CreateOffer(constraints, OFFER_AUDIO,
+              SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferNoAudioStream)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOffer(constraints, false, true);
+  CreateOffer(constraints, OFFER_VIDEO,
+              SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveAudio)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
   constraints.setBooleanConstraint("VoiceActivityDetection", true, true);
-  CreateOffer(constraints, true, true);
+  CreateOffer(constraints, OFFER_AV,
+              SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveVideo)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  CreateOffer(constraints, true, true);
+  CreateOffer(constraints, OFFER_AV,
+              SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferRemoveAudioStream)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOfferRemoveStream(constraints, false, true);
+  CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO,
+              SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveAudioRemoveAudioStream)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  CreateOfferRemoveStream(constraints, false, true);
+  CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO,
+              SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, CreateOfferDontReceiveVideoRemoveVideoStream)
 {
   sipcc::MediaConstraints constraints;
   constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
   constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  CreateOfferRemoveStream(constraints, true, false);
+  CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_VIDEO,
+              SHOULD_SENDRECV_AUDIO);
+}
+
+TEST_F(SignalingTest, OfferAnswerNothingDisabled)
+{
+  sipcc::MediaConstraints constraints;
+  OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, false,
+              SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
+}
+
+TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnOffer)
+{
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+              false, SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO,
+              SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontReceiveAudio)
+TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnOffer)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(aconstraints, bconstraints, true, true, false);
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+              false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
+              SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontReceiveVideo)
+TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnAnswer)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(aconstraints, bconstraints, true, true, false);
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+              false, SHOULD_SENDRECV_AV,
+              SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
 TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnAnswer)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(aconstraints, bconstraints, true, true, false);
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
+              false, SHOULD_SENDRECV_AV,
+              SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
+}
+
+TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOffer)
+{
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
+              false, SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO,
+              SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontSendReceiveVideoNoVideoStream)
+TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOffer)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
-  OfferAnswer(aconstraints, bconstraints, true, false, false);
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
+              false, SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO,
+              SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
+}
+
+TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswer)
+{
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
+              false, SHOULD_SENDRECV_AV,
+              SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
 }
 
-TEST_F(SignalingTest, OfferAnswerDontSendReceiveAudioNoAudioStream)
+TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswer)
 {
-  sipcc::MediaConstraints aconstraints;
-  aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  sipcc::MediaConstraints bconstraints;
-  bconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
-  bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
-  OfferAnswer(aconstraints, bconstraints, false, true, false);
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+              false, SHOULD_SENDRECV_AV,
+              SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
+}
+
+TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerDontReceiveVideoOnAnswer)
+{
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
+  OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
+              false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO );
 }
 
-TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamDontReceiveVideo)
+TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerDontReceiveAudioOnAnswer)
+{
+  sipcc::MediaConstraints offerconstraints;
+  offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
+  offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
+  sipcc::MediaConstraints answerconstraints;
+  answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
+  answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);