Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <emorley@mozilla.com>
Thu, 26 Jul 2012 13:04:00 +0100
changeset 100555 20db7c6d82cc5bcb0e916bfe72d1ab04d3c3be2d
parent 100413 c0a32cf903d83ff024242e1a64e86e7dfc7a2fa2 (current diff)
parent 100554 ff7d09c5c94590102341c9e7932a1a866c7ce837 (diff)
child 100556 9d8cc914ad36c644a37344b9b118916fc7e68d3d
child 100568 f50ebe5069160cbc6d6eb7dd74c39c7ec4dcbb86
push id23182
push useremorley@mozilla.com
push dateThu, 26 Jul 2012 12:04:56 +0000
treeherdermozilla-central@20db7c6d82cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.0a1
first release with
nightly linux32
20db7c6d82cc / 17.0a1 / 20120726052803 / files
nightly linux64
20db7c6d82cc / 17.0a1 / 20120726052803 / files
nightly mac
20db7c6d82cc / 17.0a1 / 20120726052803 / files
nightly win32
20db7c6d82cc / 17.0a1 / 20120726052803 / files
nightly win64
20db7c6d82cc / 17.0a1 / 20120726052803 / 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 last PGO-green changeset of mozilla-inbound to mozilla-central
b2g/chrome/content/shell.js
browser/base/content/browser.js
gfx/angle/angle-castrate-bug-241.patch
gfx/angle/angle-intrinsic-msvc2005.patch
gfx/angle/angle-use-xmalloc.patch
gfx/angle/src/compiler/UnfoldSelect.cpp
gfx/angle/src/compiler/UnfoldSelect.h
gfx/angle/src/compiler/compilerdebug.cpp
gfx/angle/src/compiler/compilerdebug.h
gfx/angle/src/compiler/preprocessor/lexer_glue.cpp
gfx/angle/src/compiler/preprocessor/lexer_glue.h
gfx/angle/src/compiler/preprocessor/new/Context.cpp
gfx/angle/src/compiler/preprocessor/new/Context.h
gfx/angle/src/compiler/preprocessor/new/pp.l
gfx/angle/src/compiler/preprocessor/new/pp.y
gfx/angle/src/compiler/preprocessor/new/pp_lex.cpp
gfx/angle/src/compiler/preprocessor/new/pp_tab.cpp
gfx/angle/src/compiler/preprocessor/new/pp_tab.h
gfx/angle/src/compiler/preprocessor/new/token_type.h
gfx/angle/src/libEGL/Makefile.in
gfx/angle/src/libGLESv2/Makefile.in
mobile/android/chrome/content/browser.js
--- a/accessible/src/msaa/DocAccessibleWrap.cpp
+++ b/accessible/src/msaa/DocAccessibleWrap.cpp
@@ -253,17 +253,17 @@ DocAccessibleWrap::DoInitialUpdate()
   if (nsWinUtils::IsWindowEmulationStarted()) {
     // Create window for tab document.
     if (nsCoreUtils::IsTabDocument(mDocument)) {
       mozilla::dom::TabChild* tabChild =
         mozilla::dom::GetTabChildFrom(mDocument->GetShell());
 
       a11y::RootAccessible* rootDocument = RootAccessible();
 
-      mozilla::WindowsHandle nativeData = nsnull;
+      mozilla::WindowsHandle nativeData = NULL;
       if (tabChild)
         tabChild->SendGetWidgetNativeData(&nativeData);
       else
         nativeData = reinterpret_cast<mozilla::WindowsHandle>(
           rootDocument->GetNativeWindow());
 
       bool isActive = true;
       PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -609,8 +609,28 @@ Services.obs.addObserver(function Conten
     name: 'view',
     data: {
       type: handler.type,
       url: handler.url
     }
   });
 }, 'content-handler', false);
 
+(function geolocationStatusTracker() {
+  gGeolocationActiveCount = 0;
+
+  Services.obs.addObserver(function(aSubject, aTopic, aData) {
+    let oldCount = gGeolocationActiveCount;
+    if (aData == "starting") {
+      gGeolocationActiveCount += 1;
+    } else if (aData == "shutdown") {
+      gGeolocationActiveCount -= 1;
+    }
+
+    // We need to track changes from 1 <-> 0
+    if (gGeolocationActiveCount + oldCount == 1) {
+      shell.sendChromeEvent({
+        type: 'geolocation-status',
+        active: (gGeolocationActiveCount == 1)
+      });
+    }
+}, "geolocation-device-events", false);
+})();
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -327,30 +327,30 @@
                 key="key_openAddons"/>
       <splitmenu id="appmenu_customize"
 #ifdef XP_UNIX
                  label="&preferencesCmdUnix.label;"
 #else
                  label="&preferencesCmd2.label;"
 #endif
                  oncommand="openPreferences();">
-          <menuitem id="appmenu_socialToggle"
-                    type="checkbox"
-                    autocheck="false"
-                    command="Social:Toggle"/>
           <menupopup id="appmenu_customizeMenu"
                      onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
             <menuitem id="appmenu_preferences"
 #ifdef XP_UNIX
                       label="&preferencesCmdUnix.label;"
 #else
                       label="&preferencesCmd2.label;"
 #endif
                       oncommand="openPreferences();"/>
             <menuseparator/>
+            <menuitem id="appmenu_socialToggle"
+                      type="checkbox"
+                      autocheck="false"
+                      command="Social:Toggle"/>
             <menuseparator id="appmenu_toggleToolbarsSeparator"/>
             <menuitem id="appmenu_toggleTabsOnTop"
                       label="&viewTabsOnTop.label;"
                       type="checkbox"
                       command="cmd_ToggleTabsOnTop"/>
             <menuitem id="appmenu_toolbarLayout"
                       label="&appMenuToolbarLayout.label;"
                       command="cmd_CustomizeToolbars"/>
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -38,16 +38,17 @@ let SocialUI = {
         SocialToolbar.updateButtonHiddenState();
         SocialSidebar.updateSidebar();
         break;
       case "social:ambient-notification-changed":
         SocialToolbar.updateButton();
         break;
       case "social:profile-changed":
         SocialToolbar.updateProfile();
+        SocialShareButton.updateProfileInfo();
         break;
       case "nsPref:changed":
         SocialSidebar.updateSidebar();
     }
   },
 
   get toggleCommand() {
     return document.getElementById("Social:Toggle");
@@ -148,17 +149,20 @@ let SocialUI = {
     this.notificationPanel.hidePopup();
   }
 }
 
 let SocialShareButton = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
     this.updateButtonHiddenState();
+    this.updateProfileInfo();
+  },
 
+  updateProfileInfo: function SSB_updateProfileInfo() {
     let profileRow = document.getElementById("editSharePopupHeader");
     let profile = Social.provider.profile;
     if (profile && profile.portrait && profile.displayName) {
       profileRow.hidden = false;
       let portrait = document.getElementById("socialUserPortrait");
       portrait.style.listStyleImage = profile.portrait;
       let displayName = document.getElementById("socialUserDisplayName");
       displayName.setAttribute("label", profile.displayName);
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1263,16 +1263,17 @@ window[tabsontop="false"] richlistitem[t
 
 #socialUserDisplayName,
 #socialUserPortrait {
   cursor: pointer;
 }
 
 #socialUserDisplayName {
   -moz-appearance: none;
+  color: #fff;
   border: none;
   background-color: transparent;
   margin-top: 0;
   padding-top: 0;
   font-size: 130%;
   font-weight: bold;
 }
 
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -102,30 +102,31 @@ public class DoCommand {
 
     String    currentDir = "/";
     String    sErrorPrefix = "##AGENT-WARNING## ";
     boolean bTraceOn = false;
 
     String ffxProvider = "org.mozilla.ffxcp";
     String fenProvider = "org.mozilla.fencp";
 
-    private final String prgVersion = "SUTAgentAndroid Version 1.10";
+    private final String prgVersion = "SUTAgentAndroid Version 1.11";
 
     public enum Command
         {
         RUN ("run"),
         EXEC ("exec"),
         EXECCWD ("execcwd"),
         ENVRUN ("envrun"),
         KILL ("kill"),
         PS ("ps"),
         DEVINFO ("info"),
         OS ("os"),
         ID ("id"),
         UPTIME ("uptime"),
+        UPTIMEMILLIS ("uptimemillis"),
         SETTIME ("settime"),
         SYSTIME ("systime"),
         SCREEN ("screen"),
         ROTATION ("rotation"),
         MEMORY ("memory"),
         POWER ("power"),
         PROCESS ("process"),
         GETAPPROOT ("getapproot"),
@@ -416,16 +417,18 @@ public class DoCommand {
                     strReturn += SUTAgentAndroid.sUniqueID;
                     strReturn += "\n";
                     strReturn += GetOSInfo();
                     strReturn += "\n";
                     strReturn += GetSystemTime();
                     strReturn += "\n";
                     strReturn += GetUptime();
                     strReturn += "\n";
+                    strReturn += GetUptimeMillis();
+                    strReturn += "\n";
                     strReturn += GetScreenInfo();
                     strReturn += "\n";
                     strReturn += GetRotationInfo();
                     strReturn += "\n";
                     strReturn += GetMemoryInfo();
                     strReturn += "\n";
                     strReturn += GetPowerInfo();
                     strReturn += "\n";
@@ -459,16 +462,20 @@ public class DoCommand {
                         case SYSTIME:
                             strReturn = GetSystemTime();
                             break;
 
                         case UPTIME:
                             strReturn = GetUptime();
                             break;
 
+                        case UPTIMEMILLIS:
+                            strReturn = GetUptimeMillis();
+                            break;
+
                         case MEMORY:
                             strReturn = GetMemoryInfo();
                             break;
 
                         case POWER:
                             strReturn += GetPowerInfo();
                             break;
 
@@ -2919,16 +2926,21 @@ private void CancelNotification()
             nSecs = (int)(lHold / 1000L);
             nMilliseconds = (int)(lHold % 1000);
             sRet = "" + nDays + " days " + nHours + " hours " + nMinutes + " minutes " + nSecs + " seconds " + nMilliseconds + " ms";
             }
 
         return (sRet);
         }
 
+    public String GetUptimeMillis()
+        {
+        return Long.toString(SystemClock.uptimeMillis());
+        }
+ 
     public String NewKillProc(String sProcId, OutputStream out)
         {
         String sRet = "";
 
         try
             {
             pProc = Runtime.getRuntime().exec("kill "+sProcId);
             RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
@@ -3766,16 +3778,17 @@ private void CancelNotification()
             "                               key=value pairs (comma separated)\n" +
             "kill [program name]          - kill program no path\n" +
             "killall                      - kill all processes started\n" +
             "ps                           - list of running processes\n" +
             "info                         - list of device info\n" +
             "        [os]                 - os version for device\n" +
             "        [id]                 - unique identifier for device\n" +
             "        [uptime]             - uptime for device\n" +
+            "        [uptimemillis]       - uptime for device in milliseconds\n" +
             "        [systime]            - current system time\n" +
             "        [screen]             - width, height and bits per pixel for device\n" +
             "        [memory]             - physical, free, available, storage memory\n" +
             "                               for device\n" +
             "        [processes]          - list of running processes see 'ps'\n" +
             "deadman timeout              - set the duration for the deadman timer\n" +
             "alrt [on/off]                - start or stop sysalert behavior\n" +
             "disk [arg]                   - prints disk space info\n" +
--- a/build/pymake/tests/vpath-directive.mk
+++ b/build/pymake/tests/vpath-directive.mk
@@ -1,13 +1,10 @@
-ifdef __WIN32__
-VPSEP = ;
-else
-VPSEP = :
-endif
+# On Windows, MSYS make takes Unix paths but Pymake takes Windows paths
+VPSEP := $(if $(and $(__WIN32__),$(.PYMAKE)),;,:)
 
 $(shell \
 mkdir subd1 subd2 subd3; \
 printf "reallybaddata" >subd1/foo.in; \
 printf "gooddata" >subd2/foo.in; \
 printf "baddata" >subd3/foo.in; \
 touch subd1/foo.in2 subd2/foo.in2 subd3/foo.in2; \
 )
--- a/build/virtualenv/packages.txt
+++ b/build/virtualenv/packages.txt
@@ -2,8 +2,10 @@ setup.py:other-licenses/simplejson-2.1.1
 setup.py:testing/mozbase/manifestdestiny:develop
 setup.py:testing/mozbase/mozinfo:develop
 setup.py:testing/mozbase/mozinstall:develop
 setup.py:testing/mozbase/mozlog:develop
 setup.py:testing/mozbase/mozprocess:develop
 setup.py:testing/mozbase/mozprofile:develop
 setup.py:testing/mozbase/mozrunner:develop
 setup.py:python/blessings:develop
+mozilla.pth:build
+mozilla.pth:config
--- a/build/virtualenv/populate_virtualenv.py
+++ b/build/virtualenv/populate_virtualenv.py
@@ -1,18 +1,20 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # This file contains code for populating the virtualenv environment for
 # Mozilla's build system. It is typically called as part of configure.
 
+from __future__ import with_statement
 import os.path
 import subprocess
 import sys
+import distutils.sysconfig
 
 def populate_virtualenv(top_source_directory, manifest_filename):
     """Populate the virtualenv from the contents of a manifest.
 
     The manifest file consists of colon-delimited fields. The first field
     specifies the action. The remaining fields are arguments to that action.
     The following actions are supported:
 
@@ -33,16 +35,21 @@ def populate_virtualenv(top_source_direc
     fh.close()
 
     for package in packages:
         if package[0] == 'setup.py':
             assert len(package) >= 2
 
             call_setup(os.path.join(top_source_directory, package[1]),
                 package[2:])
+        if package[0].endswith('.pth'):
+            assert len(package) == 2
+
+            with open(os.path.join(distutils.sysconfig.get_python_lib(), package[0]), 'a') as f:
+                f.write("%s\n" % os.path.join(top_source_directory, package[1]))
 
 def call_setup(directory, arguments):
     """Calls setup.py in a directory."""
     setup = os.path.join(directory, 'setup.py')
 
     program = [sys.executable, setup]
     program.extend(arguments)
 
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -156,16 +156,17 @@ PYUNITS := \
   unit-Expression.py \
   unit-Preprocessor.py \
   unit-nsinstall.py \
   unit-printprereleasesuffix.py \
   unit-JarMaker.py \
   unit-buildlist.py \
   unit-expandlibs.py \
   unit-writemozinfo.py \
+  unit-mozunit.py \
   $(NULL)
 
 check-preqs = \
   check-python-modules \
   check-jar-mn \
   check-makefiles \
   $(NULL)
 
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -121,21 +121,23 @@ class Preprocessor:
     if self.checkLineNumbers:
       self.writtenLines += 1
       ln = self.context['LINE']
       if self.writtenLines != ln:
         self.out.write('//@line %(line)d "%(file)s"%(le)s'%{'line': ln,
                                                             'file': self.context['FILE'],
                                                             'le': self.LE})
         self.writtenLines = ln
-    aLine = self.applyFilters(aLine)
+    filteredLine = self.applyFilters(aLine)
+    if filteredLine != aLine:
+      self.actionLevel = 2
     # ensure our line ending. Only need to handle \n, as we're reading
     # with universal line ending support, at least for files.
-    aLine = re.sub('\n', self.LE, aLine)
-    self.out.write(aLine)
+    filteredLine = re.sub('\n', self.LE, filteredLine)
+    self.out.write(filteredLine)
   
   def handleCommandLine(self, args, defaultToStdin = False):
     """
     Parse a commandline into this parser.
     Uses OptionParser internally, no args mean sys.argv[1:].
     """
     p = self.getCommandLineParser()
     (options, args) = p.parse_args(args=args)
--- a/config/mozunit.py
+++ b/config/mozunit.py
@@ -1,25 +1,28 @@
 # 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/.
 
 from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
+import unittest
 import inspect
+from StringIO import StringIO
+import os
 
 '''Helper to make python unit tests report the way that the Mozilla
 unit test infrastructure expects tests to report.
 
 Usage:
 
 import unittest
-from mozunit import MozTestRunner
+import mozunit
 
 if __name__ == '__main__':
-    unittest.main(testRunner=MozTestRunner())
+    mozunit.main()
 '''
 
 class _MozTestResult(_TestResult):
     def __init__(self, stream, descriptions):
         _TestResult.__init__(self)
         self.stream = stream
         self.descriptions = descriptions
 
@@ -63,8 +66,74 @@ class _MozTestResult(_TestResult):
 class MozTestRunner(_TestRunner):
     def _makeResult(self):
         return _MozTestResult(self.stream, self.descriptions)
     def run(self, test):
         result = self._makeResult()
         test(result)
         result.printErrorList()
         return result
+
+class MockedFile(StringIO):
+    def __init__(self, context, filename, content = ''):
+        self.context = context
+        self.name = filename
+        StringIO.__init__(self, content)
+
+    def close(self):
+        self.context.files[self.name] = self.getvalue()
+        StringIO.close(self)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
+class MockedOpen(object):
+    '''
+    Context manager diverting the open builtin such that opening files
+    can open "virtual" file instances given when creating a MockedOpen.
+
+    with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
+        f = open('foo', 'r')
+
+    will thus open the virtual file instance for the file 'foo' to f.
+
+    MockedOpen also masks writes, so that creating or replacing files
+    doesn't touch the file system, while subsequently opening the file
+    will return the recorded content.
+
+    with MockedOpen():
+        f = open('foo', 'w')
+        f.write('foo')
+    self.assertRaises(Exception,f.open('foo', 'r'))
+    '''
+    def __init__(self, files = {}):
+        self.files = {}
+        for name, content in files.iteritems():
+            self.files[os.path.abspath(name)] = content
+
+    def __call__(self, name, mode = 'r'):
+        absname = os.path.abspath(name)
+        if 'w' in mode:
+            file = MockedFile(self, absname)
+        elif absname in self.files:
+            file = MockedFile(self, absname, self.files[absname])
+        elif 'a' in mode:
+            file = MockedFile(self, absname, self.open(name, 'r').read())
+        else:
+            file = self.open(name, mode)
+        if 'a' in mode:
+            file.seek(0, os.SEEK_END)
+        return file
+
+    def __enter__(self):
+        import __builtin__
+        self.open = __builtin__.open
+        __builtin__.open = self
+
+    def __exit__(self, type, value, traceback):
+        import __builtin__
+        __builtin__.open = self.open
+
+def main(*args):
+    unittest.main(testRunner=MozTestRunner(),*args)
--- a/config/tests/unit-Expression.py
+++ b/config/tests/unit-Expression.py
@@ -1,13 +1,13 @@
 import unittest
 
 import sys
 import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 
 from Expression import Expression, Context
 
 class TestContext(unittest.TestCase):
   """
   Unit tests for the Context class
   """
 
@@ -55,9 +55,9 @@ class TestExpression(unittest.TestCase):
     """ Test for the == operator"""
     self.assert_(Expression('FAIL == PASS').evaluate(self.c))
 
   def test_notequals(self):
     """ Test for the != operator"""
     self.assert_(Expression('FAIL != 1').evaluate(self.c))
 
 if __name__ == '__main__':
-  unittest.main()
+  mozunit.main()
--- a/config/tests/unit-JarMaker.py
+++ b/config/tests/unit-JarMaker.py
@@ -1,18 +1,16 @@
 import unittest
 
 import os, sys, os.path, time, inspect
 from filecmp import dircmp
 from tempfile import mkdtemp
 from shutil import rmtree, copy2
 from zipfile import ZipFile
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-
-from mozunit import MozTestRunner
+import mozunit
 from JarMaker import JarMaker
 
 if sys.platform == "win32":
     import ctypes
     from ctypes import POINTER, WinError
     DWORD = ctypes.c_ulong
     LPDWORD = POINTER(DWORD)
     HANDLE = ctypes.c_void_p
@@ -275,9 +273,9 @@ class TestJarMaker(unittest.TestCase):
             open(os.path.join(ldir, relpath), 'w').write(relpath+" content\n")
         # call JarMaker
         difference = self._jar_and_compare(jars,
                                            (_mangle,),
                                            sourcedirs = [])
         self.assertTrue(not difference, difference)
 
 if __name__ == '__main__':
-    unittest.main(testRunner=MozTestRunner())
+    mozunit.main()
--- a/config/tests/unit-LineEndings.py
+++ b/config/tests/unit-LineEndings.py
@@ -1,15 +1,15 @@
 import unittest
 
 from StringIO import StringIO
 import os
 import sys
 import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 
 from Preprocessor import Preprocessor
 
 class TestLineEndings(unittest.TestCase):
   """
   Unit tests for the Context class
   """
 
@@ -38,9 +38,9 @@ class TestLineEndings(unittest.TestCase)
     self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
 
   def testWindows(self):
     self.createFile(['\x0D\x0A']*3)
     self.pp.do_include(self.tempnam)
     self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
 
 if __name__ == '__main__':
-  unittest.main()
+  mozunit.main()
--- a/config/tests/unit-Preprocessor.py
+++ b/config/tests/unit-Preprocessor.py
@@ -1,50 +1,23 @@
 from __future__ import with_statement
 import unittest
 
 from StringIO import StringIO
 import os
 import sys
 import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+from mozunit import main, MockedOpen
 
 from Preprocessor import Preprocessor
 
-class NamedIO(StringIO):
-  def __init__(self, name, content):
-    self.name = name
-    StringIO.__init__(self, content)
-
-class MockedOpen(object):
-  """
-  Context manager diverting the open builtin such that opening files
-  can open NamedIO instances given when creating a MockedOpen.
-
-  with MockedOpen(NamedIO('foo', 'foo'), NamedIO('bar', 'bar')):
-    f = open('foo', 'r')
-
-  will thus assign the NamedIO instance for the file 'foo' to f.
-  """
-  def __init__(self, *files):
-    self.files = {}
-    for f in files:
-      self.files[os.path.abspath(f.name)] = f
-  def __call__(self, name, args):
-    absname = os.path.abspath(name)
-    if absname in self.files:
-      return self.files[absname]
-    return self.open(name, args)
-  def __enter__(self):
-    import __builtin__
-    self.open = __builtin__.open
-    __builtin__.open = self
-  def __exit__(self, type, value, traceback):
-    import __builtin__
-    __builtin__.open = self.open
+def NamedIO(name, content):
+  with open(name, 'w') as f:
+    f.write(content)
+  return name
 
 class TestPreprocessor(unittest.TestCase):
   """
   Unit tests for the Context class
   """
 
   def setUp(self):
     self.pp = Preprocessor()
@@ -534,23 +507,23 @@ octal value is not equal
     try:
       self.pp.do_include(f)
     except Preprocessor.Error, exception:
       self.assertEqual(exception.key, 'UNDEFINED_VAR')
     else:
       self.fail("Expected a Preprocessor.Error")
 
   def test_include(self):
-    with MockedOpen(NamedIO("foo/test", """#define foo foobarbaz
+    with MockedOpen({"foo/test": """#define foo foobarbaz
 #include @inc@
 @bar@
-"""),
-                      NamedIO("bar", """#define bar barfoobaz
+""",
+                     "bar": """#define bar barfoobaz
 @foo@
-""")):
+"""}):
       f = NamedIO("include.in", """#filter substitution
 #define inc ../bar
 #include foo/test""")
       self.pp.do_include(f)
       self.assertEqual(self.pp.out.getvalue(), """foobarbaz
 barfoobaz
 """)
 
@@ -570,26 +543,26 @@ barfoobaz
     try:
       self.pp.do_include(f)
     except Preprocessor.Error, exception:
       self.assertEqual(exception.key, 'UNDEFINED_VAR')
     else:
       self.fail("Expected a Preprocessor.Error")
 
   def test_include_literal_at(self):
-    with MockedOpen(NamedIO("@foo@", "#define foo foobarbaz")):
+    with MockedOpen({"@foo@": "#define foo foobarbaz"}):
       f = NamedIO("include_literal_at.in", """#include @foo@
 #filter substitution
 @foo@
 """)
       self.pp.do_include(f)
       self.assertEqual(self.pp.out.getvalue(), """foobarbaz
 """)
 
   def test_command_line_literal_at(self):
-    with MockedOpen(NamedIO("@foo@.in", """@foo@
-""")):
+    with MockedOpen({"@foo@.in": """@foo@
+"""}):
       self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
       self.assertEqual(self.pp.out.getvalue(), """foobarbaz
 """)
 
 if __name__ == '__main__':
-  unittest.main()
+  main()
--- a/config/tests/unit-buildlist.py
+++ b/config/tests/unit-buildlist.py
@@ -1,14 +1,14 @@
 import unittest
 
 import os, sys, os.path, time
 from tempfile import mkdtemp
 from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 
 from buildlist import addEntriesToListFile
 
 class TestBuildList(unittest.TestCase):
   """
   Unit tests for buildlist.py
   """
   def setUp(self):
@@ -72,9 +72,9 @@ class TestBuildList(unittest.TestCase):
     only one entry being added."""
     testfile = os.path.join(self.tmpdir, "test.list")
     addEntriesToListFile(testfile, ["a","b","a","a","b"])
     self.assertFileContains(testfile, ["a","b"])
     addEntriesToListFile(testfile, ["c","a","c","b","c"])
     self.assertFileContains(testfile, ["a","b","c"])
 
 if __name__ == '__main__':
-  unittest.main()
+  mozunit.main()
--- a/config/tests/unit-expandlibs.py
+++ b/config/tests/unit-expandlibs.py
@@ -1,18 +1,17 @@
 from __future__ import with_statement
 import subprocess
 import unittest
 import sys
 import os
 import imp
 from tempfile import mkdtemp
 from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from mozunit import MozTestRunner
+import mozunit
 
 from UserString import UserString
 # Create a controlled configuration for use by expandlibs
 config_win = {
     'AR_EXTRACT': '',
     'DLL_PREFIX': '',
     'LIB_PREFIX': '',
     'OBJ_SUFFIX': '.obj',
@@ -380,9 +379,9 @@ class TestSymbolOrder(unittest.TestCase)
         config.LD_PRINT_ICF_SECTIONS = '-Wl,--print-icf-sections'
         args = ExpandArgsMore(['foo', '-bar', 'bar.o', 'foo.o'])
         self.assertEqual(args._getOrderedSections(['hello', '_Z6barbazv']), ['.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
         self.assertEqual(args._getOrderedSections(['_ZThn4_6foobarv', 'hi', '_Z6barbazv']), ['.text._Z6foobarv', '.text._ZThn4_6foobarv', '.text.hi', '.text.hello', '.text.hot._Z6barbazv'])
         subprocess.Popen = subprocess_popen
 
 
 if __name__ == '__main__':
-    unittest.main(testRunner=MozTestRunner())
+    mozunit.main()
new file mode 100644
--- /dev/null
+++ b/config/tests/unit-mozunit.py
@@ -0,0 +1,75 @@
+# 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/.
+
+from __future__ import with_statement
+import sys
+import os
+from mozunit import main, MockedOpen
+import unittest
+from tempfile import mkstemp
+
+class TestMozUnit(unittest.TestCase):
+    def test_mocked_open(self):
+        # Create a temporary file on the file system.
+        (fd, path) = mkstemp()
+        with os.fdopen(fd, 'w') as file:
+            file.write('foobar');
+
+        with MockedOpen({'file1': 'content1',
+                         'file2': 'content2'}):
+            # Check the contents of the files given at MockedOpen creation.
+            self.assertEqual(open('file1', 'r').read(), 'content1')
+            self.assertEqual(open('file2', 'r').read(), 'content2')
+
+            # Check that overwriting these files alters their content.
+            with open('file1', 'w') as file:
+                file.write('foo')
+            self.assertEqual(open('file1', 'r').read(), 'foo')
+
+            # ... but not until the file is closed.
+            file = open('file2', 'w')
+            file.write('bar')
+            self.assertEqual(open('file2', 'r').read(), 'content2')
+            file.close()
+            self.assertEqual(open('file2', 'r').read(), 'bar')
+
+            # Check that appending to a file does append
+            with open('file1', 'a') as file:
+                file.write('bar')
+            self.assertEqual(open('file1', 'r').read(), 'foobar')
+
+            # Opening a non-existing file ought to fail.
+            self.assertRaises(IOError, open, 'file3', 'r')
+
+            # Check that writing a new file does create the file.
+            with open('file3', 'w') as file:
+                file.write('baz')
+            self.assertEqual(open('file3', 'r').read(), 'baz')
+
+            # Check the content of the file created outside MockedOpen.
+            self.assertEqual(open(path, 'r').read(), 'foobar')
+
+            # Check that overwriting a file existing on the file system
+            # does modify its content.
+            with open(path, 'w') as file:
+                file.write('bazqux')
+            self.assertEqual(open(path, 'r').read(), 'bazqux')
+
+        with MockedOpen():
+            # Check that appending to a file existing on the file system
+            # does modify its content.
+            with open(path, 'a') as file:
+                file.write('bazqux')
+            self.assertEqual(open(path, 'r').read(), 'foobarbazqux')
+
+        # Check that the file was not actually modified on the file system.
+        self.assertEqual(open(path, 'r').read(), 'foobar')
+        os.remove(path)
+
+        # Check that the file created inside MockedOpen wasn't actually
+        # created.
+        self.assertRaises(IOError, open, 'file3', 'r')
+
+if __name__ == "__main__":
+    main()
--- a/config/tests/unit-nsinstall.py
+++ b/config/tests/unit-nsinstall.py
@@ -1,14 +1,14 @@
 import unittest
 
 import os, sys, os.path, time
 from tempfile import mkdtemp
 from shutil import rmtree
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 from mozprocess import processhandler
 
 from nsinstall import nsinstall
 import nsinstall as nsinstall_module
 NSINSTALL_PATH = nsinstall_module.__file__
 
 # Run the non-ASCII tests on (a) Windows, or (b) any platform with
 # sys.stdin.encoding set to UTF-8
@@ -165,9 +165,9 @@ class TestNsinstall(unittest.TestCase):
 
             self.assertEqual(rv, 0)
             destfile = os.path.join(testdir, filename)
             self.assert_(os.path.isfile(destfile))
 
     #TODO: implement -R, -l, -L and test them!
 
 if __name__ == '__main__':
-  unittest.main()
+  mozunit.main()
--- a/config/tests/unit-printprereleasesuffix.py
+++ b/config/tests/unit-printprereleasesuffix.py
@@ -1,13 +1,13 @@
 import unittest
 
 import sys
 import os.path
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 
 from printprereleasesuffix import get_prerelease_suffix
 
 class TestGetPreReleaseSuffix(unittest.TestCase):
   """
   Unit tests for the get_prerelease_suffix function
   """
 
@@ -72,9 +72,9 @@ class TestGetPreReleaseSuffix(unittest.T
     self.assertEqual(self.c, '')
 
   def test_plus(self):
     """test 1.2+ version string """
     self.c = get_prerelease_suffix('1.2+')
     self.assertEqual(self.c, '')
 
 if __name__ == '__main__':
-  unittest.main()
+  mozunit.main()
--- a/config/tests/unit-writemozinfo.py
+++ b/config/tests/unit-writemozinfo.py
@@ -1,15 +1,14 @@
 #!/usr/bin/env python
 from __future__ import with_statement
 import unittest
 import os, sys, time, tempfile
 from StringIO import StringIO
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+import mozunit
 
 from writemozinfo import build_dict, write_json, JsonValue, jsonify
 
 class TestBuildDict(unittest.TestCase):
     def testMissing(self):
         """
         Test that missing required values raises.
         """
@@ -234,10 +233,9 @@ class TestWriteJson(unittest.TestCase):
                            'MOZ_WIDGET_TOOLKIT':'windows'})
         d = parse_json(s.getvalue())
         self.assertEqual('win', d['os'])
         self.assertEqual('x86', d['processor'])
         self.assertEqual('windows', d['toolkit'])
         self.assertEqual(32, d['bits'])
 
 if __name__ == '__main__':
-    unittest.main()
-  
+    mozunit.main()
--- a/configure.in
+++ b/configure.in
@@ -745,16 +745,19 @@ if test -n "$_WIN32_MSVC"; then
     SKIP_COMPILER_CHECKS=1
     SKIP_LIBRARY_CHECKS=1
 
     # Since we're skipping compiler and library checks, hard-code
     # some facts here.
     AC_DEFINE(HAVE_IO_H)
     AC_DEFINE(HAVE_SETBUF)
     AC_DEFINE(HAVE_ISATTY)
+    if test $_MSC_VER -ge 1600; then
+        AC_DEFINE(HAVE_NULLPTR)
+    fi
 fi
 
 fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MIDL_FLAGS)
 AC_SUBST(_MSC_VER)
 
 AC_SUBST(GNU_AS)
@@ -5585,17 +5588,17 @@ if test "$MOZ_GSTREAMER"; then
     # introduced
     GST_VERSION=0.10.33
     PKG_CHECK_MODULES(GSTREAMER,
                       gstreamer-$GST_API_VERSION >= $GST_VERSION
                       gstreamer-app-$GST_API_VERSION
                       gstreamer-plugins-base-$GST_API_VERSION)
     if test -n "$GSTREAMER_LIBS"; then
        _SAVE_LDFLAGS=$LDFLAGS
-       LDFLAGS="$LDFLAGS -lgstvideo-$GST_API_VERSION"
+       LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
        AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
        if test -n "$_HAVE_LIBGSTVIDEO" ; then
           GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
        else
           AC_MSG_ERROR([gstreamer video backend requires libgstvideo])
        fi
        LDFLAGS=$_SAVE_LDFLAGS
     else
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -36,16 +36,17 @@
 #include "nsIScriptChannel.h"
 #include "nsIBlocklistService.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIAppShell.h"
 
 #include "nsPluginError.h"
 
 // Util headers
+#include "prenv.h"
 #include "prlog.h"
 
 #include "nsAutoPtr.h"
 #include "nsCURILoader.h"
 #include "nsContentPolicyUtils.h"
 #include "nsContentUtils.h"
 #include "nsDocShellCID.h"
 #include "nsGkAtoms.h"
@@ -1215,19 +1216,26 @@ nsObjectLoadingContent::ObjectState() co
           state |= NS_EVENT_STATE_HANDLER_DISABLED;
           break;
         case ePluginBlocklisted:
           state |= NS_EVENT_STATE_HANDLER_BLOCKED;
           break;
         case ePluginCrashed:
           state |= NS_EVENT_STATE_HANDLER_CRASHED;
           break;
-        case ePluginUnsupported:
-          state |= NS_EVENT_STATE_TYPE_UNSUPPORTED;
+        case ePluginUnsupported: {
+          // Check to see if plugins are blocked on this platform.
+          char* pluginsBlocked = PR_GetEnv("MOZ_PLUGINS_BLOCKED");
+          if (pluginsBlocked && pluginsBlocked[0] == '1') {
+            state |= NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM;
+          } else {
+            state |= NS_EVENT_STATE_TYPE_UNSUPPORTED;
+          }
           break;
+        }
         case ePluginOutdated:
         case ePluginOtherState:
           // Do nothing, but avoid a compile warning
           break;
       }
       return state;
   };
   NS_NOTREACHED("unknown type?");
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -151,16 +151,17 @@ WebGLContext::WebGLContext()
     mAllowRestore = true;
     mContextLossTimerRunning = false;
     mDrawSinceContextLossTimerSet = false;
     mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
     mContextStatus = ContextStable;
     mContextLostErrorSet = false;
 
     mAlreadyGeneratedWarnings = 0;
+    mAlreadyWarnedAboutFakeVertexAttrib0 = false;
 }
 
 WebGLContext::~WebGLContext()
 {
     DestroyResourcesAndContext();
     WebGLMemoryMultiReporterWrapper::RemoveWebGLContext(this);
     TerminateContextLossTimer();
     mContextRestorer = nsnull;
@@ -928,19 +929,27 @@ WebGLContext::GetExtension(const nsAStri
             ext = OES_texture_float;
     }
     else if (aName.Equals(NS_LITERAL_STRING("OES_standard_derivatives"),
              nsCaseInsensitiveStringComparator()))
     {
         if (IsExtensionSupported(OES_standard_derivatives))
             ext = OES_standard_derivatives;
     }
+    else if (aName.Equals(NS_LITERAL_STRING("EXT_texture_filter_anisotropic"),
+             nsCaseInsensitiveStringComparator()))
+    {
+        if (IsExtensionSupported(EXT_texture_filter_anisotropic))
+            ext = EXT_texture_filter_anisotropic;
+    }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"),
              nsCaseInsensitiveStringComparator()))
     {
+        GenerateWarning("MOZ_EXT_texture_filter_anisotropic has been renamed to EXT_texture_filter_anisotropic. "
+                        "Support for the MOZ_-prefixed string will be removed very soon.");
         if (IsExtensionSupported(EXT_texture_filter_anisotropic))
             ext = EXT_texture_filter_anisotropic;
     }
     else if (aName.Equals(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"),
              nsCaseInsensitiveStringComparator()))
     {
         if (IsExtensionSupported(WEBGL_lose_context))
             ext = WEBGL_lose_context;
@@ -1533,18 +1542,20 @@ WebGLContext::GetSupportedExtensions(Nul
     }
 
     nsTArray<nsString>& arr = retval.SetValue();
     
     if (IsExtensionSupported(OES_texture_float))
         arr.AppendElement(NS_LITERAL_STRING("OES_texture_float"));
     if (IsExtensionSupported(OES_standard_derivatives))
         arr.AppendElement(NS_LITERAL_STRING("OES_standard_derivatives"));
-    if (IsExtensionSupported(EXT_texture_filter_anisotropic))
+    if (IsExtensionSupported(EXT_texture_filter_anisotropic)) {
+        arr.AppendElement(NS_LITERAL_STRING("EXT_texture_filter_anisotropic"));
         arr.AppendElement(NS_LITERAL_STRING("MOZ_EXT_texture_filter_anisotropic"));
+    }
     if (IsExtensionSupported(WEBGL_lose_context))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"));
     if (IsExtensionSupported(WEBGL_compressed_texture_s3tc))
         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"));
 }
 
 NS_IMETHODIMP
 WebGLContext::IsContextLost(WebGLboolean *retval)
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1354,16 +1354,17 @@ protected:
     nsCOMPtr<nsITimer> mContextRestorer;
     bool mAllowRestore;
     bool mContextLossTimerRunning;
     bool mDrawSinceContextLossTimerSet;
     ContextStatus mContextStatus;
     bool mContextLostErrorSet;
 
     int mAlreadyGeneratedWarnings;
+    bool mAlreadyWarnedAboutFakeVertexAttrib0;
 
     bool ShouldGenerateWarnings() const {
         return mAlreadyGeneratedWarnings < 32;
     }
 
 #ifdef XP_MACOSX
     // see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
     // Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -437,16 +437,19 @@ GLenum WebGLContext::CheckedBufferData(G
         return LOCAL_GL_NO_ERROR;
     }
 }
 
 NS_IMETHODIMP
 WebGLContext::BufferData(WebGLenum target, const JS::Value& data, GLenum usage,
                          JSContext* cx)
 {
+    if (!IsContextStable())
+        return NS_OK;
+
     if (data.isNull()) {
         BufferData(target, static_cast<ArrayBuffer*>(nsnull), usage);
         return NS_OK;
     }
 
     if (data.isObject()) {
         JSObject& dataObj = data.toObject();
         if (JS_IsArrayBufferObject(&dataObj, cx)) {
@@ -1520,18 +1523,27 @@ WebGLContext::WhatDoesVertexAttrib0Need(
 bool
 WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount)
 {
     int whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
 
     if (whatDoesAttrib0Need == VertexAttrib0Status::Default)
         return true;
 
+    if (!mAlreadyWarnedAboutFakeVertexAttrib0) {
+        GenerateWarning("Drawing without vertex attrib 0 array enabled forces the browser "
+                        "to do expensive emulation work when running on desktop OpenGL "
+                        "platforms, for example on Mac. It is preferable to always draw "
+                        "with vertex attrib 0 array enabled, by using bindAttribLocation "
+                        "to bind some always-used attribute to location 0.");
+        mAlreadyWarnedAboutFakeVertexAttrib0 = true;
+    }
+
     CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
-    
+
     if (!checked_dataSize.isValid()) {
         ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
                          "with %d vertices. Try reducing the number of vertices.", vertexCount);
         return false;
     }
     
     WebGLuint dataSize = checked_dataSize.value();
 
@@ -5017,19 +5029,23 @@ WebGLContext::CompileShader(WebGLShader 
                 shader->mUniforms.AppendElement(WebGLMappedIdentifier(
                                                     nsDependentCString(uniform_name),
                                                     nsDependentCString(mapped_name)));
             }
 
             // we always query uniform info, regardless of useShaderSourceTranslation,
             // as we need it to validate uniform setter calls, and it doesn't rely on
             // shader translation.
+            char mappedNameLength = strlen(mapped_name);
+            char mappedNameLastChar = mappedNameLength > 1
+                                      ? mapped_name[mappedNameLength - 1]
+                                      : 0;
             shader->mUniformInfos.AppendElement(WebGLUniformInfo(
                                                     size,
-                                                    length > 1 && mapped_name[length - 1] == ']',
+                                                    mappedNameLastChar == ']',
                                                     type));
         }
 
         if (useShaderSourceTranslation) {
 
             for (int i = 0; i < num_attributes; i++) {
                 int length, size;
                 ShDataType type;
--- a/content/events/public/nsEventStates.h
+++ b/content/events/public/nsEventStates.h
@@ -241,16 +241,18 @@ private:
 // Content is in the suboptimal region.
 #define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
 // Content is in the sub-suboptimal region.
 #define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(39)
 // Handler for click to play plugin (vulnerable w/update)
 #define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(40)
 // Handler for click to play plugin (vulnerable w/no update)
 #define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(41)
+// Platform does not support plugin content (some mobile platforms)
+#define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(42)
 
 /**
  * NOTE: do not go over 63 without updating nsEventStates::InternalType!
  */
 
 #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS |     \
                             NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER |   \
                             NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -758,21 +758,32 @@ ChannelMediaResource::CacheClientSeek(PR
   CloseChannel();
 
   if (aResume) {
     NS_ASSERTION(mSuspendCount > 0, "Too many resumes!");
     // No need to mess with the channel, since we're making a new one
     --mSuspendCount;
   }
 
+  mOffset = aOffset;
+
+  if (mSuspendCount > 0) {
+    // Close the existing channel to force the channel to be recreated at
+    // the correct offset upon resume.
+    if (mChannel) {
+      mIgnoreClose = true;
+      CloseChannel();
+    }
+    return NS_OK;
+  }
+
   nsresult rv = RecreateChannel();
   if (NS_FAILED(rv))
     return rv;
 
-  mOffset = aOffset;
   return OpenChannel(nsnull);
 }
 
 nsresult
 ChannelMediaResource::CacheClientSuspend()
 {
   Suspend(false);
 
--- a/dom/contacts/fallback/ContactService.jsm
+++ b/dom/contacts/fallback/ContactService.jsm
@@ -62,16 +62,17 @@ let DOMContactManager = {
     this._messages = null;
     if (this._db)
       this._db.close();
     this._db = null;
   },
 
   receiveMessage: function(aMessage) {
     debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
+    let mm = aMessage.target.QueryInterface(Ci.nsIFrameMessageManager);
     let msg = aMessage.json;
 
     /*
      * Sorting the contacts by sortBy field. sortBy can either be familyName or givenName.
      * If 2 entries have the same sortyBy field or no sortBy field is present, we continue 
      * sorting with the other sortyBy field.
      */
     function sortfunction(a, b){
@@ -119,37 +120,37 @@ let DOMContactManager = {
             if (msg.findOptions.sortOrder !== 'undefined' && msg.findOptions.sortBy !== 'undefined') {
               debug('sortBy: ' + msg.findOptions.sortBy + ', sortOrder: ' + msg.findOptions.sortOrder );
               result.sort(sortfunction);
               if (msg.findOptions.filterLimit)
                 result = result.slice(0, msg.findOptions.filterLimit);
             }
 
             debug("result:" + JSON.stringify(result));
-            ppmm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
+            mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
           }.bind(this),
-          function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
+          function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
           msg.findOptions);
         break;
       case "Contact:Save":
         this._db.saveContact(
           msg.contact, 
-          function() { ppmm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.contact.id }); }.bind(this),
-          function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+          function() { mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID, contactID: msg.contact.id }); }.bind(this),
+          function(aErrorMsg) { mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
         break;
       case "Contact:Remove":
         this._db.removeContact(
           msg.id, 
-          function() { ppmm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.id }); }.bind(this),
-          function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+          function() { mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID, contactID: msg.id }); }.bind(this),
+          function(aErrorMsg) { mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
         break;
       case "Contacts:Clear":
         this._db.clear(
-          function() { ppmm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
-          function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
+          function() { mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
+          function(aErrorMsg) { mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this)
         );
     }
   }
 }
 
 DOMContactManager.init();
--- a/dom/contacts/tests/Makefile.in
+++ b/dom/contacts/tests/Makefile.in
@@ -11,12 +11,13 @@ relativesrcdir   = dom/contacts/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS = \
   $(NULL)
 
 MOCHITEST_FILES = \
   test_contacts_basics.html \
+  test_contacts_events.html \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/dom/mms/src/ril/MmsPduHelper.jsm
+++ b/dom/mms/src/ril/MmsPduHelper.jsm
@@ -21,16 +21,23 @@ function translatePduErrorToStatus(error
   if ((error >= MMS_PDU_ERROR_TRANSIENT_FAILURE)
       && (error < MMS_PDU_ERROR_PERMANENT_FAILURE)) {
     return MMS_PDU_STATUS_DEFERRED;
   }
 
   return MMS_PDU_STATUS_UNRECOGNISED;
 }
 
+function defineLazyRegExp(obj, name, pattern) {
+  obj.__defineGetter__(name, function() {
+    delete obj[name];
+    return obj[name] = new RegExp(pattern);
+  });
+}
+
 /**
  * Internal decoding function for boolean values.
  *
  * Boolean-value = Yes | No
  * Yes = <Octet 128>
  * No = <Octet 129>
  */
 let BooleanValue = {
@@ -75,36 +82,111 @@ let Address = {
    *        A wrapped object to store encoded raw data.
    *
    * @return An object of two string-typed attributes: address and type.
    */
   decode: function decode(data) {
     let str = EncodedStringValue.decode(data);
 
     let result;
-    if (((result = str.match(/^(\+?[\d.-]+)\/TYPE=(PLMN)$/)) != null)
-        || ((result = str.match(/^(\d{1,3}(?:\.\d{1,3}){3})\/TYPE=(IPv4)$/)) != null)
-        || ((result = str.match(/^([\da-fA-F]{4}(?::[\da-fA-F]{4}){7})\/TYPE=(IPv6)$/)) != null)
-        || ((result = str.match(/^([\w\+\-.%]+)\/TYPE=(\w+)$/)) != null)) {
+    if (((result = str.match(this.REGEXP_DECODE_PLMN)) != null)
+        || ((result = str.match(this.REGEXP_DECODE_IPV4)) != null)
+        || ((result = str.match(this.REGEXP_DECODE_IPV6)) != null)
+        || ((result = str.match(this.REGEXP_DECODE_CUSTOM)) != null)) {
       return {address: result[1], type: result[2]};
     }
 
     let type;
-    if (str.match(/^[\+*#]\d+$/)) {
+    if (str.match(this.REGEXP_NUM)) {
       type = "num";
-    } else if (str.match(/^\w+$/)) {
+    } else if (str.match(this.REGEXP_ALPHANUM)) {
       type = "alphanum";
+    } else if (str.indexOf("@") > 0) {
+      // E-mail should match the definition of `mailbox` as described in section
+      // 3.4 of RFC2822, but excluding the obsolete definitions as indicated by
+      // the "obs-" prefix. Here we match only a `@` character.
+      type = "email";
     } else {
-      type = "unknown";
+      throw new WSP.CodeError("Address: invalid address");
     }
 
     return {address: str, type: type};
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object of two string-typed attributes: address and type.
+   */
+  encode: function encode(data, value) {
+    if (!value || !value.type || !value.address) {
+      throw new WSP.CodeError("Address: invalid value");
+    }
+
+    let str;
+    switch (value.type) {
+      case "email":
+        if (value.address.indexOf("@") > 0) {
+          str = value.address;
+        }
+        break;
+      case "num":
+        if (value.address.match(this.REGEXP_NUM)) {
+          str = value.address;
+        }
+        break;
+      case "alphanum":
+        if (value.address.match(this.REGEXP_ALPHANUM)) {
+          str = value.address;
+        }
+        break;
+      case "IPv4":
+        if (value.address.match(this.REGEXP_ENCODE_IPV4)) {
+          str = value.address + "/TYPE=IPv4";
+        }
+        break;
+      case "IPv6":
+        if (value.address.match(this.REGEXP_ENCODE_IPV6)) {
+          str = value.address + "/TYPE=IPv6";
+        }
+        break;
+      case "PLMN":
+        if (value.address.match(this.REGEXP_ENCODE_PLMN)) {
+          str = value.address + "/TYPE=PLMN";
+        }
+        break;
+      default:
+        if (value.type.match(this.REGEXP_ENCODE_CUSTOM_TYPE)
+            && value.address.match(this.REGEXP_ENCODE_CUSTOM_ADDR)) {
+          str = value.address + "/TYPE=" + value.type;
+	}
+        break;
+    }
+
+    if (!str) {
+      throw new WSP.CodeError("Address: invalid value: " + JSON.stringify(value));
+    }
+
+    EncodedStringValue.encode(data, str);
+  },
 };
 
+defineLazyRegExp(Address, "REGEXP_DECODE_PLMN",        "^(\\+?[\\d.-]+)\\/TYPE=(PLMN)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_IPV4",        "^(\\d{1,3}(?:\\.\\d{1,3}){3})\\/TYPE=(IPv4)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_IPV6",        "^([\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7})\\/TYPE=(IPv6)$");
+defineLazyRegExp(Address, "REGEXP_DECODE_CUSTOM",      "^([\\w\\+\\-.%]+)\\/TYPE=(\\w+)$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_PLMN",        "^\\+?[\\d.-]+$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_IPV4",        "^\\d{1,3}(?:\\.\\d{1,3}){3}$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_IPV6",        "^[\\da-fA-F]{4}(?::[\\da-fA-F]{4}){7}$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_TYPE", "^\\w+$");
+defineLazyRegExp(Address, "REGEXP_ENCODE_CUSTOM_ADDR", "^[\\w\\+\\-.%]+$");
+defineLazyRegExp(Address, "REGEXP_NUM",                "^[\\+*#]\\d+$");
+defineLazyRegExp(Address, "REGEXP_ALPHANUM",           "^\\w+$");
+
 /**
  * Header-field = MMS-header | Application-header
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.2
  */
 let HeaderField = {
   /**
    * @param data
@@ -230,16 +312,30 @@ let ContentClassValue = {
   decode: function decode(data) {
     let value = WSP.Octet.decode(data);
     if ((value >= 128) && (value <= 135)) {
       return value;
     }
 
     throw new WSP.CodeError("Content-class-value: invalid class " + value);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        A numeric content class value to be encoded.
+   */
+  encode: function encode(data, value) {
+    if ((value < 128) || (value > 135)) {
+      throw new WSP.CodeError("Content-class-value: invalid class " + value);
+    }
+
+    WSP.Octet.encode(data, value);
+  },
 };
 
 /**
  * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
  *
  *   Content-location-value = Uri-value
  *
  * When used in the M-Mbox-Delete.conf and M-Delete.conf PDU:
@@ -396,16 +492,40 @@ let Parameter = {
           params = {};
         }
         params[param.name] = param.value;
       }
     }
 
     return params;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param param
+   *        An object containing two attributes: `name` and `value`.
+   * @param options
+   *        Extra context for encoding.
+   */
+  encode: function encode(data, param, options) {
+    if (!param || !param.name) {
+      throw new WSP.CodeError("Parameter-name: empty param name");
+    }
+
+    let entry = MMS_WELL_KNOWN_PARAMS[param.name.toLowerCase()];
+    if (entry) {
+      WSP.ShortInteger.encode(data, entry.number);
+    } else {
+      WSP.TextString.encode(data, param.name);
+    }
+
+    WSP.encodeAlternatives(data, param.value, options,
+                           WSP.ConstrainedEncoding, WSP.TextString);
+  },
 };
 
 /**
  * The Char-set values are registered by IANA as MIBEnum value and SHALL be
  * encoded as Integer-value.
  *
  *   Encoded-string-value = Text-string | Value-length Char-set Text-string
  *
@@ -479,16 +599,73 @@ let EncodedStringValue = {
     let begin = data.offset;
     try {
       return WSP.TextString.decode(data);
     } catch (e) {
       data.offset = begin;
       return this.decodeCharsetEncodedString(data);
     }
   },
+
+  /**
+   * Always encode target string with UTF-8 encoding.
+   *
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param str
+   *        A string.
+   */
+  encodeCharsetEncodedString: function encodeCharsetEncodedString(data, str) {
+    let conv = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+               .createInstance(Ci.nsIScriptableUnicodeConverter);
+    // `When the text string cannot be represented as us-ascii, the character
+    // set SHALL be encoded as utf-8(IANA MIBenum 106) which has unique byte
+    // ordering.` ~ OMA-TS-MMS_CONF-V1_3-20110913-A clause 10.2.1
+    conv.charset = "UTF-8";
+
+    let raw;
+    try {
+      raw = conv.convertToByteArray(str);
+    } catch (e) {
+      throw new WSP.CodeError("Charset-encoded-string: " + e.message);
+    }
+
+    let length = raw.length + 2; // Charset number and NUL character
+    // Prepend <Octet 127> if necessary.
+    if (raw[0] >= 128) {
+      ++length;
+    }
+
+    WSP.ValueLength.encode(data, length);
+
+    let entry = WSP.WSP_WELL_KNOWN_CHARSETS["utf-8"];
+    WSP.IntegerValue.encode(data, entry.number);
+
+    if (raw[0] >= 128) {
+      WSP.Octet.encode(data, 127);
+    }
+    WSP.Octet.encodeMultiple(data, raw);
+    WSP.Octet.encode(data, 0);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param str
+   *        A string.
+   */
+  encode: function encode(data, str) {
+    let begin = data.offset;
+    try {
+      WSP.TextString.encode(data, str);
+    } catch (e) {
+      data.offset = begin;
+      this.encodeCharsetEncodedString(data, str);
+    }
+  },
 };
 
 /**
  * Expiry-value = Value-length (Absolute-token Date-value | Relative-token Delta-seconds-value)
  * Absolute-token = <Octet 128>
  * Relative-token = <Octet 129>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.20
@@ -519,16 +696,49 @@ let ExpiryValue = {
     }
 
     if (data.offset != end) {
       data.offset = end;
     }
 
     return result;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        A Date object for absolute expiry or an integer for relative one.
+   */
+  encode: function encode(data, value) {
+    let isDate, begin = data.offset;
+    if (value instanceof Date) {
+      isDate = true;
+      WSP.DateValue.encode(data, value);
+    } else if (typeof value == "number") {
+      isDate = false;
+      WSP.DeltaSecondsValue.encode(data, value);
+    } else {
+      throw new CodeError("Expiry-value: invalid value type");
+    }
+
+    // Calculate how much octets will be written and seek back.
+    // TODO: use memmove, see bug 730873
+    let len = data.offset - begin;
+    data.offset = begin;
+
+    WSP.ValueLength.encode(data, len + 1);
+    if (isDate) {
+      WSP.Octet.encode(data, 128);
+      WSP.DateValue.encode(data, value);
+    } else {
+      WSP.Octet.encode(data, 129);
+      WSP.DeltaSecondsValue.encode(data, value);
+    }
+  },
 };
 
 /**
  * From-value = Value-length (Address-present-token Address | Insert-address-token)
  * Address-present-token = <Octet 128>
  * Insert-address-token = <Octet 129>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.21
@@ -558,16 +768,41 @@ let FromValue = {
     }
 
     if (data.offset != end) {
       data.offset = end;
     }
 
     return result;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        A Address-value or null for MMS Proxy-Relay Insert-Address mode.
+   */
+  encode: function encode(data, value) {
+    if (!value) {
+      WSP.ValueLength.encode(data, 1);
+      WSP.Octet.encode(data, 129);
+      return;
+    }
+
+    // Calculate how much octets will be written and seek back.
+    // TODO: use memmove, see bug 730873
+    let begin = data.offset;
+    Address.encode(data, value);
+    let len = data.offset - begin;
+    data.offset = begin;
+
+    WSP.ValueLength.encode(data, len + 1);
+    WSP.Octet.encode(data, 128);
+    Address.encode(data, value);
+  },
 };
 
 /**
  * Previously-sent-by-value = Value-length Forwarded-count-value Address
  * Forwarded-count-value = Integer-value
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.23
  */
@@ -631,31 +866,30 @@ let PreviouslySentDateValue = {
  * Personal = <Octet 128>
  * Advertisement = <Octet 129>
  * Informational = <Octet 130>
  * Auto = <Octet 131>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.27
  */
 let MessageClassValue = {
+  WELL_KNOWN_CLASSES: ["personal", "advertisement", "informational", "auto"],
+
   /**
    * @param data
    *        A wrapped object containing raw PDU data.
    *
    * @return A decoded string.
    *
    * @throws CodeError if decoded value is not in the range 128..131.
    */
   decodeClassIdentifier: function decodeClassIdentifier(data) {
     let value = WSP.Octet.decode(data);
-    switch (value) {
-      case 128: return "personal";
-      case 129: return "advertisement";
-      case 130: return "informational";
-      case 131: return "auto";
+    if ((value >= 128) && (value < (128 + this.WELL_KNOWN_CLASSES.length))) {
+      return this.WELL_KNOWN_CLASSES[value - 128];
     }
 
     throw new WSP.CodeError("Class-identifier: invalid id " + value);
   },
 
   /**
    * @param data
    *        A wrapped object containing raw PDU data.
@@ -666,16 +900,30 @@ let MessageClassValue = {
     let begin = data.offset;
     try {
       return this.decodeClassIdentifier(data);
     } catch (e) {
       data.offset = begin;
       return WSP.TokenText.decode(data);
     }
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param klass
+   */
+  encode: function encode(data, klass) {
+    let index = this.WELL_KNOWN_CLASSES.indexOf(klass.toLowerCase());
+    if (index >= 0) {
+      WSP.Octet.encode(data, index + 128);
+    } else {
+      WSP.TokenText.encode(data, klass);
+    }
+  },
 };
 
  /**
  * Message-type-value = <Octet 128..151>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.30
  */
 let MessageTypeValue = {
@@ -743,16 +991,40 @@ let MmFlagsValue = {
     result.text = EncodedStringValue.decode(data);
 
     if (data.offset != end) {
       data.offset = end;
     }
 
     return result;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object containing an integer `type` and an string-typed
+   *        `text` attributes.
+   */
+  encode: function encode(data, value) {
+    if ((value.type < 128) || (value.type > 130)) {
+      throw new WSP.CodeError("MM-flags-value: invalid type " + value.type);
+    }
+
+    // Calculate how much octets will be written and seek back.
+    // TODO: use memmove, see bug 730873
+    let begin = data.offset;
+    EncodedStringValue.encode(data, value.text);
+    let len = data.offset - begin;
+    data.offset = begin;
+
+    WSP.ValueLength.encode(data, len + 1);
+    WSP.Octet.encode(data, value.type);
+    EncodedStringValue.encode(data, value.text);
+  },
 };
 
 /**
  * MM-state-value = Draft | Sent | New | Retrieved | Forwarded
  * Draft = <Octet 128>
  * Sent = <Octet 129>
  * New = <Octet 130>
  * Retrieved = <Octet 131>
@@ -772,16 +1044,32 @@ let MmStateValue = {
   decode: function decode(data) {
     let state = WSP.Octet.decode(data);
     if ((state >= 128) && (state <= 132)) {
       return state;
     }
 
     throw new WSP.CodeError("MM-state-value: invalid state " + state);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param state
+   *        A numeric state value to be encoded.
+   *
+   * @throws CodeError if state is not in the range 128..132.
+   */
+  encode: function encode(data, state) {
+    if ((state < 128) || (state > 132)) {
+      throw new WSP.CodeError("MM-state-value: invalid state " + state);
+    }
+
+    WSP.Octet.encode(data, state);
+  },
 };
 
 /**
  * Priority-value = Low | Normal | High
  * Low = <Octet 128>
  * Normal = <Octet 129>
  * High = <Octet 130>
  *
@@ -799,16 +1087,30 @@ let PriorityValue = {
   decode: function decode(data) {
     let priority = WSP.Octet.decode(data);
     if ((priority >= 128) && (priority <= 130)) {
       return priority;
     }
 
     throw new WSP.CodeError("Priority-value: invalid priority " + priority);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param priority
+   *        A numeric priority value to be encoded.
+   */
+  encode: function encode(data, priority) {
+    if ((priority < 128) || (priority > 130)) {
+      throw new WSP.CodeError("Priority-value: invalid priority " + priority);
+    }
+
+    WSP.Octet.encode(data, priority);
+  },
 };
 
 /**
  * Recommended-Retrieval-Mode-value = Manual
  * Manual = <Octet 128>
  *
  * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.39
  */
@@ -846,16 +1148,74 @@ let ReplyChargingValue = {
   decode: function decode(data) {
     let value = WSP.Octet.decode(data);
     if ((value >= 128) && (value <= 131)) {
       return value;
     }
 
     throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer value within thr range 128..131.
+   */
+  encode: function encode(data, value) {
+    if ((value < 128) || (value > 131)) {
+      throw new WSP.CodeError("Reply-charging-value: invalid value " + value);
+    }
+
+    WSP.Octet.encode(data, value);
+  },
+};
+
+/**
+ * When used in a PDU other than M-Mbox-Delete.conf and M-Delete.conf:
+ *
+ *   Response-text-value = Encoded-string-value
+ *
+ * When used in the M-Mbox-Delete.conf and M-Delete.conf PDUs:
+ *
+ *   Response-text-Del-value = Value-length Status-count-value Response-text-value
+ *
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.49
+ */
+let ResponseText = {
+  /**
+   * @param data
+   *        A wrapped object containing raw PDU data.
+   * @param options
+   *        Extra context for decoding.
+   *
+   * @return An object containing a string-typed `text` attribute and a
+   *         integer-typed `statusCount` one.
+   */
+  decode: function decode(data, options) {
+    let type = WSP.ensureHeader(options, "x-mms-message-type");
+
+    let result = {};
+    if ((type == MMS_PDU_TYPE_MBOX_DELETE_CONF)
+        || (type == MMS_PDU_TYPE_DELETE_CONF)) {
+      let length = WSP.ValueLength.decode(data);
+      let end = data.offset + length;
+
+      result.statusCount = WSP.IntegerValue.decode(data);
+      result.text = EncodedStringValue.decode(data);
+
+      if (data.offset != end) {
+        data.offset = end;
+      }
+    } else {
+      result.text = EncodedStringValue.decode(data);
+    }
+
+    return result;
+  },
 };
 
 /**
  * Retrieve-status-value = Ok | Error-transient-failure |
  *                         Error-transient-message-not-found |
  *                         Error-transient-network-problem |
  *                         Error-permanent-failure |
  *                         Error-permanent-service-denied |
@@ -1068,82 +1428,81 @@ let PduHelper = {
       debug("Failed to parse MMS message, error message: " + e.message);
       return null;
     }
 
     return msg;
   },
 
   /**
-   * Convert javascript Array to an nsIInputStream.
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param headers
+   *        A dictionary object containing multiple name/value mapping.
+   * @param name
+   *        Name of the header field to be encoded.
    */
-  convertArrayToInputStream: function convertDataToInputStream(array) {
-    let storageStream = Cc["@mozilla.org/storagestream;1"]
-                        .createInstance(Ci.nsIStorageStream);
-    storageStream.init(4096, array.length, null);
+  encodeHeader: function encodeHeader(data, headers, name) {
+    let value = headers[name];
+    if (Array.isArray(value)) {
+      for (let i = 0; i < value.length; i++) {
+        HeaderField.encode(data, {name: name, value: value[i]}, headers);
+      }
+    } else {
+      HeaderField.encode(data, {name: name, value: value}, headers);
+    }
+  },
 
-    let boStream = Cc["@mozilla.org/binaryoutputstream;1"]
-                   .createInstance(Ci.nsIBinaryOutputStream);
-    boStream.setOutputStream(storageStream.getOutputStream(0));
-    boStream.writeByteArray(array, array.length)
-    boStream.close();
-
-    return storageStream.newInputStream(0);
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param headers
+   *        A dictionary object containing multiple name/value mapping.
+   */
+  encodeHeaderIfExists: function encodeHeaderIfExists(data, headers, name) {
+    // Header value could be zero or null.
+    if (headers[name] !== undefined) {
+      this.encodeHeader(data, headers, name);
+    }
   },
 
   /**
    * @param data [optional]
    *        A wrapped object to store encoded raw data. Created if undefined.
    * @param headers
    *        A dictionary object containing multiple name/value mapping.
    *
    * @return the passed data parameter or a created one.
    */
   encodeHeaders: function encodeHeaders(data, headers) {
     if (!data) {
       data = {array: [], offset: 0};
     }
 
-    function encodeHeader(name) {
-      HeaderField.encode(data, {name: name, value: headers[name]});
-    }
-
-    function encodeHeaderIfExists(name) {
-      // Header value could be zero or null.
-      if (headers[name] !== undefined) {
-        encodeHeader(name);
-      }
-    }
-
     // `In the encoding of the header fields, the order of the fields is not
     // significant, except that X-Mms-Message-Type, X-Mms-Transaction-ID (when
     // present) and X-Mms-MMS-Version MUST be at the beginning of the message
     // headers, in that order, and if the PDU contains a message body the
     // Content Type MUST be the last header field, followed by message body.`
     // ~ OMA-TS-MMS_ENC-V1_3-20110913-A section 7
-    encodeHeader("x-mms-message-type");
-    encodeHeaderIfExists("x-mms-transaction-id");
-    encodeHeaderIfExists("x-mms-mms-version");
+    this.encodeHeader(data, headers, "x-mms-message-type");
+    this.encodeHeaderIfExists(data, headers, "x-mms-transaction-id");
+    this.encodeHeaderIfExists(data, headers, "x-mms-mms-version");
 
     for (let key in headers) {
       if ((key == "x-mms-message-type")
           || (key == "x-mms-transaction-id")
           || (key == "x-mms-mms-version")
           || (key == "content-type")) {
         continue;
       }
-      encodeHeader(key);
+      this.encodeHeader(data, headers, key);
     }
 
-    encodeHeaderIfExists("content-type");
-
-    // Remove extra space consumed during encoding.
-    while (data.array.length > data.offset) {
-      data.array.pop();
-    }
+    this.encodeHeaderIfExists(data, headers, "content-type");
 
     return data;
   },
 
   /**
    * @param multiStream
    *        An exsiting nsIMultiplexInputStream.
    * @param msg
@@ -1158,18 +1517,25 @@ let PduHelper = {
     }
 
     try {
       // Validity checks
       let typeinfo = this.checkMandatoryFields(msg);
 
       let data = this.encodeHeaders(null, msg.headers);
       debug("Composed PDU Header: " + JSON.stringify(data.array));
-      let headerStream = this.convertArrayToInputStream(data.array);
-      multiStream.appendStream(headerStream);
+      WSP.PduHelper.appendArrayToMultiStream(multiStream, data.array, data.offset);
+
+      if (msg.content) {
+        WSP.PduHelper.appendArrayToMultiStream(multiStream, msg.content, msg.content.length);
+      } else if (msg.parts) {
+        WSP.PduHelper.composeMultiPart(multiStream, msg.parts);
+      } else if (typeinfo.hasContent) {
+        throw new WSP.CodeError("Missing message content");
+      }
 
       return multiStream;
     } catch (e) {
       debug("Failed to compose MMS message, error message: " + e.message);
       return null;
     }
   },
 };
@@ -1179,39 +1545,54 @@ const MMS_PDU_TYPES = (function () {
   function add(number, hasContent, mandatoryFields) {
     pdus[number] = {
       number: number,
       hasContent: hasContent,
       mandatoryFields: mandatoryFields,
     };
   }
 
+  add(MMS_PDU_TYPE_SEND_REQ, true, ["x-mms-message-type",
+                                    "x-mms-transaction-id",
+                                    "x-mms-mms-version",
+                                    "from",
+                                    "content-type"]);
+  add(MMS_PDU_TYPE_SEND_CONF, false, ["x-mms-message-type",
+                                      "x-mms-transaction-id",
+                                      "x-mms-mms-version",
+                                      "x-mms-response-status"]);
   add(MMS_PDU_TYPE_NOTIFICATION_IND, false, ["x-mms-message-type",
                                              "x-mms-transaction-id",
                                              "x-mms-mms-version",
                                              "x-mms-message-class",
                                              "x-mms-message-size",
                                              "x-mms-expiry",
                                              "x-mms-content-location"]);
   add(MMS_PDU_TYPE_RETRIEVE_CONF, true, ["x-mms-message-type",
                                          "x-mms-mms-version",
                                          "date",
                                          "content-type"]);
   add(MMS_PDU_TYPE_NOTIFYRESP_IND, false, ["x-mms-message-type",
                                            "x-mms-transaction-id",
                                            "x-mms-mms-version",
                                            "x-mms-status"]);
+  add(MMS_PDU_TYPE_DELIVERY_IND, false, ["x-mms-message-type",
+                                         "x-mms-mms-version",
+                                         "message-id",
+                                         "to",
+                                         "date",
+                                         "x-mms-status"]);
 
   return pdus;
 })();
 
 /**
  * Header field names and assigned numbers.
  *
- * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.4
+ * @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.4
  */
 const MMS_HEADER_FIELDS = (function () {
   let names = {};
   function add(name, number, coder) {
     let entry = {
       name: name,
       number: number,
       coder: coder,
@@ -1220,48 +1601,48 @@ const MMS_HEADER_FIELDS = (function () {
   }
 
   add("bcc",                                     0x01, Address);
   add("cc",                                      0x02, Address);
   add("x-mms-content-location",                  0x03, ContentLocationValue);
   add("content-type",                            0x04, WSP.ContentTypeValue);
   add("date",                                    0x05, WSP.DateValue);
   add("x-mms-delivery-report",                   0x06, BooleanValue);
-  //add("x-mms-delivery-time", 0x07);
+  add("x-mms-delivery-time",                     0x07, ExpiryValue);
   add("x-mms-expiry",                            0x08, ExpiryValue);
   add("from",                                    0x09, FromValue);
   add("x-mms-message-class",                     0x0A, MessageClassValue);
   add("message-id",                              0x0B, WSP.TextString);
   add("x-mms-message-type",                      0x0C, MessageTypeValue);
   add("x-mms-mms-version",                       0x0D, WSP.ShortInteger);
   add("x-mms-message-size",                      0x0E, WSP.LongInteger);
   add("x-mms-priority",                          0x0F, PriorityValue);
   add("x-mms-read-report",                       0x10, BooleanValue);
   add("x-mms-report-allowed",                    0x11, BooleanValue);
-  //add("x-mms-response-status", 0x12);
-  //add("x-mms-response-text", 0x13);
-  //add("x-mms-sender-visibility", 0x14);
+  add("x-mms-response-status",                   0x12, RetrieveStatusValue);
+  add("x-mms-response-text",                     0x13, ResponseText);
+  add("x-mms-sender-visibility",                 0x14, BooleanValue);
   add("x-mms-status",                            0x15, StatusValue);
   add("subject",                                 0x16, EncodedStringValue);
   add("to",                                      0x17, Address);
   add("x-mms-transaction-id",                    0x18, WSP.TextString);
   add("x-mms-retrieve-status",                   0x19, RetrieveStatusValue);
   add("x-mms-retrieve-text",                     0x1A, EncodedStringValue);
   //add("x-mms-read-status", 0x1B);
   add("x-mms-reply-charging",                    0x1C, ReplyChargingValue);
   add("x-mms-reply-charging-deadline",           0x1D, ExpiryValue);
   add("x-mms-reply-charging-id",                 0x1E, WSP.TextString);
   add("x-mms-reply-charging-size",               0x1F, WSP.LongInteger);
   add("x-mms-previously-sent-by",                0x20, PreviouslySentByValue);
   add("x-mms-previously-sent-date",              0x21, PreviouslySentDateValue);
   add("x-mms-store",                             0x22, BooleanValue);
   add("x-mms-mm-state",                          0x23, MmStateValue);
   add("x-mms-mm-flags",                          0x24, MmFlagsValue);
-  //add("x-mms-store-status", 0x25);
-  //add("x-mms-store-status-text", 0x26);
+  add("x-mms-store-status",                      0x25, RetrieveStatusValue);
+  add("x-mms-store-status-text",                 0x26, EncodedStringValue);
   add("x-mms-stored",                            0x27, BooleanValue);
   //add("x-mms-attributes", 0x28);
   add("x-mms-totals",                            0x29, BooleanValue);
   //add("x-mms-mbox-totals", 0x2A);
   add("x-mms-quotas",                            0x2B, BooleanValue);
   //add("x-mms-mbox-quotas", 0x2C);
   add("x-mms-message-count",                     0x2D, WSP.IntegerValue);
   //add("content", 0x2E);
@@ -1294,16 +1675,17 @@ const MMS_WELL_KNOWN_PARAMS = (function 
     let entry = {
       name: name,
       number: number,
       coder: coder,
     };
     params[name] = params[number] = entry;
   }
 
+  // Encoding Version: 1.2
   add("type", 0x02, WSP.TypeValue);
 
   return params;
 })();
 
 let debug;
 if (DEBUG) {
   debug = function (s) {
@@ -1333,15 +1715,16 @@ const EXPORTED_SYMBOLS = ALL_CONST_SYMBO
   "PreviouslySentDateValue",
   "MessageClassValue",
   "MessageTypeValue",
   "MmFlagsValue",
   "MmStateValue",
   "PriorityValue",
   "RecommendedRetrievalModeValue",
   "ReplyChargingValue",
+  "ResponseText",
   "RetrieveStatusValue",
   "StatusValue",
 
   // Parser
   "PduHelper",
 ]);
 
--- a/dom/mms/src/ril/MmsService.js
+++ b/dom/mms/src/ril/MmsService.js
@@ -36,16 +36,20 @@ const CONFIG_SEND_REPORT_NEVER       = 0
 const CONFIG_SEND_REPORT_DEFAULT_NO  = 1;
 const CONFIG_SEND_REPORT_DEFAULT_YES = 2;
 const CONFIG_SEND_REPORT_ALWAYS      = 3;
 
 XPCOMUtils.defineLazyServiceGetter(this, "gpps",
                                    "@mozilla.org/network/protocol-proxy-service;1",
                                    "nsIProtocolProxyService");
 
+XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
+                                   "@mozilla.org/uuid-generator;1",
+                                   "nsIUUIDGenerator");
+
 XPCOMUtils.defineLazyGetter(this, "MMS", function () {
   let MMS = {};
   Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
   return MMS;
 });
 
 /**
  * MmsService
@@ -223,16 +227,94 @@ MmsService.prototype = {
     // Optional fields
     headers["x-mms-report-allowed"] = ra;
 
     let istream = MMS.PduHelper.compose(null, {headers: headers});
     this.sendMmsRequest("POST", this.MMSC, istream);
   },
 
   /**
+   * Send M-Send.req to MMSC
+   */
+  sendSendRequest: function sendSendRequest(msg, callback) {
+    msg.headers["x-mms-message-type"] = MMS.MMS_PDU_TYPE_SEND_REQ;
+    if (!msg.headers["x-mms-transaction-id"]) {
+      // Create an unique transaction id
+      let tid = gUUIDGenerator.generateUUID().toString();
+      msg.headers["x-mms-transaction-id"] = tid;
+    }
+    msg.headers["x-mms-mms-version"] = MMS.MMS_VERSION;
+
+    // Let MMS Proxy Relay insert from address automatically for us
+    msg.headers["from"] = null;
+
+    msg.headers["date"] = new Date();
+    msg.headers["x-mms-message-class"] = "personal";
+    msg.headers["x-mms-expiry"] = 7 * 24 * 60 * 60;
+    msg.headers["x-mms-priority"] = 129;
+    msg.headers["x-mms-read-report"] = true;
+    msg.headers["x-mms-delivery-report"] = true;
+
+    let messageSize = 0;
+
+    if (msg.content) {
+      messageSize = msg.content.length;
+    } else if (msg.parts) {
+      for (let i = 0; i < msg.parts.length; i++) {
+        messageSize += msg.parts[i].content.length;
+      }
+
+      let contentType = {
+        params: {
+          // `The type parameter must be specified and its value is the MIME
+          // media type of the "root" body part.` ~ RFC 2387 clause 3.1
+          type: msg.parts[0].headers["content-type"].media,
+        },
+      };
+
+      // `The Content-Type in M-Send.req and M-Retrieve.conf SHALL be
+      // application/vnd.wap.multipart.mixed when there is no presentation, and
+      // application/vnd.wap.multipart.related SHALL be used when there is SMIL
+      // presentation available.` ~ OMA-TS-MMS_CONF-V1_3-20110913-A clause 10.2.1
+      if (contentType.params.type === "application/smil") {
+        contentType.media = "application/vnd.wap.multipart.related";
+
+        // `The start parameter, if given, is the content-ID of the compound
+        // object's "root".` ~ RFC 2387 clause 3.2
+        contentType.params.start = msg.parts[0].headers["content-id"];
+      } else {
+        contentType.media = "application/vnd.wap.multipart.mixed";
+      }
+
+      // Assign to Content-Type
+      msg.headers["content-type"] = contentType;
+    }
+
+    // Assign to X-Mms-Message-Size
+    msg.headers["x-mms-message-size"] = messageSize;
+
+    debug("msg: " + JSON.stringify(msg));
+
+    let istream = MMS.PduHelper.compose(null, msg);
+    if (!istream) {
+      debug("sendSendRequest: failed to compose M-Send.ind PDU");
+      callback(MMS.MMS_PDU_ERROR_PERMANENT_FAILURE, null);
+      return;
+    }
+
+    this.sendMmsRequest("POST", this.MMSC, istream, (function (status, data) {
+      if (!data) {
+        callback(MMS.MMS_PDU_ERROR_PERMANENT_FAILURE, null);
+      } else if (!this.parseStreamAndDispatch(data, {msg: msg, callback: callback})) {
+        callback(MMS.MMS_PDU_RESPONSE_ERROR_UNSUPPORTED_MESSAGE, null);
+      }
+    }).bind(this));
+  },
+
+  /**
    * @param file
    *        A nsIFile object indicating where to save the data.
    * @param data
    *        An array of raw octets.
    * @param callback
    *        Callback function when I/O is done.
    *
    * @return An nsIRequest representing the copy operation returned by
@@ -312,31 +394,65 @@ MmsService.prototype = {
   parseStreamAndDispatch: function parseStreamAndDispatch(data, options) {
     let msg = MMS.PduHelper.parse(data, null);
     if (!msg) {
       return false;
     }
     debug("parseStreamAndDispatch: msg = " + JSON.stringify(msg));
 
     switch (msg.type) {
+      case MMS.MMS_PDU_TYPE_SEND_CONF:
+        this.handleSendConfirmation(msg, options);
+        break;
       case MMS.MMS_PDU_TYPE_NOTIFICATION_IND:
         this.handleNotificationIndication(msg, options);
         break;
       case MMS.MMS_PDU_TYPE_RETRIEVE_CONF:
         this.handleRetrieveConfirmation(msg, options);
         break;
+      case MMS.MMS_PDU_TYPE_DELIVERY_IND:
+        this.handleDeliveryIndication(msg, options);
+        break;
       default:
         debug("Unsupported X-MMS-Message-Type: " + msg.type);
         return false;
     }
 
     return true;
   },
 
   /**
+   * Handle incoming M-Send.conf PDU.
+   *
+   * @param msg
+   *        The M-Send.conf message object.
+   */
+  handleSendConfirmation: function handleSendConfirmation(msg, options) {
+    let status = msg.headers["x-mms-response-status"];
+    if (status == null) {
+      return;
+    }
+
+    if (status == MMS.MMS_PDU_ERROR_OK) {
+      // `This ID SHALL always be present after the MMS Proxy-Relay accepted
+      // the corresponding M-Send.req PDU. The ID enables a MMS Client to match
+      // delivery reports or read-report PDUs with previously sent MM.`
+      let messageId = msg.headers["message-id"];
+      options.msg.headers["message-id"] = messageId;
+    } else if ((status >= MMS.MMS_PDU_ERROR_TRANSIENT_FAILURE)
+               && (status < MMS.MMS_PDU_ERROR_PERMANENT_FAILURE)) {
+      return;
+    }
+
+    if (options.callback) {
+      options.callback(status, msg);
+    }
+  },
+
+  /**
    * Handle incoming M-Notification.ind PDU.
    *
    * @param msg
    *        The MMS message object.
    */
   handleNotificationIndication: function handleNotificationIndication(msg) {
     function callback(status, retr) {
       let tid = msg.headers["x-mms-transaction-id"];
@@ -392,16 +508,24 @@ MmsService.prototype = {
       callbackIfValid(status, msg);
       return;
     }
 
     this.saveMessageContent(msg, callbackIfValid.bind(null, MMS.MMS_PDU_ERROR_OK));
   },
 
   /**
+   * Handle incoming M-Delivery.ind PDU.
+   */
+  handleDeliveryIndication: function handleDeliveryIndication(msg) {
+    let messageId = msg.headers["message-id"];
+    debug("handleDeliveryIndication: got delivery report for " + messageId);
+  },
+
+  /**
    * Update proxyInfo & MMSC from preferences.
    *
    * @param enabled
    *        Enable or disable MMS proxy.
    */
   updateProxyInfo: function updateProxyInfo(enabled) {
     try {
       if (enabled) {
--- a/dom/mms/src/ril/WspPduHelper.jsm
+++ b/dom/mms/src/ril/WspPduHelper.jsm
@@ -284,16 +284,28 @@ let Octet = {
   encode: function encode(data, octet) {
     if (data.offset >= data.array.length) {
       data.array.push(octet);
       data.offset++;
     } else {
       data.array[data.offset++] = octet;
     }
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param octet
+   *        An octet array object.
+   */
+  encodeMultiple: function encodeMultiple(data, array) {
+    for (let i = 0; i < array.length; i++) {
+      this.encode(data, array[i]);
+    }
+  },
 };
 
 /**
  * TEXT = <any OCTET except CTLs, but including LWS>
  * CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
  * LWS = [CRLF] 1*(SP|HT)
  * CRLF = CR LF
  * CR = <US-ASCII CR, carriage return (13)>
@@ -654,16 +666,27 @@ let QuotedString = {
   decode: function decode(data) {
     let value = Octet.decode(data);
     if (value != 34) {
       throw new CodeError("Quoted-string: not quote " + value);
     }
 
     return NullTerminatedTexts.decode(data);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param str
+   *        A String to be encoded.
+   */
+  encode: function encode(data, str) {
+    Octet.encode(data, 34);
+    NullTerminatedTexts.encode(data, str);
+  },
 };
 
 /**
  * Integers in range 0-127 shall be encoded as a one octet value with the
  * most significant bit set to one (1xxx xxxx) and with the value in the
  * remaining least significant bits.
  *
  *   Short-integer = OCTET
@@ -752,16 +775,52 @@ let LongInteger = {
   decode: function decode(data) {
     let length = Octet.decode(data);
     if ((length < 1) || (length > 30)) {
       throw new CodeError("Long-integer: invalid length " + length);
     }
 
     return this.decodeMultiOctetInteger(data, length);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param numOrArray
+   *        An octet array of less-equal than 30 elements or an integer
+   *        greater-equal than 128.
+   */
+  encode: function encode(data, numOrArray) {
+    if (typeof numOrArray === "number") {
+      let num = numOrArray;
+      if (num >= 0x1000000000000) {
+        throw new CodeError("Long-integer: number too large " + num);
+      }
+
+      let stack = [];
+      do {
+        stack.push(Math.floor(num % 256));
+        num = Math.floor(num / 256);
+      } while (num);
+
+      Octet.encode(data, stack.length);
+      while (stack.length) {
+        Octet.encode(data, stack.pop());
+      }
+      return;
+    }
+
+    let array = numOrArray;
+    if ((array.length < 1) || (array.length > 30)) {
+      throw new CodeError("Long-integer: invalid length " + array.length);
+    }
+
+    Octet.encode(data, array.length);
+    Octet.encodeMultiple(data, array);
+  },
 };
 
 /**
  * @see WAP-230-WSP-20010705-a clause 8.4.2.1
  */
 let UintVar = {
   /**
    * @param data
@@ -774,16 +833,40 @@ let UintVar = {
     let result = value & 0x7F;
     while (value & 0x80) {
       value = Octet.decode(data);
       result = result * 128 + (value & 0x7F);
     }
 
     return result;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer value.
+   */
+  encode: function encode(data, value) {
+    if (value < 0) {
+      throw new CodeError("UintVar: invalid value " + value);
+    }
+
+    let stack = [];
+    while (value >= 128) {
+      stack.push(Math.floor(value % 128));
+      value = Math.floor(value / 128);
+    }
+
+    while (stack.length) {
+      Octet.encode(data, value | 0x80);
+      value = stack.pop();
+    }
+    Octet.encode(data, value);
+  },
 };
 
 /**
  * This encoding is used for token values, which have no well-known binary
  * encoding, or when the assigned number of the well-known encoding is small
  * enough to fit into Short-Integer.
  *
  *   Constrained-encoding = Extension-Media | Short-integer
@@ -796,16 +879,30 @@ let ConstrainedEncoding = {
    * @param data
    *        A wrapped object containing raw PDU data.
    *
    * @return Decode integer value or string.
    */
   decode: function decode(data) {
     return decodeAlternatives(data, null, NullTerminatedTexts, ShortInteger);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer or a string value.
+   */
+  encode: function encode(data, value) {
+    if (typeof value == "number") {
+      ShortInteger.encode(data, value);
+    } else {
+      NullTerminatedTexts.encode(data, value);
+    }
+  },
 };
 
 /**
  * Value-length = Short-length | (Length-quote Length)
  * Short-length = <Any octet 0-30>
  * Length-quote = <Octet 31>
  * Length = Uintvar-integer
  *
@@ -827,16 +924,30 @@ let ValueLength = {
     }
 
     if (value == 31) {
       return UintVar.decode(data);
     }
 
     throw new CodeError("Value-length: invalid value " + value);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   */
+  encode: function encode(data, value) {
+    if (value <= 30) {
+      Octet.encode(data, value);
+    } else {
+      Octet.encode(data, 31);
+      UintVar.encode(data, value);
+    }
+  },
 };
 
 /**
  * No-value = <Octet 0>
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.3
  */
 let NoValue = {
@@ -845,16 +956,29 @@ let NoValue = {
    *        A wrapped object containing raw PDU data.
    *
    * @return Always returns null.
    */
   decode: function decode(data) {
     Octet.decodeEqualTo(data, 0);
     return null;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        A null or undefined value.
+   */
+  encode: function encode(data, value) {
+    if (value != null) {
+      throw new CodeError("No-value: invalid value " + value);
+    }
+    Octet.encode(data, 0);
+  },
 };
 
 /**
  * Text-value = No-value | Token-text | Quoted-string
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.3
  */
 let TextValue = {
@@ -862,16 +986,26 @@ let TextValue = {
    * @param data
    *        A wrapped object containing raw PDU data.
    *
    * @return Decoded string or null for No-value.
    */
   decode: function decode(data) {
     return decodeAlternatives(data, null, NoValue, TokenText, QuotedString);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param text
+   *        A null or undefined or text string.
+   */
+  encode: function encode(data, text) {
+    encodeAlternatives(data, text, null, NoValue, TokenText, QuotedString);
+  },
 };
 
 /**
  * Integer-Value = Short-integer | Long-integer
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.3
  */
 let IntegerValue = {
@@ -879,16 +1013,32 @@ let IntegerValue = {
    * @param data
    *        A wrapped object containing raw PDU data.
    *
    * @return Decoded integer value or array of octets.
    */
   decode: function decode(data) {
     return decodeAlternatives(data, null, ShortInteger, LongInteger);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer value or an octet array of less-equal than 31 elements.
+   */
+  encode: function encode(data, value) {
+    if (typeof value === "number") {
+      encodeAlternatives(data, value, null, ShortInteger, LongInteger);
+    } else if (Array.isArray(value) || (value instanceof Uint8Array)) {
+      LongInteger.encode(data, value);
+    } else {
+      throw new CodeError("Integer-Value: invalid value type");
+    }
+  },
 };
 
 /**
  * The encoding of dates shall be done in number of seconds from
  * 1970-01-01, 00:00:00 GMT.
  *
  *   Date-value = Long-integer
  *
@@ -910,16 +1060,31 @@ let DateValue = {
       seconds = 0;
       for (let i = 0; i < numOrArray.length; i++) {
         seconds = seconds * 256 + numOrArray[i];
       }
     }
 
     return new Date(seconds * 1000);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param date
+   *        A Date object.
+   */
+  encode: function encode(data, date) {
+    let seconds = date.getTime() / 1000;
+    if (seconds < 0) {
+      throw new CodeError("Date-value: negative seconds " + seconds);
+    }
+
+    LongInteger.encode(data, seconds);
+  },
 };
 
 /**
  * Delta-seconds-value = Integer-value
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.3
  */
 let DeltaSecondsValue = IntegerValue;
@@ -949,16 +1114,37 @@ let QValue = {
       }
       if (value <= 1099) {
         return (value - 100) / 1000.0;
       }
     }
 
     throw new CodeError("Q-value: invalid value " + value);
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An integer within the range 1..1099.
+   */
+  encode: function encode(data, value) {
+    if ((value < 0) || (value >= 1)) {
+      throw new CodeError("Q-value: invalid value " + value);
+    }
+
+    value *= 1000;
+    if ((value % 10) == 0) {
+      // Two digits only.
+      UintVar.encode(data, Math.floor(value / 10 + 1));
+    } else {
+      // Three digits.
+      UintVar.encode(data, Math.floor(value + 100));
+    }
+  },
 };
 
 /**
  * The three most significant bits of the Short-integer value are interpreted
  * to encode a major version number in the range 1-7, and the four least
  * significant bits contain a minor version number in the range 0-14. If
  * there is only a major version number, this is encoded by placing the value
  * 15 in the four least significant bits.
@@ -1002,16 +1188,30 @@ let VersionValue = {
         if (minor > 14) {
           throw new CodeError("Version-value: invalid minor " + minor);
         }
       }
     }
 
     return major << 4 | minor;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param version
+   *        A binary encoded version number.
+   */
+  encode: function encode(data, version) {
+    if ((version < 0x10) || (version >= 0x80)) {
+      throw new CodeError("Version-value: invalid version " + version);
+    }
+
+    ShortInteger.encode(data, version);
+  },
 };
 
 /**
  * URI value should be encoded per [RFC2616], but service user may use a
  * different format.
  *
  *   Uri-value = Text-string
  *
@@ -1062,16 +1262,31 @@ let TypeValue = {
     let entry = WSP_WELL_KNOWN_CONTENT_TYPES[number];
     if (!entry) {
       throw new NotWellKnownEncodingError(
         "Constrained-media: not well known media " + number);
     }
 
     return entry.type;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param type
+   *        A content type string.
+   */
+  encode: function encode(data, type) {
+    let entry = WSP_WELL_KNOWN_CONTENT_TYPES[type.toLowerCase()];
+    if (entry) {
+      ShortInteger.encode(data, entry.number);
+    } else {
+      NullTerminatedTexts.encode(data, type);
+    }
+  },
 };
 
 /**
  * Parameter = Typed-parameter | Untyped-parameter
  *
  * For Typed-parameters, the actual expected type of the value is implied by
  * the well-known parameter. In addition to the expected type, there may be no
  * value. If the value cannot be encoded using expected type, it shall be
@@ -1215,16 +1430,73 @@ let Parameter = {
           params = {};
         }
         params[param.name] = param.value;
       }
     }
 
     return params;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param param
+   *        An object containing `name` and `value` properties.
+   */
+  encodeTypedParameter: function decodeTypedParameter(data, param) {
+    let entry = WSP_WELL_KNOWN_PARAMS[param.name.toLowerCase()];
+    if (!entry) {
+      throw new NotWellKnownEncodingError(
+        "Typed-parameter: not well known parameter " + param.name);
+    }
+
+    IntegerValue.encode(data, entry.number);
+    encodeAlternatives(data, param.value, null,
+                       entry.coder, TextValue, TextString);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param param
+   *        An object containing `name` and `value` properties.
+   */
+  encodeUntypedParameter: function encodeUntypedParameter(data, param) {
+    TokenText.encode(data, param.name);
+    encodeAlternatives(data, param.value, null, IntegerValue, TextValue);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param param
+   *        An array of parameter objects.
+   */
+  encodeMultiple: function encodeMultiple(data, params) {
+    for (let name in params) {
+      this.encode(data, {name: name, value: params[name]});
+    }
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param param
+   *        An object containing `name` and `value` properties.
+   */
+  encode: function encode(data, param) {
+    let begin = data.offset;
+    try {
+      this.encodeTypedParameter(data, param);
+    } catch (e) {
+      data.offset = begin;
+      this.encodeUntypedParameter(data, param);
+    }
+  },
 };
 
 /**
  * Header = Message-header | Shift-sequence
  * Message-header = Well-known-header | Application-header
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.6
  */
@@ -1250,16 +1522,32 @@ let Header = {
    *         in case of a failed parsing. The `name` property must be a string,
    *         but the `value` property can be many different types depending on
    *         `name`.
    */
   decode: function decode(data) {
     // TODO: support header code page shift-sequence
     return this.decodeMessageHeader(data);
   },
+
+  encodeMessageHeader: function encodeMessageHeader(data, header) {
+    encodeAlternatives(data, header, null, WellKnownHeader, ApplicationHeader);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param header
+   *        An object containing two attributes: a string-typed `name` and a
+   *        `value` of arbitrary type.
+   */
+  encode: function encode(data, header) {
+    // TODO: support header code page shift-sequence
+    this.encodeMessageHeader(data, header);
+  },
 };
 
 /**
  * Well-known-header = Well-known-field-name Wap-value
  * Well-known-field-name = Short-integer
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.6
  */
@@ -1298,16 +1586,34 @@ let WellKnownHeader = {
       return null;
     }
 
     return {
       name: entry.name,
       value: value,
     };
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param header
+   *        An object containing two attributes: a string-typed `name` and a
+   *        `value` of arbitrary type.
+   */
+  encode: function encode(data, header) {
+    let entry = WSP_HEADER_FIELDS[header.name.toLowerCase()];
+    if (!entry) {
+      throw new NotWellKnownEncodingError(
+        "Well-known-header: not well known header " + header.name);
+    }
+
+    ShortInteger.encode(data, entry.number);
+    encodeAlternatives(data, header.value, null, entry.coder, TextValue);
+  },
 };
 
 /**
  * Application-header = Token-text Application-specific-value
  * Application-specific-value = Text-string
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.6
  */
@@ -1390,16 +1696,31 @@ let FieldName = {
     let entry = WSP_HEADER_FIELDS[number];
     if (!entry) {
       throw new NotWellKnownEncodingError(
         "Field-name: not well known encoding " + number);
     }
 
     return entry.name;
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param name
+   *        A field name string.
+   */
+  encode: function encode(data, name) {
+    let entry = WSP_HEADER_FIELDS[name.toLowerCase()];
+    if (entry) {
+      ShortInteger.encode(data, entry.number);
+    } else {
+      TokenText.encode(data, name);
+    }
+  },
 };
 
 /**
  * Accept-charset-value = Constrained-charset | Accept-charset-general-form
  * Constrained-charset = Any-charset | Constrained-encoding
  * Any-charset = <Octet 128>
  * Accept-charset-general-form = Value-length (Well-known-charset | Token-text) [Q-value]
  *
@@ -1493,16 +1814,31 @@ let AcceptCharsetValue = {
     let begin = data.offset;
     try {
       return this.decodeConstrainedCharset(data);
     } catch (e) {
       data.offset = begin;
       return this.decodeAcceptCharsetGeneralForm(data);
     }
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object with a string property `charset`.
+   */
+  encodeAnyCharset: function encodeAnyCharset(data, value) {
+    if (!value || !value.charset || (value.charset === "*")) {
+      Octet.encode(data, 128);
+      return;
+    }
+
+    throw new CodeError("Any-charset: invalid value " + value);
+  },
 };
 
 /**
  * Well-known-charset = Any-charset | Integer-value
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.8
  */
 let WellKnownCharset = {
@@ -1535,16 +1871,38 @@ let WellKnownCharset = {
     let entry = WSP_WELL_KNOWN_CHARSETS[charset];
     if (!entry) {
       throw new NotWellKnownEncodingError(
         "Well-known-charset: not well known charset " + charset);
     }
 
     return {charset: entry.name};
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   */
+  encode: function encode(data, value) {
+    let begin = data.offset;
+    try {
+      AcceptCharsetValue.encodeAnyCharset(data, value);
+      return;
+    } catch (e) {}
+
+    data.offset = begin;
+    let entry = WSP_WELL_KNOWN_CHARSETS[value.charset.toLowerCase()];
+    if (!entry) {
+      throw new NotWellKnownEncodingError(
+        "Well-known-charset: not well known charset " + value.charset);
+    }
+
+    IntegerValue.encode(data, entry.number);
+  },
 };
 
 /**
  * The short form of the Content-type-value MUST only be used when the
  * well-known media is in the range of 0-127 or a text string. In all other
  * cases the general form MUST be used.
  *
  *   Content-type-value = Constrained-media | Content-general-form
@@ -1665,16 +2023,83 @@ let ContentTypeValue = {
 
     try {
       return this.decodeConstrainedMedia(data);
     } catch (e) {
       data.offset = begin;
       return this.decodeContentGeneralForm(data);
     }
   },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object containing `media` and `params` properties.
+   */
+  encodeConstrainedMedia: function encodeConstrainedMedia(data, value) {
+    if (value.params) {
+      throw new CodeError("Constrained-media: should use general form instread");
+    }
+
+    TypeValue.encode(data, value.media);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object containing `media` and `params` properties.
+   */
+  encodeMediaType: function encodeMediaType(data, value) {
+    let entry = WSP_WELL_KNOWN_CONTENT_TYPES[value.media.toLowerCase()];
+    if (entry) {
+      IntegerValue.encode(data, entry.number);
+    } else {
+      NullTerminatedTexts.encode(data, value.media);
+    }
+
+    Parameter.encodeMultiple(data, value.params);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object containing `media` and `params` properties.
+   */
+  encodeContentGeneralForm: function encodeContentGeneralForm(data, value) {
+    let begin = data.offset;
+    this.encodeMediaType(data, value);
+
+    // Calculate how much octets will be written and seek back.
+    // TODO: use memmove, see bug 730873
+    let len = data.offset - begin;
+    data.offset = begin;
+
+    ValueLength.encode(data, len);
+    this.encodeMediaType(data, value);
+  },
+
+  /**
+   * @param data
+   *        A wrapped object to store encoded raw data.
+   * @param value
+   *        An object containing `media` and `params` properties.
+   */
+  encode: function encode(data, value) {
+    let begin = data.offset;
+
+    try {
+      this.encodeConstrainedMedia(data, value);
+    } catch (e) {
+      data.offset = begin;
+      this.encodeContentGeneralForm(data, value);
+    }
+  },
 };
 
 /**
  * Application-id-value = Uri-value | App-assigned-code
  * App-assigned-code = Integer-value
  *
  * @see WAP-230-WSP-20010705-a clause 8.4.2.54
  */
@@ -1864,16 +2289,95 @@ let PduHelper = {
       }
     } catch (e) {
       debug("Parse error. Message: " + e.message);
       msg = null;
     }
 
     return msg;
   },
+
+  /**
+   * @param multiStream
+   *        An exsiting nsIMultiplexInputStream.
+   * @param array
+   *        An octet array.
+   * @param length
+   *        Max number of octets to be coverted into an input stream.
+   */
+  appendArrayToMultiStream: function appendArrayToMultiStream(multiStream, array, length) {
+    let storageStream = Cc["@mozilla.org/storagestream;1"]
+                        .createInstance(Ci.nsIStorageStream);
+    storageStream.init(4096, length, null);
+
+    let boStream = Cc["@mozilla.org/binaryoutputstream;1"]
+                   .createInstance(Ci.nsIBinaryOutputStream);
+    boStream.setOutputStream(storageStream.getOutputStream(0));
+    boStream.writeByteArray(array, length);
+    boStream.close();
+
+    multiStream.appendStream(storageStream.newInputStream(0));
+  },
+
+  /**
+   * @param multiStream
+   *        An exsiting nsIMultiplexInputStream.
+   * @param parts
+   *        An array of objects representing multipart entries.
+   *
+   * @see WAP-230-WSP-20010705-a section 8.5
+   */
+  composeMultiPart: function composeMultiPart(multiStream, parts) {
+    // Encode multipart header
+    {
+      let data = {array: [], offset: 0};
+      UintVar.encode(data, parts.length);
+      debug("Encoded multipart header: " + JSON.stringify(data.array));
+      this.appendArrayToMultiStream(multiStream, data.array, data.offset);
+    }
+
+    // Encode each part
+    for (let i = 0; i < parts.length; i++) {
+      let part = parts[i];
+      let data = {array: [], offset: 0};
+
+      // Encode Content-Type
+      let contentType = part.headers["content-type"];
+      ContentTypeValue.encode(data, contentType);
+
+      // Encode other headers
+      if (Object.keys(part).length > 1) {
+        // Remove Content-Type temporarily
+        delete part.headers["content-type"];
+
+        for (let name in part.headers) {
+          Header.encode(data, {name: name, value: part.headers[name]});
+        }
+
+        // Restore Content-Type back
+        part.headers["content-type"] = contentType;
+      }
+
+      // Encode headersLen, DataLen
+      let headersLen = data.offset;
+      UintVar.encode(data, headersLen);
+      UintVar.encode(data, part.content.length);
+
+      // Move them to the beginning of encoded octet array.
+      let slice1 = data.array.slice(headersLen);
+      let slice2 = data.array.slice(0, headersLen);
+      data.array = slice1.concat(slice2);
+      debug("Encoded per-part header: " + JSON.stringify(data.array));
+
+      // Append per-part header
+      this.appendArrayToMultiStream(multiStream, data.array, data.offset);
+      // Append part content
+      this.appendArrayToMultiStream(multiStream, part.content, part.content.length);
+    }
+  },
 };
 
 // WSP Header Field Name Assignments
 // Note: Items commented out are either deprecated or not implemented.
 //       Deprecated items should only be supported for backward compatibility
 //       purpose.
 // @see WAP-230-WSP-20010705-a Appendix A. Assigned Numbers.
 const WSP_HEADER_FIELDS = (function () {
@@ -1882,16 +2386,17 @@ const WSP_HEADER_FIELDS = (function () {
     let entry = {
       name: name,
       number: number,
       coder: coder,
     };
     names[name] = names[number] = entry;
   }
 
+  // Encoding Version: 1.1
   //add("accept",               0x00);
   //add("accept-charset",       0x01); Deprecated
   //add("accept-encoding",      0x02); Deprecated
   //add("accept-language",      0x03);
   //add("accept-ranges",        0x04);
   add("age",                    0x05, DeltaSecondsValue);
   //add("allow",                0x06);
   //add("authorization",        0x07);
@@ -1929,37 +2434,43 @@ const WSP_HEADER_FIELDS = (function () {
   //add("transfer-encoding",    0x27);
   add("upgrade",                0x28, TextString);
   add("user-agent",             0x29, TextString);
   //add("vary",                 0x2A);
   add("via",                    0x2B, TextString);
   //add("warning",              0x2C);
   //add("www-authenticate",     0x2D);
   //add("content-disposition",  0x2E); Deprecated
+
+  // Encoding Version: 1.2
   add("x-wap-application-id",   0x2F, ApplicationIdValue);
   add("x-wap-content-uri",      0x30, UriValue);
   add("x-wap-initiator-uri",    0x31, UriValue);
   //add("accept-application",   0x32);
   add("bearer-indication",      0x33, IntegerValue);
   add("push-flag",              0x34, ShortInteger);
   add("profile",                0x35, UriValue);
   //add("profile-diff",         0x36);
   //add("profile-warning",      0x37); Deprecated
+
+  // Encoding Version: 1.3
   //add("expect",               0x38);
   //add("te",                   0x39);
   //add("trailer",              0x3A);
   add("accept-charset",         0x3B, AcceptCharsetValue);
   //add("accept-encoding",      0x3C);
   //add("cache-control",        0x3D); Deprecated
   //add("content-range",        0x3E);
   add("x-wap-tod",              0x3F, DateValue);
   add("content-id",             0x40, QuotedString);
   //add("set-cookie",           0x41);
   //add("cookie",               0x42);
   //add("encoding-version",     0x43);
+
+  // Encoding Version: 1.4
   //add("profile-warning",      0x44);
   //add("content-disposition",  0x45);
   //add("x-wap-security",       0x46);
   //add("cache-control",        0x47);
 
   return names;
 })();
 
@@ -1972,17 +2483,23 @@ const WSP_WELL_KNOWN_CONTENT_TYPES = (fu
     let entry = {
       type: type,
       number: number,
     };
     types[type] = types[number] = entry;
   }
 
   // Well Known Values
+  // Encoding Version: 1.1
+  add("application/vnd.wap.multipart.mixed", 0x23);
+
+  // Encoding Version: 1.2
   add("application/vnd.wap.multipart.related", 0x33);
+
+  // Encoding Version: 1.4
   add("application/vnd.wap.mms-message", 0x3E);
 
   return types;
 })();
 
 // WSP Well-Known Parameter Assignments
 // Note: Items commented out are either deprecated or not implemented.
 //       Deprecated items should not be used.
@@ -1994,41 +2511,48 @@ const WSP_WELL_KNOWN_PARAMS = (function 
     let entry = {
       name: name,
       number: number,
       coder: coder,
     };
     params[name] = params[number] = entry;
   }
 
+  // Encoding Version: 1.1
   add("q",                 0x00, QValue);
   add("charset",           0x01, WellKnownCharset);
   add("level",             0x02, VersionValue);
   add("type",              0x03, IntegerValue);
   add("name",              0x05, TextValue); // Deprecated, but used in some carriers, eg. Hinet.
   //add("filename",        0x06); Deprecated
   add("differences",       0x07, FieldName);
   add("padding",           0x08, ShortInteger);
+
+  // Encoding Version: 1.2
   add("type",              0x09, TypeValue);
   add("start",             0x0A, TextValue); // Deprecated, but used in some carriers, eg. T-Mobile.
   //add("start-info",      0x0B); Deprecated
+
+  // Encoding Version: 1.3
   //add("comment",         0x0C); Deprecated
   //add("domain",          0x0D); Deprecated
   add("max-age",           0x0E, DeltaSecondsValue);
   //add("path",            0x0F); Deprecated
   add("secure",            0x10, NoValue);
+
+  // Encoding Version: 1.4
   add("sec",               0x11, ShortInteger);
   add("mac",               0x12, TextValue);
   add("creation-date",     0x13, DateValue);
   add("modification-date", 0x14, DateValue);
   add("read-date",         0x15, DateValue);
   add("size",              0x16, IntegerValue);
-  add("name",              0x17, TextValue);
+  //add("name",            0x17, TextValue); // Not supported in some carriers, eg. Hinet.
   add("filename",          0x18, TextValue);
-  add("start",             0x19, TextValue);
+  //add("start",           0x19, TextValue); // Not supported in some carriers, eg. Hinet.
   add("start-info",        0x1A, TextValue);
   add("comment",           0x1B, TextValue);
   add("domain",            0x1C, TextValue);
   add("path",              0x1D, TextValue);
 
   return params;
 })();
 
--- a/dom/mms/src/ril/mms_consts.js
+++ b/dom/mms/src/ril/mms_consts.js
@@ -33,24 +33,61 @@ const MMS_PDU_TYPE_CANCEL_CONF = 151;
 // @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.34
 const MMS_VERSION = (0x01 << 4) | 0x03;
 
 // Common Status Values
 const MMS_PDU_ERROR_OK                = 128;
 const MMS_PDU_ERROR_TRANSIENT_FAILURE = 192;
 const MMS_PDU_ERROR_PERMANENT_FAILURE = 224;
 
+// X-Mms-Response-Status values
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.48
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 28, 29, 30
+//const MMS_PDU_RESPONSE_ERROR_UNSPECIFIED                                 = 129; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_SERVICE_DENIED                              = 130; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_MESSAGE_FORMAT_CORRUPT                      = 131; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_SENDING_ADDRESS_UNRESOLVED                  = 132; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_MESSAGE_NOT_FOUND                           = 133; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_NETWORK_PROBLEM                             = 134; (obsolete)
+//const MMS_PDU_RESPONSE_ERROR_CONTENT_NOT_ACCEPTED                        = 135; (obsolete)
+const MMS_PDU_RESPONSE_ERROR_UNSUPPORTED_MESSAGE                           = 136;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_SENDING_ADDRESS_UNRESOLVED          = 193;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_MESSAGE_NOT_FOUND                   = 194;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_NETWORK_PROBLEM                     = 195;
+const MMS_PDU_RESPONSE_ERROR_TRANSIENT_PARTIAL_SUCCESS                     = 196;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_SERVICE_DENIED                      = 225;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT              = 226;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_SENDING_ADDRESS_UNRESOLVED          = 227;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_MESSAGE_NOT_FOUND                   = 228;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_CONTENT_NOT_ACCEPTED                = 229;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_LIMITATIONS_NOT_MET  = 230;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_REQUEST_NOT_ACCEPTED = 231;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_FORWARDING_DENIED    = 232;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_REPLY_CHARGING_NOT_SUPPORTED        = 233;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_ADDRESS_HIDING_NOT_SUPPORTED        = 234;
+const MMS_PDU_RESPONSE_ERROR_PERMANENT_LACK_OF_PREPAID                     = 235;
+
 // X-Mms-Retrieve-Status values
 // @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.50
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 31
 const MMS_PDU_RETRIEVE_ERROR_TRANSIENT_MESSAGE_NOT_FOUND   = 193;
 const MMS_PDU_RETRIEVE_ERROR_TRANSIENT_NETWORK_PROBLEM     = 194;
 const MMS_PDU_RETRIEVE_ERROR_PERMANENT_SERVICE_DENIED      = 225;
 const MMS_PDU_RETRIEVE_ERROR_PERMANENT_MESSAGE_NOT_FOUND   = 226;
 const MMS_PDU_RETRIEVE_ERROR_PERMANENT_CONTENT_UNSUPPORTED = 227;
 
+// X-Mms-Store-Status values
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.58
+// @see OMA-TS-MMS_ENC-V1_3-20110913-A Table 35
+const MMS_PDU_STORE_ERROR_TRANSIENT_NETWORK_PROBLEM        = 193;
+const MMS_PDU_STORE_ERROR_PERMANENT_SERVICE_DENIED         = 225;
+const MMS_PDU_STORE_ERROR_PERMANENT_MESSAGE_FORMAT_CORRUPT = 226;
+const MMS_PDU_STORE_ERROR_PERMANENT_MESSAGE_NOT_FOUND      = 227;
+const MMS_PDU_STORE_ERROR_PERMANENT_MMBOX_FULL             = 228;
+
 // X-Mms-Status values
 // @see OMA-TS-MMS_ENC-V1_3-20110913-A clause 7.3.54
 const MMS_PDU_STATUS_EXPIRED       = 128;
 const MMS_PDU_STATUS_RETRIEVED     = 129;
 const MMS_PDU_STATUS_REJECTED      = 130;
 const MMS_PDU_STATUS_DEFERRED      = 131;
 const MMS_PDU_STATUS_UNRECOGNISED  = 132;
 const MMS_PDU_STATUS_INDETERMINATE = 133;
--- a/dom/mms/tests/test_mms_pdu_helper.js
+++ b/dom/mms/tests/test_mms_pdu_helper.js
@@ -66,19 +66,58 @@ add_test(function test_Address_decode() 
                       {address: "+123", type: "num"});
   wsp_decode_test(MMS.Address, strToCharCodeArray("*123"),
                       {address: "*123", type: "num"});
   wsp_decode_test(MMS.Address, strToCharCodeArray("#123"),
                       {address: "#123", type: "num"});
   // Test for alphanum-shortcode
   wsp_decode_test(MMS.Address, strToCharCodeArray("H0wD0Y0uTurnTh1s0n"),
                       {address: "H0wD0Y0uTurnTh1s0n", type: "alphanum"});
-  // Test for other unknown typed sequence
+  // Test for email address
   wsp_decode_test(MMS.Address, strToCharCodeArray("Joe User <joe@user.org>"),
-                      {address: "Joe User <joe@user.org>", type: "unknown"});
+                      {address: "Joe User <joe@user.org>", type: "email"});
+  // Test for invalid address
+  wsp_decode_test(MMS.Address, strToCharCodeArray("@@@@@"),
+                  null, "CodeError");
+
+  run_next_test();
+});
+
+//// Address.encode ////
+
+add_test(function test_Address_encode() {
+  // Test for PLMN address
+  wsp_encode_test(MMS.Address, {address: "+123.456-789", type: "PLMN"},
+                  strToCharCodeArray("+123.456-789/TYPE=PLMN"));
+  wsp_encode_test(MMS.Address, {address: "123456789", type: "PLMN"},
+                  strToCharCodeArray("123456789/TYPE=PLMN"));
+  // Test for IPv4
+  wsp_encode_test(MMS.Address, {address: "1.2.3.4", type: "IPv4"},
+                  strToCharCodeArray("1.2.3.4/TYPE=IPv4"));
+  // Test for IPv6
+  wsp_encode_test(MMS.Address,
+    {address: "1111:AAAA:bbbb:CdEf:1ABC:2cde:3Def:0000", type: "IPv6"},
+    strToCharCodeArray("1111:AAAA:bbbb:CdEf:1ABC:2cde:3Def:0000/TYPE=IPv6")
+  );
+  // Test for other device-address
+  wsp_encode_test(MMS.Address, {address: "+H-e.l%l_o", type: "W0r1d_"},
+                  strToCharCodeArray("+H-e.l%l_o/TYPE=W0r1d_"));
+  // Test for num-shortcode
+  wsp_encode_test(MMS.Address, {address: "+123", type: "num"},
+                  strToCharCodeArray("+123"));
+  wsp_encode_test(MMS.Address, {address: "*123", type: "num"},
+                  strToCharCodeArray("*123"));
+  wsp_encode_test(MMS.Address, {address: "#123", type: "num"},
+                  strToCharCodeArray("#123"));
+  // Test for alphanum-shortcode
+  wsp_encode_test(MMS.Address, {address: "H0wD0Y0uTurnTh1s0n", type: "alphanum"},
+                  strToCharCodeArray("H0wD0Y0uTurnTh1s0n"));
+  // Test for email address
+  wsp_encode_test(MMS.Address, {address: "Joe User <joe@user.org>", type: "email"},
+                  strToCharCodeArray("Joe User <joe@user.org>"));
 
   run_next_test();
 });
 
 //
 // Test target: HeaderField
 //
 
@@ -151,16 +190,30 @@ add_test(function test_ContentClassValue
     } else {
       wsp_decode_test(MMS.ContentClassValue, [i], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// ContentClassValue.encode ////
+
+add_test(function test_ContentClassValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 135)) {
+      wsp_encode_test(MMS.ContentClassValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.ContentClassValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: ContentLocationValue
 //
 
 //// ContentLocationValue.decode ////
 
 add_test(function test_ContentLocationValue_decode() {
   // Test for MMS_PDU_TYPE_MBOX_DELETE_CONF & MMS_PDU_TYPE_DELETE_CONF
@@ -258,16 +311,34 @@ add_test(function test_Parameter_decodeM
   //    return MMS.Parameter.decodeMultiple(data, data.array.length);
   //  }, [0x80 | 0x02, 0x80 | 0x00].concat(strToCharCodeArray("good")).concat([0x80 | 0x01]),
   //  {type: 0, good: 1}
   //);
 
   run_next_test();
 });
 
+//// Parameter.encode ////
+
+add_test(function test_Parameter_encode() {
+  // Test for invalid parameter value
+  wsp_encode_test(MMS.Parameter, null, null, "CodeError");
+  wsp_encode_test(MMS.Parameter, undefined, null, "CodeError");
+  wsp_encode_test(MMS.Parameter, {}, null, "CodeError");
+  // Test for case-insensitive parameter name
+  wsp_encode_test(MMS.Parameter, {name: "TYPE", value: 0}, [130, 128]);
+  wsp_encode_test(MMS.Parameter, {name: "type", value: 0}, [130, 128]);
+  // Test for non-well-known parameter name
+  wsp_encode_test(MMS.Parameter, {name: "name", value: 0}, [110, 97, 109, 101, 0, 128]);
+  // Test for constrained encoding value
+  wsp_encode_test(MMS.Parameter, {name: "type", value: "0"}, [130, 48, 0]);
+
+  run_next_test();
+});
+
 //
 // Test target: EncodedStringValue
 //
 
 //// EncodedStringValue.decode ////
 
 add_test(function test_EncodedStringValue_decode() {
   // Test for normal TextString
@@ -286,31 +357,64 @@ add_test(function test_EncodedStringValu
     let raw = conv.convertToByteArray(str).concat([0]);
     wsp_decode_test(MMS.EncodedStringValue,
                     [raw.length + 2, 0x80 | entry.number, 127].concat(raw), str);
   }
 
   run_next_test();
 });
 
+//// EncodedStringValue.encode ////
+
+add_test(function test_EncodedStringValue_encode() {
+  // Test for normal TextString
+  wsp_encode_test(MMS.EncodedStringValue, "Hello", strToCharCodeArray("Hello"));
+  // Test for utf-8
+  let (entry = MMS.WSP.WSP_WELL_KNOWN_CHARSETS["utf-8"]) {
+    // "Mozilla" in full width.
+    let str = "\uff2d\uff4f\uff5a\uff49\uff4c\uff4c\uff41";
+
+    let conv = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+               .createInstance(Ci.nsIScriptableUnicodeConverter);
+    conv.charset = entry.converter;
+
+    let raw = conv.convertToByteArray(str).concat([0]);
+    wsp_encode_test(MMS.EncodedStringValue, str,
+                    [raw.length + 2, 0x80 | entry.number, 127].concat(raw));
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: ExpiryValue
 //
 
 //// ExpiryValue.decode ////
 
 add_test(function test_ExpiryValue_decode() {
   // Test for Absolute-token Date-value
   wsp_decode_test(MMS.ExpiryValue, [3, 128, 1, 0x80], new Date(0x80 * 1000));
   // Test for Relative-token Delta-seconds-value
   wsp_decode_test(MMS.ExpiryValue, [2, 129, 0x80], 0);
 
   run_next_test();
 });
 
+//// ExpiryValue.encode ////
+
+add_test(function test_ExpiryValue_encode() {
+  // Test for Absolute-token Date-value
+  wsp_encode_test(MMS.ExpiryValue, new Date(0x80 * 1000), [3, 128, 1, 0x80]);
+  // Test for Relative-token Delta-seconds-value
+  wsp_encode_test(MMS.ExpiryValue, 0, [2, 129, 0x80]);
+
+  run_next_test();
+});
+
 //
 // Test target: PreviouslySentByValue
 //
 
 //// PreviouslySentByValue.decode ////
 
 add_test(function test_PreviouslySentByValue_decode() {
   wsp_decode_test(MMS.PreviouslySentByValue, [3, 0x80 | 0x03, 65, 0],
@@ -346,16 +450,30 @@ add_test(function test_FromValue_decode(
   let (addr = strToCharCodeArray("+123/TYPE=PLMN")) {
     wsp_decode_test(MMS.FromValue, [addr.length + 1, 128].concat(addr),
                         {address: "+123", type: "PLMN"});
   }
 
   run_next_test();
 });
 
+//// FromValue.encode ////
+
+add_test(function test_FromValue_encode() {
+  // Test for Insert-address-token:
+  wsp_encode_test(MMS.FromValue, null, [1, 129]);
+  // Test for Address-present-token:
+  let (addr = strToCharCodeArray("+123/TYPE=PLMN")) {
+    wsp_encode_test(MMS.FromValue, {address: "+123", type: "PLMN"},
+                    [addr.length + 1, 128].concat(addr));
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: MessageClassValue
 //
 
 //// MessageClassValue.decodeClassIdentifier ////
 
 add_test(function test_MessageClassValue_decodeClassIdentifier() {
   let (IDs = ["personal", "advertisement", "informational", "auto"]) {
@@ -381,16 +499,28 @@ add_test(function test_MessageClassValue
 
 add_test(function test_MessageClassValue_decode() {
   wsp_decode_test(MMS.MessageClassValue, [65, 0], "A");
   wsp_decode_test(MMS.MessageClassValue, [128], "personal");
 
   run_next_test();
 });
 
+//// MessageClassValue.encode ////
+
+add_test(function test_MessageClassValue_encode() {
+  wsp_encode_test(MMS.MessageClassValue, "personal", [128]);
+  wsp_encode_test(MMS.MessageClassValue, "advertisement", [129]);
+  wsp_encode_test(MMS.MessageClassValue, "informational", [130]);
+  wsp_encode_test(MMS.MessageClassValue, "auto", [131]);
+  wsp_encode_test(MMS.MessageClassValue, "A", [65, 0]);
+
+  run_next_test();
+});
+
 //
 // Test target: MessageTypeValue
 //
 
 //// MessageTypeValue.decode ////
 
 add_test(function test_MessageTypeValue_decode() {
   for (let i = 0; i < 256; i++) {
@@ -431,16 +561,30 @@ add_test(function test_MmFlagsValue_deco
     } else {
       wsp_decode_test(MMS.MmFlagsValue, [3, i, 65, 0], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// MmFlagsValue.encode ////
+
+add_test(function test_MmFlagsValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 130)) {
+      wsp_encode_test(MMS.MmFlagsValue, {type: i, text: "A"}, [3, i, 65, 0]);
+    } else {
+      wsp_encode_test(MMS.MmFlagsValue, {type: i, text: "A"}, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: MmStateValue
 //
 
 //// MmStateValue.decode ////
 
 add_test(function test_MmStateValue_decode() {
   for (let i = 0; i < 256; i++) {
@@ -449,16 +593,30 @@ add_test(function test_MmStateValue_deco
     } else {
       wsp_decode_test(MMS.MmStateValue, [i], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// MmStateValue.encode ////
+
+add_test(function test_MmStateValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 132)) {
+      wsp_encode_test(MMS.MmStateValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.MmStateValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: PriorityValue
 //
 
 //// PriorityValue.decode ////
 
 add_test(function test_PriorityValue_decode() {
   for (let i = 0; i < 256; i++) {
@@ -467,16 +625,30 @@ add_test(function test_PriorityValue_dec
     } else {
       wsp_decode_test(MMS.PriorityValue, [i], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// PriorityValue.encode ////
+
+add_test(function test_PriorityValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 130)) {
+      wsp_encode_test(MMS.PriorityValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.PriorityValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: RecommendedRetrievalModeValue
 //
 
 //// RecommendedRetrievalModeValue.decode ////
 
 add_test(function test_RecommendedRetrievalModeValue_decode() {
   for (let i = 0; i < 256; i++) {
@@ -503,16 +675,68 @@ add_test(function test_ReplyChargingValu
     } else {
       wsp_decode_test(MMS.ReplyChargingValue, [i], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// ReplyChargingValue.encode ////
+
+add_test(function test_ReplyChargingValue_encode() {
+  for (let i = 0; i < 256; i++) {
+    if ((i >= 128) && (i <= 131)) {
+      wsp_encode_test(MMS.ReplyChargingValue, i, [i]);
+    } else {
+      wsp_encode_test(MMS.ReplyChargingValue, i, null, "CodeError");
+    }
+  }
+
+  run_next_test();
+});
+
+//
+// Test target: ResponseText
+//
+
+//// ResponseText.decode ////
+
+add_test(function test_ResponseText_decode() {
+  // Test for MMS_PDU_TYPE_MBOX_DELETE_CONF & MMS_PDU_TYPE_DELETE_CONF
+  wsp_decode_test_ex(function (data) {
+      data.array[0] = data.array.length - 1;
+
+      let options = {};
+      options["x-mms-message-type"] = MMS_PDU_TYPE_MBOX_DELETE_CONF;
+      return MMS.ResponseText.decode(data, options);
+    }, [0, 0x80 | 0x00].concat(strToCharCodeArray("http://no.such.com/path")),
+    {statusCount: 0, text: "http://no.such.com/path"}
+  );
+  wsp_decode_test_ex(function (data) {
+      data.array[0] = data.array.length - 1;
+
+      let options = {};
+      options["x-mms-message-type"] = MMS_PDU_TYPE_DELETE_CONF;
+      return MMS.ResponseText.decode(data, options);
+    }, [0, 0x80 | 0x00].concat(strToCharCodeArray("http://no.such.com/path")),
+    {statusCount: 0, text: "http://no.such.com/path"}
+  );
+  // Test for other situations
+  wsp_decode_test_ex(function (data) {
+      let options = {};
+      options["x-mms-message-type"] = MMS_PDU_TYPE_SEND_REQ;
+      return MMS.ResponseText.decode(data, options);
+    }, strToCharCodeArray("http://no.such.com/path"),
+    {text: "http://no.such.com/path"}
+  );
+
+  run_next_test();
+});
+
 //
 // Test target: RetrieveStatusValue
 //
 
 //// RetrieveStatusValue.decode ////
 
 add_test(function test_RetrieveStatusValue_decode() {
   for (let i = 0; i < 256; i++) {
@@ -577,17 +801,17 @@ add_test(function test_PduHelper_parseHe
   let expect = {};
   expect["x-mms-mms-version"] = MMS_VERSION;
   expect["content-type"] = {
     media: "application/vnd.wap.multipart.related",
     params: null,
   };
   parse([0x80 | 0x0D, 0x80 | MMS_VERSION,   // X-Mms-Mms-Version: 1.3
          0x80 | 0x04, 0x80 | 0x33,          // Content-Type: application/vnd.wap.multipart.related
-	 0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
+         0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ // X-Mms-Message-Type: M-Send.req
         ], expect);
 
   // Parse header fields with multiple entries
   expect = {
     to: [
       { address: "+123", type: "PLMN" },
       { address: "+456", type: "num" },
     ],
@@ -598,8 +822,88 @@ add_test(function test_PduHelper_parseHe
   };
   parse(Array.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
              .concat([0x80 | 0x17]).concat(strToCharCodeArray("+456"))
              .concat([0x80 | 0x04, 0x80 | 0x33]),
         expect);
 
   run_next_test();
 });
+
+//// PduHelper.encodeHeader ////
+
+add_test(function test_PduHelper_encodeHeader() {
+  function func(name, data, headers) {
+    MMS.PduHelper.encodeHeader(data, headers, name);
+
+    // Remove extra space consumed during encoding.
+    while (data.array.length > data.offset) {
+      data.array.pop();
+    }
+
+    return data.array;
+  }
+
+  // Encode header fields with multiple entries
+  let headers = {
+    to: [
+      { address: "+123", type: "PLMN" },
+      { address: "+456", type: "num" },
+    ],
+  };
+  wsp_encode_test_ex(func.bind(null, "to"), headers,
+                     Array.concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
+                          .concat([0x80 | 0x17]).concat(strToCharCodeArray("+456")));
+
+  run_next_test();
+});
+
+//// PduHelper.encodeHeaderIfExists ////
+
+add_test(function test_PduHelper_encodeHeaderIfExists() {
+  function func(name, data, headers) {
+    MMS.PduHelper.encodeHeaderIfExists(data, headers, name);
+
+    // Remove extra space consumed during encoding.
+    while (data.array.length > data.offset) {
+      data.array.pop();
+    }
+
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func.bind(null, "to"), {}, []);
+
+  run_next_test();
+});
+
+//// PduHelper.encodeHeaders ////
+
+add_test(function test_PduHelper_encodeHeaders() {
+  function func(data, headers) {
+    MMS.PduHelper.encodeHeaders(data, headers);
+
+    // Remove extra space consumed during encoding.
+    while (data.array.length > data.offset) {
+      data.array.pop();
+    }
+
+    return data.array;
+  }
+
+  let headers = {};
+  headers["x-mms-message-type"] = MMS_PDU_TYPE_SEND_REQ;
+  headers["x-mms-mms-version"] = MMS_VERSION;
+  headers["x-mms-transaction-id"] = "asdf";
+  headers["to"] = { address: "+123", type: "PLMN" };
+  headers["content-type"] = {
+    media: "application/vnd.wap.multipart.related",
+  };
+  wsp_encode_test_ex(func, headers,
+                     Array.concat([0x80 | 0x0C, MMS_PDU_TYPE_SEND_REQ])
+                          .concat([0x80 | 0x18]).concat(strToCharCodeArray(headers["x-mms-transaction-id"]))
+                          .concat([0x80 | 0x0D, 0x80 | MMS_VERSION])
+                          .concat([0x80 | 0x17]).concat(strToCharCodeArray("+123/TYPE=PLMN"))
+                          .concat([0x80 | 0x04, 0x80 | 0x33]));
+
+  run_next_test();
+});
+
--- a/dom/mms/tests/test_wsp_pdu_helper.js
+++ b/dom/mms/tests/test_wsp_pdu_helper.js
@@ -102,16 +102,27 @@ add_test(function test_Octet_decodeEqual
 add_test(function test_Octet_encode() {
   for (let i = 0; i < 256; i++) {
     wsp_encode_test(WSP.Octet, i, [i]);
   }
 
   run_next_test();
 });
 
+//// Octet.encodeMultiple ////
+
+add_test(function test_Octet_encodeMultiple() {
+  wsp_encode_test_ex(function (data, input) {
+    WSP.Octet.encodeMultiple(data, input);
+    return data.array;
+  }, [0, 1, 2, 3], [0, 1, 2, 3]);
+
+  run_next_test();
+});
+
 //
 // Test target: Text
 //
 
 //// Text.decode ////
 
 add_test(function test_Text_decode() {
   for (let i = 0; i < 256; i++) {
@@ -298,16 +309,24 @@ add_test(function test_QuotedString_deco
   wsp_decode_test(WSP.QuotedString, [32, 0], null, "CodeError");
   // Test incompleted string
   wsp_decode_test(WSP.QuotedString, [34, 32], null, "RangeError");
   wsp_decode_test(WSP.QuotedString, [34, 32, 0], " ");
 
   run_next_test();
 });
 
+//// QuotedString.encode ////
+
+add_test(function test_QuotedString_encode() {
+  wsp_encode_test(WSP.QuotedString, "B2G", [34].concat(strToCharCodeArray("B2G")));
+
+  run_next_test();
+});
+
 //
 // Test target: ShortInteger
 //
 
 //// ShortInteger.decode ////
 
 add_test(function test_ShortInteger_decode() {
   for (let i = 0; i < 256; i++) {
@@ -336,32 +355,63 @@ add_test(function test_ShortInteger_enco
 });
 
 //
 // Test target: LongInteger
 //
 
 //// LongInteger.decode ////
 
-function LongInteger_testcases(target) {
+function LongInteger_decode_testcases(target) {
   // Test LongInteger of zero octet
   wsp_decode_test(target, [0, 0], null, "CodeError");
   wsp_decode_test(target, [1, 0x80], 0x80);
   wsp_decode_test(target, [2, 0x80, 2], 0x8002);
   wsp_decode_test(target, [3, 0x80, 2, 3], 0x800203);
   wsp_decode_test(target, [4, 0x80, 2, 3, 4], 0x80020304);
   wsp_decode_test(target, [5, 0x80, 2, 3, 4, 5], 0x8002030405);
   wsp_decode_test(target, [6, 0x80, 2, 3, 4, 5, 6], 0x800203040506);
   // Test LongInteger of more than 6 octets
   wsp_decode_test(target, [7, 0x80, 2, 3, 4, 5, 6, 7], [0x80, 2, 3, 4, 5, 6, 7]);
   // Test LongInteger of more than 30 octets
   wsp_decode_test(target, [31], null, "CodeError");
 }
 add_test(function test_LongInteger_decode() {
-  LongInteger_testcases(WSP.LongInteger);
+  LongInteger_decode_testcases(WSP.LongInteger);
+
+  run_next_test();
+});
+
+//// LongInteger.encode ////
+
+function LongInteger_encode_testcases(target) {
+  wsp_encode_test(target, 0x80,           [1, 0x80]);
+  wsp_encode_test(target, 0x8002,         [2, 0x80, 2]);
+  wsp_encode_test(target, 0x800203,       [3, 0x80, 2, 3]);
+  wsp_encode_test(target, 0x80020304,     [4, 0x80, 2, 3, 4]);
+  wsp_encode_test(target, 0x8002030405,   [5, 0x80, 2, 3, 4, 5]);
+  wsp_encode_test(target, 0x800203040506, [6, 0x80, 2, 3, 4, 5, 6]);
+  // Test LongInteger of more than 6 octets
+  wsp_encode_test(target, 0x1000000000000, null, "CodeError");
+  // Test input empty array
+  wsp_encode_test(target, [], null, "CodeError");
+  // Test input octets array of length 1..30
+  let array = [];
+  for (let i = 1; i <= 30; i++) {
+    array.push(i);
+    wsp_encode_test(target, array, [i].concat(array));
+  }
+  // Test input octets array of 31 elements.
+  array.push(31);
+  wsp_encode_test(target, array, null, "CodeError");
+}
+add_test(function test_LongInteger_encode() {
+  wsp_encode_test(WSP.LongInteger, 0, [1, 0]);
+
+  LongInteger_encode_testcases(WSP.LongInteger);
 
   run_next_test();
 });
 
 //
 // Test target: UintVar
 //
 
@@ -380,29 +430,55 @@ add_test(function test_UintVar_decode() 
   wsp_decode_test(WSP.UintVar, [0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F], 0x1FFFFFFFFFFFFF);
   wsp_decode_test(WSP.UintVar, [0x01, 0x02], 1);
   wsp_decode_test(WSP.UintVar, [0x80, 0x01, 0x02], 1);
   wsp_decode_test(WSP.UintVar, [0x80, 0x80, 0x80, 0x01, 0x2], 1);
 
   run_next_test();
 });
 
+//// UintVar.encode ////
+
+add_test(function test_UintVar_encode() {
+  // Test up to max 53 bits integer
+  wsp_encode_test(WSP.UintVar, 0, [0]);
+  wsp_encode_test(WSP.UintVar, 0x7F, [0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x3FFF, [0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x1FFFFF, [0xFF, 0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0xFFFFFFF, [0xFF, 0xFF, 0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x7FFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x3FFFFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x1FFFFFFFFFFFF, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+  wsp_encode_test(WSP.UintVar, 0x1FFFFFFFFFFFFF, [0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]);
+
+  run_next_test();
+});
+
 //
-// Test target: ConstrainedEncoding (decodeAlternatives)
+// Test target: ConstrainedEncoding
 //
 
 //// ConstrainedEncoding.decode ////
 
 add_test(function test_ConstrainedEncoding_decode() {
   wsp_decode_test(WSP.ConstrainedEncoding, [0x80], 0);
   wsp_decode_test(WSP.ConstrainedEncoding, [32, 0], " ");
 
   run_next_test();
 });
 
+//// ConstrainedEncoding.encode ////
+
+add_test(function test_ConstrainedEncoding_encode() {
+  wsp_encode_test(WSP.ConstrainedEncoding, 0, [0x80 | 0]);
+  wsp_encode_test(WSP.ConstrainedEncoding, "A", [65, 0]);
+
+  run_next_test();
+});
+
 //
 // Test target: ValueLength
 //
 
 //// ValueLength.decode ////
 
 add_test(function test_ValueLength_decode() {
   for (let i = 0; i < 256; i++) {
@@ -413,58 +489,111 @@ add_test(function test_ValueLength_decod
     } else {
       wsp_decode_test(WSP.ValueLength, [i, 0x8F, 0x7F], null, "CodeError");
     }
   }
 
   run_next_test();
 });
 
+//// ValueLength.encode ////
+
+add_test(function test_ValueLength_encode() {
+  for (let i = 0; i < 256; i++) {
+    if (i < 31) {
+      wsp_encode_test(WSP.ValueLength, i, [i]);
+    } else if (i < 128) {
+      wsp_encode_test(WSP.ValueLength, i, [31, i]);
+    } else {
+      wsp_encode_test(WSP.ValueLength, i, [31, (0x80 | (i / 128)), i % 128]);
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: NoValue
 //
 
 //// NoValue.decode ////
 
 add_test(function test_NoValue_decode() {
   wsp_decode_test(WSP.NoValue, [0], null);
   for (let i = 1; i < 256; i++) {
     wsp_decode_test(WSP.NoValue, [i], null, "CodeError");
   }
 
   run_next_test();
 });
 
+//// NoValue.encode ////
+
+add_test(function test_NoValue_encode() {
+  wsp_encode_test(WSP.NoValue, undefined, [0]);
+  wsp_encode_test(WSP.NoValue, null, [0]);
+  wsp_encode_test(WSP.NoValue, 0, null, "CodeError");
+  wsp_encode_test(WSP.NoValue, "", null, "CodeError");
+  wsp_encode_test(WSP.NoValue, [], null, "CodeError");
+  wsp_encode_test(WSP.NoValue, {}, null, "CodeError");
+
+  run_next_test();
+});
+
 //
 // Test target: TextValue
 //
 
 //// TextValue.decode ////
 
 add_test(function test_TextValue_decode() {
   wsp_decode_test(WSP.TextValue, [0], null);
   wsp_decode_test(WSP.TextValue, [65, 0], "A");
   wsp_decode_test(WSP.TextValue, [32, 0], null, "CodeError");
   wsp_decode_test(WSP.TextValue, [34, 32, 0], " ");
 
   run_next_test();
 });
 
+//// TextValue.encode ////
+
+add_test(function test_TextValue_encode() {
+  wsp_encode_test(WSP.TextValue, undefined, [0]);
+  wsp_encode_test(WSP.TextValue, null, [0]);
+  wsp_encode_test(WSP.TextValue, "", [0]);
+  wsp_encode_test(WSP.TextValue, "A", [65, 0]);
+  wsp_encode_test(WSP.TextValue, "\x80", [34, 128, 0]);
+
+  run_next_test();
+});
+
 //
 // Test target: IntegerValue
 //
 
 //// IntegerValue.decode ////
 
 add_test(function test_IntegerValue_decode() {
   for (let i = 128; i < 256; i++) {
     wsp_decode_test(WSP.IntegerValue, [i], i & 0x7F);
   }
 
-  LongInteger_testcases(WSP.IntegerValue);
+  LongInteger_decode_testcases(WSP.IntegerValue);
+
+  run_next_test();
+});
+
+//// IntegerValue.decode ////
+
+add_test(function test_IntegerValue_encode() {
+  for (let i = 0; i < 128; i++) {
+    wsp_encode_test(WSP.IntegerValue, i, [0x80 | i]);
+  }
+
+  LongInteger_encode_testcases(WSP.IntegerValue);
 
   run_next_test();
 });
 
 //
 // Test target: DateValue
 //
 
@@ -473,16 +602,24 @@ add_test(function test_IntegerValue_deco
 add_test(function test_DateValue_decode() {
   wsp_decode_test(WSP.DateValue, [0, 0], null, "CodeError");
   wsp_decode_test(WSP.DateValue, [1, 0x80], new Date(0x80 * 1000));
   wsp_decode_test(WSP.DateValue, [31], null, "CodeError");
 
   run_next_test();
 });
 
+//// DateValue.encode ////
+
+add_test(function test_DateValue_encode() {
+  wsp_encode_test(WSP.DateValue, new Date(0x80 * 1000), [1, 0x80]);
+
+  run_next_test();
+});
+
 //
 // Test target: DeltaSecondsValue
 //
 // DeltaSecondsValue is only an alias of IntegerValue.
 
 //
 // Test target: QValue
 //
@@ -495,16 +632,28 @@ add_test(function test_QValue_decode() {
   wsp_decode_test(WSP.QValue, [100], 0.99);
   wsp_decode_test(WSP.QValue, [101], 0.001);
   wsp_decode_test(WSP.QValue, [0x88, 0x4B], 0.999);
   wsp_decode_test(WSP.QValue, [0x88, 0x4C], null, "CodeError");
 
   run_next_test();
 });
 
+//// QValue.encode ////
+
+add_test(function test_QValue_encode() {
+  wsp_encode_test(WSP.QValue, 0, [1]);
+  wsp_encode_test(WSP.QValue, 0.99, [100]);
+  wsp_encode_test(WSP.QValue, 0.001, [101]);
+  wsp_encode_test(WSP.QValue, 0.999, [0x88, 0x4B]);
+  wsp_encode_test(WSP.QValue, 1, null, "CodeError");
+
+  run_next_test();
+});
+
 //
 // Test target: VersionValue
 //
 
 //// VersionValue.decode ////
 
 add_test(function test_VersionValue_decode() {
   for (let major = 1; major < 8; major++) {
@@ -521,16 +670,32 @@ add_test(function test_VersionValue_deco
         wsp_decode_test(WSP.VersionValue, [major + 0x30, 0x2E, minor + 0x30, 0], version);
       }
     }
   }
 
   run_next_test();
 });
 
+//// VersionValue.encode ////
+
+add_test(function test_VersionValue_encode() {
+  for (let major = 1; major < 8; major++) {
+    let version = (major << 4) | 0x0F;
+    wsp_encode_test(WSP.VersionValue, version, [0x80 | version]);
+
+    for (let minor = 0; minor < 15; minor++) {
+      version = (major << 4) | minor;
+      wsp_encode_test(WSP.VersionValue, version, [0x80 | version]);
+    }
+  }
+
+  run_next_test();
+});
+
 //
 // Test target: UriValue
 //
 
 //// UriValue.decode ////
 
 add_test(function test_UriValue_decode() {
   wsp_decode_test(WSP.UriValue, [97], null, "RangeError");
@@ -553,16 +718,27 @@ add_test(function test_TypeValue_decode(
   wsp_decode_test(WSP.TypeValue, [0x33 | 0x80],
                   "application/vnd.wap.multipart.related");
   // Test for NotWellKnownEncodingError
   wsp_decode_test(WSP.TypeValue, [0x80], null, "NotWellKnownEncodingError");
 
   run_next_test();
 });
 
+//// TypeValue.encode ////
+
+add_test(function test_TypeValue_encode() {
+  wsp_encode_test(WSP.TypeValue, "no/such.type",
+                  [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+  wsp_encode_test(WSP.TypeValue, "application/vnd.wap.multipart.related",
+                  [0x33 | 0x80]);
+
+  run_next_test();
+});
+
 //
 // Test target: Parameter
 //
 
 //// Parameter.decodeTypedParameter ////
 
 add_test(function test_Parameter_decodeTypedParameter() {
   function func(data) {
@@ -576,20 +752,20 @@ add_test(function test_Parameter_decodeT
   // Test for NotWellKnownEncodingError
   wsp_decode_test_ex(func, [1, 0xFF], null, "NotWellKnownEncodingError");
   // Test for parameter specific decoder
   wsp_decode_test_ex(func, [1, 0, 100], {name: "q", value: 0.99});
   // Test for TextValue
   wsp_decode_test_ex(func, [1, 0x10, 48, 46, 57, 57, 0],
                      {name: "secure", value: "0.99"});
   // Test for TextString
-  wsp_decode_test_ex(func, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
+  wsp_decode_test_ex(func, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0],
                      {name: "start", value: "<smil>"});
   // Test for skipValue
-  wsp_decode_test_ex(func, [1, 0x19, 128], null);
+  wsp_decode_test_ex(func, [1, 0x0A, 128], null);
 
   run_next_test();
 });
 
 //// Parameter.decodeUntypedParameter ////
 
 add_test(function test_Parameter_decodeUntypedParameter() {
   function func (data) {
@@ -604,34 +780,87 @@ add_test(function test_Parameter_decodeU
   wsp_decode_test_ex(func, [65, 0, 66, 0], {name: "a", value: "B"});
 
   run_next_test();
 });
 
 //// Parameter.decode ////
 
 add_test(function test_Parameter_decode() {
-  wsp_decode_test(WSP.Parameter, [1, 0x19, 60, 115, 109, 105, 108, 62, 0],
+  wsp_decode_test(WSP.Parameter, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0],
                   {name: "start", value: "<smil>"});
   wsp_decode_test(WSP.Parameter, [65, 0, 66, 0], {name: "a", value: "B"});
 
   run_next_test();
 });
 
 //// Parameter.decodeMultiple ////
 
 add_test(function test_Parameter_decodeMultiple() {
   wsp_decode_test_ex(function (data) {
       return WSP.Parameter.decodeMultiple(data, 13);
-    }, [1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0], {start: "<smil>", a: "B"}
+    }, [1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0], {start: "<smil>", a: "B"}
   );
 
   run_next_test();
 });
 
+//// Parameter.encodeTypedParameter ////
+
+add_test(function test_Parameter_encodeTypedParameter() {
+  function func(data, input) {
+    WSP.Parameter.encodeTypedParameter(data, input);
+    return data.array;
+  }
+
+  // Test for NotWellKnownEncodingError
+  wsp_encode_test_ex(func, {name: "xxx", value: 0}, null, "NotWellKnownEncodingError");
+  wsp_encode_test_ex(func, {name: "q", value: 0}, [0x80, 1]);
+  wsp_encode_test_ex(func, {name: "name", value: "A"}, [0x85, 65, 0]);
+
+  run_next_test();
+});
+
+//// Parameter.encodeUntypedParameter ////
+
+add_test(function test_Parameter_encodeUntypedParameter() {
+  function func(data, input) {
+    WSP.Parameter.encodeUntypedParameter(data, input);
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func, {name: "q", value: 0}, [113, 0, 0x80]);
+  wsp_encode_test_ex(func, {name: "name", value: "A"}, [110, 97, 109, 101, 0, 65, 0]);
+
+  run_next_test();
+});
+
+//// Parameter.encodeMultiple ////
+
+add_test(function test_Parameter_encodeMultiple() {
+  function func(data, input) {
+    WSP.Parameter.encodeMultiple(data, input);
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func, {q: 0, n: "A"}, [0x80, 1, 110, 0, 65, 0]);
+
+  run_next_test();
+});
+
+//// Parameter.encode ////
+
+add_test(function test_Parameter_encode() {
+
+  wsp_encode_test(WSP.Parameter, {name: "q", value: 0}, [0x80, 1]);
+  wsp_encode_test(WSP.Parameter, {name: "n", value: "A"}, [110, 0, 65, 0]);
+
+  run_next_test();
+});
+
 //
 // Test target: Header
 //
 
 //// Header.decode ////
 
 add_test(function test_Header_decode() {
   wsp_decode_test(WSP.Header, [0x34 | 0x80, 0x80], {name: "push-flag", value: 0});
@@ -717,16 +946,25 @@ add_test(function test_FieldName_decode(
   let (entry = WSP.WSP_HEADER_FIELDS["content-length"]) {
     wsp_decode_test(WSP.FieldName, [entry.number | 0x80], entry.name);
   }
   wsp_decode_test(WSP.FieldName, [0xFF], null, "NotWellKnownEncodingError");
 
   run_next_test();
 });
 
+//// FieldName.encode ////
+
+add_test(function test_FieldName_encode() {
+  wsp_encode_test(WSP.FieldName, "", [0]);
+  wsp_encode_test(WSP.FieldName, "date", [0x92]);
+
+  run_next_test();
+});
+
 //
 // Test target: AcceptCharsetValue
 //
 
 //// AcceptCharsetValue.decode ////
 
 add_test(function test_AcceptCharsetValue_decode() {
   wsp_decode_test(WSP.AcceptCharsetValue, [0xFF], null, "CodeError");
@@ -743,16 +981,34 @@ add_test(function test_AcceptCharsetValu
     wsp_decode_test(WSP.AcceptCharsetValue, [2, 1, entry.number], {charset: entry.name});
     wsp_decode_test(WSP.AcceptCharsetValue, [1, entry.number | 0x80], {charset: entry.name});
   }
   wsp_decode_test(WSP.AcceptCharsetValue, [3, 65, 0, 100], {charset: "A", q: 0.99});
 
   run_next_test();
 });
 
+//// AcceptCharsetValue.encodeAnyCharset ////
+
+add_test(function test_AcceptCharsetValue_encodeAnyCharset() {
+  function func(data, input) {
+    WSP.AcceptCharsetValue.encodeAnyCharset(data, input);
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func, null, [0x80]);
+  wsp_encode_test_ex(func, undefined, [0x80]);
+  wsp_encode_test_ex(func, {}, [0x80]);
+  wsp_encode_test_ex(func, {charset: null}, [0x80]);
+  wsp_encode_test_ex(func, {charset: "*"}, [0x80]);
+  wsp_encode_test_ex(func, {charset: "en"}, null, "CodeError");
+
+  run_next_test();
+});
+
 //
 // Test target: WellKnownCharset
 //
 
 //// WellKnownCharset.decode ////
 
 add_test(function test_WellKnownCharset_decode() {
   wsp_decode_test(WSP.WellKnownCharset, [0xFF], null, "NotWellKnownEncodingError");
@@ -761,16 +1017,26 @@ add_test(function test_WellKnownCharset_
   // Test for number-typed return value from IntegerValue
   wsp_decode_test(WSP.WellKnownCharset, [1, 3], {charset: "ansi_x3.4-1968"});
   // Test for array-typed return value from IntegerValue
   wsp_decode_test(WSP.WellKnownCharset, [7, 0, 0, 0, 0, 0, 0, 0, 3], null, "CodeError");
 
   run_next_test();
 });
 
+//// WellKnownCharset.encode ////
+
+add_test(function test_WellKnownCharset_encode() {
+  // Test for Any-charset
+  wsp_encode_test(WSP.WellKnownCharset, {charset: "*"}, [0x80]);
+  wsp_encode_test(WSP.WellKnownCharset, {charset: "UTF-8"}, [128 + 106]);
+
+  run_next_test();
+});
+
 //
 // Test target: ContentTypeValue
 //
 
 //// ContentTypeValue.decodeConstrainedMedia ////
 
 add_test(function test_ContentTypeValue_decodeConstrainedMedia() {
   function func(data) {
@@ -809,50 +1075,114 @@ add_test(function test_ContentTypeValue_
 add_test(function test_ContentTypeValue_decodeMediaType() {
   wsp_decode_test_ex(function (data) {
       return WSP.ContentTypeValue.decodeMediaType(data, 1);
     }, [0x3E | 0x80],
     {media: "application/vnd.wap.mms-message", params: null}
   );
   wsp_decode_test_ex(function (data) {
       return WSP.ContentTypeValue.decodeMediaType(data, 14);
-    }, [0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+    }, [0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
     {media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
   );
 
   run_next_test();
 });
 
 //// ContentTypeValue.decodeContentGeneralForm ////
 
 add_test(function test_ContentTypeValue_decodeContentGeneralForm() {
   wsp_decode_test_ex(function (data) {
       return WSP.ContentTypeValue.decodeContentGeneralForm(data);
-    }, [14, 0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+    }, [14, 0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
     {media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
   );
 
   run_next_test();
 });
 
 //// ContentTypeValue.decode ////
 
 add_test(function test_ContentTypeValue_decode() {
   wsp_decode_test(WSP.ContentTypeValue,
-    [14, 0x3E | 0x80, 1, 0x19, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
+    [14, 0x3E | 0x80, 1, 0x0A, 60, 115, 109, 105, 108, 62, 0, 65, 0, 66, 0],
     {media: "application/vnd.wap.mms-message", params: {start: "<smil>", a: "B"}}
   );
 
   wsp_decode_test(WSP.ContentTypeValue, [0x33 | 0x80],
     {media: "application/vnd.wap.multipart.related", params: null}
   );
 
   run_next_test();
 });
 
+//// ContentTypeValue.encodeConstrainedMedia ////
+
+add_test(function test_ContentTypeValue_encodeConstrainedMedia() {
+  function func(data, input) {
+    WSP.ContentTypeValue.encodeConstrainedMedia(data, input);
+    return data.array;
+  }
+
+  // Test media type with additional parameters.
+  wsp_encode_test_ex(func, {media: "a", params: [{a: "b"}]}, null, "CodeError");
+  wsp_encode_test_ex(func, {media: "no/such.type"},
+                     [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+  wsp_encode_test_ex(func, {media: "application/vnd.wap.multipart.related"},
+                     [0x33 | 0x80]);
+
+  run_next_test();
+});
+
+//// ContentTypeValue.encodeMediaType ////
+
+add_test(function test_ContentTypeValue_encodeMediaType() {
+  function func(data, input) {
+    WSP.ContentTypeValue.encodeMediaType(data, input);
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func, {media: "no/such.type"},
+                     [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+  wsp_encode_test_ex(func, {media: "application/vnd.wap.multipart.related"},
+                     [0x33 | 0x80]);
+  wsp_encode_test_ex(func, {media: "a", params: {b: "c", q: 0}},
+                     [97, 0, 98, 0, 99, 0, 128, 1]);
+
+  run_next_test();
+});
+
+//// ContentTypeValue.encodeContentGeneralForm ////
+
+add_test(function test_ContentTypeValue_encodeContentGeneralForm() {
+  function func(data, input) {
+    WSP.ContentTypeValue.encodeContentGeneralForm(data, input);
+    return data.array;
+  }
+
+  wsp_encode_test_ex(func, {media: "a", params: {b: "c", q: 0}},
+                     [8, 97, 0, 98, 0, 99, 0, 128, 1]);
+
+  run_next_test();
+});
+
+//// ContentTypeValue.encode ////
+
+add_test(function test_ContentTypeValue_encode() {
+  wsp_encode_test(WSP.ContentTypeValue, {media: "no/such.type"},
+                  [110, 111, 47, 115, 117, 99, 104, 46, 116, 121, 112, 101, 0]);
+  wsp_encode_test(WSP.ContentTypeValue,
+                  {media: "application/vnd.wap.multipart.related"},
+                  [0x33 | 0x80]);
+  wsp_encode_test(WSP.ContentTypeValue, {media: "a", params: {b: "c", q: 0}},
+                  [8, 97, 0, 98, 0, 99, 0, 128, 1]);
+
+  run_next_test();
+});
+
 //
 // Test target: ApplicationIdValue
 //
 
 //// ApplicationIdValue.decode ////
 
 add_test(function test_ApplicationIdValue_decode() {
   wsp_decode_test(WSP.ApplicationIdValue, [0], "");
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1917,17 +1917,17 @@ PluginInstanceParent::SharedSurfaceRelea
 {
     mSharedSurfaceDib.Close();
 }
 
 bool
 PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
                                              NPRemoteWindow& aRemoteWindow)
 {
-    aRemoteWindow.window = nsnull;
+    aRemoteWindow.window = 0;
     aRemoteWindow.x      = aWindow->x;
     aRemoteWindow.y      = aWindow->y;
     aRemoteWindow.width  = aWindow->width;
     aRemoteWindow.height = aWindow->height;
     aRemoteWindow.type   = aWindow->type;
 
     nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
 
--- a/dom/system/gonk/AutoMounterSetting.cpp
+++ b/dom/system/gonk/AutoMounterSetting.cpp
@@ -94,18 +94,16 @@ NS_IMPL_ISUPPORTS1(AutoMounterSetting, n
 NS_IMETHODIMP
 AutoMounterSetting::Observe(nsISupports *aSubject,
                             const char *aTopic,
                             const PRUnichar *aData)
 {
   if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) {
     return NS_OK;
   }
-  LOG("%s: detected %s data = '%s'", __FUNCTION__, aTopic,
-      NS_LossyConvertUTF16toASCII(aData).get());
 
   // Note that this function gets called for any and all settings changes,
   // so we need to carefully check if we have the one we're interested in.
   //
   // The string that we're interested in will be a JSON string that looks like:
   //  {"key":"ums.autoMount","value":true}
 
   nsCOMPtr<nsIThreadJSContextStack> stack =
--- a/dom/telephony/test/marionette/pdu_builder.js
+++ b/dom/telephony/test/marionette/pdu_builder.js
@@ -1,12 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
+let Cu = SpecialPowers.wrap(Components).utils;
+let RIL = {};
+
+Cu.import("resource://gre/modules/ril_consts.js", RIL);
+
 // Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
 // that code turns out to be a nightmare, so there is some code duplication.
 let PDUBuilder = {
   toHexString: function toHexString(n, length) {
     let str = n.toString(16);
     if (str.length < length) {
       for (let i = 0; i < length - str.length; i++) {
         str = "0" + str;
@@ -41,42 +46,42 @@ let PDUBuilder = {
     }
   },
 
   writeStringAsSeptets: function writeStringAsSeptets(message,
                                                       paddingBits,
                                                       langIndex,
                                                       langShiftIndex)
   {
-    const langTable = PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
-    const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
+    const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
+    const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
 
     let dataBits = paddingBits;
     let data = 0;
     for (let i = 0; i < message.length; i++) {
       let septet = langTable.indexOf(message[i]);
-      if (septet == PDU_NL_EXTENDED_ESCAPE) {
+      if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
         continue;
       }
 
       if (septet >= 0) {
         data |= septet << dataBits;
         dataBits += 7;
       } else {
         septet = langShiftTable.indexOf(message[i]);
         if (septet == -1) {
           throw new Error(message[i] + " not in 7 bit alphabet "
                           + langIndex + ":" + langShiftIndex + "!");
         }
 
-        if (septet == PDU_NL_RESERVED_CONTROL) {
+        if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
           continue;
         }
 
-        data |= PDU_NL_EXTENDED_ESCAPE << dataBits;
+        data |= RIL.PDU_NL_EXTENDED_ESCAPE << dataBits;
         dataBits += 7;
         data |= septet << dataBits;
         dataBits += 7;
       }
 
       for (; dataBits >= 8; dataBits -= 8) {
         this.writeHexOctet(data & 0xFF);
         data >>>= 8;
@@ -84,19 +89,19 @@ let PDUBuilder = {
     }
 
     if (dataBits != 0) {
       this.writeHexOctet(data & 0xFF);
     }
   },
 
   buildAddress: function buildAddress(address) {
-    let addressFormat = PDU_TOA_ISDN; // 81
+    let addressFormat = RIL.PDU_TOA_ISDN; // 81
     if (address[0] == '+') {
-      addressFormat = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
+      addressFormat = RIL.PDU_TOA_INTERNATIONAL | RIL.PDU_TOA_ISDN; // 91
       address = address.substring(1);
     }
 
     this.buf = "";
     this.writeHexOctet(address.length);
     this.writeHexOctet(addressFormat);
     this.writeSwappedNibbleBCD(address);
 
@@ -137,13 +142,13 @@ let PDUBuilder = {
           for each (let octet in header.octets) {
             this.writeHexOctet(octet);
           }
         }
       }
     }
 
     this.writeStringAsSeptets(options.body, paddingBits,
-                              PDU_NL_IDENTIFIER_DEFAULT,
-                              PDU_NL_IDENTIFIER_DEFAULT);
+                              RIL.PDU_NL_IDENTIFIER_DEFAULT,
+                              RIL.PDU_NL_IDENTIFIER_DEFAULT);
     return this.buf;
   }
 };
--- a/dom/telephony/test/marionette/test_voicemail_statuschanged.js
+++ b/dom/telephony/test/marionette/test_voicemail_statuschanged.js
@@ -9,17 +9,17 @@ let voicemail = window.navigator.mozVoic
 ok(voicemail instanceof MozVoicemail);
 is(voicemail.status, null);
 
 function sendIndicatorPDU(pdu, listener, nextTest) {
   let smsCommand = "sms pdu " + pdu;
   let commandCompleted = false;
   let sawEvent = false;
 
- voicemail.addEventListener("statuschanged", function statusChanged(event) {
+  voicemail.addEventListener("statuschanged", function statusChanged(event) {
     voicemail.removeEventListener("statuschanged", statusChanged);
 
     try {
       listener(event);
     } catch (e) {
       ok(false, String(e));
     }
 
@@ -146,20 +146,20 @@ function testLevel2DiscardInactive() {
 // Tests for Level 3 MWI with a message count in the User Data Header
 const MWI_LEVEL3_SENDER = "+15125551236";
 const MWI_LEVEL3_PDU_ADDRESS = PDUBuilder.buildAddress(MWI_LEVEL3_SENDER);
 
 const MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT = 3;
 const MWI_LEVEL3_ACTIVE_BODY = "3 new voicemails";
 const MWI_LEVEL3_ACTIVE_UD = PDUBuilder.buildUserData({
   headers: [{
-    id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
+    id: RIL.PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
     length: 2,
     octets: [
-      PDU_MWI_STORE_TYPE_DISCARD,
+      RIL.PDU_MWI_STORE_TYPE_DISCARD,
       MWI_LEVEL3_ACTIVE_UDH_MSG_COUNT
     ]
   }],
   body: MWI_LEVEL3_ACTIVE_BODY
 });
 
 const MWI_LEVEL3_DISCARD_ACTIVE_PDU =
   MWI_PDU_UDH_PREFIX +
@@ -184,20 +184,20 @@ function testLevel3DiscardActive() {
   sendIndicatorPDU(MWI_LEVEL3_DISCARD_ACTIVE_PDU,
                    onLevel3Active,
                    testLevel3DiscardInactive);
 }
 
 const MWI_LEVEL3_INACTIVE_BODY = "No unread voicemails";
 const MWI_LEVEL3_INACTIVE_UD = PDUBuilder.buildUserData({
   headers: [{
-    id: PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
+    id: RIL.PDU_IEI_SPECIAL_SMS_MESSAGE_INDICATION,
     length: 2,
     octets: [
-      PDU_MWI_STORE_TYPE_DISCARD,
+      RIL.PDU_MWI_STORE_TYPE_DISCARD,
       0 // messageCount
     ]
   }],
   body: MWI_LEVEL3_INACTIVE_BODY
 });
 
 const MWI_LEVEL3_DISCARD_INACTIVE_PDU =
   MWI_PDU_UDH_PREFIX +
--- a/dom/telephony/test/marionette/test_voicemail_statuschanged.py
+++ b/dom/telephony/test/marionette/test_voicemail_statuschanged.py
@@ -1,20 +1,14 @@
 from marionette_test import MarionetteTestCase
 import os
 
 class TestVoicemailStatusChanged(MarionetteTestCase):
 
     def testStatusChanged(self):
         this_dir = os.path.abspath(os.path.dirname(__file__))
-        system_gonk_dir = os.path.abspath(os.path.join(this_dir,
-            os.path.pardir, os.path.pardir, os.path.pardir, "system", "gonk"))
-
-        ril_consts_path = os.path.join(system_gonk_dir, "ril_consts.js")
-        self.marionette.import_script(ril_consts_path)
-
         pdu_builder_path = os.path.join(this_dir, "pdu_builder.js")
         self.marionette.import_script(pdu_builder_path)
 
         test_path = os.path.join(this_dir, "test_voicemail_statuschanged.js")
         test = open(test_path, "r").read()
         self.marionette.set_script_timeout(30000)
         self.marionette.execute_async_script(test)
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1599,20 +1599,24 @@ XMLHttpRequest::MaybeDispatchPrematureAb
 
 void
 XMLHttpRequest::DispatchPrematureAbortEvent(JSObject* aTarget,
                                             uint8_t aEventType,
                                             bool aUploadTarget,
                                             ErrorResult& aRv)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
-  MOZ_ASSERT(mProxy);
   MOZ_ASSERT(aTarget);
   MOZ_ASSERT(aEventType <= STRING_COUNT);
 
+  if (!mProxy) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
   JSContext* cx = GetJSContext();
 
   JSString* type = JS_NewStringCopyZ(cx, sEventStrings[aEventType]);
   if (!type) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
--- a/dom/workers/test/test_xhrAbort.html
+++ b/dom/workers/test/test_xhrAbort.html
@@ -30,21 +30,15 @@ Tests of DOM Worker Threads XHR(Bug 4504
     worker.onmessage = function(event) {
       is (data.toString(), event.data.toString(), "Got different results!");
       SimpleTest.finish();
     };
 
     worker.postMessage("start");
   }
 
-  SimpleTest.waitForExplicitFinish();
+  runTest();
 
-  const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
-  if (isWinXP){
-    todo(false, "Test disabled on WinXP due to bug 718260 crashes");
-    SimpleTest.finish();
-  } else {
-    runTest();
-  }
+  SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 </body>
 </html>
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -201,20 +201,24 @@ void SetPaintPattern(SkPaint& aPaint, co
         points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
         points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));
 
         SkShader* shader = SkGradientShader::CreateLinear(points, 
                                                           &stops->mColors.front(), 
                                                           &stops->mPositions.front(), 
                                                           stops->mCount, 
                                                           mode);
-        SkMatrix mat;
-        GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
-        shader->setLocalMatrix(mat);
-        SkSafeUnref(aPaint.setShader(shader));
+
+        if (shader) {
+            SkMatrix mat;
+            GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
+            shader->setLocalMatrix(mat);
+            SkSafeUnref(aPaint.setShader(shader));
+        }
+
       } else {
         aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
       }
       break;
     }
     case PATTERN_RADIAL_GRADIENT: {
       const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
       GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
@@ -228,20 +232,23 @@ void SetPaintPattern(SkPaint& aPaint, co
         SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0], 
                                                                   SkFloatToScalar(pat.mRadius1),
                                                                   points[1], 
                                                                   SkFloatToScalar(pat.mRadius2),
                                                                   &stops->mColors.front(), 
                                                                   &stops->mPositions.front(), 
                                                                   stops->mCount, 
                                                                   mode);
-        SkMatrix mat;
-        GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
-        shader->setLocalMatrix(mat);
-        SkSafeUnref(aPaint.setShader(shader));
+        if (shader) {
+            SkMatrix mat;
+            GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
+            shader->setLocalMatrix(mat);
+            SkSafeUnref(aPaint.setShader(shader));
+        }
+
       } else {
         aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
       }
       break;
     }
     case PATTERN_SURFACE: {
       const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
       const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(pat.mSurface.get())->GetBitmap();
--- a/gfx/angle/AUTHORS
+++ b/gfx/angle/AUTHORS
@@ -8,8 +8,10 @@
 # The email address is not required for organizations.
 
 TransGaming Inc.
 
 Google Inc.
 
 3DLabs Inc. Ltd.
 
+Cloud Party, Inc.
+
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -12,16 +12,17 @@ TransGaming Inc.
  Andrew Lewycky
  Gavriel State
  Shannon Woods
 
 Google Inc.
  Brent Austin
  Michael Bai
  John Bauman
+ Steve Block
  Henry Bridge
  Nat Duca
  Vangelis Kokkevis
  Zhenyao Mo
  Daniel Nicoara
  Alastair Patrick
  Alok Priyadarshi
  Kenneth Russell
@@ -34,18 +35,26 @@ Mozilla Corp.
  Mike Hommey
  Benoit Jacob
  Makoto Kato
  Vladimir Vukicevic
 
 Apple Inc.
  David Kilzer
 
+Adobe Systems Inc.
+ Alexandru Chiculita
+ Max Vujovic
+
+Cloud Party, Inc.
+ Conor Dickinson
+
 Aitor Moreno <aitormoreno at gmail.com>
 Jim Hauxwell <james at dattrax.co.uk>
 ddefrostt
 timeless
 Yore Apex
 Mark Callow
 Yuriy O'Donnell
 Sam Hocevar
 Pierre Leveille
+Jin Yang
 
--- a/gfx/angle/DEPS
+++ b/gfx/angle/DEPS
@@ -1,14 +1,17 @@
 deps = {
   "trunk/third_party/gyp":
       "http://gyp.googlecode.com/svn/trunk@1080",
 
   "trunk/third_party/googletest":
       "http://googletest.googlecode.com/svn/trunk@573", #release 1.6.0
+
+  "trunk/third_party/googlemock":
+      "http://googlemock.googlecode.com/svn/trunk@387", #release 1.6.0
 }
 
 hooks = [
   {
     # A change to a .gyp, .gypi, or to GYP itself should run the generator.
     "pattern": ".",
     "action": ["python", "trunk/build/gyp_angle"],
   },
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -24,48 +24,63 @@ EXPORTS_angle = \
 	$(NULL)
 
 LOCAL_INCLUDES += -I$(srcdir)/include -I$(srcdir)/src
 
 VPATH += $(srcdir)/src
 VPATH += $(srcdir)/src/compiler
 VPATH += $(srcdir)/src/compiler/preprocessor
 VPATH += $(srcdir)/src/compiler/preprocessor/new
+VPATH += $(srcdir)/src/compiler/timing
+VPATH += $(srcdir)/src/compiler/depgraph
 
 CPPSRCS = \
-	Compiler.cpp \
+        Diagnostics.cpp \
+        PreprocessorDiagnostics.cpp \
+        DirectiveHandler.cpp \
+        PreprocessorDirectiveHandler.cpp \
+        DirectiveParser.cpp \
+        ExpressionParser.cpp \
+        Macro.cpp \
+        MacroExpander.cpp \
+        Tokenizer.cpp \
+        InitializeParseContext.cpp \
+        DependencyGraph.cpp \
+        DependencyGraphBuilder.cpp \
+        DependencyGraphOutput.cpp \
+        DependencyGraphTraverse.cpp \
+        RestrictFragmentShaderTiming.cpp \
+        RestrictVertexShaderTiming.cpp \
+        Compiler.cpp \
         DetectRecursion.cpp \
         InfoSink.cpp \
         Initialize.cpp \
         InitializeDll.cpp \
         Intermediate.cpp \
         intermOut.cpp \
         IntermTraverse.cpp \
         parseConst.cpp \
         ParseHelper.cpp \
         PoolAlloc.cpp \
         QualifierAlive.cpp \
         RemoveTree.cpp \
         ShaderLang.cpp \
         SymbolTable.cpp \
         VariableInfo.cpp \
         compilerdebug.cpp \
-        ossource_nspr.cpp \
         util.cpp \
         ValidateLimitations.cpp \
         ForLoopUnroll.cpp \
         MapLongVariableNames.cpp \
         spooky.cpp \
         BuiltInFunctionEmulator.cpp \
         Input.cpp \
         Lexer.cpp \
-        pp_lex.cpp \
         Preprocessor.cpp \
         Token.cpp \
-        lexer_glue.cpp \
         $(NULL)
 
 # flex/yacc generated files
 CPPSRCS += \
         glslang_lex.cpp \
         glslang_tab.cpp \
         $(NULL)
 
@@ -73,45 +88,40 @@ CPPSRCS += \
 CPPSRCS += \
         CodeGenGLSL.cpp \
         OutputGLSL.cpp \
         TranslatorGLSL.cpp \
         VersionGLSL.cpp \
         OutputESSL.cpp \
         OutputGLSLBase.cpp \
         TranslatorESSL.cpp \
-	$(NULL)
-
-# Currently, only one or the other
-# can be selected.
+        $(NULL)
 
-## HLSL translator backend
-##CPPSRCS += \
-##	CodeGenHLSL.cpp \
-##	OutputHLSL.cpp \
-##	TranslatorHLSL.cpp \
-##	UnfoldSelect.cpp \
-##	SearchSymbol.cpp \
-##	$(NULL)
+ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
+CPPSRCS += ossource_win.cpp $(NULL)
+else
+CPPSRCS += ossource_posix.cpp $(NULL)
+endif
 
 CSRCS   = \
         atom.c \
         cpp.c \
         cppstruct.c \
         memory.c \
         scanner.c \
         symbols.c \
         tokens.c \
-	$(NULL)
+        $(NULL)
 
-DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
+DEFINES += -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
 
 #these defines are from ANGLE's build_angle.gyp
 DEFINES += -DANGLE_DISABLE_TRACE
 DEFINES += -DANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0
+DEFINES += -DANGLE_USE_NEW_PREPROCESSOR=1
 
 ifdef MOZ_ANGLE_RENDERER
 
 # libEGL depends on (links against!) libGLESv2!
 DIRS = src/libGLESv2 src/libEGL
 
 libs::
 	expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,23 +1,40 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/
 
-Current revision: r1042
+Current revision: r1242
 
 == Applied local patches ==
 
 In this order:
-  angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
-  angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
-  angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
-  angle-enforce-readpixels-spec.patch - see bug 724476.
-  angle-impl-read-bgra.patch - see bug 724476.
-  angle-long-identifier-hash-spooky.patch - see bug 676071
+
+  angle-renaming-debug.patch
+    rename debug.h to compilerdebug.h to avoid conflict in our makefiles
+
+  angle-renaming-preprocessor-diagonostics.patch
+    rename one of the two Diagnostics.cpp to avoid conflict in our makefiles
+
+  angle-renaming-preprocessor-directivehandler.patch
+    rename one of the two DirectiveHandler.cpp to avoid conflict in our makefiles
+
+  angle-enforce-readpixels-spec.patch
+    see bug 724476
+
+  angle-impl-read-bgra.patch
+    see bug 724476
+
+  gfx/angle/angle-long-identifier-hash-spooky.patch
+    see bug 676071
+
+  angle-abort-on-oom-in-preprocessor.patch
+    see bug 680840. Probably not useful anymore now that we're on the new
+    preprocessor, but it doesn't hurt to keep it around a bit longer.
 
 In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
+Therefore, changes made to the Makefile.in files should not be stored in the local .patch files.
 
 == How to update this ANGLE copy ==
 
 1. Unapply patches
 2. Apply diff with new ANGLE version
 3. Reapply patches.
 4. Check for changes in src/build_angle.gyp, update our Makefile.in files accordingly. Note that a single file may be recorded in more than one Makefile.
 
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-abort-on-oom-in-preprocessor.patch
@@ -0,0 +1,29 @@
+# HG changeset patch
+# Parent 11023ab3d23865b71678e9a4b22a45646ec0c0f0
+diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
+--- a/gfx/angle/src/compiler/preprocessor/atom.c
++++ b/gfx/angle/src/compiler/preprocessor/atom.c
+@@ -327,22 +327,17 @@ static int GrowAtomTable(AtomTable *atab
+             newmap = realloc(atable->amap, sizeof(int)*size);
+             newrev = realloc(atable->arev, sizeof(int)*size);
+         } else {
+             newmap = malloc(sizeof(int)*size);
+             newrev = malloc(sizeof(int)*size);
+             atable->size = 0;
+         }
+         if (!newmap || !newrev) {
+-            /* failed to grow -- error */
+-            if (newmap)
+-                atable->amap = newmap;
+-            if (newrev)
+-                atable->arev = newrev;
+-            return -1;
++            abort();
+         }
+         memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
+         memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
+         atable->amap = newmap;
+         atable->arev = newrev;
+         atable->size = size;
+     }
+     return 0;
deleted file mode 100644
--- a/gfx/angle/angle-castrate-bug-241.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-# HG changeset patch
-# User Benoit Jacob <bjacob@mozilla.com>
-# Parent 7dcbce54a953090ae8e537f93c6c99ab8eb0dc62
-
-diff --git a/gfx/angle/README.mozilla b/gfx/angle/README.mozilla
---- a/gfx/angle/README.mozilla
-+++ b/gfx/angle/README.mozilla
-@@ -4,16 +4,17 @@ Current revision: r963
- 
- == Applied local patches ==
- 
- In this order:
-   angle-renaming-debug.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
-   angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
-   angle-limit-identifiers-to-250-chars.patch - see bug 675625
-   angle-use-xmalloc.patch - see bug 680840. Can drop this patch whenever the new preprocessor lands.
-+  angle-castrate-bug-241.patch - see bug 699033 / angle bug 241
- 
- In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
- 
- == How to update this ANGLE copy ==
- 
- 1. Unapply patches
- 2. Apply diff with new ANGLE version
- 3. Reapply patches.
-diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
---- a/gfx/angle/src/compiler/Types.h
-+++ b/gfx/angle/src/compiler/Types.h
-@@ -5,16 +5,17 @@
- //
- 
- #ifndef _TYPES_INCLUDED
- #define _TYPES_INCLUDED
- 
- #include "compiler/BaseTypes.h"
- #include "compiler/Common.h"
- #include "compiler/compilerdebug.h"
-+#include <cstdlib>
- 
- //
- // Need to have association of line numbers to types in a list for building structs.
- //
- class TType;
- struct TTypeLine {
-     TType* type;
-     int line;
-@@ -203,17 +204,17 @@ public:
-     bool isVector() const { return size > 1 && !matrix; }
-     bool isScalar() const { return size == 1 && !matrix && !structure; }
- 
-     TTypeList* getStruct() const { return structure; }
-     void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); }
- 
-     const TString& getTypeName() const
-     {
--        assert(typeName);
-+        if(!typeName) abort();
-         return *typeName;
-     }
-     void setTypeName(const TString& n)
-     {
-         typeName = NewPoolTString(n.c_str());
-     }
- 
-     bool isField() const { return fieldName != 0; }
--- a/gfx/angle/angle-enforce-readpixels-spec.patch
+++ b/gfx/angle/angle-enforce-readpixels-spec.patch
@@ -1,14 +1,14 @@
 # HG changeset patch
-# Parent 8d84c8d4e3ed41a4941afdf9d51819b19ca64716
+# Parent a1fed68f51737972901e0d6fc829d3e044a453bd
 diff --git a/gfx/angle/src/libGLESv2/libGLESv2.cpp b/gfx/angle/src/libGLESv2/libGLESv2.cpp
 --- a/gfx/angle/src/libGLESv2/libGLESv2.cpp
 +++ b/gfx/angle/src/libGLESv2/libGLESv2.cpp
-@@ -98,27 +98,16 @@ bool validReadFormatType(GLenum format, 
+@@ -231,27 +231,16 @@ bool validReadFormatType(GLenum format, 
          switch (type)
          {
            case GL_UNSIGNED_BYTE:
              break;
            default:
              return false;
          }
          break;
--- a/gfx/angle/angle-impl-read-bgra.patch
+++ b/gfx/angle/angle-impl-read-bgra.patch
@@ -1,14 +1,14 @@
 # HG changeset patch
-# Parent 8b838be49f115022e403c850c24b28ad62d72ad6
+# Parent 97ded57f965865c06306a8ef82d082064542caff
 diff --git a/gfx/angle/src/libGLESv2/Context.cpp b/gfx/angle/src/libGLESv2/Context.cpp
 --- a/gfx/angle/src/libGLESv2/Context.cpp
 +++ b/gfx/angle/src/libGLESv2/Context.cpp
-@@ -2518,16 +2518,17 @@ void Context::readPixels(GLint x, GLint 
+@@ -2585,16 +2585,17 @@ void Context::readPixels(GLint x, GLint 
      {
          if (desc.Format == D3DFMT_A8R8G8B8 &&
              format == GL_BGRA_EXT &&
              type == GL_UNSIGNED_BYTE)
          {
              // Fast path for EXT_read_format_bgra, given
              // an RGBA source buffer.  Note that buffers with no
              // alpha go through the slow path below.
@@ -16,17 +16,17 @@ diff --git a/gfx/angle/src/libGLESv2/Con
              memcpy(dest + j * outputPitch,
                     source + j * inputPitch,
                     (rect.right - rect.left) * 4);
              continue;
          }
  
          for (int i = 0; i < rect.right - rect.left; i++)
          {
-@@ -2665,20 +2666,20 @@ void Context::readPixels(GLint x, GLint 
+@@ -2732,20 +2733,20 @@ void Context::readPixels(GLint x, GLint 
                          ((unsigned short)(     a + 0.5f) << 15) |
                          ((unsigned short)(31 * r + 0.5f) << 10) |
                          ((unsigned short)(31 * g + 0.5f) << 5) |
                          ((unsigned short)(31 * b + 0.5f) << 0);
                      break;
                    default: UNREACHABLE();
                  }
                  break;
deleted file mode 100644
--- a/gfx/angle/angle-intrinsic-msvc2005.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-# HG changeset patch
-# Parent 4ef86d96d456866537beea57b0a4451cf919cd34
-diff --git a/gfx/angle/src/libGLESv2/Texture.cpp b/gfx/angle/src/libGLESv2/Texture.cpp
---- a/gfx/angle/src/libGLESv2/Texture.cpp
-+++ b/gfx/angle/src/libGLESv2/Texture.cpp
-@@ -8,16 +8,22 @@
- // Texture2D and TextureCubeMap. Implements GL texture objects and related
- // functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
- 
- #include "libGLESv2/Texture.h"
- 
- #include <d3dx9tex.h>
- 
- #include <algorithm>
-+
-+#if _MSC_VER <= 1400
-+#define _interlockedbittestandreset _interlockedbittestandreset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#define _interlockedbittestandset _interlockedbittestandset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#endif
-+
- #include <intrin.h>
- 
- #include "common/debug.h"
- 
- #include "libEGL/Display.h"
- 
- #include "libGLESv2/main.h"
- #include "libGLESv2/mathutil.h"
-diff --git a/gfx/angle/src/libGLESv2/mathutil.h b/gfx/angle/src/libGLESv2/mathutil.h
---- a/gfx/angle/src/libGLESv2/mathutil.h
-+++ b/gfx/angle/src/libGLESv2/mathutil.h
-@@ -3,16 +3,21 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- //
- 
- // mathutil.h: Math and bit manipulation functions.
- 
- #ifndef LIBGLESV2_MATHUTIL_H_
- #define LIBGLESV2_MATHUTIL_H_
-+
-+#if _MSC_VER <= 1400
-+#define _interlockedbittestandreset _interlockedbittestandreset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#define _interlockedbittestandset _interlockedbittestandset_NAME_CHANGED_TO_AVOID_MSVS2005_ERROR
-+#endif
- 
- #include <intrin.h>
- #include <math.h>
- #include <windows.h>
- 
- namespace gl
- {
- inline bool isPow2(int x)
--- a/gfx/angle/angle-long-identifier-hash-spooky.patch
+++ b/gfx/angle/angle-long-identifier-hash-spooky.patch
@@ -1,35 +1,15 @@
 # HG changeset patch
-# Parent 268bda9ac676b6f4cca5aa044d0dcefff2008535
-diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
---- a/gfx/angle/Makefile.in
-+++ b/gfx/angle/Makefile.in
-@@ -79,16 +79,17 @@ CPPSRCS = \
-         SymbolTable.cpp \
-         VariableInfo.cpp \
-         compilerdebug.cpp \
-         ossource_nspr.cpp \
-         util.cpp \
-         ValidateLimitations.cpp \
-         ForLoopUnroll.cpp \
-         MapLongVariableNames.cpp \
-+        spooky.cpp \
-         BuiltInFunctionEmulator.cpp \
-         $(NULL)
- 
- # flex/yacc generated files
- CPPSRCS += \
-         glslang_lex.cpp \
-         glslang_tab.cpp \
-         $(NULL)
+# Parent c5e7517cbb1c38ce9821ba3deca88768b4dff066
+
 diff --git a/gfx/angle/src/compiler/MapLongVariableNames.cpp b/gfx/angle/src/compiler/MapLongVariableNames.cpp
 --- a/gfx/angle/src/compiler/MapLongVariableNames.cpp
 +++ b/gfx/angle/src/compiler/MapLongVariableNames.cpp
-@@ -1,27 +1,30 @@
+@@ -1,29 +1,36 @@
  //
  // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  //
  
  #include "compiler/MapLongVariableNames.h"
 +#include "spooky.h"
@@ -38,25 +18,33 @@ diff --git a/gfx/angle/src/compiler/MapL
  
  TString mapLongName(int id, const TString& name, bool isGlobal)
  {
      ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
      TStringStream stream;
 -    stream << "webgl_";
 -    if (isGlobal)
 -        stream << "g";
--    stream << id << "_";
+-    stream << id;
+-    if (name[0] != '_')
+-        stream << "_";
 -    stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size());
 +    uint64 hash = SpookyHash::Hash64(name.data(), name.length(), 0);
-+    stream << "webgl_"
++
++    // We want to avoid producing a string with a double underscore,
++    // which would be an illegal GLSL identifier. We can assume that the
++    // original identifier doesn't have a double underscore, otherwise
++    // it's illegal anyway.
++    stream << (name[0] == '_' ? "webgl" : "webgl_")
 +           << name.substr(0, 9)
-+           << "_"
++           << (name[8] == '_' ? "" : "_")
 +           << std::hex
 +           << hash;
-+    ASSERT(stream.str().length() == MAX_SHORTENED_IDENTIFIER_SIZE);
++    ASSERT(stream.str().length() <= MAX_SHORTENED_IDENTIFIER_SIZE);
++    ASSERT(stream.str().length() >= MAX_SHORTENED_IDENTIFIER_SIZE - 2);
      return stream.str();
  }
  
  LongNameMap* gLongNameMapInstance = NULL;
  
  }  // anonymous namespace
  
  LongNameMap::LongNameMap()
@@ -706,50 +694,8 @@ new file mode 100644
 +    uint64 m_data[2*sc_numVars];   // unhashed data, for partial messages
 +    uint64 m_state[sc_numVars];  // internal state of the hash
 +    size_t m_length;             // total length of the input so far
 +    uint8  m_remainder;          // length of unhashed data stashed in m_data
 +};
 +
 +
 +
-diff --git a/gfx/angle/src/libEGL/Makefile.in b/gfx/angle/src/libEGL/Makefile.in
---- a/gfx/angle/src/libEGL/Makefile.in
-+++ b/gfx/angle/src/libEGL/Makefile.in
-@@ -91,16 +91,17 @@ CPPSRCS = \
-   SymbolTable.cpp \
-   VariableInfo.cpp \
-   compilerdebug.cpp \
-   ossource_win.cpp \
-   util.cpp \
-   ValidateLimitations.cpp \
-   ForLoopUnroll.cpp \
-   MapLongVariableNames.cpp \
-+  spooky.cpp \
-   BuiltInFunctionEmulator.cpp \
-   $(NULL)
- 
- # flex/yacc generated files
- CPPSRCS += \
-   glslang_lex.cpp \
-   glslang_tab.cpp \
-   $(NULL)
-diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
---- a/gfx/angle/src/libGLESv2/Makefile.in
-+++ b/gfx/angle/src/libGLESv2/Makefile.in
-@@ -91,16 +91,17 @@ CPPSRCS = \
-         SymbolTable.cpp \
-         VariableInfo.cpp \
-         compilerdebug.cpp \
-         ossource_win.cpp \
-         util.cpp \
-         ValidateLimitations.cpp \
- 	ForLoopUnroll.cpp \
- 	MapLongVariableNames.cpp \
-+	spooky.cpp \
-         BuiltInFunctionEmulator.cpp \
- 	$(NULL)
- 
- # flex/yacc generated files
- CPPSRCS += \
- 	glslang_lex.cpp \
- 	glslang_tab.cpp \
- 	$(NULL)
--- a/gfx/angle/angle-renaming-debug.patch
+++ b/gfx/angle/angle-renaming-debug.patch
@@ -1,32 +1,55 @@
 # HG changeset patch
-# Parent f22671e05062a082c7b22192868b804fbf42653b
-diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
---- a/gfx/angle/Makefile.in
-+++ b/gfx/angle/Makefile.in
-@@ -73,17 +73,17 @@ CPPSRCS = \
-         parseConst.cpp \
-         ParseHelper.cpp \
-         PoolAlloc.cpp \
-         QualifierAlive.cpp \
-         RemoveTree.cpp \
-         ShaderLang.cpp \
-         SymbolTable.cpp \
-         VariableInfo.cpp \
--        debug.cpp \
-+        compilerdebug.cpp \
-         ossource_nspr.cpp \
-         util.cpp \
-         ValidateLimitations.cpp \
-         ForLoopUnroll.cpp \
-         MapLongVariableNames.cpp \
-         BuiltInFunctionEmulator.cpp \
-         $(NULL)
+# Parent 8e2ee5b1a34208fd10f501fdee330878e20df599
+
+diff --git a/gfx/angle/src/compiler/Diagnostics.cpp b/gfx/angle/src/compiler/Diagnostics.cpp
+--- a/gfx/angle/src/compiler/Diagnostics.cpp
++++ b/gfx/angle/src/compiler/Diagnostics.cpp
+@@ -1,17 +1,17 @@
+ //
+ // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ //
+ 
+ #include "compiler/Diagnostics.h"
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/InfoSink.h"
+ #include "compiler/preprocessor/new/SourceLocation.h"
  
+ TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
+     mInfoSink(infoSink),
+     mNumErrors(0),
+     mNumWarnings(0)
+ {
+diff --git a/gfx/angle/src/compiler/DirectiveHandler.cpp b/gfx/angle/src/compiler/DirectiveHandler.cpp
+--- a/gfx/angle/src/compiler/DirectiveHandler.cpp
++++ b/gfx/angle/src/compiler/DirectiveHandler.cpp
+@@ -3,17 +3,17 @@
+ // Use of this source code is governed by a BSD-style license that can be
+ // found in the LICENSE file.
+ //
+ 
+ #include "compiler/DirectiveHandler.h"
+ 
+ #include <sstream>
+ 
+-#include "compiler/debug.h"
++#include "compiler/compilerdebug.h"
+ #include "compiler/Diagnostics.h"
+ 
+ static TBehavior getBehavior(const std::string& str)
+ {
+     static const std::string kRequire("require");
+     static const std::string kEnable("enable");
+     static const std::string kDisable("disable");
+     static const std::string kWarn("warn");
 diff --git a/gfx/angle/src/compiler/OutputGLSLBase.cpp b/gfx/angle/src/compiler/OutputGLSLBase.cpp
 --- a/gfx/angle/src/compiler/OutputGLSLBase.cpp
 +++ b/gfx/angle/src/compiler/OutputGLSLBase.cpp
 @@ -1,16 +1,16 @@
  //
  // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
@@ -41,35 +64,35 @@ diff --git a/gfx/angle/src/compiler/Outp
  TString getTypeName(const TType& type)
  {
      TInfoSinkBase out;
      if (type.isMatrix())
      {
 diff --git a/gfx/angle/src/compiler/OutputHLSL.cpp b/gfx/angle/src/compiler/OutputHLSL.cpp
 --- a/gfx/angle/src/compiler/OutputHLSL.cpp
 +++ b/gfx/angle/src/compiler/OutputHLSL.cpp
-@@ -1,17 +1,17 @@
- //
+@@ -2,17 +2,17 @@
  // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  //
  
  #include "compiler/OutputHLSL.h"
  
+ #include "common/angleutils.h"
 -#include "compiler/debug.h"
 +#include "compiler/compilerdebug.h"
  #include "compiler/InfoSink.h"
- #include "compiler/UnfoldSelect.h"
+ #include "compiler/UnfoldShortCircuit.h"
  #include "compiler/SearchSymbol.h"
+ #include "compiler/DetectDiscontinuity.h"
  
  #include <stdio.h>
  #include <algorithm>
  
- namespace sh
 diff --git a/gfx/angle/src/compiler/Types.h b/gfx/angle/src/compiler/Types.h
 --- a/gfx/angle/src/compiler/Types.h
 +++ b/gfx/angle/src/compiler/Types.h
 @@ -4,17 +4,17 @@
  // found in the LICENSE file.
  //
  
  #ifndef _TYPES_INCLUDED
@@ -82,41 +105,44 @@ diff --git a/gfx/angle/src/compiler/Type
  
  //
  // Need to have association of line numbers to types in a list for building structs.
  //
  class TType;
  struct TTypeLine {
      TType* type;
      int line;
-diff --git a/gfx/angle/src/compiler/compilerdebug.cpp b/gfx/angle/src/compiler/compilerdebug.cpp
---- a/gfx/angle/src/compiler/compilerdebug.cpp
+diff --git a/gfx/angle/src/compiler/debug.cpp b/gfx/angle/src/compiler/compilerdebug.cpp
+rename from gfx/angle/src/compiler/debug.cpp
+rename to gfx/angle/src/compiler/compilerdebug.cpp
+--- a/gfx/angle/src/compiler/debug.cpp
 +++ b/gfx/angle/src/compiler/compilerdebug.cpp
 @@ -1,17 +1,17 @@
  //
  // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  //
  
--// debug.cpp: Debugging utilities.
-+// compilerdebug.cpp: Debugging utilities.
+ // debug.cpp: Debugging utilities.
  
 -#include "compiler/debug.h"
 +#include "compiler/compilerdebug.h"
  
  #include <stdarg.h>
  #include <stdio.h>
  
+ #include "compiler/InitializeParseContext.h"
  #include "compiler/ParseHelper.h"
  
  static const int kTraceBufferLen = 1024;
- 
-diff --git a/gfx/angle/src/compiler/compilerdebug.h b/gfx/angle/src/compiler/compilerdebug.h
---- a/gfx/angle/src/compiler/compilerdebug.h
+diff --git a/gfx/angle/src/compiler/debug.h b/gfx/angle/src/compiler/compilerdebug.h
+rename from gfx/angle/src/compiler/debug.h
+rename to gfx/angle/src/compiler/compilerdebug.h
+--- a/gfx/angle/src/compiler/debug.h
 +++ b/gfx/angle/src/compiler/compilerdebug.h
 @@ -1,15 +1,15 @@
  //
  // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  //
  
@@ -128,17 +154,17 @@ diff --git a/gfx/angle/src/compiler/comp
  
  #include <assert.h>
  
  #ifdef _DEBUG
  #define TRACE_ENABLED  // define to enable debug message tracing
 diff --git a/gfx/angle/src/compiler/osinclude.h b/gfx/angle/src/compiler/osinclude.h
 --- a/gfx/angle/src/compiler/osinclude.h
 +++ b/gfx/angle/src/compiler/osinclude.h
-@@ -31,17 +31,17 @@
+@@ -32,17 +32,17 @@
  #include <windows.h>
  #elif defined(ANGLE_OS_POSIX)
  #include <pthread.h>
  #include <semaphore.h>
  #include <errno.h>
  #endif  // ANGLE_USE_NSPR
  
  
@@ -150,49 +176,71 @@ diff --git a/gfx/angle/src/compiler/osin
  //
  #if defined(ANGLE_USE_NSPR)
  typedef PRUintn OS_TLSIndex;
  #define OS_INVALID_TLS_INDEX 0xFFFFFFFF
  #elif defined(ANGLE_OS_WIN)
 diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
 --- a/gfx/angle/src/compiler/preprocessor/atom.c
 +++ b/gfx/angle/src/compiler/preprocessor/atom.c
-@@ -45,17 +45,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
- //
+@@ -46,17 +46,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
  // atom.c
  //
  
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  
+ #include "common/angleutils.h"
 -#include "compiler/debug.h"
 +#include "compiler/compilerdebug.h"
  #include "compiler/preprocessor/slglobals.h"
  
  #undef malloc
  #undef realloc
  #undef free
  
  ///////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////////////////// String table: //////////////////////////////////////
 diff --git a/gfx/angle/src/compiler/preprocessor/tokens.c b/gfx/angle/src/compiler/preprocessor/tokens.c
 --- a/gfx/angle/src/compiler/preprocessor/tokens.c
 +++ b/gfx/angle/src/compiler/preprocessor/tokens.c
-@@ -45,17 +45,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
- // tokens.c
+@@ -46,17 +46,17 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
  //
  
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <ctype.h>
  
+ #include "common/angleutils.h"
 -#include "compiler/debug.h"
 +#include "compiler/compilerdebug.h"
  #include "compiler/preprocessor/slglobals.h"
  #include "compiler/util.h"
  
  #if defined(_MSC_VER)
  #pragma warning(disable: 4054)
  #pragma warning(disable: 4152)
  #endif
  
+diff --git a/gfx/angle/src/compiler/translator_common.vcproj b/gfx/angle/src/compiler/translator_common.vcproj
+--- a/gfx/angle/src/compiler/translator_common.vcproj
++++ b/gfx/angle/src/compiler/translator_common.vcproj
+@@ -580,17 +580,17 @@
+ 				RelativePath=".\Common.h"
+ 				>
+ 			</File>
+ 			<File
+ 				RelativePath=".\ConstantUnion.h"
+ 				>
+ 			</File>
+ 			<File
+-				RelativePath=".\debug.h"
++				RelativePath=".\compilerdebug.h"
+ 				>
+ 			</File>
+ 			<File
+ 				RelativePath=".\DetectRecursion.h"
+ 				>
+ 			</File>
+ 			<File
+ 				RelativePath=".\Diagnostics.h"
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-renaming-preprocessor-diagonostics.patch
@@ -0,0 +1,6 @@
+# HG changeset patch
+# Parent 2cd2556d673d90f79dc29a78a927d2a38b92e14b
+
+diff --git a/gfx/angle/src/compiler/preprocessor/new/Diagnostics.cpp b/gfx/angle/src/compiler/preprocessor/new/PreprocessorDiagnostics.cpp
+rename from gfx/angle/src/compiler/preprocessor/new/Diagnostics.cpp
+rename to gfx/angle/src/compiler/preprocessor/new/PreprocessorDiagnostics.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-renaming-preprocessor-directivehandler.patch
@@ -0,0 +1,6 @@
+# HG changeset patch
+# Parent a98ccd93f2ab811670cb50edca50f6381274a345
+
+diff --git a/gfx/angle/src/compiler/preprocessor/new/DirectiveHandler.cpp b/gfx/angle/src/compiler/preprocessor/new/PreprocessorDirectiveHandler.cpp
+rename from gfx/angle/src/compiler/preprocessor/new/DirectiveHandler.cpp
+rename to gfx/angle/src/compiler/preprocessor/new/PreprocessorDirectiveHandler.cpp
deleted file mode 100644
--- a/gfx/angle/angle-use-xmalloc.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-# HG changeset patch
-# Parent 6ccfe6b908da8ade8b37e772ed8a9f3c494d8ef9
-diff --git a/gfx/angle/Makefile.in b/gfx/angle/Makefile.in
---- a/gfx/angle/Makefile.in
-+++ b/gfx/angle/Makefile.in
-@@ -127,16 +127,18 @@ CSRCS   = \
- 	$(NULL)
- 
- DEFINES += -DANGLE_USE_NSPR -DANGLE_BUILD -DCOMPILER_IMPLEMENTATION
- 
- #these defines are from ANGLE's build_angle.gyp
- DEFINES += -DANGLE_DISABLE_TRACE
- DEFINES += -DANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0
- 
-+EXTRA_DSO_LDOPTS = $(MOZALLOC_LIB)
-+
- ifdef MOZ_ANGLE_RENDERER
- 
- # libEGL depends on (links against!) libGLESv2!
- DIRS = src/libGLESv2 src/libEGL
- 
- libs::
- 	expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
- 	expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
-diff --git a/gfx/angle/src/compiler/preprocessor/atom.c b/gfx/angle/src/compiler/preprocessor/atom.c
---- a/gfx/angle/src/compiler/preprocessor/atom.c
-+++ b/gfx/angle/src/compiler/preprocessor/atom.c
-@@ -48,16 +48,18 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILI
- 
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- 
- #include "compiler/compilerdebug.h"
- #include "compiler/preprocessor/slglobals.h"
- 
-+#include "../../../../../memory/mozalloc/mozalloc.h"
-+
- #undef malloc
- #undef realloc
- #undef free
- 
- ///////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////// String table: //////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////////////////
- 
-@@ -318,31 +320,23 @@ static int AddAtomFixed(AtomTable *atabl
-  */
- 
- static int GrowAtomTable(AtomTable *atable, int size)
- {
-     int *newmap, *newrev;
- 
-     if (atable->size < size) {
-         if (atable->amap) {
--            newmap = realloc(atable->amap, sizeof(int)*size);
--            newrev = realloc(atable->arev, sizeof(int)*size);
-+            newmap = moz_xrealloc(atable->amap, sizeof(int)*size);
-+            newrev = moz_xrealloc(atable->arev, sizeof(int)*size);
-         } else {
--            newmap = malloc(sizeof(int)*size);
--            newrev = malloc(sizeof(int)*size);
-+            newmap = moz_xmalloc(sizeof(int)*size);
-+            newrev = moz_xmalloc(sizeof(int)*size);
-             atable->size = 0;
-         }
--        if (!newmap || !newrev) {
--            /* failed to grow -- error */
--            if (newmap)
--                atable->amap = newmap;
--            if (newrev)
--                atable->arev = newrev;
--            return -1;
--        }
-         memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
-         memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
-         atable->amap = newmap;
-         atable->arev = newrev;
-         atable->size = size;
-     }
-     return 0;
- } // GrowAtomTable
-diff --git a/gfx/angle/src/libEGL/Makefile.in b/gfx/angle/src/libEGL/Makefile.in
---- a/gfx/angle/src/libEGL/Makefile.in
-+++ b/gfx/angle/src/libEGL/Makefile.in
-@@ -153,8 +153,10 @@ RCFILE = $(srcdir)/libEGL.rc
- include $(topsrcdir)/config/rules.mk
- 
- EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
-                    "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/dxguid.lib" \
- 		   "$(DIST)/lib/libGLESv2.lib" \
- 		   dwmapi.lib \
- 		   delayimp.lib \
- 		   /delayload:dwmapi.dll
-+
-+EXTRA_DSO_LDOPTS += $(MOZALLOC_LIB)
-diff --git a/gfx/angle/src/libGLESv2/Makefile.in b/gfx/angle/src/libGLESv2/Makefile.in
---- a/gfx/angle/src/libGLESv2/Makefile.in
-+++ b/gfx/angle/src/libGLESv2/Makefile.in
-@@ -162,8 +162,10 @@ CPPSRCS	+= \
- DEFFILE = $(srcdir)/libGLESv2.def
- RCFILE = $(srcdir)/libGLESv2.rc
- 
- include $(topsrcdir)/config/rules.mk
- 
- EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
-                    "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3dx9.lib" \
- 		   "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/D3DCompiler.lib"
-+
-+EXTRA_DSO_LDOPTS += $(MOZALLOC_LIB)
--- a/gfx/angle/build/common.gypi
+++ b/gfx/angle/build/common.gypi
@@ -1,15 +1,31 @@
 # Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 {
   'variables': {
     'component%': 'static_library',
+    'gcc_or_clang_warnings': [
+      '-Wall',
+      '-Wchar-subscripts',
+      '-Werror',
+      '-Wextra',
+      '-Wformat=2',
+      '-Winit-self',
+      '-Wno-sign-compare',
+      '-Wno-unused-function',
+      '-Wno-unused-parameter',
+      '-Wno-unknown-pragmas',
+      '-Wpacked',
+      '-Wpointer-arith',
+      '-Wundef',
+      '-Wwrite-strings',
+    ],
   },
   'target_defaults': {
     'default_configuration': 'Debug',
     'variables': {
       'warn_as_error%': 1,
     },
     'target_conditions': [
       ['warn_as_error == 1', {
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_depth_texture.txt
@@ -0,0 +1,399 @@
+Name
+
+    ANGLE_depth_texture
+
+Name Strings
+
+    GL_ANGLE_depth_texture
+
+Contributors
+
+    Nicolas Capens, TransGaming
+    Kenneth Russell, Google
+    Vangelis Kokkevis, Google
+    Gregg Tavares, Google
+    Contributors to OES_depth_texture
+    Contributors to OES_packed_depth_stencil
+
+Contact
+
+    Daniel Koch, TransGaming (daniel 'at' transgaming.com)
+
+Status
+
+    Implemented in ANGLE.
+
+Version
+
+    Last Modifed Date: June 4, 2012
+    Revision: #3
+
+Number
+
+    TBD
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+    This extension is written against the OpenGL ES 2.0.25 specification
+
+    OES_packed_depth_stencil affects the definition of this extension.
+
+    EXT_texture_storage affects the definition of this extension.
+
+Overview
+
+    This extension defines support for 2D depth and depth-stencil
+    textures in an OpenGL ES implementation.
+
+    This extension incorporates the depth texturing functionality of 
+    OES_depth_texture and OES_packed_depth_stencil, but does not 
+    provide the ability to load existing data via TexImage2D or
+    TexSubImage2D. This extension also allows implementation 
+    variability in which components from a sampled depth texture
+    contain the depth data. Depth textures created with this
+    extension only support 1 level.
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted by the <format> parameter of TexImage2D and TexSubImage2D and
+    <internalformat> parameter of TexImage2D:
+    
+        DEPTH_COMPONENT             0x1902
+        DEPTH_STENCIL_OES           0x84F9
+        
+    Accepted by the <type> parameter of TexImage2D, TexSubImage2D: 
+
+        UNSIGNED_SHORT              0x1403
+        UNSIGNED_INT                0x1405
+        UNSIGNED_INT_24_8_OES       0x84FA
+
+    Accepted by the <internalformat> parameter of TexStorage2DEXT:
+
+        DEPTH_COMPONENT16           0x81A5
+        DEPTH_COMPONENT32_OES       0x81A7
+        DEPTH24_STENCIL8_OES        0x88F0
+
+Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL Operation)
+
+    Update Section 2.10.5 "Shader Execution" in the subsection titled 
+    "Texture Access" add a new paragraph before the last paragraph add
+    this line:
+
+    "The stencil index texture internal component is ignored if the base
+    internal format is DEPTH_STENCIL_OES.
+
+    If a vertex shader uses..."
+
+Additions to Chapter 3 of the OpenGL ES 2.0 specification (Rasterizatoin)
+
+    Add the following rows to Table 3.2 (page 62):
+
+      type Parameter           GL Data Type    Special
+      ------------------------------------------------
+      ...                      ...              ...
+      UNSIGNED_SHORT           ushort           No
+      UNSIGNED_INT             uint             No
+      UNSIGNED_INT_24_8_OES    uint             Yes
+
+    Add the following rows to Table 3.3 (page 62):
+
+      Format Name       Element Meaning and Order      Target Buffer
+      ------------------------------------------------------------------
+      ...               ...                            ...
+      DEPTH_COMPONENT   Depth                          Depth
+      DEPTH_STENCIL_OES Depth and Stencil Index        Depth and Stencil
+      ...               ...                            ...
+
+    Add a row to Table 3.5 "Packed pixel formats" (page 64):
+
+      type Parameter               GL Type  Components  Pixel Formats
+      ------------------------------------------------------------------
+      ...                          ...      ...         ...
+      UNSIGNED_INT_24_8_OES        uint     2           DEPTH_STENCIL_OES
+
+    Add a new table after Table 3.6 (page 64):
+
+    UNSIGNED_INT_24_8_OES
+
+       31 30 29 28 27 26 ... 12 11 10 9 8 7 6 5 4 3 2 1 0
+      +----------------------------------+---------------+
+      |           1st Component          | 2nd Component |
+      +----------------------------------+---------------+
+
+      Table 3.6.B: UNSIGNED_INT formats
+
+    Add a row to Table 3.7 "Packed pixel field assignments" (page 65):
+
+      Format            |  1st     2nd     3rd     4th
+      ------------------+-------------------------------
+      ...               |  ...     ...     ...     ...
+      DEPTH_STENCIL_OES |  depth   stencil N/A     N/A
+
+    Add the following paragraph to the end of the section "Conversion to
+    floating-point" (page 65):
+
+    "For groups of components that contain both standard components and index
+    elements, such as DEPTH_STENCIL_OES, the index elements are not converted."
+
+    In section 3.7.1 "Texture Image Specification", update page 67 to
+    say:
+
+    "The selected groups are processed as described in section 3.6.2, stopping
+    just before final conversion.  Each R, G, B, A, or depth value so generated
+    is clamped to [0, 1], while the stencil index values are masked by 2^n-1,
+    where n is the number of stencil bits in the internal format resolution
+    (see below).
+
+    Components are then selected from the resulting R, G, B, A, depth, or
+    stencil index values to obtain a texture with the base internal format
+    specified by <internalformat>.  Table 3.8 summarizes the mapping of R, G,
+    B, A, depth, or stencil values to texture components, as a function of the
+    base internal format of the texture image.  <internalformat> may be
+    specified as one of the internal format symbolic constants listed in
+    table 3.8. Specifying a value for <internalformat> that is not one of the
+    above values generates the error INVALID_VALUE. If <internalformat> does
+    not match <format>, the error INVALID_OPERATION is generated.
+
+    Textures with a base internal format of DEPTH_COMPONENT or 
+    DEPTH_STENCIL_OES are supported by texture image specification commands
+    only if <target> is TEXTURE_2D.  Using these formats in conjunction with
+    any other <target> will result in an INVALID_OPERATION error.
+
+    Textures with a base internal format of DEPTH_COMPONENT or
+    DEPTH_STENCIL_OES only support one level of image data.  Specifying a
+    non-zero value for <level> will result in an INVALID_OPERATION error.
+
+    Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL_OES
+    require either depth component data or depth/stencil component data.
+    Textures with other base internal formats require RGBA component data.  The
+    error INVALID_OPERATION is generated if the base internal format is
+    DEPTH_COMPONENT or DEPTH_STENCIL_OES and <format> is not DEPTH_COMPONENT or
+    DEPTH_STENCIL_OES, or if the base internal format is not DEPTH_COMPONENT or
+    DEPTH_STENCIL_OES and <format> is DEPTH_COMPONENT or DEPTH_STENCIL_OES.
+
+    Textures with a base internal format of DEPTH_COMPONENT or
+    DEPTH_STENCIL_OES do not support loading image data via the TexImage
+    commands. They can only have their contents specified by rendering
+    to them. The INVALID_OPERATION error is generated by the TexImage2D
+    command if <data> is not NULL for such textures."
+
+    Add a row to table 3.8 (page 68), and update the title of the
+    second column:
+
+      Base Internal Format  RGBA, Depth and Stencil Values  Internal Components
+      -------------------------------------------------------------------------
+      ...                   ...                             ...
+      DEPTH_COMPONENT       Depth                           D
+      DEPTH_STENCIL_OES     Depth,Stencil                   D,S
+      ...                   ...                             ...
+
+    Update the caption for table 3.8 (page 68)
+
+    "Table 3.8: Conversion from RGBA, depth, and stencil pixel components to
+    internal texture components.  Texture components R, G, B, A, and L are 
+    converted back to RGBA colors during filtering as shown in table 3.12.
+    Texture components D are converted to RGBA colors as described in 
+    section 3.7.8-1/2."
+
+    Add the following to section 3.7.2 "Alternate Texture Image Specification
+    Commands":
+
+    "CopyTexImage2D and CopyTexSubImage2D generate the INVALID_OPERATION 
+    error if the base internal format of the destination texture is 
+    DEPTH_COMPONENT or DEPTH_STENCIL_OES.
+
+    TexSubImage2D generates the INVALID_OPERATION error if the base internal
+    format of the texture is DEPTH_COMPONENT or DEPTH_STENCIL_OES."
+
+    Add a new section between sections 3.7.8 and 3.7.9:
+
+    "3.7.8-1/2 Depth/Stencil Textures
+
+    If the currently bound texture's base internal format is DEPTH_COMPONENT or
+    DEPTH_STENCIL_OES, then the output of the texture unit is as described
+    below. Otherwise, the texture unit operates in the normal manner.
+
+    Let <D_t> be the depth texture value, provided by the shader's texture lookup
+    function. Then the effective texture value, <L_t> or <A_t> is computed
+    as follows:
+            <Tau> = <D_t>
+
+    If the texture image has a base internal format of DEPTH_STENCIL_OES, then
+    the stencil index texture component is ignored.  The texture value <Tau> does
+    not include a stencil index component, but includes only the depth
+    component.
+
+    The resulting <Tau> is assigned to <L_t>. In some implementations, 
+    <Tau> is also assigned to <A_t>. Thus in table 3.12, textures with
+    depth component data behave as if their base internal format is
+    either LUMINANCE or LUMINANCE_ALPHA."
+
+    Add the following to section 3.7.11 "Mipmap Generation":
+
+    "If the level zero array contains depth or depth-stencil data, the
+     error INVALID_OPERATION is generated."
+
+    Insert a new paragraph after the first paragraph of the "Texture Access"
+    subsection of section 3.8.2 on page 87, which says:
+
+    "Texture lookups involving textures with depth component data generate
+    a texture source color by using depth data directly, as described in
+    section 3.7.8-1/2.  The stencil texture internal component is ignored
+    if the base internal format is DEPTH_STENCIL_OES."
+
+Additions to Chapter 4 of the OpenGL ES 2.0 specification (Per-Fragment
+Operations and the Framebuffer)
+
+    In section 4.4.5 "Framebuffer Completeness", replace the the 3rd
+    paragraph with the following text:
+
+     "* An internal format is color-renderable if it is one of the formats
+        from table 4.5 noted as color-renderable or if it is unsized format
+        RGBA or RGB. No other formats, including compressed internal formats,
+        are color-renderable.
+
+      * An internal format is depth-renderable if it is one of the sized
+        internal formats from table 4.5 noted as depth-renderable, if it
+        is the unsized format DEPTH_COMPONENT or if it is the internal 
+        format value of DEPTH24_STENCIL8_OES. No other formats are 
+        depth-renderable.
+
+      * An internal format is stencil-renderable if it is one of the sized 
+        internal formats from table 4.5 noted as stencil-renderable or if it
+        is DEPTH24_STENCIL8_OES. No other formats are stencil-renderable."
+
+Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special
+Functions)
+
+    None.
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    None.
+
+Interactions with OES_packed_depth_stencil
+
+    If OES_packed_depth_stencil is not supported, mentions of
+    DEPTH_STENCIL_OES and UNSIGNED_INT_24_8_OES as a format/type combinations
+    for TexImage2D and TexSubImage2D are omitted. Mentions of
+    the internal format DEPTH24_STENCIL8_OES are also omitted.
+
+Interactions with EXT_texture_storage
+
+    If EXT_texture_storage is supported the following internalformat
+    to format/type mappings are used:
+
+        <internalformat>       <format>           <type>
+        ----------------       --------           ------
+        DEPTH_COMPONENT16      DEPTH_COMPONENT    UNSIGNED_SHORT
+        DEPTH_COMPONENT32_OES  DEPTH_COMPONENT    UNSIGNED_INT
+        DEPTH24_STENCIL8_OES   DEPTH_STENCIL_OES  UNSIGNED_INT
+
+    Textures with the above <internalformats> only support one level of
+    image data. Specifying a value other than one for the <levels> parameter
+    to TexStorage2DEXT will result in an INVALID_OPERATION error.
+
+    If EXT_texture_storage is not supported, ignore any references
+    to TexStorage2DEXT. 
+
+Errors
+
+    The error INVALID_OPERATION is generated by TexImage2D if <format> and 
+    <internalformat> are DEPTH_COMPONENT and <type> is not UNSIGNED_SHORT,
+    or UNSIGNED_INT.
+
+    The error INVALID_OPERATION is generated by TexSubImage2D if <format> is 
+    DEPTH_COMPONENT and <type> is not UNSIGNED_SHORT, or UNSIGNED_INT.
+
+    The error INVALID_OPERATION is generated by TexImage2D if <format> and
+    <internalformat> are not DEPTH_COMPONENT and <type> is UNSIGNED_SHORT,
+    or UNSIGNED_INT.
+
+    The error INVALID_OPERATION is generated by TexSubImage2D if <format> is
+    not DEPTH_COMPONENT and <type> is UNSIGNED_SHORT, or UNSIGNED_INT.
+
+    The error INVALID_OPERATION is generated by TexImage2D if <format> and
+    <internalformat> are DEPTH_STENCIL_OES and <type> is not
+    UNSIGNED_INT_24_8_OES. 
+
+    The error INVALID_OPERATION is generated by TexSubImage2D if <format>
+    is DEPTH_STENCIL_OES and <type> is not UNSIGNED_INT_24_8_OES. 
+
+    The error INVALID_OPERATION is generated by TexImage2D if <format> and
+    <internalformat> is not DEPTH_STENCIL_OES and <type> is 
+    UNSIGNED_INT_24_8_OES.
+
+    The error INVALID_OPERATION is generated by TexSubImage2D if <format>
+    is not DEPTH_STENCIL_OES and <type> is UNSIGNED_INT_24_8_OES.
+
+    The error INVALID_OPERATION is generated in the following situations:
+    - TexImage2D is called with <format> and <internalformat> of
+      DEPTH_COMPONENT or DEPTH_STENCIL_OES and
+       - <target> is not TEXTURE_2D,
+       - <data> is not NULL, or
+       - <level> is not zero.
+    - TexSubImage2D is called with <format> of DEPTH_COMPONENT or 
+      DEPTH_STENCIL_OES.
+    - TexStorage2DEXT is called with <internalformat> of DEPTH_COMPONENT16,
+      DEPTH_COMPONENT32_OES, or DEPTH24_STENCIL8_OES, and 
+       - <target> is not TEXTURE_2D, or
+       - <levels> is not one.
+    - CopyTexImage2D is called with an <internalformat> that has a base
+      internal format of DEPTH_COMPONENT or DEPTH_STENCIL_OES.
+    - CopyTexSubImage2D is called with a target texture that has a base
+      internal format of DEPTH_COMPONENT or DEPTH_STENCIL_OES.
+    - GenerateMipmap is called on a texture that has a base internal format
+      of DEPTH_COMPONENT or DEPTH_STENCIL_OES.
+    
+New State
+
+    None.
+
+Issues
+
+    1) What are the differences between this extension and OES_depth_texture
+       and OES_packed_depth_stencil?
+    
+       RESOLVED: This extension:
+         - does not support loading pre-baked depth stencil data via 
+           TexImage2D or TexSubImage2D.
+         - allows variability in w-component of the sample results from
+           depth textures.
+         - only supports one level textures.
+         - explicitly lists the errors for unsupported functionality.
+           Since these were not clearly specified in the OES_depth_texture
+           extension there may be differences in error values between 
+           implementations of OES_depth_texture and ANGLE_depth_texture.
+       This specification was also rebased to apply against the OpenGL ES 2.0
+       specification instead of the OpenGL specification, making it more 
+       obvious what all the functionality changes are.
+
+    2) Why does TexSubImage2D accept the new format/type combinations even
+       though it does not actually support loading data?
+
+       RESOLVED: This was done to be more consistent with the OES_depth_texture
+       extension and to make it easier to add support for loading texture
+       data if it is possible to support in the future.
+
+    3) Why are only 1-level depth textures supported? 
+
+       RESOLVED: The only use for multiple levels of depth textures would
+       be for fitlered texturing. However since it is not possible to
+       render to non-zero-level texture levels in OpenGL ES 2.0, and since
+       this extension forbids loading existing data and GenerateMipmap on 
+       depth textures, it is impossible to initialize or specify contents
+       for non-zero levels of depth textures.
+
+Revision History
+ 
+    06/04/2012  dgkoch  fix errors, disallow multi-level depth textures.
+    05/30/2012  dgkoch  minor updates and add issues.
+    05/23/2012  dgkoch  intial revision based on OES_depth_texture and 
+                        OES_packed_depth_stencil and rebased against the ES 2.0 spec
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/extensions/ANGLE_program_binary.txt
@@ -0,0 +1,94 @@
+Name
+
+    ANGLE_program_binary
+
+Name Strings
+
+    GL_ANGLE_program_binary
+
+Contributors
+
+    Alastair Patrick, Google Inc.
+    Daniel Koch, TransGaming Inc.
+
+Contact
+
+    Alastair Patrick, Google Inc. (apatrick 'at' google 'dot' com)
+
+Status
+
+    Under development.
+
+Version
+
+    Last Modifed Date: June 6, 2012
+    Revision: #1
+
+Number
+
+    TBD
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+    OES_get_program_binary is required.
+    This extension is written against the OpenGL ES 2.0.25 specification.
+
+Overview
+
+    This extension makes available a program binary format,
+    PROGRAM_BINARY_ANGLE. It enables retrieving and loading of pre-linked
+    ANGLE program objects.
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted by the <binaryFormat> parameter of ProgramBinaryOES:
+
+        PROGRAM_BINARY_ANGLE        0x93A6
+
+Additions to Chapter 2 of the OpenGL-ES 2.0 Specification (OpenGL Operation)
+
+    Add the following paragraph to the end of section 2.15.4, Program Binaries:
+    
+    "PROGRAM_BINARY_ANGLE, returned in the list of PROGRAM_BINARY_FORMATS_OES,
+    is a format that may be loaded into a program object via ProgramBinaryOES." 
+    
+Additions to Chapter 3 of the OpenGL ES 2.0 specification (Rasterizatoin)
+
+    None.
+
+Additions to Chapter 4 of the OpenGL ES 2.0 specification (Per-Fragment
+Operations and the Framebuffer)
+
+    None.
+
+Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special
+Functions)
+
+    None.
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    None.
+
+Errors
+
+    None
+
+New State
+
+    None.
+
+Issues
+
+    None
+
+Revision History
+ 
+    06/06/2012  apatrick  intial revision
+
--- a/gfx/angle/extensions/ANGLE_timer_query.txt
+++ b/gfx/angle/extensions/ANGLE_timer_query.txt
@@ -1,591 +1,591 @@
-Name
-
-    ANGLE_timer_query
-
-Name Strings
-
-    GL_ANGLE_timer_query
-
-Contributors
-
-    Contributors to ARB_occlusion_query
-    Contributors to EXT_timer_query
-    Contributors to ARB_timer_query
-    Ben Vanik, Google Inc.
-    Daniel Koch, TransGaming Inc.
-
-Contact
-
-    Ben Vanik, Google Inc. (benvanik 'at' google 'dot' com)
-
-Status
-
-    Draft
-
-Version
-
-    Last Modified Date: Apr 28, 2011
-    Author Revision: 1
-
-Number
-
-    OpenGL ES Extension #??
-
-Dependencies
-
-    OpenGL ES 2.0 is required.
-
-    The extension is written against the OpenGL ES 2.0 specification.
-
-Overview
-
-    Applications can benefit from accurate timing information in a number of
-    different ways.  During application development, timing information can
-    help identify application or driver bottlenecks.  At run time,
-    applications can use timing information to dynamically adjust the amount
-    of detail in a scene to achieve constant frame rates.  OpenGL
-    implementations have historically provided little to no useful timing
-    information.  Applications can get some idea of timing by reading timers
-    on the CPU, but these timers are not synchronized with the graphics
-    rendering pipeline.  Reading a CPU timer does not guarantee the completion
-    of a potentially large amount of graphics work accumulated before the
-    timer is read, and will thus produce wildly inaccurate results.
-    glFinish() can be used to determine when previous rendering commands have
-    been completed, but will idle the graphics pipeline and adversely affect
-    application performance.
-
-    This extension provides a query mechanism that can be used to determine
-    the amount of time it takes to fully complete a set of GL commands, and
-    without stalling the rendering pipeline.  It uses the query object
-    mechanisms first introduced in the occlusion query extension, which allow
-    time intervals to be polled asynchronously by the application.
-
-IP Status
-
-    No known IP claims.
-
-New Procedures and Functions
-
-    void GenQueriesANGLE(sizei n, uint *ids);
-    void DeleteQueriesANGLE(sizei n, const uint *ids);
-    boolean IsQueryANGLE(uint id);
-    void BeginQueryANGLE(enum target, uint id);
-    void EndQueryANGLE(enum target);
-    void QueryCounterANGLE(uint id, enum target);
-    void GetQueryivANGLE(enum target, enum pname, int *params);
-    void GetQueryObjectivANGLE(uint id, enum pname, int *params);
-    void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
-    void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
-    void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
-
-New Tokens
-
-    Accepted by the <pname> parameter of GetQueryivANGLE:
-
-        QUERY_COUNTER_BITS_ANGLE                       0x8864
-        CURRENT_QUERY_ANGLE                            0x8865
-
-    Accepted by the <pname> parameter of GetQueryObjectivANGLE,
-    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, and
-    GetQueryObjectui64vANGLE:
-
-        QUERY_RESULT_ANGLE                             0x8866
-        QUERY_RESULT_AVAILABLE_ANGLE                   0x8867
-        
-    Accepted by the <target> parameter of BeginQueryANGLE, EndQueryANGLE, and
-    GetQueryivANGLE:
-
-        TIME_ELAPSED_ANGLE                             0x88BF
-
-    Accepted by the <target> parameter of GetQueryivANGLE and
-    QueryCounterANGLE:
-
-        TIMESTAMP_ANGLE                                0x8E28
-
-Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
-
-    (Modify table 2.1, Correspondence of command suffix letters to GL argument)
-    Add two new types:
-    
-    Letter Corresponding GL Type
-    ------ ---------------------
-    i64    int64ANGLE
-    ui64   uint64ANGLE
-
-    (Modify table 2.2, GL data types) Add two new types:
-    
-    GL Type       Minimum Bit Width   Description
-    -------       -----------------   -----------------------------
-    int64ANGLE    64                  Signed 2's complement integer
-    uint64ANGLE   64                  Unsigned binary integer
-
-Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
-
-    Add a new section 5.3 "Timer Queries":
-
-    "5.3  Timer Queries
-
-    Timer queries use query objects to track the amount of time needed to
-    fully complete a set of GL commands, or to determine the current time
-    of the GL.
-    
-    Timer queries are associated with query objects.  The command
-
-      void GenQueriesANGLE(sizei n, uint *ids);
-
-    returns <n> previously unused query object names in <ids>.  These
-    names are marked as used, but no object is associated with them until
-    the first time they are used by BeginQueryANGLE.  Query objects contain
-    one piece of state, an integer result value.  This result value is
-    initialized to zero when the object is created.  Any positive integer
-    except for zero (which is reserved for the GL) is a valid query
-    object name.
-
-    Query objects are deleted by calling
-
-      void DeleteQueriesANGLE(sizei n, const uint *ids);
-
-    <ids> contains <n> names of query objects to be deleted.  After a
-    query object is deleted, its name is again unused.  Unused names in
-    <ids> are silently ignored.
-    If an active query object is deleted its name immediately becomes unused,
-    but the underlying object is not deleted until it is no longer active.
-
-    A timer query can be started and finished by calling
-
-      void BeginQueryANGLE(enum target, uint id);
-      void EndQueryANGLE(enum target);
-
-    where <target> is TIME_ELAPSED_ANGLE.  If BeginQueryANGLE is called
-    with an unused <id>, that name is marked as used and associated with
-    a new query object.
-    
-    If BeginQueryANGLE is called with an <id> of zero, if the active query
-    object name for <target> is non-zero, if <id> is the name of an existing
-    query object whose type does not match <target>, or if <id> is the active
-    query object name for any query type, the error INVALID_OPERATION is
-    generated.  If EndQueryANGLE is called while no query with the same target
-    is in progress, an INVALID_OPERATION error is generated.
-
-    When BeginQueryANGLE and EndQueryANGLE are called with a <target> of
-    TIME_ELAPSED_ANGLE, the GL prepares to start and stop the timer used for
-    timer queries.  The timer is started or stopped when the effects from all
-    previous commands on the GL client and server state and the framebuffer
-    have been fully realized.  The BeginQueryANGLE and EndQueryANGLE commands
-    may return before the timer is actually started or stopped.  When the timer
-    query timer is finally stopped, the elapsed time (in nanoseconds) is
-    written to the corresponding query object as the query result value, and
-    the query result for that object is marked as available.
-
-    If the elapsed time overflows the number of bits, <n>, available to hold
-    elapsed time, its value becomes undefined.  It is recommended, but not
-    required, that implementations handle this overflow case by saturating at
-    2^n - 1.
-
-    The necessary state is a single bit indicating whether an timer
-    query is active, the identifier of the currently active timer
-    query, and a counter keeping track of the time that has passed.
-
-    When the command
-
-         void QueryCounterANGLE(uint id, enum target);
-
-    is called with <target> TIMESTAMP_ANGLE, the GL records the current time
-    into the corresponding query object. The time is recorded after all
-    previous commands on the GL client and server state and the framebuffer
-    have been fully realized. When the time is recorded, the query result for
-    that object is marked available. QueryCounterANGLE timer queries can be
-    used within a BeginQueryANGLE / EndQueryANGLE block where the <target> is
-    TIME_ELAPSED_ANGLE and it does not affect the result of that query object.
-    The error INVALID_OPERATION is generated if the <id> is already in use
-    within a BeginQueryANGLE/EndQueryANGLE block."
-
-Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
-Requests)
-
-    Add a new section 6.1.9 "Timer Queries":
-
-    "The command
-
-      boolean IsQueryANGLE(uint id);
-
-    returns TRUE if <id> is the name of a query object.  If <id> is zero,
-    or if <id> is a non-zero value that is not the name of a query
-    object, IsQueryANGLE returns FALSE.
-
-    Information about a query target can be queried with the command
-
-      void GetQueryivANGLE(enum target, enum pname, int *params);
-
-    <target> identifies the query target and can be TIME_ELAPSED_ANGLE or
-    TIMESTAMP_ANGLE for timer queries.
-
-    If <pname> is CURRENT_QUERY_ANGLE, the name of the currently active query
-    for <target>, or zero if no query is active, will be placed in <params>.
-
-    If <pname> is QUERY_COUNTER_BITS_ANGLE, the implementation-dependent number
-    of bits used to hold the query result for <target> will be placed in
-    <params>.  The number of query counter bits may be zero, in which case
-    the counter contains no useful information.
-
-    For timer queries (TIME_ELAPSED_ANGLE and TIMESTAMP_ANGLE), if the number
-    of bits is non-zero, the minimum number of bits allowed is 30 which
-    will allow at least 1 second of timing.
-
-    The state of a query object can be queried with the commands
-
-      void GetQueryObjectivANGLE(uint id, enum pname, int *params);
-      void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
-      void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
-      void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
-
-    If <id> is not the name of a query object, or if the query object
-    named by <id> is currently active, then an INVALID_OPERATION error is
-    generated.
-
-    If <pname> is QUERY_RESULT_ANGLE, then the query object's result
-    value is returned as a single integer in <params>. If the value is so
-    large in magnitude that it cannot be represented with the requested type,
-    then the nearest value representable using the requested type is
-    returned. If the number of query counter bits for target is zero, then
-    the result is returned as a single integer with the value zero.
-    
-    There may be an indeterminate delay before the above query returns. If
-    <pname> is QUERY_RESULT_AVAILABLE_ANGLE, FALSE is returned if such a delay
-    would be required; otherwise TRUE is returned. It must always be true
-    that if any query object returns a result available of TRUE, all queries
-    of the same type issued prior to that query must also return TRUE.
-
-    Querying the state for a given timer query forces that timer query to
-    complete within a finite amount of time.
-
-    If multiple queries are issued on the same target and id prior to 
-    calling GetQueryObject[u]i[64]vANGLE, the result returned will always be
-    from the last query issued.  The results from any queries before the
-    last one will be lost if the results are not retrieved before starting
-    a new query on the same <target> and <id>."
-
-Errors
-
-    The error INVALID_VALUE is generated if GenQueriesANGLE is called where
-    <n> is negative.
-
-    The error INVALID_VALUE is generated if DeleteQueriesANGLE is called
-    where <n> is negative.
-
-    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
-    when a query of the given <target> is already active.
-
-    The error INVALID_OPERATION is generated if EndQueryANGLE is called
-    when a query of the given <target> is not active.
-
-    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
-    where <id> is zero.
-
-    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
-    where <id> is the name of a query currently in progress.
-    
-    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
-    where <id> is the name of an existing query object whose type does not
-    match <target>.
-
-    The error INVALID_ENUM is generated if BeginQueryANGLE or EndQueryANGLE
-    is called where <target> is not TIME_ELAPSED_ANGLE.
-
-    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
-    <target> is not TIME_ELAPSED_ANGLE or TIMESTAMP_ANGLE.
-
-    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
-    <pname> is not QUERY_COUNTER_BITS_ANGLE or CURRENT_QUERY_ANGLE.
-
-    The error INVALID_ENUM is generated if QueryCounterANGLE is called where
-    <target> is not TIMESTAMP_ANGLE.
-
-    The error INVALID_OPERATION is generated if QueryCounterANGLE is called
-    on a query object that is already in use inside a
-    BeginQueryANGLE/EndQueryANGLE.
-
-    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
-    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
-    GetQueryObjectui64vANGLE is called where <id> is not the name of a query
-    object.
-
-    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
-    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
-    GetQueryObjectui64vANGLE is called where <id> is the name of a currently
-    active query object.
-
-    The error INVALID_ENUM is generated if GetQueryObjectivANGLE,
-    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
-    GetQueryObjectui64vANGLE is called where <pname> is not
-    QUERY_RESULT_ANGLE or QUERY_RESULT_AVAILABLE_ANGLE.
-
-New State
-
-    (Add a new table 6.xx, "Query Operations")
-    
-    Get Value                      Type    Get Command              Initial Value   Description              Sec
-    ---------                      ----    -----------              -------------   -----------              ------
-    -                              B       -                        FALSE           query active             5.3
-    CURRENT_QUERY_ANGLE            Z+      GetQueryivANGLE          0               active query ID          5.3
-    QUERY_RESULT_ANGLE             Z+      GetQueryObjectuivANGLE,  0               samples-passed count     5.3
-                                           GetQueryObjectui64vANGLE
-    QUERY_RESULT_AVAILABLE_ANGLE   B       GetQueryObjectivANGLE    FALSE           query result available   5.3
-
-New Implementation Dependent State
-
-    (Add the following entry to table 6.18):
-
-    Get Value                      Type    Get Command      Minimum Value      Description           Sec
-    --------------------------     ----    -----------      -------------      ----------------      ------
-    QUERY_COUNTER_BITS_ANGLE       Z+      GetQueryivANGLE  see 6.1.9          Number of bits in     6.1.9
-                                                                               query counter
-
-Examples
-
-    (1) Here is some rough sample code that demonstrates the intended usage
-        of this extension.
-
-        GLint queries[N];
-        GLint available = 0;
-        // timer queries can contain more than 32 bits of data, so always
-        // query them using the 64 bit types to avoid overflow
-        GLuint64ANGLE timeElapsed = 0;
-
-        // Create a query object.
-        glGenQueriesANGLE(N, queries);
-
-        // Start query 1
-        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[0]);
-
-        // Draw object 1
-        ....
-
-        // End query 1
-        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
-
-        ...
-
-        // Start query N
-        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[N-1]);
-
-        // Draw object N
-        ....
-
-        // End query N
-        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
-
-        // Wait for all results to become available
-        while (!available) {
-            glGetQueryObjectivANGLE(queries[N-1], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
-        }
-
-        for (i = 0; i < N; i++) {
-            // See how much time the rendering of object i took in nanoseconds.
-            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeElapsed);
-
-            // Do something useful with the time.  Note that care should be
-            // taken to use all significant bits of the result, not just the
-            // least significant 32 bits.
-            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
-        }
-
-        This example is sub-optimal in that it stalls at the end of every
-        frame to wait for query results.  Ideally, the collection of results
-        would be delayed one frame to minimize the amount of time spent
-        waiting for the GPU to finish rendering.
-        
-    (2) This example is basically the same as the example above but uses
-        QueryCounter instead.
-    
-        GLint queries[N+1];
-        GLint available = 0;
-        // timer queries can contain more than 32 bits of data, so always
-        // query them using the 64 bit types to avoid overflow
-        GLuint64ANGLE timeStart, timeEnd, timeElapsed = 0;
-
-        // Create a query object.
-        glGenQueriesANGLE(N+1, queries);
-
-        // Query current timestamp 1
-        glQueryCounterANGLE(queries[0], GL_TIMESTAMP_ANGLE);
-
-        // Draw object 1
-        ....
-
-        // Query current timestamp N
-        glQueryCounterANGLE(queries[N-1], GL_TIMESTAMP_ANGLE);
-
-        // Draw object N
-        ....
-
-        // Query current timestamp N+1
-        glQueryCounterANGLE(queries[N], GL_TIMESTAMP_ANGLE);
-
-        // Wait for all results to become available
-        while (!available) {
-            glGetQueryObjectivANGLE(queries[N], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
-        }
-
-        for (i = 0; i < N; i++) {
-            // See how much time the rendering of object i took in nanoseconds.
-            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeStart);
-            glGetQueryObjectui64vANGLE(queries[i+1], GL_QUERY_RESULT_ANGLE, &timeEnd);
-            timeElapsed = timeEnd - timeStart;
-
-            // Do something useful with the time.  Note that care should be
-            // taken to use all significant bits of the result, not just the
-            // least significant 32 bits.
-            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
-        }
-
-Issues from EXT_timer_query
-
-    (1) What time interval is being measured?
-
-    RESOLVED:  The timer starts when all commands prior to BeginQuery() have
-    been fully executed.  At that point, everything that should be drawn by
-    those commands has been written to the framebuffer.  The timer stops
-    when all commands prior to EndQuery() have been fully executed.
-
-    (2) What unit of time will time intervals be returned in?
-
-    RESOLVED:  Nanoseconds (10^-9 seconds).  This unit of measurement allows
-    for reasonably accurate timing of even small blocks of rendering
-    commands.  The granularity of the timer is implementation-dependent.  A
-    32-bit query counter can express intervals of up to approximately 4
-    seconds.
-
-    (3) What should be the minimum number of counter bits for timer queries?
-
-    RESOLVED:  30 bits, which will allow timing sections that take up to 1
-    second to render.
-
-    (4) How are counter results of more than 32 bits returned?
-
-    RESOLVED:  Via two new datatypes, int64ANGLE and uint64ANGLE, and their
-    corresponding GetQueryObject entry points.  These types hold integer
-    values and have a minimum bit width of 64.
-
-    (5) Should the extension measure total time elapsed between the full
-        completion of the BeginQuery and EndQuery commands, or just time
-        spent in the graphics library?
-
-    RESOLVED:  This extension will measure the total time elapsed between
-    the full completion of these commands.  Future extensions may implement
-    a query to determine time elapsed at different stages of the graphics
-    pipeline.
-
-    (6) If multiple query types are supported, can multiple query types be
-        active simultaneously?
-
-    RESOLVED:  Yes; an application may perform a timer query and another
-    type of query simultaneously.  An application can not perform multiple
-    timer queries or multiple queries of other types simultaneously.  An
-    application also can not use the same query object for another query
-    and a timer query simultaneously.
-
-    (7) Do query objects have a query type permanently associated with them?
-
-    RESOLVED:  No.  A single query object can be used to perform different
-    types of queries, but not at the same time.
-
-    Having a fixed type for each query object simplifies some aspects of the
-    implementation -- not having to deal with queries with different result
-    sizes, for example.  It would also mean that BeginQuery() with a query
-    object of the "wrong" type would result in an INVALID_OPERATION error.
-
-    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
-    Since EXT_transform_feedback has since been incorporated into the core,
-    the resolution is that BeginQuery will generate error INVALID_OPERATION
-    if <id> represents a query object of a different type.
-
-    (8) How predictable/repeatable are the results returned by the timer
-        query?
-
-    RESOLVED:  In general, the amount of time needed to render the same
-    primitives should be fairly constant.  But there may be many other
-    system issues (e.g., context switching on the CPU and GPU, virtual
-    memory page faults, memory cache behavior on the CPU and GPU) that can
-    cause times to vary wildly.
-
-    Note that modern GPUs are generally highly pipelined, and may be
-    processing different primitives in different pipeline stages
-    simultaneously.  In this extension, the timers start and stop when the
-    BeginQuery/EndQuery commands reach the bottom of the rendering pipeline.
-    What that means is that by the time the timer starts, the GL driver on
-    the CPU may have started work on GL commands issued after BeginQuery,
-    and the higher pipeline stages (e.g., vertex transformation) may have
-    started as well.
-
-   (9) What should the new 64 bit integer type be called?
-
-    RESOLVED: The new types will be called GLint64ANGLE/GLuint64ANGLE.  The new
-    command suffixes will be i64 and ui64.  These names clearly convey the
-    minimum size of the types.  These types are similar to the C99 standard
-    type int_least64_t, but we use names similar to the C99 optional type
-    int64_t for simplicity.
-
-Issues from ARB_timer_query
-
-   (10) What about tile-based implementations? The effects of a command are
-        not complete until the frame is completely rendered. Timing recorded
-        before the frame is complete may not be what developers expect. Also
-        the amount of time needed to render the same primitives is not
-        consistent, which conflicts with issue (8) above. The time depends on
-        how early or late in the scene it is placed.
-
-    RESOLVED: The current language supports tile-based rendering okay as it
-    is written. Developers are warned that using timers on tile-based
-    implementation may not produce results they expect since rendering is not
-    done in a linear order. Timing results are calculated when the frame is
-    completed and may depend on how early or late in the scene it is placed.
-    
-   (11) Can the GL implementation use different clocks to implement the
-        TIME_ELAPSED and TIMESTAMP queries?
-
-   RESOLVED: Yes, the implemenation can use different internal clocks to
-   implement TIME_ELAPSED and TIMESTAMP. If different clocks are
-   used it is possible there is a slight discrepancy when comparing queries
-   made from TIME_ELAPSED and TIMESTAMP; they may have slight
-   differences when both are used to measure the same sequence. However, this
-   is unlikely to affect real applications since comparing the two queries is
-   not expected to be useful.
-
-Issues
-
-    (12) What should we call this extension?
-
-    RESOLVED: ANGLE_timer_query
-
-    (13) Why is this done as a separate extension instead of just supporting
-         ARB_timer_query?
-
-    ARB_timer_query is written against OpenGL 3.2, which includes a lot of
-    the required support for dealing with query objects. None of these
-    functions or tokens exist in OpenGL ES, and as such have to be added in
-    this specification.
-
-    (14) How does this extension differ from ARB_timer_query?
-
-    This extension contains most ARB_timer_query behavior unchanged as well
-    as a subset of the query support required to use it from the core
-    OpenGL 3.2 spec. It omits the glGetInteger(TIMESTAMP) functionality used to
-    query the current time on the GPU, but the behavior for all remaining
-    functionality taken from ARB_timer_query is the same.
-    
-    (15) Are query objects shareable between multiple contexts?
-
-    RESOLVED: No.  Query objects are lightweight and we normally share 
-    large data across contexts.  Also, being able to share query objects
-    across contexts is not particularly useful.  In order to do the async 
-    query across contexts, a query on one context would have to be finished 
-    before the other context could query it. 
-
-Revision History
-
-    Revision 1, 2011/04/28
-      - copied from revision 9 of ARB_timer_query and revision 7 of
-        ARB_occlusion_query
-      - removed language that was clearly not relevant to ES2
-      - rebased changes against the OpenGL ES 2.0 specification
+Name
+
+    ANGLE_timer_query
+
+Name Strings
+
+    GL_ANGLE_timer_query
+
+Contributors
+
+    Contributors to ARB_occlusion_query
+    Contributors to EXT_timer_query
+    Contributors to ARB_timer_query
+    Ben Vanik, Google Inc.
+    Daniel Koch, TransGaming Inc.
+
+Contact
+
+    Ben Vanik, Google Inc. (benvanik 'at' google 'dot' com)
+
+Status
+
+    Draft
+
+Version
+
+    Last Modified Date: Apr 28, 2011
+    Author Revision: 1
+
+Number
+
+    OpenGL ES Extension #??
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+    The extension is written against the OpenGL ES 2.0 specification.
+
+Overview
+
+    Applications can benefit from accurate timing information in a number of
+    different ways.  During application development, timing information can
+    help identify application or driver bottlenecks.  At run time,
+    applications can use timing information to dynamically adjust the amount
+    of detail in a scene to achieve constant frame rates.  OpenGL
+    implementations have historically provided little to no useful timing
+    information.  Applications can get some idea of timing by reading timers
+    on the CPU, but these timers are not synchronized with the graphics
+    rendering pipeline.  Reading a CPU timer does not guarantee the completion
+    of a potentially large amount of graphics work accumulated before the
+    timer is read, and will thus produce wildly inaccurate results.
+    glFinish() can be used to determine when previous rendering commands have
+    been completed, but will idle the graphics pipeline and adversely affect
+    application performance.
+
+    This extension provides a query mechanism that can be used to determine
+    the amount of time it takes to fully complete a set of GL commands, and
+    without stalling the rendering pipeline.  It uses the query object
+    mechanisms first introduced in the occlusion query extension, which allow
+    time intervals to be polled asynchronously by the application.
+
+IP Status
+
+    No known IP claims.
+
+New Procedures and Functions
+
+    void GenQueriesANGLE(sizei n, uint *ids);
+    void DeleteQueriesANGLE(sizei n, const uint *ids);
+    boolean IsQueryANGLE(uint id);
+    void BeginQueryANGLE(enum target, uint id);
+    void EndQueryANGLE(enum target);
+    void QueryCounterANGLE(uint id, enum target);
+    void GetQueryivANGLE(enum target, enum pname, int *params);
+    void GetQueryObjectivANGLE(uint id, enum pname, int *params);
+    void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
+    void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
+    void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
+
+New Tokens
+
+    Accepted by the <pname> parameter of GetQueryivANGLE:
+
+        QUERY_COUNTER_BITS_ANGLE                       0x8864
+        CURRENT_QUERY_ANGLE                            0x8865
+
+    Accepted by the <pname> parameter of GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, and
+    GetQueryObjectui64vANGLE:
+
+        QUERY_RESULT_ANGLE                             0x8866
+        QUERY_RESULT_AVAILABLE_ANGLE                   0x8867
+        
+    Accepted by the <target> parameter of BeginQueryANGLE, EndQueryANGLE, and
+    GetQueryivANGLE:
+
+        TIME_ELAPSED_ANGLE                             0x88BF
+
+    Accepted by the <target> parameter of GetQueryivANGLE and
+    QueryCounterANGLE:
+
+        TIMESTAMP_ANGLE                                0x8E28
+
+Additions to Chapter 2 of the OpenGL ES 2.0 Specification (OpenGL ES Operation)
+
+    (Modify table 2.1, Correspondence of command suffix letters to GL argument)
+    Add two new types:
+    
+    Letter Corresponding GL Type
+    ------ ---------------------
+    i64    int64ANGLE
+    ui64   uint64ANGLE
+
+    (Modify table 2.2, GL data types) Add two new types:
+    
+    GL Type       Minimum Bit Width   Description
+    -------       -----------------   -----------------------------
+    int64ANGLE    64                  Signed 2's complement integer
+    uint64ANGLE   64                  Unsigned binary integer
+
+Additions to Chapter 5 of the OpenGL ES 2.0 Specification (Special Functions)
+
+    Add a new section 5.3 "Timer Queries":
+
+    "5.3  Timer Queries
+
+    Timer queries use query objects to track the amount of time needed to
+    fully complete a set of GL commands, or to determine the current time
+    of the GL.
+    
+    Timer queries are associated with query objects.  The command
+
+      void GenQueriesANGLE(sizei n, uint *ids);
+
+    returns <n> previously unused query object names in <ids>.  These
+    names are marked as used, but no object is associated with them until
+    the first time they are used by BeginQueryANGLE.  Query objects contain
+    one piece of state, an integer result value.  This result value is
+    initialized to zero when the object is created.  Any positive integer
+    except for zero (which is reserved for the GL) is a valid query
+    object name.
+
+    Query objects are deleted by calling
+
+      void DeleteQueriesANGLE(sizei n, const uint *ids);
+
+    <ids> contains <n> names of query objects to be deleted.  After a
+    query object is deleted, its name is again unused.  Unused names in
+    <ids> are silently ignored.
+    If an active query object is deleted its name immediately becomes unused,
+    but the underlying object is not deleted until it is no longer active.
+
+    A timer query can be started and finished by calling
+
+      void BeginQueryANGLE(enum target, uint id);
+      void EndQueryANGLE(enum target);
+
+    where <target> is TIME_ELAPSED_ANGLE.  If BeginQueryANGLE is called
+    with an unused <id>, that name is marked as used and associated with
+    a new query object.
+    
+    If BeginQueryANGLE is called with an <id> of zero, if the active query
+    object name for <target> is non-zero, if <id> is the name of an existing
+    query object whose type does not match <target>, or if <id> is the active
+    query object name for any query type, the error INVALID_OPERATION is
+    generated.  If EndQueryANGLE is called while no query with the same target
+    is in progress, an INVALID_OPERATION error is generated.
+
+    When BeginQueryANGLE and EndQueryANGLE are called with a <target> of
+    TIME_ELAPSED_ANGLE, the GL prepares to start and stop the timer used for
+    timer queries.  The timer is started or stopped when the effects from all
+    previous commands on the GL client and server state and the framebuffer
+    have been fully realized.  The BeginQueryANGLE and EndQueryANGLE commands
+    may return before the timer is actually started or stopped.  When the timer
+    query timer is finally stopped, the elapsed time (in nanoseconds) is
+    written to the corresponding query object as the query result value, and
+    the query result for that object is marked as available.
+
+    If the elapsed time overflows the number of bits, <n>, available to hold
+    elapsed time, its value becomes undefined.  It is recommended, but not
+    required, that implementations handle this overflow case by saturating at
+    2^n - 1.
+
+    The necessary state is a single bit indicating whether an timer
+    query is active, the identifier of the currently active timer
+    query, and a counter keeping track of the time that has passed.
+
+    When the command
+
+         void QueryCounterANGLE(uint id, enum target);
+
+    is called with <target> TIMESTAMP_ANGLE, the GL records the current time
+    into the corresponding query object. The time is recorded after all
+    previous commands on the GL client and server state and the framebuffer
+    have been fully realized. When the time is recorded, the query result for
+    that object is marked available. QueryCounterANGLE timer queries can be
+    used within a BeginQueryANGLE / EndQueryANGLE block where the <target> is
+    TIME_ELAPSED_ANGLE and it does not affect the result of that query object.
+    The error INVALID_OPERATION is generated if the <id> is already in use
+    within a BeginQueryANGLE/EndQueryANGLE block."
+
+Additions to Chapter 6 of the OpenGL ES 2.0 Specification (State and State
+Requests)
+
+    Add a new section 6.1.9 "Timer Queries":
+
+    "The command
+
+      boolean IsQueryANGLE(uint id);
+
+    returns TRUE if <id> is the name of a query object.  If <id> is zero,
+    or if <id> is a non-zero value that is not the name of a query
+    object, IsQueryANGLE returns FALSE.
+
+    Information about a query target can be queried with the command
+
+      void GetQueryivANGLE(enum target, enum pname, int *params);
+
+    <target> identifies the query target and can be TIME_ELAPSED_ANGLE or
+    TIMESTAMP_ANGLE for timer queries.
+
+    If <pname> is CURRENT_QUERY_ANGLE, the name of the currently active query
+    for <target>, or zero if no query is active, will be placed in <params>.
+
+    If <pname> is QUERY_COUNTER_BITS_ANGLE, the implementation-dependent number
+    of bits used to hold the query result for <target> will be placed in
+    <params>.  The number of query counter bits may be zero, in which case
+    the counter contains no useful information.
+
+    For timer queries (TIME_ELAPSED_ANGLE and TIMESTAMP_ANGLE), if the number
+    of bits is non-zero, the minimum number of bits allowed is 30 which
+    will allow at least 1 second of timing.
+
+    The state of a query object can be queried with the commands
+
+      void GetQueryObjectivANGLE(uint id, enum pname, int *params);
+      void GetQueryObjectuivANGLE(uint id, enum pname, uint *params);
+      void GetQueryObjecti64vANGLE(uint id, enum pname, int64 *params);
+      void GetQueryObjectui64vANGLE(uint id, enum pname, uint64 *params);
+
+    If <id> is not the name of a query object, or if the query object
+    named by <id> is currently active, then an INVALID_OPERATION error is
+    generated.
+
+    If <pname> is QUERY_RESULT_ANGLE, then the query object's result
+    value is returned as a single integer in <params>. If the value is so
+    large in magnitude that it cannot be represented with the requested type,
+    then the nearest value representable using the requested type is
+    returned. If the number of query counter bits for target is zero, then
+    the result is returned as a single integer with the value zero.
+    
+    There may be an indeterminate delay before the above query returns. If
+    <pname> is QUERY_RESULT_AVAILABLE_ANGLE, FALSE is returned if such a delay
+    would be required; otherwise TRUE is returned. It must always be true
+    that if any query object returns a result available of TRUE, all queries
+    of the same type issued prior to that query must also return TRUE.
+
+    Querying the state for a given timer query forces that timer query to
+    complete within a finite amount of time.
+
+    If multiple queries are issued on the same target and id prior to 
+    calling GetQueryObject[u]i[64]vANGLE, the result returned will always be
+    from the last query issued.  The results from any queries before the
+    last one will be lost if the results are not retrieved before starting
+    a new query on the same <target> and <id>."
+
+Errors
+
+    The error INVALID_VALUE is generated if GenQueriesANGLE is called where
+    <n> is negative.
+
+    The error INVALID_VALUE is generated if DeleteQueriesANGLE is called
+    where <n> is negative.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    when a query of the given <target> is already active.
+
+    The error INVALID_OPERATION is generated if EndQueryANGLE is called
+    when a query of the given <target> is not active.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is zero.
+
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is the name of a query currently in progress.
+    
+    The error INVALID_OPERATION is generated if BeginQueryANGLE is called
+    where <id> is the name of an existing query object whose type does not
+    match <target>.
+
+    The error INVALID_ENUM is generated if BeginQueryANGLE or EndQueryANGLE
+    is called where <target> is not TIME_ELAPSED_ANGLE.
+
+    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
+    <target> is not TIME_ELAPSED_ANGLE or TIMESTAMP_ANGLE.
+
+    The error INVALID_ENUM is generated if GetQueryivANGLE is called where
+    <pname> is not QUERY_COUNTER_BITS_ANGLE or CURRENT_QUERY_ANGLE.
+
+    The error INVALID_ENUM is generated if QueryCounterANGLE is called where
+    <target> is not TIMESTAMP_ANGLE.
+
+    The error INVALID_OPERATION is generated if QueryCounterANGLE is called
+    on a query object that is already in use inside a
+    BeginQueryANGLE/EndQueryANGLE.
+
+    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <id> is not the name of a query
+    object.
+
+    The error INVALID_OPERATION is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <id> is the name of a currently
+    active query object.
+
+    The error INVALID_ENUM is generated if GetQueryObjectivANGLE,
+    GetQueryObjectuivANGLE, GetQueryObjecti64vANGLE, or
+    GetQueryObjectui64vANGLE is called where <pname> is not
+    QUERY_RESULT_ANGLE or QUERY_RESULT_AVAILABLE_ANGLE.
+
+New State
+
+    (Add a new table 6.xx, "Query Operations")
+    
+    Get Value                      Type    Get Command              Initial Value   Description              Sec
+    ---------                      ----    -----------              -------------   -----------              ------
+    -                              B       -                        FALSE           query active             5.3
+    CURRENT_QUERY_ANGLE            Z+      GetQueryivANGLE          0               active query ID          5.3
+    QUERY_RESULT_ANGLE             Z+      GetQueryObjectuivANGLE,  0               samples-passed count     5.3
+                                           GetQueryObjectui64vANGLE
+    QUERY_RESULT_AVAILABLE_ANGLE   B       GetQueryObjectivANGLE    FALSE           query result available   5.3
+
+New Implementation Dependent State
+
+    (Add the following entry to table 6.18):
+
+    Get Value                      Type    Get Command      Minimum Value      Description           Sec
+    --------------------------     ----    -----------      -------------      ----------------      ------
+    QUERY_COUNTER_BITS_ANGLE       Z+      GetQueryivANGLE  see 6.1.9          Number of bits in     6.1.9
+                                                                               query counter
+
+Examples
+
+    (1) Here is some rough sample code that demonstrates the intended usage
+        of this extension.
+
+        GLint queries[N];
+        GLint available = 0;
+        // timer queries can contain more than 32 bits of data, so always
+        // query them using the 64 bit types to avoid overflow
+        GLuint64ANGLE timeElapsed = 0;
+
+        // Create a query object.
+        glGenQueriesANGLE(N, queries);
+
+        // Start query 1
+        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[0]);
+
+        // Draw object 1
+        ....
+
+        // End query 1
+        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
+
+        ...
+
+        // Start query N
+        glBeginQueryANGLE(GL_TIME_ELAPSED_ANGLE, queries[N-1]);
+
+        // Draw object N
+        ....
+
+        // End query N
+        glEndQueryANGLE(GL_TIME_ELAPSED_ANGLE);
+
+        // Wait for all results to become available
+        while (!available) {
+            glGetQueryObjectivANGLE(queries[N-1], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
+        }
+
+        for (i = 0; i < N; i++) {
+            // See how much time the rendering of object i took in nanoseconds.
+            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeElapsed);
+
+            // Do something useful with the time.  Note that care should be
+            // taken to use all significant bits of the result, not just the
+            // least significant 32 bits.
+            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
+        }
+
+        This example is sub-optimal in that it stalls at the end of every
+        frame to wait for query results.  Ideally, the collection of results
+        would be delayed one frame to minimize the amount of time spent
+        waiting for the GPU to finish rendering.
+        
+    (2) This example is basically the same as the example above but uses
+        QueryCounter instead.
+    
+        GLint queries[N+1];
+        GLint available = 0;
+        // timer queries can contain more than 32 bits of data, so always
+        // query them using the 64 bit types to avoid overflow
+        GLuint64ANGLE timeStart, timeEnd, timeElapsed = 0;
+
+        // Create a query object.
+        glGenQueriesANGLE(N+1, queries);
+
+        // Query current timestamp 1
+        glQueryCounterANGLE(queries[0], GL_TIMESTAMP_ANGLE);
+
+        // Draw object 1
+        ....
+
+        // Query current timestamp N
+        glQueryCounterANGLE(queries[N-1], GL_TIMESTAMP_ANGLE);
+
+        // Draw object N
+        ....
+
+        // Query current timestamp N+1
+        glQueryCounterANGLE(queries[N], GL_TIMESTAMP_ANGLE);
+
+        // Wait for all results to become available
+        while (!available) {
+            glGetQueryObjectivANGLE(queries[N], GL_QUERY_RESULT_AVAILABLE_ANGLE, &available);
+        }
+
+        for (i = 0; i < N; i++) {
+            // See how much time the rendering of object i took in nanoseconds.
+            glGetQueryObjectui64vANGLE(queries[i], GL_QUERY_RESULT_ANGLE, &timeStart);
+            glGetQueryObjectui64vANGLE(queries[i+1], GL_QUERY_RESULT_ANGLE, &timeEnd);
+            timeElapsed = timeEnd - timeStart;
+
+            // Do something useful with the time.  Note that care should be
+            // taken to use all significant bits of the result, not just the
+            // least significant 32 bits.
+            AdjustObjectLODBasedOnDrawTime(i, timeElapsed);
+        }
+
+Issues from EXT_timer_query
+
+    (1) What time interval is being measured?
+
+    RESOLVED:  The timer starts when all commands prior to BeginQuery() have
+    been fully executed.  At that point, everything that should be drawn by
+    those commands has been written to the framebuffer.  The timer stops
+    when all commands prior to EndQuery() have been fully executed.
+
+    (2) What unit of time will time intervals be returned in?
+
+    RESOLVED:  Nanoseconds (10^-9 seconds).  This unit of measurement allows
+    for reasonably accurate timing of even small blocks of rendering
+    commands.  The granularity of the timer is implementation-dependent.  A
+    32-bit query counter can express intervals of up to approximately 4
+    seconds.
+
+    (3) What should be the minimum number of counter bits for timer queries?
+
+    RESOLVED:  30 bits, which will allow timing sections that take up to 1
+    second to render.
+
+    (4) How are counter results of more than 32 bits returned?
+
+    RESOLVED:  Via two new datatypes, int64ANGLE and uint64ANGLE, and their
+    corresponding GetQueryObject entry points.  These types hold integer
+    values and have a minimum bit width of 64.
+
+    (5) Should the extension measure total time elapsed between the full
+        completion of the BeginQuery and EndQuery commands, or just time
+        spent in the graphics library?
+
+    RESOLVED:  This extension will measure the total time elapsed between
+    the full completion of these commands.  Future extensions may implement
+    a query to determine time elapsed at different stages of the graphics
+    pipeline.
+
+    (6) If multiple query types are supported, can multiple query types be
+        active simultaneously?
+
+    RESOLVED:  Yes; an application may perform a timer query and another
+    type of query simultaneously.  An application can not perform multiple
+    timer queries or multiple queries of other types simultaneously.  An
+    application also can not use the same query object for another query
+    and a timer query simultaneously.
+
+    (7) Do query objects have a query type permanently associated with them?
+
+    RESOLVED:  No.  A single query object can be used to perform different
+    types of queries, but not at the same time.
+
+    Having a fixed type for each query object simplifies some aspects of the
+    implementation -- not having to deal with queries with different result
+    sizes, for example.  It would also mean that BeginQuery() with a query
+    object of the "wrong" type would result in an INVALID_OPERATION error.
+
+    UPDATE: This resolution was relevant for EXT_timer_query and OpenGL 2.0.
+    Since EXT_transform_feedback has since been incorporated into the core,
+    the resolution is that BeginQuery will generate error INVALID_OPERATION
+    if <id> represents a query object of a different type.
+
+    (8) How predictable/repeatable are the results returned by the timer
+        query?
+
+    RESOLVED:  In general, the amount of time needed to render the same
+    primitives should be fairly constant.  But there may be many other
+    system issues (e.g., context switching on the CPU and GPU, virtual
+    memory page faults, memory cache behavior on the CPU and GPU) that can
+    cause times to vary wildly.
+
+    Note that modern GPUs are generally highly pipelined, and may be
+    processing different primitives in different pipeline stages
+    simultaneously.  In this extension, the timers start and stop when the
+    BeginQuery/EndQuery commands reach the bottom of the rendering pipeline.
+    What that means is that by the time the timer starts, the GL driver on
+    the CPU may have started work on GL commands issued after BeginQuery,
+    and the higher pipeline stages (e.g., vertex transformation) may have
+    started as well.
+
+   (9) What should the new 64 bit integer type be called?
+
+    RESOLVED: The new types will be called GLint64ANGLE/GLuint64ANGLE.  The new
+    command suffixes will be i64 and ui64.  These names clearly convey the
+    minimum size of the types.  These types are similar to the C99 standard
+    type int_least64_t, but we use names similar to the C99 optional type
+    int64_t for simplicity.
+
+Issues from ARB_timer_query
+
+   (10) What about tile-based implementations? The effects of a command are
+        not complete until the frame is completely rendered. Timing recorded
+        before the frame is complete may not be what developers expect. Also
+        the amount of time needed to render the same primitives is not
+        consistent, which conflicts with issue (8) above. The time depends on
+        how early or late in the scene it is placed.
+
+    RESOLVED: The current language supports tile-based rendering okay as it
+    is written. Developers are warned that using timers on tile-based
+    implementation may not produce results they expect since rendering is not
+    done in a linear order. Timing results are calculated when the frame is
+    completed and may depend on how early or late in the scene it is placed.
+    
+   (11) Can the GL implementation use different clocks to implement the
+        TIME_ELAPSED and TIMESTAMP queries?
+
+   RESOLVED: Yes, the implemenation can use different internal clocks to
+   implement TIME_ELAPSED and TIMESTAMP. If different clocks are
+   used it is possible there is a slight discrepancy when comparing queries
+   made from TIME_ELAPSED and TIMESTAMP; they may have slight
+   differences when both are used to measure the same sequence. However, this
+   is unlikely to affect real applications since comparing the two queries is
+   not expected to be useful.
+
+Issues
+
+    (12) What should we call this extension?
+
+    RESOLVED: ANGLE_timer_query
+
+    (13) Why is this done as a separate extension instead of just supporting
+         ARB_timer_query?
+
+    ARB_timer_query is written against OpenGL 3.2, which includes a lot of
+    the required support for dealing with query objects. None of these
+    functions or tokens exist in OpenGL ES, and as such have to be added in
+    this specification.
+
+    (14) How does this extension differ from ARB_timer_query?
+
+    This extension contains most ARB_timer_query behavior unchanged as well
+    as a subset of the query support required to use it from the core
+    OpenGL 3.2 spec. It omits the glGetInteger(TIMESTAMP) functionality used to
+    query the current time on the GPU, but the behavior for all remaining
+    functionality taken from ARB_timer_query is the same.
+    
+    (15) Are query objects shareable between multiple contexts?
+
+    RESOLVED: No.  Query objects are lightweight and we normally share 
+    large data across contexts.  Also, being able to share query objects
+    across contexts is not particularly useful.  In order to do the async 
+    query across contexts, a query on one context would have to be finished 
+    before the other context could query it. 
+
+Revision History
+
+    Revision 1, 2011/04/28
+      - copied from revision 9 of ARB_timer_query and revision 7 of
+        ARB_occlusion_query
+      - removed language that was clearly not relevant to ES2
+      - rebased changes against the OpenGL ES 2.0 specification
--- a/gfx/angle/include/GLES2/gl2ext.h
+++ b/gfx/angle/include/GLES2/gl2ext.h
@@ -233,16 +233,21 @@ typedef void* GLeglImageOES;
 #define GL_FRAMEBUFFER_ATTACHMENT_ANGLE                         0x93A3
 #endif
 
 /* GL_ANGLE_instanced_arrays */
 #ifndef GL_ANGLE_instanced_arrays
 #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE                    0x88FE
 #endif
 
+/* GL_ANGLE_program_binary */
+#ifndef GL_ANGLE_program_binary
+#define GL_PROGRAM_BINARY_ANGLE                                 0x93A6
+#endif
+
 /*------------------------------------------------------------------------*
  * APPLE extension tokens
  *------------------------------------------------------------------------*/
 
 /* GL_APPLE_rgb_422 */
 #ifndef GL_APPLE_rgb_422
 #define GL_RGB_422_APPLE                                        0x8A1F
 #define GL_UNSIGNED_SHORT_8_8_APPLE                             0x85BA
@@ -1482,13 +1487,18 @@ typedef void (GL_APIENTRYP PFNGLENDTILIN
  * VIV extension tokens
  *------------------------------------------------------------------------*/
 
 /* GL_VIV_shader_binary */
 #ifndef GL_VIV_shader_binary
 #define GL_VIV_shader_binary 1
 #endif
 
+/* GL_ANGLE_program_binary */
+#ifndef GL_ANGLE_program_binary
+#define GL_ANGLE_program_binary 1
+#endif
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* __gl2ext_h_ */
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -29,32 +29,54 @@
 //
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // Version number for shader translation API.
 // It is incremented everytime the API changes.
-#define SH_VERSION 105
+#define SH_VERSION 107
 
 //
 // The names of the following enums have been derived by replacing GL prefix
 // with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
 // The enum values are also equal to the values of their GL counterpart. This
 // is done to make it easier for applications to use the shader library.
 //
 typedef enum {
   SH_FRAGMENT_SHADER = 0x8B30,
   SH_VERTEX_SHADER   = 0x8B31
 } ShShaderType;
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
-  SH_WEBGL_SPEC = 0x8B41
+  SH_WEBGL_SPEC = 0x8B41,
+
+  // The CSS Shaders spec is a subset of the WebGL spec.
+  //
+  // In both CSS vertex and fragment shaders, ANGLE:
+  // (1) Reserves the "css_" prefix.
+  // (2) Renames the main function to css_main.
+  // (3) Disables the gl_MaxDrawBuffers built-in.
+  //
+  // In CSS fragment shaders, ANGLE:
+  // (1) Disables the gl_FragColor built-in.
+  // (2) Disables the gl_FragData built-in.
+  // (3) Enables the css_MixColor built-in.
+  // (4) Enables the css_ColorMatrix built-in.
+  //
+  // After passing a CSS shader through ANGLE, the browser is expected to append
+  // a new main function to it.
+  // This new main function will call the css_main function.
+  // It may also perform additional operations like varying assignment, texture
+  // access, and gl_FragColor assignment in order to implement the CSS Shaders
+  // blend modes.
+  //
+  SH_CSS_SHADERS_SPEC = 0x8B42
 } ShShaderSpec;
 
 typedef enum {
   SH_ESSL_OUTPUT = 0x8B45,
   SH_GLSL_OUTPUT = 0x8B46,
   SH_HLSL_OUTPUT = 0x8B47
 } ShShaderOutput;
 
@@ -99,17 +121,33 @@ typedef enum {
   SH_OBJECT_CODE             = 0x0004,
   SH_ATTRIBUTES_UNIFORMS     = 0x0008,
   SH_LINE_DIRECTIVES         = 0x0010,
   SH_SOURCE_PATH             = 0x0020,
   SH_MAP_LONG_VARIABLE_NAMES = 0x0040,
   SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0080,
 
   // This is needed only as a workaround for certain OpenGL driver bugs.
-  SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100
+  SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100,
+
+  // This is an experimental flag to enforce restrictions that aim to prevent 
+  // timing attacks.
+  // It generates compilation errors for shaders that could expose sensitive
+  // texture information via the timing channel.
+  // To use this flag, you must compile the shader under the WebGL spec
+  // (using the SH_WEBGL_SPEC flag).
+  SH_TIMING_RESTRICTIONS = 0x0200,
+    
+  // This flag prints the dependency graph that is used to enforce timing
+  // restrictions on fragment shaders.
+  // This flag only has an effect if all of the following are true:
+  // - The shader spec is SH_WEBGL_SPEC.
+  // - The compile options contain the SH_TIMING_RESTRICTIONS flag.
+  // - The shader type is SH_FRAGMENT_SHADER.
+  SH_DEPENDENCY_GRAPH = 0x0400
 } ShCompileOptions;
 
 //
 // Driver must call this first, once, before doing any other
 // compiler operations.
 // If the function succeeds, the return value is nonzero, else zero.
 //
 COMPILER_EXPORT int ShInitialize();
--- a/gfx/angle/samples/gles2_book/Common/esUtil.vcproj
+++ b/gfx/angle/samples/gles2_book/Common/esUtil.vcproj
@@ -1,70 +1,190 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="esUtil" ProjectGUID="{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}" RootNamespace="esUtil" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="4" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="./;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLibrarianTool" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="4" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="./;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLibrarianTool" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <Filter Name="Win32">
-      <File RelativePath=".\Win32\esUtil_TGA.c">
-      </File>
-      <File RelativePath=".\esUtil_win.h">
-      </File>
-      <File RelativePath=".\Win32\esUtil_win32.c">
-      </File>
-    </Filter>
-    <Filter Name="Common">
-      <File RelativePath=".\esShader.c">
-      </File>
-      <File RelativePath=".\esShapes.c">
-      </File>
-      <File RelativePath=".\esTransform.c">
-      </File>
-      <File RelativePath=".\esUtil.c">
-      </File>
-      <File RelativePath=".\esUtil.h">
-      </File>
-    </Filter>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="esUtil"
+	ProjectGUID="{47C93F52-AB4E-4FF9-8D4F-B38CD60A183F}"
+	RootNamespace="esUtil"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="./;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="./;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Win32"
+			>
+			<File
+				RelativePath=".\Win32\esUtil_TGA.c"
+				>
+			</File>
+			<File
+				RelativePath=".\esUtil_win.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Win32\esUtil_win32.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Common"
+			>
+			<File
+				RelativePath=".\esShader.c"
+				>
+			</File>
+			<File
+				RelativePath=".\esShapes.c"
+				>
+			</File>
+			<File
+				RelativePath=".\esTransform.c"
+				>
+			</File>
+			<File
+				RelativePath=".\esUtil.c"
+				>
+			</File>
+			<File
+				RelativePath=".\esUtil.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/Hello_Triangle/Hello_Triangle.vcproj
+++ b/gfx/angle/samples/gles2_book/Hello_Triangle/Hello_Triangle.vcproj
@@ -1,56 +1,182 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="Hello_Triangle" ProjectGUID="{8278251F-6C1F-4D80-8499-FA7B590FAFE6}" RootNamespace="Hello_Triangle" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\Hello_Triangle.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Hello_Triangle"
+	ProjectGUID="{8278251F-6C1F-4D80-8499-FA7B590FAFE6}"
+	RootNamespace="Hello_Triangle"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\Hello_Triangle.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/MipMap2D/MipMap2D.vcproj
+++ b/gfx/angle/samples/gles2_book/MipMap2D/MipMap2D.vcproj
@@ -1,56 +1,183 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="MipMap2D" ProjectGUID="{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}" RootNamespace="MipMap2D" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\MipMap2D.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="MipMap2D"
+	ProjectGUID="{4E69AC1F-1C7A-4D58-917C-E764FBEB489A}"
+	RootNamespace="MipMap2D"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\MipMap2D.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/MultiTexture/MultiTexture.vcproj
+++ b/gfx/angle/samples/gles2_book/MultiTexture/MultiTexture.vcproj
@@ -1,56 +1,185 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="MultiTexture" ProjectGUID="{120CFF94-ED4B-4C5B-9587-9E40889F15F7}" RootNamespace="MultiTexture" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" CommandLine="xcopy /D /Y basemap.tga $(OutDir)&#xD;&#xA;xcopy /D /Y lightmap.tga $(OutDir)" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" CommandLine="xcopy /D /Y basemap.tga $(OutDir)&#xD;&#xA;xcopy /D /Y lightmap.tga $(OutDir)" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\MultiTexture.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="MultiTexture"
+	ProjectGUID="{120CFF94-ED4B-4C5B-9587-9E40889F15F7}"
+	RootNamespace="MultiTexture"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="xcopy /D /Y basemap.tga &quot;$(OutDir)&quot;&#x0D;&#x0A;xcopy /D /Y lightmap.tga &quot;$(OutDir)&quot;&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="xcopy /D /Y basemap.tga &quot;$(OutDir)&quot;&#x0D;&#x0A;xcopy /D /Y lightmap.tga &quot;$(OutDir)&quot;&#x0D;&#x0A;"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\MultiTexture.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/ParticleSystem/ParticleSystem.vcproj
+++ b/gfx/angle/samples/gles2_book/ParticleSystem/ParticleSystem.vcproj
@@ -1,56 +1,185 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="ParticleSystem" ProjectGUID="{B9E5BFFC-D843-4E0E-9D3E-23913A613473}" RootNamespace="ParticleSystem" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" CommandLine="xcopy /D /Y smoke.tga $(outDir)" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" CommandLine="xcopy /D /Y smoke.tga $(outDir)" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\ParticleSystem.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="ParticleSystem"
+	ProjectGUID="{B9E5BFFC-D843-4E0E-9D3E-23913A613473}"
+	RootNamespace="ParticleSystem"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="xcopy /D /Y smoke.tga &quot;$(outDir)&quot;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="xcopy /D /Y smoke.tga &quot;$(outDir)&quot;"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\ParticleSystem.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
new file mode 100644
--- /dev/null
+++ b/gfx/angle/samples/gles2_book/PostSubBuffer/PostSubBuffer.vcproj
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="PostSubBuffer"
+	ProjectGUID="{667CE95F-5DD8-4495-8C18-5CA8A175B12D}"
+	RootNamespace="Simple_VertexShader"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\PostSubBuffer.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.vcproj
+++ b/gfx/angle/samples/gles2_book/Simple_Texture2D/Simple_Texture2D.vcproj
@@ -1,56 +1,183 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="Simple_Texture2D" ProjectGUID="{2E54D748-781B-4DF2-A1DD-B9384A821810}" RootNamespace="Simple_Texture2D" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\Simple_Texture2D.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Simple_Texture2D"
+	ProjectGUID="{2E54D748-781B-4DF2-A1DD-B9384A821810}"
+	RootNamespace="Simple_Texture2D"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\Simple_Texture2D.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.vcproj
+++ b/gfx/angle/samples/gles2_book/Simple_TextureCubemap/Simple_TextureCubemap.vcproj
@@ -1,56 +1,184 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="Simple_TextureCubemap" ProjectGUID="{5EE56061-643D-406E-B42D-4299D2411056}" RootNamespace="Simple_TextureCubemap" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" UseLibraryDependencyInputs="false" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\Simple_TextureCubemap.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Simple_TextureCubemap"
+	ProjectGUID="{5EE56061-643D-406E-B42D-4299D2411056}"
+	RootNamespace="Simple_TextureCubemap"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				UseLibraryDependencyInputs="false"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\Simple_TextureCubemap.c"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- a/gfx/angle/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.vcproj
+++ b/gfx/angle/samples/gles2_book/Simple_VertexShader/Simple_VertexShader.vcproj
@@ -1,56 +1,183 @@
 <?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="Simple_VertexShader" ProjectGUID="{667CE95F-5DD8-4395-8C18-5CA8A175B12D}" RootNamespace="Simple_VertexShader" Keyword="Win32Proj" TargetFrameworkVersion="131072">
-  <Platforms>
-    <Platform Name="Win32" />
-  </Platforms>
-  <ToolFiles>
-  </ToolFiles>
-  <Configurations>
-    <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="2" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" EmbedManifest="true" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-    <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" CharacterSet="0" WholeProgramOptimization="1">
-      <Tool Name="VCPreBuildEventTool" />
-      <Tool Name="VCCustomBuildTool" />
-      <Tool Name="VCXMLDataGeneratorTool" />
-      <Tool Name="VCWebServiceProxyGeneratorTool" />
-      <Tool Name="VCMIDLTool" />
-      <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories="../Common;../../../include" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" />
-      <Tool Name="VCManagedResourceCompilerTool" />
-      <Tool Name="VCResourceCompilerTool" />
-      <Tool Name="VCPreLinkEventTool" />
-      <Tool Name="VCLinkerTool" LinkIncremental="1" AdditionalLibraryDirectories="" GenerateDebugInformation="true" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" />
-      <Tool Name="VCALinkTool" />
-      <Tool Name="VCManifestTool" />
-      <Tool Name="VCXDCMakeTool" />
-      <Tool Name="VCBscMakeTool" />
-      <Tool Name="VCFxCopTool" />
-      <Tool Name="VCAppVerifierTool" />
-      <Tool Name="VCPostBuildEventTool" />
-    </Configuration>
-  </Configurations>
-  <References>
-  </References>
-  <Files>
-    <File RelativePath=".\Simple_VertexShader.c">
-    </File>
-  </Files>
-  <Globals>
-  </Globals>
-</VisualStudioProject>
\ No newline at end of file
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Simple_VertexShader"
+	ProjectGUID="{667CE95F-5DD8-4395-8C18-5CA8A175B12D}"
+	RootNamespace="Simple_VertexShader"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+				EmbedManifest="true"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="0"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../Common;../../../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="false"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories=""
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				Optimiz