[EME] Update Encrypted Media Extensions to object-oriented API.
authorDavid Dorwin <ddorwin@google.com>
Thu, 16 Aug 2012 20:39:29 -0700
changeset 25 7656808bb99c
parent 24 9caa5bd3667f
child 26 032f7b8681d1
[EME] Update Encrypted Media Extensions to object-oriented API.
encrypted-media/encrypted-media.html
encrypted-media/encrypted-media.xml
--- a/encrypted-media/encrypted-media.html	Thu Aug 16 20:23:41 2012 -0700
+++ b/encrypted-media/encrypted-media.html	Thu Aug 16 20:39:29 2012 -0700
@@ -17,24 +17,25 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="http://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48"></a></p>
       <h1>Encrypted Media Extensions</h1>
-      <h2>W3C Editor's Draft 19 July 2012</h2>
+      <h2>W3C Editor's Draft 16 August 2012</h2>
+      <h2><font color="red">Work in progress. For the latest stable revision, see <a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html">v0.1b</a>.</font></h2>
       <dl>
-	<dt>Latest published version:</dt>
-	<dd>Not yet published</dd>
+  <dt>Latest published version:</dt>
+  <dd>Not yet published</dd>
         <dt>Latest editor's draft:</dt>
         <dd><a href="http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html">http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html</a></dd>
         <dt>Editors:</dt>
         <dd>David Dorwin, Google, Inc.</dd>
         <dd>Adrian Bateman, Microsoft Corporation</dd>
         <dd>Mark Watson, Netflix, Inc.</dd>
-	<dt>Bug/Issue lists:</dt>
-	<dd>
+  <dt>Bug/Issue lists:</dt>
+  <dd>
 <a href="http://w3.org/brief/MjY5">Bugzilla</a>, <a href="http://www.w3.org/html/wg/tracker/products/19">Tracker</a>
 </dd>
-	<dt>Discussion list:</dt>
-	<dd><a href="http://lists.w3.org/Archives/Public/public-html-media/">public-html-media@w3.org</a></dd>
-	<dt>Test Suite:</dt>
-	<dd>None yet</dd>
+  <dt>Discussion list:</dt>
+  <dd><a href="http://lists.w3.org/Archives/Public/public-html-media/">public-html-media@w3.org</a></dd>
+  <dt>Test Suite:</dt>
+  <dd>None yet</dd>
       </dl>
     </div>
 
@@ -183,21 +184,19 @@
     If supported by the <a href="#key-system">Key System</a>, it is generated by the user agent/CDM and provided to the application in the <code><a href="#dom-keymessage">keymessage</a></code> event.
     <span class="non-normative">(Session IDs need not necessarily be supported by the underlying content protection client or server.)</span>
     </p>
-    <p>Each successful call to <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> generates a new Session ID (returned in the <code><a href="#dom-keymessage">keymessage</a></code> event).</p>
+    <p>Each successful call to <code><a href="#dom-createsession">createSession()</a></code> generates a new Session ID.</p>
 
     <p class="non-normative">Applications should always provide the session ID from an event in subsequent calls for this key or license.
     (This is a best practice, even if the current Key System does not support session IDs.)
     This may mean that the application must associate a server response with the session ID and provide them both to <code><a href="#dom-addkey">addKey()</a></code>.
     </p>
 
-    <p>If Session IDs are supported, a new one will be created each time <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> is called.
+    <p>If Session IDs are supported, a new one will be created each time <code><a href="#dom-createsession">createSession()</a></code> is called.
     The user agent/CDM manage the lifetime of Session IDs.
     All Session IDs are cleared from the <a href="#media-element">media element</a> when a load occurs, although
     the CDM may retain them for longer.
     </p>
 
-    <p>NOTE: The key acquisition process (calling <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code>/<code><a href="#dom-addkey">addKey()</a></code>) may be executed multiple times for different sessions (each identified by a <var title="true"><a href="#session-id">sessionId</a></var>).</p>
-
     <h4 id="initialization-data">1.2.4. Initialization Data</h4>
     <p><i>This section is non-normative.</i></p>
     <p>Initialization Data is a generic term for container-specific data that is used by <a href="#cdm">Content Decryption Modules</a> to generate a key request.
@@ -214,8 +213,6 @@
     This data has a container-specific format and is assumed to contain one or more generic or Key System-specific sets of initialization information.
     </p>
 
-    <p>Initialization Data - generic or containing information for the selected Key System - must be provided, in the same format, in the first <a href="#media-element">media element</a> method call that specifies a <var title="true">keySystem</var>.</p>
-
 
     <h2 id="extensions">2. Media Element Extensions</h2>
     <p>We extend <dfn id="media-element" title="media element"><a href="http://dev.w3.org/html5/spec/video.html#media-element">media element</a></dfn> to allow decryption key acquisition to be handled in JavaScript. We also extend <code><a href="#dom-canplaytype">canPlayType()</a></code> to provide <em>basic</em> information about the <a href="#key-system">Key Systems</a> supported by the user agent.</p>
@@ -226,9 +223,28 @@
   // Adds optional 'keySystem' parameter.
   DOMString <a href="#dom-canplaytype">canPlayType</a>(in DOMString type, in DOMstring? <a href="#key-system">keySystem</a>);
 
-  void <a href="#dom-generatekeyrequest">generateKeyRequest</a>(in DOMString <a href="#key-system">keySystem</a>, in Uint8Array? initData);
-  void <a href="#dom-addkey">addKey</a>(in DOMString <a href="#key-system">keySystem</a>, in Uint8Array key, in Uint8Array? initData, in DOMString? <a href="#session-id">sessionId</a>);
-  void <a href="#dom-cancelkeyrequest">cancelKeyRequest</a>(in DOMString <a href="#key-system">keySystem</a>, in DOMString? <a href="#session-id">sessionId</a>);
+  // Encrypted Media
+             attribute <a href="#dom-mediakeys">MediaKeys</a> <a href="#dom-keys">keys</a>;
+};
+
+[<a href="#dom-media-keys-constructor">Constructor</a> (in DOMString <a href="#key-system">keySystem</a>)]
+interface <dfn id="dom-mediakeys">MediaKeys</dfn> {
+  <a href="#dom-mediakeysession">MediaKeySession</a> <a href="#dom-createsession">createSession</a>(in DOMString? type, in Uint8Array? initData);
+
+  readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
+};
+
+interface <dfn id="dom-mediakeysession">MediaKeySession</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventtarget">EventTarget</a> {
+  // error state
+  readonly attribute <a href="#dom-mediakeyerror">MediaKeyError</a>? <a href="#dom-error">error</a>;
+
+  // session properties
+  readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
+  readonly attribute DOMString <a href="#dom-sessionid">sessionId</a>;
+
+  // session operations
+  void <a href="#dom-addkey">addKey</a>(in Uint8Array key);
+  void <a href="#dom-close">close</a>();
 };
 
 partial interface <dfn id="dom-htmlsourceelement">HTMLSourceElement</dfn> {
@@ -257,6 +273,7 @@
     </div>
     
     <p>In addition to the steps in the current specification, this method must run the following steps:</p>
+    
     <ol>
       <li>
 <p>Check whether the <a href="#key-system">Key System</a> is supported with the specified container and codec type(s) by following the steps for the first matching condition from the following list:</p>
@@ -273,245 +290,228 @@
       <li><p>Return "maybe" or "probably" as appropriate per the existing specification of <code><a href="http://dev.w3.org/html5/spec/video.html#dom-navigator-canplaytype">canPlayType()</a></code>.</p></li>
     </ol>
 
-    <p>The <dfn id="dom-generatekeyrequest"><code>generateKeyRequest(keySystem, initData)</code></dfn> method must run the following steps:</p>
+    <p>The <dfn id="dom-keys"><code>keys</code></dfn> attribute is a <code><a href="#dom-mediakeys">MediaKeys</a></code> to be used when decrypting encrypted <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a> for this <a href="#media-element">media element</a>.</p>
+    <p>When setting this attribute, the media element must run the following steps:</p>
+    
+    <ol>
+      <li>
+<p>If loading has not started, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code>.</p>
+      <p class="non-normative">In general, applications should wait for an event named <code><a href="#dom-needkey">needkey</a></code> or <code><a href="http://dev.w3.org/html5/spec/video.html#event-media-loadstart">loadstart</a></code> (per the <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>) before calling this method.</p>
+      </li>
+    </ol>
+
+    <p>The <dfn id="dom-media-keys-constructor"><code>MediaKeys(<var title="true">keySystem</var>)</code></dfn> constructor must run the following steps:</p>
+
+    <ol>
+      <li><p>If <var title="true">keySystem</var> is null or an empty string, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</p></li>
+
+      <li><p>If <var title="true">keySystem</var> is not one of the user agent's supported <a href="#key-system">Key Systems</a>, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code> and abort these steps.</p></li>
+
+      <li><p>Let <var title="true">cdm</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</p></li>
+
+      <li>
+<p>Load <var title="true">cdm</var> if necessary.</p>
+        <dl class="switch">
+          <dt>If <var title="true">cdm</var> fails to load or initialize</dt>
+          <dd><ol>
+            <li>
+<p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
+              <ul style="list-style-type:none"><li>
+                <code><a href="#dom-code">code</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
+                <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
+              </li></ul>
+            </li>
+            <li><p>Set the new object's <code><a href="#dom-error">error</a></code> attribute to the error object created in the previous step.</p></li>
+            <li><p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the new object.</p></li>
+            <li><p>Abort these steps.</p></li>
+          </ol></dd>
+        </dl>
+      </li>
+      
+      <li>Create a new <code><a href="#dom-mediakeys">MediaKeys</a></code> object.
+        <ol>
+          <li><p>Let the <code><a href="#dom-keysystem">keySystem</a></code> attribute be <var title="true">keySystem</var>.</p></li>
+        </ol>
+      </li>
+
+      <li>Return the new object to the caller.</li>
+    </ol>
+
+    <p>When destroying a <code><a href="#dom-mediakeys">MediaKeys</a></code> object, follow the steps in <code><a href="#dom-close">close()</a></code>.</p>
+
+    <p>The <dfn id="dom-createsession"><code>createSession(type, initData)</code></dfn> method must run the following steps:</p>
     <p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a>.</p>
 
     <ol>
-      <li><p>If the first argument is null, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-syntax_err">SYNTAX_ERR</a></code>.</p></li>
-
-      <li>
-<p>If <code><a href="http://dev.w3.org/html5/spec/video.html#dom-media-networkstate">networkState</a></code> is <code><a href="http://dev.w3.org/html5/spec/video.html#dom-media-network_empty">NETWORK_EMPTY</a></code>, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code>.</p>
-      <p class="non-normative">In general, applications should wait for an event named <code><a href="#dom-needkey">needkey</a></code> or <code><a href="http://dev.w3.org/html5/spec/video.html#event-media-loadstart">loadstart</a></code> (per the <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>) before calling this method.</p>
-      </li>
+      <li><p>If <var title="true">type</var> is null or an empty string and <var title="true">initData</var> is <em>not</em> null or an empty string, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code> exception and abort these steps.</p></li>
+      
+      <li><p>If <var title="true">type</var> contains a MIME type that is not supported or is not supported by the <code><a href="#dom-keysystem">keySystem</a></code>, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code> exception and abort these steps.</p></li>
 
-      <li>
-<p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keySystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a>
-</dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code>.</dd>
-        </dl>
+      <li>Create a new <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.
+        <ol>
+          <li><p>Let the <code><a href="#dom-keysystem">keySystem</a></code> attribute be <var title="true">keySystem</var>.</p></li>
+          <li><p>Let the <code><a href="#dom-sessionid">sessionId</a></code> attribute be a unique <a href="#session-id">Session ID</a> string. It may be generated by <var title="true">cdm</var>.</p></li>
+        </ol>
       </li>
+      
+      <li><p>Add the new object to an internal list of session objects.</p></li>
 
       <li>
-<p>Schedule a task to handle the call, providing <var title="true">initData</var>.</p>
+<p>Schedule a task to generate a key request, providing <var title="true">type</var>, <var title="true">initData</var>, and the new object.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
-          <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
 
           <li><p>Let <var title="true">defaultURL</var> be null.</p></li>
           <li>
-<p>Use <var title="true">handler</var> to generate a key request and follow the steps for the first matching condition from the following list:</p>
+<p>Use <var title="true">cdm</var> to generate a key request and follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
               <dt>If a request is successfully generated</dt>
               <dd>
               <ol>
                 <li>
 <p>Let <var title="true">key request</var> be a key request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>, if provided.</p>
-                  <p>Note: <var title="true">handler</var> must not use any data, including <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a>, not provided via <var title="true">initData</var>.</p>
+                  <p>Note: <var title="true">cdm</var> must not use any data, including <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a>, not provided via <var title="true">initData</var>.</p>
+                  <p class="non-normative"><var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
                 </li>
                 <li><p>If <var title="true">initData</var> is not null and contains a default URL for <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
               </ol>
               </dd>
               <dt>Otherwise</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
+              <dd><ol>
+                <li>
+<p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <code><a href="#dom-code">code</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
+                    <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object's <code><a href="#dom-error">error</a></code> attribute to the error object created in the previous step.</p></li>
+                <li><p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol></dd>
             </dl>
           </li>
-          <li><p>Let <var title="true">sessionId</var> be a unique <a href="#session-id">Session ID</a> string. It may be generated by <var title="true">handler</var>.</p></li>
           <li>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the <a href="#media-element">media element</a></p>
+<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the new object</p>
             <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
             <ul style="list-style-type:none"><li>
-              <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-              <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
               <code><a href="#dom-message">message</a></code> = <var title="true">key request</var><br>
-              <code><a href="#dom-defaulturl">defaultURL</a></code> = <var title="true">defaultURL</var>
+              <code><a href="#dom-destinationurl">destinationURL</a></code> = <var title="true">defaultURL</var>
             </li></ul>
             <p class="non-normative">Note: <code><a href="#dom-message">message</a></code> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>
           </li>
         </ol>
       </li>
+      
+      <li>Return the new object to the caller.</li>
     </ol>
 
-    <p>The <dfn id="dom-addkey"><code>addKey(keySystem, key, initData, sessionId)</code></dfn> method must run the following steps:</p>
+    <p>The <dfn id="dom-error"><code>error</code></dfn> attribute is a <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> representing the current error state of the session. It is null if there is no error.</p>
+
+    <p>The <dfn id="dom-keysystem"><code>keySystem</code></dfn> attribute is an identifier for the <a href="#key-system">Key System</a> being used.</p>
+
+    <p>The <dfn id="dom-sessionid"><code>sessionId</code></dfn> attribute is the <a href="#session-id">Session ID</a> for this objects and the associated key(s) or license(s).</p>
+
+    <p>The <dfn id="dom-addkey"><code>addKey(key)</code></dfn> method must run the following steps:</p>
     <p class="non-normative">Note: The contents of <var title="true">key</var> are <var title="true"><a href="#key-system">keySystem</a></var>-specific.
     It may be a raw key or a license containing a key.
     The contents may also vary depending on the container, key length, etc.</p>
-    <p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a> and should be the same format as the same parameter in <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code>.
-    It may be null.
-    </p>
 
     <ol>
-      <li><p>If the first or second argument is null, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-syntax_err">SYNTAX_ERR</a></code>.</p></li>
-
-      <li><p>If the second argument is an empty array, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-type_mismatch_err">TYPE_MISMATCH_ERR</a></code>.</p></li>
-
-      <li>
-<p>If <code><a href="http://dev.w3.org/html5/spec/video.html#dom-media-networkstate">networkState</a></code> is <code><a href="http://dev.w3.org/html5/spec/video.html#dom-media-network_empty">NETWORK_EMPTY</a></code>, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code>.</p>
-      <p class="non-normative">In general, applications should wait for an event named <code><a href="#dom-needkey">needkey</a></code> or <code><a href="http://dev.w3.org/html5/spec/video.html#event-media-loadstart">loadstart</a></code> (per the <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>) before calling this method.</p>
-      </li>
+      <li><p>If the first or second argument is null or an empty array, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code>.</p></li>
 
       <li>
-<p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keySystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a>
-</dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code>.</dd>
-        </dl>
-      </li>
-
-      <li><p>If <var title="true">sessionId</var> is not null and is unrecognized, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code>.</p></li>
-
-      <li>
-<p>Schedule a task to handle the call, providing <var title="true">key</var>, <var title="true">initData</var>, and <var title="true">sessionId</var>.</p>
+<p>Schedule a task to handle the call, providing <var title="true">key</var>.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
-          <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
 
-          <li><p>Let <var title="true">key stored</var> be false.</p></li>
+          <li><p>Let <var title="true">did store key</var> be false.</p></li>
           <li><p>Let <var title="true">next message</var> be null.</p></li>
           <li>
-<p>Use <var title="true">handler</var> to handle <var title="true">key</var>.</p>
+<p>Use <var title="true">cdm</var> to handle <var title="true">key</var>.</p>
+          <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
             <ol>
               <li><p>Process <var title="true">key</var>.</p></li>
               <li>
-<p>If <var title="true">key</var> contains a key or license, store the key.</p>
+<p>For each <var title="true">individual key</var> in <var title="true">key</var>, store the <var title="true">individual key</var>.</p>
                 <ol>
                   <li><p>Let <var title="true">key ID</var> be null.</p></li>
-                  <li><p>If <var title="true">sessionId</var> is not null and refers to a session with <a href="#initialization-data">Initialization Data</a> that contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
-                  <li><p>If <var title="true">key</var> is not null and contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
-                  <li><p>If <var title="true">initData</var> is not null and contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
+                  <li><p>If there is a key ID associated with the <var title="true">individual key</var>, let <var title="true">key ID</var> be that ID.</p></li>
                   <li>
-<p>Store the key by following the steps for the first matching condition from the following list:</p>  
+<p>Store the <var title="true">individual key</var> by following the steps for the first matching condition from the following list:</p>  
                     <dl class="switch">
                       <dt>If <var title="true">key ID</var> is not null</dt>
                       <dd>
                         <ol>
-                          <li><p>Clear any key not associated with a key ID.</p></li>
-                          <li><p>If a key already exists for <var title="true">key ID</var>, delete that element.</p></li>
-                          <li><p>Store the key and/or license in <var title="true">key</var> indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
+                          <li><p>Clear any stored key not associated with a key ID.</p></li>
+                          <li><p>If a stored key already exists for <var title="true">key ID</var>, delete that key.</p></li>
+                          <li><p>Store the <var title="true">individual key</var>, license, and/or license information indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
                         </ol>
                       </dd>
                       <dt>Otherwise</dt>
                       <dd>
                         <ol>
                           <li><p>Clear all stored keys.</p></li>
-                          <li><p>Store the key and/or license in <var title="true">key</var> with no associated key ID.</p></li>
+                          <li><p>Store the <var title="true">individual key</var>, license, and/or license information with no associated key ID.</p></li>
                         </ol>
                       </dd>
                     </dl>
                     <p class="non-normative">At most one key may be stored if key IDs are not used.</p>
                     <p class="non-normative">Clearing keys avoids needing to handle a mixture of keys with and without IDs in the <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a>.</p>
-                    <p class="non-normative">Note: It is recommended that CDM providers support a standard and reasonably high minimum number of cached keys/licenses (with IDs) per media element as well as a standard replacement algorithm.
+                    <p class="non-normative">Note: It is recommended that CDMs support a standard and reasonably high minimum number of cached keys/licenses (with IDs) per media element as well as a standard replacement algorithm.
                     This enables a reasonable number of key rotation algorithms to be implemented across user agents and may reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (i.e. adaptive streams, various audio and video tracks) using different keys.
                     </p>
                   </li>
-                  <li><p>Let <var title="true">key stored</var> be true.</p></li>
+                  <li><p>Let <var title="true">did store key</var> be true.</p></li>
                 </ol>
               </li>
               <li><p>If another message needs to be sent to the server, let <var title="true">next message</var> be that message.</p></li>
             </ol>
           </li>
-          <li>If <var title="true">key stored</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to attempt to resume playback.
+          <li>If <var title="true">did store key</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to attempt to resume playback.
             <p class="non-normative">In other words, resume playback if the necessary key is provided.</p>
           </li>
           <li>
-<p>Fire the appropriate event by following the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If <var title="true">next message</var> is null</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyadded">keyadded</a></code> at the <a href="#media-element">media element</a></p>
-                <p>The event is of type <code><a href="#dom-mediakeycompleteevent">MediaKeyCompleteEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                </li></ul>
-              </dd>
-              <dt>Otherwise</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the <a href="#media-element">media element</a></p>
-                <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                  <code><a href="#dom-message">message</a></code> = <var title="true">next message</var><br>
-                  <code><a href="#dom-defaulturl">defaultURL</a></code> = null
-                </li></ul>
-              </dd>
-            </dl>
-          <p>If any of the preceding steps in the task failed, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a>.</p>
-            <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-              <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-              <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-              <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
+<p>If <var title="true">next message</var> is not null, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p>
+             <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
+             <ul style="list-style-type:none"><li>
+               <code><a href="#dom-message">message</a></code> = <var title="true">next message</var><br>
+               <code><a href="#dom-destinationurl">destinationURL</a></code> = null
+             </li></ul>
+          </li>
+          <li><p>If <var title="true">did store key</var> is true, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyadded">keyadded</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
+          <li>
+<p>If any of the preceding steps in the task failed</p>
+              <ol>
+                <li>
+<p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <code><a href="#dom-code">code</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
+                    <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object's <code><a href="#dom-error">error</a></code> attribute to the error object created in the previous step.</p></li>
+                <li><p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol>
           </li>
       </ol>
       </li>
     </ol>
 
     <p>The key acquisition process <em>may</em> involve the web page handling <code><a href="#dom-keymessage">keymessage</a></code> events, sending the message to a Key System-specific service, and calling <code><a href="#dom-addkey">addKey</a></code> with the response message.
-    This continues until the <code><a href="#dom-keyadded">keyadded</a></code> event is fired.
+    <code><a href="#dom-addkey">addKey</a></code> calls may generate <code><a href="#dom-keyadded">keyadded</a></code> or <code><a href="#dom-keymessage">keymessage</a></code> events.
     During the process, the web page may wish to cancel the acquisition process.
     <span class="non-normative">For example, if the page cannot contact the license service because of network issues it may wish to fallback to an alternative key system.</span>
-    The page calls <code><a href="#dom-cancelkeyrequest">cancelKeyRequest()</a></code> to cancel the a key acquisition and return the media element to a state where <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> may be called again.
+    The page calls <code><a href="#dom-close">close()</a></code> to cancel the a key acquisition session.
     </p>
 
-    <p>The <dfn id="dom-cancelkeyrequest"><code>cancelKeyRequest(keySystem, sessionId)</code></dfn> method must run the following steps:</p>
+    <p>The <dfn id="dom-close"><code>close()</code></dfn> method causes the key acquisition session to close and all keys to be released. It must run the following steps:</p>
 
      <ol>
-      <li><p>If the first argument is null, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-syntax_err">SYNTAX_ERR</a></code>.</p></li>
-      <li><p>If <var title="true">sessionId</var> is not null and is unrecognized or not mapped to the <var title="true"><a href="#key-system">keySystem</a></var>, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_access_err">INVALID_ACCESS_ERR</a></code>.</p></li>
-      <li>If a <code><a href="#dom-keyadded">keyadded</a></code> event has already been fired for this <var title="true">sessionId</var>, throw an <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-invalid_state_err">INVALID_STATE_ERR</a></code>.</li>
-      <li>Clear any internal state associated with the <var title="true">sessionId</var> (or if this is null with the <var title="true"><a href="#key-system">keySystem</a></var> for this media element).
-      This <var title="true">sessionId</var> will now be unrecognized.
-      </li>
-      <li><b>TBD</b></li>
+      <li>Clear any internal state associated with the session, including all keys and licenses.</li>
     </ol>
 
     <p>The <dfn id="dom-sourcekeysystem"><code>keySystem</code></dfn> attribute of <code><a href="#dom-htmlsourceelement">HTMLSourceElement</a></code> specifies the <a href="#key-system">Key System</a> to be used with the <code><a href="http://dev.w3.org/html5/spec/video.html#media-resource">media resource</a></code>.
@@ -521,17 +521,6 @@
       <li><p>⌛ If <var title="">candidate</var> has a <code><a href="#dom-sourcekeysystem">keySystem</a></code> attribute whose value represents a <a href="#key-system">Key System</a> that the user agent knows it cannot use with <code><a href="http://dev.w3.org/html5/spec/video.html#attr-source-type">type</a></code>, then end the <a href="http://dev.w3.org/html5/spec/webappapis.html#synchronous-section">synchronous section</a>, and jump down to the <i title="">failed</i> step below.</p></li>
     </ol>
 
-    <p>A <a href="#media-element">media element</a> is said to <dfn id="have-selected-key-system">have a selected Key System</dfn> when one of the following has occurred:</p>
-    <ul>
-      <li>The media source was selected from a <code><a href="#dom-htmlsourceelement">HTMLSourceElement</a></code>.
-      <p>In this case, the selected key system is the <code><a href="#dom-keysystem">keySystem</a></code> attribute of the selected <code><a href="#dom-htmlsourceelement">HTMLSourceElement</a></code>.</p>
-</li>
-
-      <li>One of the <a href="#dom-htmlmediaelement">new methods</a> has been called successfully (asynchronous steps may not have completed)
-      <p>In this case, the selected key system is the <var title="true">keySystem</var> parameter for the last successful call.</p>
-</li>
-    </ul>
-
     <h3 id="error-codes">2.1. Error Codes</h3>
     <p><code><a href="http://dev.w3.org/html5/spec/video.html#mediaerror">MediaError</a></code> is extended, and a new error type is added.</p>
     <pre class="idl">
@@ -546,9 +535,26 @@
   const unsigned short <a href="#dom-media_keyerr_output">MEDIA_KEYERR_OUTPUT</a> = 4;
   const unsigned short <a href="#dom-media_keyerr_hardwarechange">MEDIA_KEYERR_HARDWARECHANGE</a> = 5;
   const unsigned short <a href="#dom-media_keyerr_domain">MEDIA_KEYERR_DOMAIN</a> = 6;
+  readonly attribute unsigned short <a href="#dom-code">code</a>;
+  readonly attribute unsigned long <a href="#dom-systemcode">systemCode</a>;
 };</pre>
 
-    <p>The <dfn id="dom-code"><code>code</code></dfn> attribute of a <code><a href="#dom-mediaerror">MediaError</a></code> may additionally return the following:</p>
+    <dl class="domintro">
+     <dt>
+<var title="">session</var> . <var title="">error</var> . <code><a href="#dom-code">code</a></code>
+</dt>
+     <dd>
+       <p>Returns the current error's error code, from the list below.</p>
+     </dd>
+     <dt>
+<var title="">session</var> . <var title="">error</var> . <code><a href="#dom-systemcode">systemCode</a></code>
+</dt>
+     <dd>
+       <p>Returns the current error's system code.</p>
+     </dd>
+    </dl>
+
+    <p>The <dfn id="dom-mediaerrorcode"><code>code</code></dfn> attribute of a <code><a href="#dom-mediaerror">MediaError</a></code> may additionally return the following:</p>
     <dl>
       <dt>
 <dfn id="dom-media_err_encrypted"><code>MEDIA_ERR_ENCRYPTED</code></dfn> (numeric value 5)</dt>
@@ -562,7 +568,8 @@
       </dd>
     </dl>
 
-    <p>A <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> may be one of the following:</p>
+    <div class="impl">
+    <p>The <dfn id="dom-code"><code>code</code></dfn> attribute of a <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object must return the code for the error, which must be one of the following:</p>
     <dl>
       <dt>
 <dfn id="dom-media_keyerr_unknown"><code>MEDIA_KEYERR_UNKNOWN</code></dfn> (numeric value 1)</dt>
@@ -585,81 +592,44 @@
 </dd>
     </dl>
 
+    <p>The <dfn id="dom-systemcode"><code>systemCode</code></dfn> attribute of a <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object is a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.
+    <span class="non-normative">This allows a more granular status to be returned than the more general <code><a href="#dom-errorcode">errorCode</a></code>.</span>
+    It should be 0 if there is no associated status code or such status codes are not supported by the Key System.
+    </p>
+    </div>
+
 
     <h2 id="events">3. Events</h2>
 
     <h3 id="event-definitions">3.1. Event Definitions</h3>
+    <pre class="idl">
+[Constructor(DOMString type, optional <a href="#dom-mediakeymessageeventinit">MediaKeyMessageEventInit</a> eventInitDict)]
+interface <dfn id="dom-mediakeymessageevent">MediaKeyMessageEvent</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a> {
+  readonly attribute Uint8Array <a href="#dom-message">message</a>;
+  readonly attribute DOMString? <a href="#dom-destinationurl">destinationURL</a>;
+};
+
+dictionary <dfn id="dom-mediakeymessageeventinit">MediaKeyMessageEventInit</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit">EventInit</a> {
+  Uint8Array <a href="#dom-message">message</a>;
+  DOMString? <a href="#dom-destinationurl">destinationURL</a>;
+};</pre>
 
     <pre class="idl">
 [Constructor(DOMString type, optional <a href="#dom-mediakeyneededeventinit">MediaKeyNeededEventInit</a> eventInitDict)]
 interface <dfn id="dom-mediakeyneededevent">MediaKeyNeededEvent</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a> {
-  readonly attribute DOMString? <a href="#dom-keysystem">keySystem</a>;
-  readonly attribute DOMString? <a href="#dom-sessionid">sessionId</a>;
   readonly attribute Uint8Array? <a href="#dom-initdata">initData</a>;
 };
 
 dictionary <dfn id="dom-mediakeyneededeventinit">MediaKeyNeededEventInit</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit">EventInit</a> {
-  DOMString? <a href="#dom-keysystem">keySystem</a>;
-  DOMString? <a href="#dom-sessionid">sessionId</a>;
   Uint8Array? <a href="#dom-initdata">initData</a>;
 };</pre>
 
-    <pre class="idl">
-[Constructor(DOMString type, optional <a href="#dom-mediakeymessageeventinit">MediaKeyMessageEventInit</a> eventInitDict)]
-interface <dfn id="dom-mediakeymessageevent">MediaKeyMessageEvent</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a> {
-  readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
-  readonly attribute DOMString? <a href="#dom-sessionid">sessionId</a>;
-  readonly attribute Uint8Array <a href="#dom-message">message</a>;
-  readonly attribute DOMString? <a href="#dom-defaulturl">defaultURL</a>;
-};
-
-dictionary <dfn id="dom-mediakeymessageeventinit">MediaKeyMessageEventInit</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit">EventInit</a> {
-  DOMString <a href="#dom-keysystem">keySystem</a>;
-  DOMString? <a href="#dom-sessionid">sessionId</a>;
-  Uint8Array <a href="#dom-message">message</a>;
-  DOMString? <a href="#dom-defaulturl">defaultURL</a>;
-};</pre>
-
-    <pre class="idl">
-[Constructor(DOMString type, optional <a href="#dom-mediakeycompleteeventinit">MediaKeyCompleteEventInit</a> eventInitDict)]
-interface <dfn id="dom-mediakeycompleteevent">MediaKeyCompleteEvent</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a> {
-  readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
-  readonly attribute DOMString? <a href="#dom-sessionid">sessionId</a>;
-};
-
-dictionary <dfn id="dom-mediakeycompleteeventinit">MediaKeyCompleteEventInit</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit">EventInit</a> {
-  DOMString <a href="#dom-keysystem">keySystem</a>;
-  DOMString? <a href="#dom-sessionid">sessionId</a>;
-};</pre>
-
-    <pre class="idl">
-[Constructor(DOMString type, optional <a href="#dom-mediakeyerroreventinit">MediaKeyErrorEventInit</a> eventInitDict)]
-interface <dfn id="dom-mediakeyerrorevent">MediaKeyErrorEvent</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a> {
-  readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
-  readonly attribute DOMString? <a href="#dom-sessionid">sessionId</a>;
-  readonly attribute <a href="#dom-mediakeyerror">MediaKeyError</a> <a href="#dom-errorcode">errorCode</a>;
-  readonly attribute unsigned short <a href="#dom-systemcode">systemCode</a>;
-};
-
-dictionary <dfn id="dom-mediakeyerroreventinit">MediaKeyErrorEventInit</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventinit">EventInit</a> {
-  DOMString <a href="#dom-keysystem">keySystem</a>;
-  DOMString? <a href="#dom-sessionid">sessionId</a>;
-  <a href="#dom-mediakeyerror">MediaKeyError</a> <a href="#dom-errorcode">errorCode</a>;
-  unsigned short <a href="#dom-systemcode">systemCode</a>;
-};</pre>
-
     <dl class="domintro">
      <dt>
-<var title="">event</var> . <code><a href="#dom-keysystem">keySystem</a></code>
+<var title="">event</var> . <code><a href="#dom-destinationurl">destinationURL</a></code>
 </dt>
      <dd>
-       <p>Returns the name of the <a href="#key-system">Key System</a> that generated the event.</p>
-     </dd>
-     <dt>
-<var title="">event</var> . <code><a href="#dom-sessionid">sessionId</a></code>
-</dt>
-     <dd>
-       <p>Returns the <a href="#session-id">Session ID</a> the event is related to, if applicable.</p>
+       <p>Returns the URL to send the <code><a href="#dom-message">message</a></code> to.</p>
      </dd>
      <dt>
 <var title="">event</var> . <code><a href="#dom-initdata">initData</a></code>
@@ -673,43 +643,22 @@
      <dd>
        <p>Returns the message <span class="non-normative">(i.e. key request)</span> to send.</p>
      </dd>
-     <dt>
-<var title="">event</var> . <code><a href="#dom-defaulturl">defaultURL</a></code>
-</dt>
-     <dd>
-       <p>Returns the default key exchange URL.</p>
-     </dd>
-     <dt>
-<var title="">event</var> . <code><a href="#dom-errorcode">errorCode</a></code>
-</dt>
-     <dd>
-       <p>Returns the <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> for the error that occurred.</p>
-     </dd>
-     <dt>
-<var title="">event</var> . <code><a href="#dom-systemcode">systemCode</a></code>
-</dt>
-     <dd>
-       <p>Returns a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.</p>
-     </dd>
     </dl>
     <div class="impl">
-    <p>The <dfn id="dom-keysystem"><code>keySystem</code></dfn> attribute is an identifier for the <a href="#key-system">Key System</a> that generated the event.
-    It may be null in the <code><a href="#dom-needkey">needkey</a></code> event if the media element does not <a href="#have-selected-key-system">have a selected Key System</a>.
-    </p>
-    <p>The <dfn id="dom-sessionid"><code>sessionId</code></dfn> attribute is the <a href="#session-id">Session ID</a> for the key or license that this event refers to. It may be null.</p>
     <p>The <dfn id="dom-initdata"><code>initData</code></dfn> attribute contains <a href="#initialization-data">Initialization Data</a> specific to the event.</p>
     <p>The <dfn id="dom-message"><code>message</code></dfn> attribute contains a message from the CDM. Messages are Key System-specific. <span class="non-normative">In most cases, it should be sent to a key server.</span></p>
-    <p>The <dfn id="dom-defaulturl"><code>defaultURL</code></dfn> is the default URL to send the key request to as provided by the <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a>. It may be null.</p>
-    <p>The <dfn id="dom-errorcode"><code>errorCode</code></dfn> attribute contains the <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code for the error that occurred.</p>
-    <p>The <dfn id="dom-systemcode"><code>systemCode</code></dfn> attribute contains a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.
-    <span class="non-normative">This allows a more granular status to be returned than the more general <code><a href="#dom-errorcode">errorCode</a></code>.</span>
-    It should be 0 if there is no associated status code or such status codes are not supported by the Key System.
+    <p>The <dfn id="dom-destinationurl"><code>destinationURL</code></dfn> is the URL to send the <code><a href="#dom-message">message</a></code> to.
+       An application <em>may</em> override this.
+       <span class="non-normative">In some cases, it may have been provided by the <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a>.</span>
+       It may be null.
     </p>
 
     <p>If a response (i.e. a license) is necessary, applications should use one of the <a href="#dom-htmlmediaelement">new methods</a> to provide the response.</p>
     </div>
 
     <h3 id="event-summary">3.2. Event Summary</h3>
+
+    <p>The following events are fired at <code><a href="#dom-mediakeysession">MediaKeySession</a></code>.</p>
     <table>
       <thead>
         <tr>
@@ -722,26 +671,40 @@
       <tbody>
         <tr>
           <td><dfn id="dom-keyadded"><code>keyadded</code></dfn></td>
-          <td><code><a href="#dom-mediakeycompleteevent">MediaKeyCompleteEvent</a></code></td>
+          <td><code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a></code></td>
           <td>A key has been added as the result of a <code><a href="#dom-addkey">addKey()</a></code> call.
           </td>
           <td></td>
         </tr>
         <tr>
           <td><dfn id="dom-keyerror"><code>keyerror</code></dfn></td>
-          <td><code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code></td>
-          <td>An error occurs in one of the <a href="#dom-htmlmediaelement">new methods</a> or <a href="#cdm">CDM</a>.</td>
+          <td><code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#event">Event</a></code></td>
+          <td>An error occurs in the session.</td>
           <td></td>
         </tr>
         <tr>
           <td><dfn id="dom-keymessage"><code>keymessage</code></dfn></td>
           <td><code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code></td>
           <td>
-            A message has been generated <span class="non-normative">(and likely needs to be sent to a key server)</span>.
-            <span class="non-normative">For example, a key request has been generated as the result of a <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> call or another message must be sent in response to an <code><a href="#dom-addkey">addKey()</a></code> call.</span>
+            A message has been generated <span class="non-normative">(and likely needs to be sent to a server)</span>.
+            <span class="non-normative">For example, a key request has been generated as the result of a <code><a href="#dom-createsession">createSession()</a></code> call or another message must be sent in response to an <code><a href="#dom-addkey">addKey()</a></code> call.</span>
           </td>
           <td></td>
         </tr>
+      </tbody>
+    </table>
+
+    <p>The following event is fired at <code><a href="#dom-htmlmediaelement">HTMLMediaElement</a></code>.</p>
+    <table>
+      <thead>
+        <tr>
+          <th>Event name</th>
+          <th>Interface</th>
+          <th>Dispatched when...</th>
+          <th>Preconditions</th>
+        </tr>
+      </thead>
+      <tbody>
         <tr>
           <td><dfn id="dom-needkey"><code>needkey</code></dfn></td>
           <td><code><a href="#dom-mediakeyneededevent">MediaKeyNeededEvent</a></code></td>
@@ -776,144 +739,6 @@
     This is because proof-of-release messages may be cached in CDMs after the associated media elements have been destroyed.
     Proof-of-key-release messages are subject to the same origin policy: they shall only be delivered to scripts with the same origin as the script which created the media element that provided the key/license.
     </p>
-    
-    <h3>4.2. Key Release Manager</h3>
-    <p>The following interface is defined for management of key release messages:</p>
-    
-    <pre class="idl" id="key-release-manager">
-    [Constructor()]
-    interface <dfn id="dom-keyreleasemanager">KeyReleaseManager</dfn> : <a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#eventtarget">EventTarget</a> {
-        void <a href="#dom-getkeyreleases">getKeyReleases</a>(in DOMString <a href="#key-system">keySystem</a>);
-        void <a href="#dom-addkeyreleasecommit">addKeyReleaseCommit</a>(in DOMString <a href="#key-system">keySystem</a>, in DOMString <a href="#session-id">sessionId</a>, in Uint8Array message);
-    }
-    </pre>
-    <p>The <dfn id="dom-getkeyreleases"><code>getKeyReleases(keysystem)</code></dfn> method must run the following steps:</p>
-
-    <ol>
-      <li><p>If the first argument is null, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-syntax_err">SYNTAX_ERR</a></code>.</p></li>
-      <li>
-<p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keysystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a>
-</dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code>.</dd>
-        </dl>
-      </li>
-
-      <li>
-<p>Schedule a task to handle the call.</p>
-        <p>The user agent will asynchronously execute the following steps in the task:</p>
-        <ol>
-          <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-          <li>
-<p>Use <var title="true">handler</var> to generate one or more key release messages, if supported.
-            <var title="true">handler</var> should follow the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If generating a key release message is not supported</dt>
-              <dd>Let <var title="true">key release messages</var> be null</dd>
-              <dt>Otherwise</dt>
-              <dd>Let <var title="true">key release messages</var> be a set of key release messages generated by the <a href="#cdm">CDM</a> for the current origin.</dd>
-            </dl>
-          </li>
-          <li>
-<p>For each <var title="true">key release message</var> in <var title="true">key release messages</var>, <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyrelease">keyrelease</a></code> at the <a href="#key-release-manager">key release manager</a>.</p>
-            <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-              <code><a href="#dom-sessionid">sessionId</a></code> = the sessionId originally associated with the provision of the key<br>
-              <code><a href="#dom-message">message</a></code> = <var title="true">key release message</var><br>
-              <code><a href="#dom-defaulturl">defaultURL</a></code> = value of the default URL, if stored by the CDM.
-            </li></ul>
-          </li>
-        </ol>
-      </li>
-    </ol>
-    
-    <p>The <dfn id="dom-addkeyreleasecommit"><code>addKeyReleaseCommit(keysystem,
-                                                                     sessionId,
-                                                                     message)</code></dfn>
-    method must run the following steps:
-    </p>
-
-    <ol>
-      <li><p>If the first argument is null, throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-syntax_err">SYNTAX_ERR</a></code>.</p></li>
-      <li>
-<p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keysystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a>
-</dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <code><a href="http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-domexception-not_supported_err">NOT_SUPPORTED_ERR</a></code>.</dd>
-        </dl>
-      </li>
-
-      <li>
-<p>Schedule a task to handle the call, providing <var title="true">sessionId</var> and <var title="true">message</var>.</p>
-        <p>The user agent will asynchronously execute the following steps in the task:</p>
-        <ol>
-          <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-          <li>
-<p>Use <var title="true">handler</var> to commit the message.
-            <var title="true">handler</var> should follow the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If committing a key release message is supported and the <var title="true">message</var> is valid:</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyreleasecommitted">keyreleasecommitted</a></code> at the <a href="#key-release-manager">key release manager</a>.</p>
-                <p>The event is of type <code><a href="#dom-mediakeycompleteevent">MediaKeyCompleteEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                </li></ul>
-              </dd>
-              <dt>Otherwise</dt>
-              <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#key-release-manager">key release manager</a>.</p>
-                <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">keySystem</var><br>
-                  <code><a href="#dom-sessionid">sessionId</a></code> = <var title="true">sessionId</var><br>
-                  <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                  <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-        </ol>
-      </li>
-    </ol>
 
     <h2 id="algorithms">5. Algorithms</h2>
 
@@ -921,44 +746,21 @@
     <p>The following steps are run when the <a href="#media-element">media element</a> encounters a block <span class="non-normative">(i.e. frame)</span> of encrypted <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a> during the <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>:</p>
 
     <ol>
-      <li><p>Let <var title="">key system</var> be null.</p></li>
-      <li><p>Let <var title="">handler</var> be null.</p></li>
+      <li><p>Let <var title="">cdm</var> be null.</p></li>
       <li><p>Let <var title="">block initData</var> be null.</p></li>
       <li><p>Let <var title="">block key</var> be null.</p></li>
       <li><p>If the block (or its parent entity) has <a href="#initialization-data">Initialization Data</a>, let <var title="">block initData</var> be that initialization data.</p></li>
       <li>
-<p>Select the key system and handler by following the steps for the first matching condition from the following list:</p>
+<p>Determine whether there is an active <a href="#cdm">CDM</a> by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If the media element <a href="#have-selected-key-system">has a selected Key System</a>
-</dt>
-        <dd>Run the following steps:
-          <ol>
-            <li><p>Let <var title="true">key system</var> be the selected Key System.</p></li>
-            <li><p>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">key system</var>.</p></li>
-          </ol>
-        </dd>
+        <dt>If the media element's <code><a href="#dom-keys">keys</a></code> attribute is not null</dt>
+        <dd>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</dd>
         <dt>Otherwise</dt>
         <dd>Jump to the <i>Key Presence</i> step below.</dd>
       </dl>
       </li>
       <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-        <dl class="switch">
-          <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-          <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-            <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">key system</var><br>
-              <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
-              <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-              <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
-          </dd>
-        </dl>
-      </li>
-      <li>
-<p>Use <var title="true">handler</var> to select the key:</p>
+<p>Use <var title="true">cdm</var> to select the key:</p>
         <ol>
           <li><p>Let <var title="">block key ID</var> be null.</p></li>
           <li><p>If <var title="">block initData</var> is not null and contains a key ID, let <var title="">block key ID</var> be that ID.</p></li>
@@ -967,25 +769,25 @@
           <dl class="switch">
             <dt>If <var title="">block key ID</var> is not null</dt>
             <dd>
-            <p>Select the key by using <var title="true">handler</var> to follow the steps for the first matching condition from the following list:</p>
+            <p>Select the key by using <var title="true">cdm</var> to follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
-              <dt>If <var title="true">handler</var>  has a key cached for <var title="">block key ID</var>
+              <dt>If <var title="true">cdm</var>  has a key cached for <var title="">block key ID</var>
 </dt>
               <dd>Let <var title="">block key</var> be the matching cached key.</dd>
-              <dt>If <var title="true">handler</var> has a key cached with no ID <span class="non-normative">(there can be one at most)</span>
+              <dt>If <var title="true">cdm</var> has a key cached with no ID <span class="non-normative">(there can be one at most)</span>
 </dt>
               <dd>Let <var title="">block key</var> be the single cached key.</dd>
-              <dt>Otherwise (<var title="true">handler</var> has no keys cached OR has one or more keys cached, none of which have a matching key ID)</dt>
+              <dt>Otherwise (<var title="true">cdm</var> has no keys cached OR has one or more keys cached, none of which have a matching key ID)</dt>
               <dd>Jump to the <i>Key Presence</i> step below.</dd>
             </dl>
             </dd>
             <dt>Otherwise</dt>
             <dd>
-            <p>Select the key by using <var title="true">handler</var> to follow the steps for the first matching condition from the following list:</p>
+            <p>Select the key by using <var title="true">cdm</var> to follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
-              <dt>If <var title="true">handler</var> has a single key cached (with or without a key ID)</dt>
+              <dt>If <var title="true">cdm</var> has a single key cached (with or without a key ID)</dt>
               <dd>Let <var title="">block key</var> be the single cached key.</dd>
-              <dt>If <var title="true">handler</var> has more than one key cached <span class="non-normative">(all would have IDs)</span>
+              <dt>If <var title="true">cdm</var> has more than one key cached <span class="non-normative">(all would have IDs)</span>
 </dt>
               <dd>Abort media element's <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a> and run the steps to report a <code><a href="#dom-media_err_encrypted">MEDIA_ERR_ENCRYPTED</a></code> error.</dd>
               <dt>Otherwise</dt>
@@ -999,8 +801,8 @@
       <li>
 <p><i>Key Presence</i>: Handle the presence of a key by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If <var title="">handler</var> is not null and <var title="">block key</var> is not null.</dt>
-        <dd>Use <var title="true">handler</var> to Decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:
+        <dt>If <var title="">cdm</var> is not null and <var title="">block key</var> is not null.</dt>
+        <dd>Use <var title="true">cdm</var> to Decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:
           <dl class="switch">
             <dt>If decryption fails</dt>
             <dd>Abort media element's <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a> and run the steps to report a <code><a href="#dom-media_err_encrypted">MEDIA_ERR_ENCRYPTED</a></code> error.</dd>
@@ -1015,8 +817,6 @@
         <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-needkey">needkey</a></code> at the <a href="#media-element">media element</a>.
         <p>The event is of type <code><a href="#dom-mediakeyneededevent">MediaKeyNeededEvent</a></code> and has:</p>
         <ul style="list-style-type:none"><li>
-          <code><a href="#dom-keysystem">keySystem</a></code> = <var title="">key system</var><br>
-          <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
           <code><a href="#dom-initdata">initData</a></code> = <var title="">block initData</var>
         </li></ul>
         <p class="non-normative">The <a href="#media-element">media element</a> is said to be <code><a href="http://dev.w3.org/html5/spec/video.html#potentially-playing">potentially playing</a></code>
@@ -1060,43 +860,20 @@
     <p>The following steps are run when the <a href="#media-element">media element</a> encounters a source that may contain encrypted blocks or streams during the <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>:</p>
 
     <ol>
-      <li><p>Let <var title="">key system</var> be null.</p></li>
-      <li><p>Let <var title="">handler</var> be null.</p></li>
+      <li><p>Let <var title="">cdm</var> be null.</p></li>
       <li><p>Let <var title="">initData</var> be null.</p></li>
       <li><p>If <a href="#initialization-data">Initialization Data</a> was encountered, let <var title="">initData</var> be that initialization data.</p></li>
       <li>
-<p>Select the key system and handler by following the steps for the first matching condition from the following list:</p>
+<p>Determine whether there is an active <a href="#cdm">CDM</a> by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If the media element <a href="#have-selected-key-system">has a selected Key System</a>
-</dt>
-        <dd>Run the following steps:
-          <ol>
-            <li><p>Let <var title="true">key system</var> be the selected Key System.</p></li>
-            <li><p>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">key system</var>.</p></li>
-          </ol>
-        </dd>
+        <dt>If the media element's <code><a href="#dom-keys">keys</a></code> attribute is not null</dt>
+        <dd>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</dd>
         <dt>Otherwise</dt>
         <dd>Jump to the <i>Need Key</i> step below.</dd>
       </dl>
       </li>
       <li>
-<p>Load <var title="true">handler</var> if necessary.</p>
-        <dl class="switch">
-          <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-          <dd>
-<p><a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <a href="#media-element">media element</a> and abort the task.</p>
-            <p>The event is of type <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <code><a href="#dom-keysystem">keySystem</a></code> = <var title="true">key system</var><br>
-              <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
-              <code><a href="#dom-errorcode">errorCode</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-              <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
-          </dd>
-        </dl>
-      </li>
-      <li>
-<p>Use <var title="true">handler</var> to determine whether the key is known:</p>
+<p>Use <var title="true">cdm</var> to determine whether the key is known:</p>
         <ol>
           <li><p>Let <var title="">key ID</var> be null.</p></li>
           <li><p>If a key ID for the source is known at this time, let <var title="">key ID</var> be that ID.</p></li>
@@ -1133,12 +910,10 @@
 <p><i>Need Key</i>: <a href="http://dev.w3.org/html5/spec/webappapis.html#queue-a-task">queue a task</a> to <a href="http://dev.w3.org/html5/spec/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-needkey">needkey</a></code> at the <a href="#media-element">media element</a>.</p>
         <p>The event is of type <code><a href="#dom-mediakeyneededevent">MediaKeyNeededEvent</a></code> and has:</p>
         <ul style="list-style-type:none"><li>
-          <code><a href="#dom-keysystem">keySystem</a></code> = <var title="">key system</var><br>
-          <code><a href="#dom-sessionid">sessionId</a></code> = null<br>
           <code><a href="#dom-initdata">initData</a></code> = <var title="">initData</var>
         </li></ul>
         <p class="non-normative">Firing this event allows the application to begin acquiring the key process before it is needed.</p>
-        <p class="non-normative">Note that <code title="dom-media-readyState"><a href="http://dev.w3.org/html5/spec/video.html#dom-media-readystate">readyState</a></code> is <em>not</em> changed and no algorithms are aborted. This algorithm is merely informative.</p>
+        <p class="non-normative">Note that <code title="dom-media-readyState"><a href="http://dev.w3.org/html5/spec/video.html#dom-media-readystate">readyState</a></code> is <em>not</em> changed and no algorithms are aborted. This event is merely informative.</p>
       </li>
 
       <li><p><i>Continue Normal Flow</i>: Continue with the existing media element's <a href="http://dev.w3.org/html5/spec/video.html#concept-media-load-resource">resource fetch algorithm</a>.</p></li>
@@ -1148,8 +923,8 @@
     <p>The following step is added to the existing <a href="http://dev.w3.org/html5/spec/video.html#media-element-load-algorithm">media element load algorithm</a>:</p>
     <ul>
       <li>
-<p>Clear all cached keys for this <a href="#media-element">media element</a>.</p>
-      <p class="non-normative">This also means the keys will be cleared when the <code><a href="http://dev.w3.org/html5/spec/video.html#attr-media-src">src</a></code> attribute is set or changed per <a href="http://dev.w3.org/html5/spec/video.html#location-of-the-media-resource">Location of the media resource</a></p>
+<p>Clear the <codref>keys</codref> attribute for this <a href="#media-element">media element</a>.</p>
+      <p class="non-normative">This also means the <codref>keys</codref> attribute will be cleared when the <code><a href="http://dev.w3.org/html5/spec/video.html#attr-media-src">src</a></code> attribute is set or changed per <a href="http://dev.w3.org/html5/spec/video.html#location-of-the-media-resource">Location of the media resource</a></p>
       </li>
     </ul>
 
@@ -1166,56 +941,24 @@
     Use of this Key System is described below.
     </p>
     
-    <p>The <var title="true">keySystem</var> parameter and <code><a href="#dom-keysystem">keySystem</a></code> attributes are always <code>"org.w3.clearkey"</code>
-    with the exception of events before the Key System <a href="#have-selected-key-system">has been selected</a>.
-    All events except <code><a href="#dom-needkey">needkey</a></code> have a valid <code><a href="#dom-sessionid">sessionId</a></code> string, which is numerical.</p>
+    <p>The <var title="true">keySystem</var> parameter and <code><a href="#dom-keysystem">keySystem</a></code> attributes are always <code>"org.w3.clearkey"</code>.
+    The <code><a href="#dom-sessionid">sessionId</a></code> string is numerical.</p>
 
-    <p>The <code><a href="#dom-initdata">initData</a></code> attribute of the <code><a href="#dom-needkey">needkey</a></code> event and the <var title="true">initData</var> parameters of <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> and <code><a href="#dom-addkey">addKey()</a></code> are the same container-specific <a href="#initialization-data">Initialization Data</a> format and values.
+    <p>The <code><a href="#dom-initdata">initData</a></code> attribute of the <code><a href="#dom-needkey">needkey</a></code> event and the <var title="true">initData</var> parameter of <code><a href="#dom-createsession">createSession()</a></code> are the same container-specific <a href="#initialization-data">Initialization Data</a> format and values.
     <span class="non-normative">
     If supported, these values should provide some type of identification of the content or key that could be used to look up the key (since there is no defined logic for parsing it).
     For containers that support a simple key ID, it should be a binary array containing the raw key ID.
     For other containers, it may be some other opaque blob or null.</span>
     </p>
 
-    <p><code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> may optionally be called.
-    The resulting <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> has:
-    </p>
+    
+    <p>The <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> generated by <code><a href="#dom-createsession">createSession()</a></code> has:</p>
     <ul style="list-style-type:none"><li>
-      <code><a href="#dom-keysystem">keySystem</a></code> = <code>"org.w3.clearkey"</code><br>
-      <code><a href="#dom-sessionid">sessionId</a></code> = a unique numerical string<br>
-      <code><a href="#dom-message">message</a></code> = a container-specific unique key identifier extracted from the <var title="true">initData</var> parameter of <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code>. null if <var title="true">initData</var> was null or a key identifier could not be extracted.<br>
-      <code><a href="#dom-defaulturl">defaultURL</a></code> = value of the default URL if present in the <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a> and null otherwise.
+      <code><a href="#dom-message">message</a></code> = a container-specific value extracted from the <var title="true">initData</var> parameter of <code><a href="#dom-createsession">createSession()</a></code>. null if <var title="true">initData</var> was null or a value could not be extracted.<br>
+      <code><a href="#dom-destinationurl">destinationURL</a></code> = value of the default URL if present in the <a href="http://dev.w3.org/html5/spec/video.html#media-data">media data</a> and null otherwise.
     </li></ul>
 
-    <p>To provide a key using this Key System, pass the following to <code><a href="#dom-addkey">addKey()</a></code>:</p>
-    <ul>
-      <li>
-<var title="true">keySystem</var>: <code>"org.w3.clearkey"</code>
-</li>
-      <li>
-<var title="true">key</var>: An array of bytes containing the key</li>
-      <li>
-<var title="true">initData</var>:
-        <dl class="switch">
-          <dt>If <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> was called:</dt>
-          <dd>The value of the <code><a href="#dom-message">message</a></code> attribute of the resulting <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code>
-</dd>
-          <dt>Otherwise</dt>
-          <dd>
-<a href="#initialization-data">Initialization Data</a> corresponding to the <var title="true">key</var> or null.</dd>
-        </dl>
-      </li>
-      <li>
-<var title="true">sessionId</var>:
-        <dl class="switch">
-          <dt>If <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> was called:</dt>
-          <dd>The value of the <code><a href="#dom-sessionid">sessionId</a></code> attribute of the resulting <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code>
-</dd>
-          <dt>Otherwise</dt>
-          <dd>null</dd>
-        </dl>
-      </li>
-    </ul>
+    <p>The <var title="true">key</var> parameter of <code><a href="#dom-addkey">addKey()</a></code> should be an array of bytes containing the key.</p>
 
 
     <h2 id="examples">7. Examples</h2>
@@ -1235,13 +978,29 @@
 &lt;script&gt;
   function load() {
     var video = document.getElementById("video");
+
+    if (!video.keys)
+      video.keys = MediaKeys("org.w3.clearkey");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession();
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<a href="#dom-keymessage">keymessage</a>="handleMessage(event)";
+  }
+
+  function handleMessage(event) {
+    var keySession = event.target;
+
     var key = new Uint8Array([ 0xaa, 0xbb, 0xcc, ... ]);
-    video.<a href="#dom-addkey">addKey</a>("org.w3.clearkey", key, null);
+    keySession.<a href="#dom-addkey">addKey</a>(key);
   }
 &lt;/script&gt;
 
 &lt;body onload="load()"&gt;
-  &lt;video src="foo.webm" autoplay id="video"&gt;&lt;/video&gt;
+  &lt;video src="foo.webm" autoplay id="video" on<a href="#dom-keymessage">keymessage</a>="handleMessage(event)"&gt;&lt;/video&gt;
 &lt;/body&gt;</pre>
     </div>
 
@@ -1259,20 +1018,34 @@
       <pre class="code">
 &lt;script&gt;
   function handleKeyNeeded(event) {
-    if (event.<a href="#dom-keysystem">keySystem</a> &amp;&amp; event.<a href="#dom-keysystem">keySystem</a> != "org.w3.clearkey")
-      throw "Unhandled keySystem in event";
+    var video = event.target;
     var initData = event.<a href="#dom-initdata">initData</a>;
-    var video = event.target;
+
+    if (!video.keys)
+      video.keys = MediaKeys("org.w3.clearkey");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<a href="#dom-keymessage">keymessage</a>="handleMessage(event)";
+  }
+
+  function handleMessage(event) {
+    var keySession = event.target;
+    var message = event.<a href="#dom-message">message</a>;
 
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", "http://.../getkey", false);
-    xmlhttp.send(initData);
+    xmlhttp.send(message);
     var key = new Uint8Array(xmlhttp.response);
-    video.<a href="#dom-addkey">addKey</a>("org.w3.clearkey", key, initData, event.<a href="#dom-sessionid">sessionId</a>);
+    keySession.<a href="#dom-addkey">addKey</a>(key);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)" on<a href="#dom-keymessage">keymessage</a>="handleMessage(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h4 class="exampleheader">7.2.2. Other Content Decryption Module</h4>
@@ -1282,32 +1055,36 @@
       <pre class="code">
 &lt;script&gt;
   function handleKeyNeeded(event) {
-    if (event.<a href="#dom-keysystem">keySystem</a> &amp;&amp; event.<a href="#dom-keysystem">keySystem</a> != "com.example.somesystem.1_0")
-      throw "Unhandled keySystem in event";
+    var video = event.target;
     var initData = event.<a href="#dom-initdata">initData</a>;
-    var video = event.target;
 
-    video.<a href="#dom-generatekeyrequest">generateKeyRequest</a>("com.example.somesystem.1_0", initData);
+    if (!video.keys)
+      video.keys = MediaKeys("com.example.somesystem.1_0");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<a href="#dom-keymessage">keymessage</a>="licenseRequestReady(event)";
   }
 
   function licenseRequestReady(event) {
-    if (event.<a href="#dom-keysystem">keySystem</a> != "com.example.somesystem.1_0")
-      throw "Unhandled keySystem in event";
+    var keySession = event.target;
     var request = event.<a href="#dom-message">message</a>;
     if (!request)
       throw "Could not create license request";
 
-    var video = event.target;
-
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", "http://.../getkey", false);
     xmlhttp.send(request);
     var license = new Uint8Array(xmlhttp.response);
-    video.<a href="#dom-addkey">addKey</a>("com.example.somesystem.1_0", license, null, event.<a href="#dom-sessionid">sessionId</a>);
+    keySession.<a href="#dom-addkey">addKey</a>(license);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)" on<a href="#dom-keymessage">keymessage</a>="licenseRequestReady(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h3 id="examples-selecting-key-system" class="exampleheader">7.3. Selecting a Supported Key System</h3>
@@ -1337,34 +1114,38 @@
   }
 
   function handleKeyNeeded(event) {
-    var targetKeySystem = event.<a href="#dom-keysystem">keySystem</a>;  
-    if (targetKeySystem == null) {
-      selectKeySystem(video);  // See previous example for implementation.
-      targetKeySystem = keySystem;
-    }
-    var initData = event.<a href="#dom-initdata">initData</a>;
     var video = event.target;
+    var initData = event.<a href="#dom-initdata">initData</a>;
 
-    video.<a href="#dom-generatekeyrequest">generateKeyRequest</a>(targetKeySystem, initData);
+    if (!video.keys) {
+      selectKeySystem(video);
+      video.keys = MediaKeys(keySystem);
+    }
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<a href="#dom-keymessage">keymessage</a>="licenseRequestReady(event)";
   }
-
+  
   function licenseRequestReady(event) {
-    if (event.<a href="#dom-keysystem">keySystem</a> != keySystem)
-      throw "Message from unexpected Key System";
+    var keySession = event.target;
     var request = event.<a href="#dom-message">message</a>;
     if (!request)
       throw "Could not create license request";
 
-    var video = event.target;
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", licenseUrl, false);
     xmlhttp.send(request);
     var license = new Uint8Array(xmlhttp.response);
-    video.<a href="#dom-addkey">addKey</a>(keySystem, license, null, event.<a href="#dom-sessionid">sessionId</a>);
+    keySession.<a href="#dom-addkey">addKey</a>(license);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)" on<a href="#dom-keymessage">keymessage</a>="licenseRequestReady(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h3 class="exampleheader">7.4. Using All Events</h3>
@@ -1379,50 +1160,57 @@
 
   function handleMessageResponse() {
     var license = new Uint8Array(xmlhttp.response);
-    var video = document.getElementById(“video”);
-    video.<a href="#dom-addkey">addKey</a>(keySystem, license, null, this.sessionId);
+    this.keySession.<a href="#dom-addkey">addKey</a>(license);
   }
   
-  function sendMessage(message, sessionId) {
+  function sendMessage(message, keySession) {
     xmlhttp = new XMLHttpRequest();
-    xmlhttp.sessionId = sessionId;
+    xmlhttp.keySession = keySession;
     xmlhttp.onreadystatechange = handleMessageResponse;
     xmlhttp.open("POST", licenseUrl, true);
     xmlhttp.send(message);
   }
 
-  function handleKeyNeeded(event) {
-    var targetKeySystem = event.<a href="#dom-keysystem">keySystem</a>;  
-    if (targetKeySystem == null) {
-      selectKeySystem(video);  // See previous example for implementation.
-      targetKeySystem = keySystem;
-    }
-    var initData = event.<a href="#dom-initdata">initData</a>;
-    var video = event.target;
-
-    video.<a href="#dom-generatekeyrequest">generateKeyRequest</a>(targetKeySystem, initData);
-  }
-
   function handleKeyMessage(event) {
-    if (event.<a href="#dom-keysystem">keySystem</a> != keySystem)
-      throw "Message from unexpected Key System";
+    var keySession = event.target;
     var message = event.<a href="#dom-message">message</a>;
     if (!message)
       throw "Invalid key message";
   
-    sendMessage(message, event.<a href="#dom-sessionid">sessionId</a>);
+    sendMessage(message, keySession);
   }
 
   function handleKeyComplete(event) {
-    // Do some bookkeeping with event.<a href="#dom-sessionid">sessionId</a> if necessary.
+    // Do some bookkeeping with event.target.<a href="#dom-sessionid">sessionId</a> if necessary.
   }
 
   function handleKeyError(event) {
-    // Report event.<a href="#dom-errorcode">errorCode</a> and do some bookkeeping with event.<a href="#dom-sessionid">sessionId</a> if necessary.
+    // Report event.target.error.<a href="#dom-code">code</a> and event.target.error.<a href="#dom-systecode">systeCode</a>,
+    // and do some bookkeeping with event.target.<a href="#dom-sessionid">sessionId</a> if necessary.
+  }
+
+  function handleKeyNeeded(event) {
+    var video = event.target;
+    var initData = event.<a href="#dom-initdata">initData</a>;
+
+    if (!video.keys) {
+      selectKeySystem(video);  // See previous example for implementation.
+      video.keys = MediaKeys(keySystem);
+    }
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = video.keys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<a href="#dom-keymessage">keymessage</a>="handleKeyMessage(event)";
+    keySession.on<a href="#dom-keyadded">keyadded</a>="handleKeyComplete(event)";
+    keySession.on<a href="#dom-keyerror">keyerror</a>="handleKeyError(event)";
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)" on<a href="#dom-keymessage">keymessage</a>="handleKeyMessage(event)" on<a href="#dom-keyadded">keyadded</a>="handleKeyComplete(event)" on<a href="#dom-keyerror">keyerror</a>="handleKeyError(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<a href="#dom-needkey">needkey</a>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
 
@@ -1439,7 +1227,7 @@
     <ul>
       <li>If adaptive streaming is handled within the user agent (Type 1), the adaptive implementation can expose the events and methods needed to provide key(s) for the streams via the APIs in this proposal.</li>
       <li>If adaptive streaming is handled in the application/JavaScript (Type 3), behavior should be very similar to the non-adaptive case.
-      For example, the proposed <a href="http://html5-mediasource-api.googlecode.com/svn/trunk/draft-spec/mediasource-draft-spec.html">MediaSource Extensions</a> allow the application to provide a dynamic <code>src</code>, which could be encrypted and handled just like a normal stream.
+      For example, the <a href="http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html">Media Source Extensions</a> allow the application to provide a dynamic <code>src</code>, which could be encrypted and handled just like a normal stream.
       </li>
     </ul>
 
@@ -1452,7 +1240,6 @@
     <h4 id="sourceelement" class="faqquestion">Can I let the user agent select the appropriate CDM using <code>&lt;source&gt;</code> elements?</h4>
     <p class="faqanswer">Yes, using the <code><a href="#dom-sourcekeysystem">keySystem</a></code> attribute of the <code><a href="#dom-htmlsourceelement">HTMLSourceElement</a></code>.
     When used with <code><a href="http://dev.w3.org/html5/spec/video.html#attr-source-type">type</a></code> attribute, this will select the first <code>&lt;source&gt;</code> element (container, codec, and <a href="#key-system">Key System</a>) that the user agent might support.
-    The selected <a href="#cdm">CDM</a> will not be reported to the application until an event is fired.
     </p>
 
     <h4 id="faq-heartbeat" class="faqquestion">Is a heartbeat supported?</h4>
@@ -1466,7 +1253,7 @@
     <h3 id="faq-use">8.2. Use</h3>
 
     <h4 class="faqquestion">Can I send a token for the signed-in user with the license request?</h4>
-    <p class="faqanswer">Yes. The application can add this to the license request (sent via <code>XMLHttpRequest</code> in the <a href="#examples">examples</a>) or send it to the <a href="#cdm">CDM</a> via <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> to be included in the license request.</p>
+    <p class="faqanswer">Yes. The application can add this to the license request (sent via <code>XMLHttpRequest</code> in the <a href="#examples">examples</a>) or send it to the <a href="#cdm">CDM</a> via <code><a href="#dom-createsession">createSession()</a></code> to be included in the license request.</p>
 
     <h4 class="faqquestion">How do I resume playback after receiving the <code><a href="#dom-needkey">needkey</a></code> event in the <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a>?</h4>
     <p class="faqanswer">Assuming there are no other issues, playback will resume when the needed key is provided by <code><a href="#dom-addkey">addKey()</a></code> and processed.</p>
@@ -1475,6 +1262,9 @@
     <p class="faqanswer">Yes, this will likely be necessary to support all or a majority of user agents.
     An application could also use different <a href="#key-system">Key Systems</a> on a single user agent for different purposes.</p>
 
+    <h4 class="faqquestion">Can an <code><a href="#dom-htmlmediaelement">HTMLMediaElement</a></code> use multiple <a href="#key-system">Key System</a>s at the same time?</h4>
+    <p class="faqanswer">No.</p>
+
     <h4 class="faqquestion">How do I add support for a CDM to my application?</h4>
     <p id="faq-cdm-library" class="faqanswer">We envision <a href="#cdm">CDM</a> providers creating JavaScript libraries that application developers can include. <code><a href="#dom-canplaytype">canPlayType()</a></code> can then be used to select from supported libraries.</p>
 
@@ -1485,12 +1275,6 @@
     Some basic Key System feature detection may be <a href="canplaytype-capability-detection">available via canPlayType()</a>.
     </p>
 
-    <h4 class="faqquestion">How should an application handle a <code><a href="#dom-needkey">needkey</a></code> event with a null <code><a href="#dom-keysystem">keySystem</a></code> attribute?</h4>
-    <p class="faqanswer">This is a very common scenario because it happens when the user agent encounters encrypted media and does not have an appropriate key.
-    If the application does not already know which <a href="#key-system">Key System</a> to use, it should use <code><a href="#dom-canplaytype">canPlayType()</a></code> to select an appropriate one.
-    When the <code><a href="#dom-keysystem">keySystem</a></code> attribute is null, the <code><a href="#dom-initdata">initData</a></code> attribute is always independent of the <a href="#key-system">Key System</a>.
-    </p>
-
     <h4 class="faqquestion">What is a license URL (<code>licenseUrl</code>) in the examples?</h4>
     <p class="faqanswer">This is the URL for a server capable of providing the key for the stream, usually using the <a href="#initialization-data">Initialization Data</a> and often after verifying the requesting user.
     The URL is application- and/or <a href="#key-system">Key System</a>-specific and may be a content provider or a Key System provider depending on the solution.</p>
@@ -1540,33 +1324,24 @@
     Instead, the Key System is passed as a second parameter to <code><a href="#dom-canplaytype">canPlayType()</a></code> and as a separate attribute to the source element.
     </p>
 
-    <h4 class="faqquestion">Will I be informed if a call to one of the <a href="#dom-htmlmediaelement">new methods</a> fails?</h4>
+    <h4 id="faq-key-system-mime-type" class="faqquestion">Why isn't the <a href="#key-system">Key System</a> part of the MIME type (like codecs)?</h4>
+    <p class="faqanswer">In many cases (especially the direction the content providers and standards are moving), the stream is not specific to any one Key System or provider. Multiple Key Systems could be used to decrypt the same generic stream. Thus, the <a href="#key-system">Key System</a> is not information about the file and should not be part of the MIME type.</p>
+    <p class="faqanswer">One could argue that the encryption algorithm (e.g. AES-128) and configuration should be in the MIME type. That is not required for this proposal, so it is not addressed here.</p>
+
+    <h4 class="faqquestion">Will my application be informed if a call to one of the <a href="#dom-htmlmediaelement">new methods</a> fails?</h4>
     <p class="faqanswer">Errors that occur during synchronous portion of the algorithms will be thrown.
     For asynchronous portions (i.e. when a task is scheduled), a <code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code> will be fired.
     </p>
 
-    <h4 id="faq-key-system-mime-type" class="faqquestion">Why isn't the <a href="#key-system">Key System</a> part of the MIME type (like codecs)?</h4>
-    <p class="faqanswer">In many cases (especially the direction the content providers and standards are moving), the stream is not specific to any one Key System or provider. Multiple Key Systems could be used to decrypt the same generic stream. Thus, the <a href="#key-system">Key System</a> is not information about the file and should not be part of the MIME type.</p>
-    <p class="faqanswer">One could argue that the encryption algorithm (e.g. AES-128) and configuration should be in the MIME type. That is not required for this proposal, so it is not addressed here.</p>
-
-    <h4 class="faqquestion">Why do we need another event?</h4>
+    <h4 class="faqquestion">Why do we need additional events?</h4>
     <p class="faqanswer">While many use case could be implemented without an additional event (by requiring the app to provide all the information up front), some use cases may be better handled by an event.</p>
 
-    <h4 class="faqquestion">Why does the event need multiple attributes?</h4>
-    <p class="faqanswer">The <code><a href="#dom-keysystem">keySystem</a></code> attribute ensures that the application knows which <a href="#cdm">CDM</a> caused the event so it can know how to handle the event. While the application could probably know or discover this in other ways, this makes it simple for the application.</p>
-
     <h4 class="faqquestion">Why do we need a new <code><a href="#dom-mediaerror">MediaError</a></code> code?</h4>
     <p class="faqanswer">Without a new error code (<code><a href="#dom-media_err_encrypted">MEDIA_ERR_ENCRYPTED</a></code>), it is not possible for user agents to clearly indicate to an application that playback failed because the content was encrypted and user agents will likely need to fire a <code>MEDIA_ERR_DECODE</code> or <code>MEDIA_ERR_SRC_NOT_SUPPORTED</code>, which would be confusing.</p>
 
     <h4 class="faqquestion">Will adding a new error code to <code><a href="#dom-mediaerror">MediaError</a></code> break existing applications?</h4>
     <p class="faqanswer">Applications that are not aware of the new error code (<code><a href="#dom-media_err_encrypted">MEDIA_ERR_ENCRYPTED</a></code>) may not correctly handle it, but they should still be able to detect that an error has occurred because a) an error event is fired and b) <var title="">media</var> . <code title="dom-media-error"><code><a href="http://dev.w3.org/html5/spec/video.html#mediaerror">error</a></code></code> is not null.</p>
 
-    <h4 class="faqquestion">Why do we need a new error type (<code><a href="#dom-mediakeyerror">MediaKeyError</a></code>) and event (<code><a href="#dom-mediakeyerrorevent">MediaKeyErrorEvent</a></code>)?</h4>
-    <p class="faqanswer">While key/license exchange errors are fatal to the exchange session, most are not fatal to playback.
-    This is especially true if the <a href="#media-element">media element</a> already has a key for the current (and future) frames or, for example, the exchange was for a different stream in an <a href="#faq-adaptive-streaming">adaptive streaming</a> scenario.
-    The separation allows the <a href="#media-element">media element</a> to continue playback while the application attempts to resolve the exchange problem or until the requested key/license is actually needed.
-    </p>    
-
     <h4 class="faqquestion">What happens if a response to the <code><a href="#dom-needkey">needkey</a></code> event from a <a href="#algorithms-encrypted-stream">encountering a potentially encrypted stream</a> is not received before <a href="#algorithms-enrypted-block">encountering an encrypted block</a>?</h4>
     <p class="faqanswer">The <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a> will proceed as normal.
     If no appropriate key has been provided, a second <code><a href="#dom-needkey">needkey</a></code> event will be fired and decoding will stop.
@@ -1575,18 +1350,8 @@
     <h4 class="faqquestion">The same <code><a href="#dom-needkey">needkey</a></code> event with the same attributes is fired for both <a href="#algorithms-enrypted-block">Encrypted Block Encountered</a> and <a href="#algorithms-encrypted-stream">Potentially Encrypted Stream Encountered</a>. How can an application distinguish between the two?</h4>
     <p class="faqanswer">The same event was used intentionally to reduce the complexity of applications. Ideally, they would not need to know.</p>
 
-    <h4 class="faqquestion">What if a different [supported] <a href="#key-system">Key System</a> is passed to one of the <a href="#dom-htmlmediaelement">new methods</a> in subsequent calls to the same <code><a href="#dom-htmlmediaelement">HTMLMediaElement</a></code>?</h4>
-    <p class="faqquestion">(Expanding on the question, this relates to the new methods, including <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> and <code><a href="#dom-addkey">addKey()</a></code>, that modify state and does not apply to <code><a href="#dom-canplaytype">canPlayType()</a></code>, which is explicitly intended to be called with multiple <a href="#key-system">Key System</a> strings.
-    For example, what if <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> is called with one Key System then <code><a href="#dom-addkey">addKey()</a></code> is called with another; or if <code><a href="#dom-addkey">addKey()</a></code> is called twice with two different Key Systems.)
-    </p>
-    <p class="faqanswer">If a load occurs between calls with different Key Systems, then there is no problem.</p>
-    <p class="faqanswer">Otherwise, the calls will be treated separately.
-    <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code> will start a new session with a new <a href="#session-id">Session ID</a>.
-    <code><a href="#dom-addkey">addKey()</a></code> will behave as normal unless <var title="true">sessionId</var> parameter is not null and is unrecognized for the specified <var title="true">keySystem</var> parameter.
-    </p>
-
     <h4 class="faqquestion">What if a key/license for the same <a href="#initialization-data">Initialization Data</a> (i.e. key ID) is provided more than once to <code><a href="#dom-addkey">addKey()</a></code>?</h4>
-    <p class="faqanswer">Replace it, updating the ordering to reflect that this key ID was most recently added.
+    <p class="faqanswer">The CDM will replace previous entries, updating the overall key ordering to reflect that this key ID was most recently added.
     In other words, simply replacing the existing key data is not sufficient.
     The exact algorithm is covered in <code><a href="#dom-addkey">addKey()</a></code>.
     </p>
@@ -1601,7 +1366,7 @@
     <p class="faqanswer">The application must use <code><a href="#dom-addkey">addKey()</a></code> to indicate the stream is encrypted and provide the key before decoding starts.</p>
 
     <h4 class="faqquestion">Must the container provide Initialization Data or a content key ID?</h4>
-    <p class="faqanswer">This is ideal, but the API would also support the application sending the <a href="#initialization-data">Initialization Data</a> or ID directly to the server or providing it to the <a href="#cdm">CDM</a> via <code><a href="#dom-generatekeyrequest">generateKeyRequest()</a></code>.</p>
+    <p class="faqanswer">This is ideal, but the API would also support the application sending the <a href="#initialization-data">Initialization Data</a> or ID directly to the server or providing it to the <a href="#cdm">CDM</a> via <code><a href="#dom-createsession">createSession()</a></code>.</p>
 
     <h4 class="faqquestion">What if a container/codec does not support key IDs or bit(s)?</h4>
     <p class="faqanswer">The application will need to use some other mechanism to select the appropriate key for the content.
@@ -1653,6 +1418,14 @@
       </thead>
       <tbody>
         <tr>
+          <td>16 August 2012</td>
+          <td>Converted to the object-oriented API.</td>
+        </tr>
+        <tr>
+          <td><a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html">0.1b</a></td>
+          <td>Last non-object-oriented revision.</td>
+        </tr>
+        <tr>
           <td><a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1a/encrypted-media/encrypted-media.html">0.1a</a></td>
           <td>Corrects minor mistakes in 0.1.</td>
         </tr>
--- a/encrypted-media/encrypted-media.xml	Thu Aug 16 20:23:41 2012 -0700
+++ b/encrypted-media/encrypted-media.xml	Thu Aug 16 20:39:29 2012 -0700
@@ -16,22 +16,23 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="http://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48" /></a></p>
       <h1>Encrypted Media Extensions</h1>
-      <h2>W3C Editor's Draft 19 July 2012</h2>
+      <h2>W3C Editor's Draft 16 August 2012</h2>
+      <h2><font color="red">Work in progress. For the latest stable revision, see <a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html">v0.1b</a>.</font></h2>
       <dl>
-	<dt>Latest published version:</dt>
-	<dd>Not yet published</dd>
+  <dt>Latest published version:</dt>
+  <dd>Not yet published</dd>
         <dt>Latest editor's draft:</dt>
         <dd><a href="http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html">http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html</a></dd>
         <dt>Editors:</dt>
         <dd>David Dorwin, Google, Inc.</dd>
         <dd>Adrian Bateman, Microsoft Corporation</dd>
         <dd>Mark Watson, Netflix, Inc.</dd>
-	<dt>Bug/Issue lists:</dt>
-	<dd><a href='http://w3.org/brief/MjY5'>Bugzilla</a>, <a href='http://www.w3.org/html/wg/tracker/products/19'>Tracker</a></dd>
-	<dt>Discussion list:</dt>
-	<dd><a href='http://lists.w3.org/Archives/Public/public-html-media/'>public-html-media@w3.org</a></dd>
-	<dt>Test Suite:</dt>
-	<dd>None yet</dd>
+  <dt>Bug/Issue lists:</dt>
+  <dd><a href='http://w3.org/brief/MjY5'>Bugzilla</a>, <a href='http://www.w3.org/html/wg/tracker/products/19'>Tracker</a></dd>
+  <dt>Discussion list:</dt>
+  <dd><a href='http://lists.w3.org/Archives/Public/public-html-media/'>public-html-media@w3.org</a></dd>
+  <dt>Test Suite:</dt>
+  <dd>None yet</dd>
       </dl>
     </div>
 
@@ -179,21 +180,19 @@
     If supported by the <a href="#key-system">Key System</a>, it is generated by the user agent/CDM and provided to the application in the <coderef>keymessage</coderef> event.
     <span class="non-normative">(Session IDs need not necessarily be supported by the underlying content protection client or server.)</span>
     </p>
-    <p>Each successful call to <methodref>generateKeyRequest</methodref> generates a new Session ID (returned in the <coderef>keymessage</coderef> event).</p>
+    <p>Each successful call to <methodref>createSession</methodref> generates a new Session ID.</p>
 
     <p class="non-normative">Applications should always provide the session ID from an event in subsequent calls for this key or license.
     (This is a best practice, even if the current Key System does not support session IDs.)
     This may mean that the application must associate a server response with the session ID and provide them both to <methodref>addKey</methodref>.
     </p>
 
-    <p>If Session IDs are supported, a new one will be created each time <methodref>generateKeyRequest</methodref> is called.
+    <p>If Session IDs are supported, a new one will be created each time <methodref>createSession</methodref> is called.
     The user agent/CDM manage the lifetime of Session IDs.
     All Session IDs are cleared from the <a href="#media-element">media element</a> when a load occurs, although
     the CDM may retain them for longer.
     </p>
 
-    <p>NOTE: The key acquisition process (calling <methodref>generateKeyRequest</methodref>/<methodref>addKey</methodref>) may be executed multiple times for different sessions (each identified by a <var title="true"><a href="#session-id">sessionId</a></var>).</p>
-
     <h4 id="initialization-data">1.2.4. Initialization Data</h4>
     <non-normative-section/>
     <p>Initialization Data is a generic term for container-specific data that is used by <a href="#cdm">Content Decryption Modules</a> to generate a key request.
@@ -210,8 +209,6 @@
     This data has a container-specific format and is assumed to contain one or more generic or Key System-specific sets of initialization information.
     </p>
 
-    <p>Initialization Data - generic or containing information for the selected Key System - must be provided, in the same format, in the first <a href="#media-element">media element</a> method call that specifies a <var title="true">keySystem</var>.</p>
-
 
     <h2 id="extensions">2. Media Element Extensions</h2>
     <p>We extend <dfn id="media-element" title="media element"><media-element/></dfn> to allow decryption key acquisition to be handled in JavaScript. We also extend <methodref>canPlayType</methodref> to provide <em>basic</em> information about the <a href="#key-system">Key Systems</a> supported by the user agent.</p>
@@ -222,9 +219,28 @@
   // Adds optional 'keySystem' parameter.
   DOMString <premethodref>canPlayType</premethodref>(in DOMString type, in DOMstring? <a href="#key-system">keySystem</a>);
 
-  void <premethodref>generateKeyRequest</premethodref>(in DOMString <a href="#key-system">keySystem</a>, in Uint8Array? initData);
-  void <premethodref>addKey</premethodref>(in DOMString <a href="#key-system">keySystem</a>, in Uint8Array key, in Uint8Array? initData, in DOMString? <a href="#session-id">sessionId</a>);
-  void <premethodref>cancelKeyRequest</premethodref>(in DOMString <a href="#key-system">keySystem</a>, in DOMString? <a href="#session-id">sessionId</a>);
+  // Encrypted Media
+             attribute <precoderef>MediaKeys</precoderef> <precoderef>keys</precoderef>;
+};
+
+[<a href="#dom-media-keys-constructor">Constructor</a> (in DOMString <a href="#key-system">keySystem</a>)]
+interface <precodedfn>MediaKeys</precodedfn> {
+  <precoderef>MediaKeySession</precoderef> <premethodref>createSession</premethodref>(in DOMString? type, in Uint8Array? initData);
+
+  readonly attribute DOMString <precoderef>keySystem</precoderef>;
+};
+
+interface <precodedfn>MediaKeySession</precodedfn> : <dom4ref name="eventtarget">EventTarget</dom4ref> {
+  // error state
+  readonly attribute <precoderef>MediaKeyError</precoderef>? <precoderef>error</precoderef>;
+
+  // session properties
+  readonly attribute DOMString <precoderef>keySystem</precoderef>;
+  readonly attribute DOMString <precoderef>sessionId</precoderef>;
+
+  // session operations
+  void <premethodref>addKey</premethodref>(in Uint8Array key);
+  void <premethodref>close</premethodref>();
 };
 
 partial interface <precodedfn>HTMLSourceElement</precodedfn> {
@@ -253,6 +269,7 @@
     </div>
     
     <p>In addition to the steps in the current specification, this method must run the following steps:</p>
+    
     <ol>
       <li><p>Check whether the <a href="#key-system">Key System</a> is supported with the specified container and codec type(s) by following the steps for the first matching condition from the following list:</p>
         <dl class="switch">
@@ -267,223 +284,213 @@
       <li><p>Return "maybe" or "probably" as appropriate per the existing specification of <videoref name="dom-navigator-canplaytype">canPlayType()</videoref>.</p></li>
     </ol>
 
-    <p>The <methoddfn name="generateKeyRequest">generateKeyRequest(<var title="true"><a href="#key-system">keySystem</a></var>, <var title="true">initData</var>)</methoddfn> method must run the following steps:</p>
+    <p>The <codedfn>keys</codedfn> attribute is a <coderef>MediaKeys</coderef> to be used when decrypting encrypted <videoanchor name="media-data">media data</videoanchor> for this <a href="#media-element">media element</a>.</p>
+    <p>When setting this attribute, the media element must run the following steps:</p>
+    
+    <ol>
+      <li><p>If loading has not started, throw an <invalid-state-err/>.</p>
+      <p class="non-normative">In general, applications should wait for an event named <coderef>needkey</coderef> or <videoref name="event-media-loadstart">loadstart</videoref> (per the <resource-fetch-algorithm/>) before calling this method.</p>
+      </li>
+    </ol>
+
+    <p>The <dfn id="dom-media-keys-constructor"><code>MediaKeys(<var title="true">keySystem</var>)</code></dfn> constructor must run the following steps:</p>
+
+    <ol>
+      <li><p>If <var title="true">keySystem</var> is null or an empty string, throw an <invalid-access-err/> exception and abort these steps.</p></li>
+
+      <li><p>If <var title="true">keySystem</var> is not one of the user agent's supported <a href="#key-system">Key Systems</a>, throw a <not-supported-err/> and abort these steps.</p></li>
+
+      <li><p>Let <var title="true">cdm</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</p></li>
+
+      <li><p>Load <var title="true">cdm</var> if necessary.</p>
+        <dl class="switch">
+          <dt>If <var title="true">cdm</var> fails to load or initialize</dt>
+          <dd><ol>
+            <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
+              <ul style="list-style-type:none"><li>
+                <coderef>code</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
+                <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
+              </li></ul>
+            </li>
+            <li><p>Set the new object's <coderef>error</coderef> attribute to the error object created in the previous step.</p></li>
+            <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the new object.</p></li>
+            <li><p>Abort these steps.</p></li>
+          </ol></dd>
+        </dl>
+      </li>
+      
+      <li>Create a new <coderef>MediaKeys</coderef> object.
+        <ol>
+          <li><p>Let the <coderef>keySystem</coderef> attribute be <var title="true">keySystem</var>.</p></li>
+        </ol>
+      </li>
+
+      <li>Return the new object to the caller.</li>
+    </ol>
+
+    <p>When destroying a <coderef>MediaKeys</coderef> object, follow the steps in <methodref>close</methodref>.</p>
+
+    <p>The <methoddfn name="createSession">createSession(<var title="true">type</var>, <var title="true">initData</var>)</methoddfn> method must run the following steps:</p>
     <p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a>.</p>
 
     <ol>
-      <li><p>If the first argument is null, throw a <syntax-err/>.</p></li>
-
-      <li><p>If <videoref name="dom-media-networkstate">networkState</videoref> is <videoref name="dom-media-network_empty">NETWORK_EMPTY</videoref>, throw an <invalid-state-err/>.</p>
-      <p class="non-normative">In general, applications should wait for an event named <coderef>needkey</coderef> or <videoref name="event-media-loadstart">loadstart</videoref> (per the <resource-fetch-algorithm/>) before calling this method.</p>
-      </li>
+      <li><p>If <var title="true">type</var> is null or an empty string and <var title="true">initData</var> is <em>not</em> null or an empty string, throw an <invalid-access-err/> exception and abort these steps.</p></li>
+      
+      <li><p>If <var title="true">type</var> contains a MIME type that is not supported or is not supported by the <coderef>keySystem</coderef>, throw a <not-supported-err/> exception and abort these steps.</p></li>
 
-      <li><p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keySystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a></dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <not-supported-err/>.</dd>
-        </dl>
+      <li>Create a new <coderef>MediaKeySession</coderef> object.
+        <ol>
+          <li><p>Let the <coderef>keySystem</coderef> attribute be <var title="true">keySystem</var>.</p></li>
+          <li><p>Let the <coderef>sessionId</coderef> attribute be a unique <a href="#session-id">Session ID</a> string. It may be generated by <var title="true">cdm</var>.</p></li>
+        </ol>
       </li>
+      
+      <li><p>Add the new object to an internal list of session objects.</p></li>
 
-      <li><p>Schedule a task to handle the call, providing <var title="true">initData</var>.</p>
+      <li><p>Schedule a task to generate a key request, providing <var title="true">type</var>, <var title="true">initData</var>, and the new object.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
-          <li><p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = null<br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-<!-- Everything above here should be the same for all methods. -->
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
+
           <li><p>Let <var title="true">defaultURL</var> be null.</p></li>
-          <li><p>Use <var title="true">handler</var> to generate a key request and follow the steps for the first matching condition from the following list:</p>
+          <li><p>Use <var title="true">cdm</var> to generate a key request and follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
               <dt>If a request is successfully generated</dt>
               <dd>
               <ol>
                 <li><p>Let <var title="true">key request</var> be a key request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>, if provided.</p>
-                  <p>Note: <var title="true">handler</var> must not use any data, including <videoanchor name="media-data">media data</videoanchor>, not provided via <var title="true">initData</var>.</p>
+                  <p>Note: <var title="true">cdm</var> must not use any data, including <videoanchor name="media-data">media data</videoanchor>, not provided via <var title="true">initData</var>.</p>
+                  <p class="non-normative"><var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
                 </li>
                 <li><p>If <var title="true">initData</var> is not null and contains a default URL for <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
               </ol>
               </dd>
               <dt>Otherwise</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = null<br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
+              <dd><ol>
+                <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <coderef>code</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
+                    <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <coderef>MediaKeySession</coderef> object's <coderef>error</coderef> attribute to the error object created in the previous step.</p></li>
+                <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol></dd>
             </dl>
           </li>
-          <li><p>Let <var title="true">sessionId</var> be a unique <a href="#session-id">Session ID</a> string. It may be generated by <var title="true">handler</var>.</p></li>
-          <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the <a href="#media-element">media element</a></p>
+          <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the new object</p>
             <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
             <ul style="list-style-type:none"><li>
-              <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-              <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
               <coderef>message</coderef> = <var title="true">key request</var><br></br>
-              <coderef>defaultURL</coderef> = <var title="true">defaultURL</var>
+              <coderef>destinationURL</coderef> = <var title="true">defaultURL</var>
             </li></ul>
             <p class="non-normative">Note: <coderef>message</coderef> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>
           </li>
         </ol>
       </li>
+      
+      <li>Return the new object to the caller.</li>
     </ol>
 
-    <p>The <methoddfn name="addKey">addKey(<var title="true"><a href="#key-system">keySystem</a></var>, <var title="true">key</var>, <var title="true">initData</var>, <var title="true"><a href="#session-id">sessionId</a></var>)</methoddfn> method must run the following steps:</p>
+    <p>The <codedfn>error</codedfn> attribute is a <coderef>MediaKeyError</coderef> representing the current error state of the session. It is null if there is no error.</p>
+
+    <p>The <codedfn>keySystem</codedfn> attribute is an identifier for the <a href="#key-system">Key System</a> being used.</p>
+
+    <p>The <codedfn>sessionId</codedfn> attribute is the <a href="#session-id">Session ID</a> for this objects and the associated key(s) or license(s).</p>
+
+    <p>The <methoddfn name="addKey">addKey(<var title="true">key</var>)</methoddfn> method must run the following steps:</p>
     <p class="non-normative">Note: The contents of <var title="true">key</var> are <var title="true"><a href="#key-system">keySystem</a></var>-specific.
     It may be a raw key or a license containing a key.
     The contents may also vary depending on the container, key length, etc.</p>
-    <p class="non-normative">Note: The contents of <var title="true">initData</var> are container-specific <a href="#initialization-data">Initialization Data</a> and should be the same format as the same parameter in <methodref>generateKeyRequest</methodref>.
-    It may be null.
-    </p>
 
     <ol>
-      <li><p>If the first or second argument is null, throw a <syntax-err/>.</p></li>
-
-      <li><p>If the second argument is an empty array, throw a <type-mismatch-err/>.</p></li>
-
-      <li><p>If <videoref name="dom-media-networkstate">networkState</videoref> is <videoref name="dom-media-network_empty">NETWORK_EMPTY</videoref>, throw an <invalid-state-err/>.</p>
-      <p class="non-normative">In general, applications should wait for an event named <coderef>needkey</coderef> or <videoref name="event-media-loadstart">loadstart</videoref> (per the <resource-fetch-algorithm/>) before calling this method.</p>
-      </li>
+      <li><p>If the first or second argument is null or an empty array, throw an <invalid-access-err/>.</p></li>
 
-      <li><p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keySystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a></dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <not-supported-err/>.</dd>
-        </dl>
-      </li>
-
-      <li><p>If <var title="true">sessionId</var> is not null and is unrecognized, throw an <invalid-access-err/>.</p></li>
-
-      <li><p>Schedule a task to handle the call, providing <var title="true">key</var>, <var title="true">initData</var>, and <var title="true">sessionId</var>.</p>
+      <li><p>Schedule a task to handle the call, providing <var title="true">key</var>.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
-          <li><p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-<!-- Everything above here except sessionId handling should be the same for all methods. -->
-          <li><p>Let <var title="true">key stored</var> be false.</p></li>
+          <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
+
+          <li><p>Let <var title="true">did store key</var> be false.</p></li>
           <li><p>Let <var title="true">next message</var> be null.</p></li>
-          <li><p>Use <var title="true">handler</var> to handle <var title="true">key</var>.</p>
+          <li><p>Use <var title="true">cdm</var> to handle <var title="true">key</var>.</p>
+          <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
             <ol>
               <li><p>Process <var title="true">key</var>.</p></li>
-              <li><p>If <var title="true">key</var> contains a key or license, store the key.</p>
+              <li><p>For each <var title="true">individual key</var> in <var title="true">key</var>, store the <var title="true">individual key</var>.</p>
                 <ol>
                   <li><p>Let <var title="true">key ID</var> be null.</p></li>
-                  <li><p>If <var title="true">sessionId</var> is not null and refers to a session with <a href="#initialization-data">Initialization Data</a> that contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
-                  <li><p>If <var title="true">key</var> is not null and contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
-                  <li><p>If <var title="true">initData</var> is not null and contains a key ID, let <var title="true">key ID</var> be that ID.</p></li>
-                  <li><p>Store the key by following the steps for the first matching condition from the following list:</p>  
+                  <li><p>If there is a key ID associated with the <var title="true">individual key</var>, let <var title="true">key ID</var> be that ID.</p></li>
+                  <li><p>Store the <var title="true">individual key</var> by following the steps for the first matching condition from the following list:</p>  
                     <dl class="switch">
                       <dt>If <var title="true">key ID</var> is not null</dt>
                       <dd>
                         <ol>
-                          <li><p>Clear any key not associated with a key ID.</p></li>
-                          <li><p>If a key already exists for <var title="true">key ID</var>, delete that element.</p></li>
-                          <li><p>Store the key and/or license in <var title="true">key</var> indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
+                          <li><p>Clear any stored key not associated with a key ID.</p></li>
+                          <li><p>If a stored key already exists for <var title="true">key ID</var>, delete that key.</p></li>
+                          <li><p>Store the <var title="true">individual key</var>, license, and/or license information indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
                         </ol>
                       </dd>
                       <dt>Otherwise</dt>
                       <dd>
                         <ol>
                           <li><p>Clear all stored keys.</p></li>
-                          <li><p>Store the key and/or license in <var title="true">key</var> with no associated key ID.</p></li>
+                          <li><p>Store the <var title="true">individual key</var>, license, and/or license information with no associated key ID.</p></li>
                         </ol>
                       </dd>
                     </dl>
                     <p class="non-normative">At most one key may be stored if key IDs are not used.</p>
                     <p class="non-normative">Clearing keys avoids needing to handle a mixture of keys with and without IDs in the <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a>.</p>
-                    <p class="non-normative">Note: It is recommended that CDM providers support a standard and reasonably high minimum number of cached keys/licenses (with IDs) per media element as well as a standard replacement algorithm.
+                    <p class="non-normative">Note: It is recommended that CDMs support a standard and reasonably high minimum number of cached keys/licenses (with IDs) per media element as well as a standard replacement algorithm.
                     This enables a reasonable number of key rotation algorithms to be implemented across user agents and may reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (i.e. adaptive streams, various audio and video tracks) using different keys.
                     </p>
                   </li>
-                  <li><p>Let <var title="true">key stored</var> be true.</p></li>
+                  <li><p>Let <var title="true">did store key</var> be true.</p></li>
                 </ol>
               </li>
               <li><p>If another message needs to be sent to the server, let <var title="true">next message</var> be that message.</p></li>
             </ol>
           </li>
-          <li>If <var title="true">key stored</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <queue-a-task/> to attempt to resume playback.
+          <li>If <var title="true">did store key</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <queue-a-task/> to attempt to resume playback.
             <p class="non-normative">In other words, resume playback if the necessary key is provided.</p>
           </li>
-          <li><p>Fire the appropriate event by following the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If <var title="true">next message</var> is null</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyadded</coderef> at the <a href="#media-element">media element</a></p>
-                <p>The event is of type <coderef>MediaKeyCompleteEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                </li></ul>
-              </dd>
-              <dt>Otherwise</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the <a href="#media-element">media element</a></p>
-                <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                  <coderef>message</coderef> = <var title="true">next message</var><br></br>
-                  <coderef>defaultURL</coderef> = null
-                </li></ul>
-              </dd>
-            </dl>
-          <p>If any of the preceding steps in the task failed, <queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a>.</p>
-            <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-              <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-              <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-              <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
+          <li><p>If <var title="true">next message</var> is not null, <queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the <coderef>MediaKeySession</coderef> object.</p>
+             <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
+             <ul style="list-style-type:none"><li>
+               <coderef>message</coderef> = <var title="true">next message</var><br></br>
+               <coderef>destinationURL</coderef> = null
+             </li></ul>
+          </li>
+          <li><p>If <var title="true">did store key</var> is true, <queue-a-task/> to <fire-a-simple-event/> named <coderef>keyadded</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
+          <li><p>If any of the preceding steps in the task failed</p>
+              <ol>
+                <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <coderef>code</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
+                    <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <coderef>MediaKeySession</coderef> object's <coderef>error</coderef> attribute to the error object created in the previous step.</p></li>
+                <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol>
           </li>
       </ol>
       </li>
     </ol>
 
     <p>The key acquisition process <em>may</em> involve the web page handling <coderef>keymessage</coderef> events, sending the message to a Key System-specific service, and calling <coderef>addKey</coderef> with the response message.
-    This continues until the <coderef>keyadded</coderef> event is fired.
+    <coderef>addKey</coderef> calls may generate <coderef>keyadded</coderef> or <coderef>keymessage</coderef> events.
     During the process, the web page may wish to cancel the acquisition process.
     <span class="non-normative">For example, if the page cannot contact the license service because of network issues it may wish to fallback to an alternative key system.</span>
-    The page calls <methodref>cancelKeyRequest</methodref> to cancel the a key acquisition and return the media element to a state where <methodref>generateKeyRequest</methodref> may be called again.
+    The page calls <methodref>close</methodref> to cancel the a key acquisition session.
     </p>
 
-    <p>The <methoddfn name="cancelKeyRequest">cancelKeyRequest(<var title="true"><a href="#key-system">keySystem</a></var>, <var title="true">sessionId</var>)</methoddfn> method must run the following steps:</p>
+    <p>The <methoddfn name="close">close()</methoddfn> method causes the key acquisition session to close and all keys to be released. It must run the following steps:</p>
 
      <ol>
-      <li><p>If the first argument is null, throw a <syntax-err/>.</p></li>
-      <li><p>If <var title="true">sessionId</var> is not null and is unrecognized or not mapped to the <var title="true"><a href="#key-system">keySystem</a></var>, throw an <invalid-access-err/>.</p></li>
-      <li>If a <coderef>keyadded</coderef> event has already been fired for this <var title="true">sessionId</var>, throw an <invalid-state-err/>.</li>
-      <li>Clear any internal state associated with the <var title="true">sessionId</var> (or if this is null with the <var title="true"><a href="#key-system">keySystem</a></var> for this media element).
-      This <var title="true">sessionId</var> will now be unrecognized.
-      </li>
-      <li><b>TBD</b></li>
+      <li>Clear any internal state associated with the session, including all keys and licenses.</li>
     </ol>
 
     <p>The <codedfn prefix="source">keySystem</codedfn> attribute of <coderef>HTMLSourceElement</coderef> specifies the <a href="#key-system">Key System</a> to be used with the <videoref name="media-resource">media resource</videoref>.
@@ -493,15 +500,6 @@
       <li><p>&#8987; If <var title="">candidate</var> has a <coderef prefix="source">keySystem</coderef> attribute whose value represents a <a href="#key-system">Key System</a> that the user agent knows it cannot use with <videoref name="attr-source-type">type</videoref>, then end the <synchronous-section/>, and jump down to the <i title="">failed</i> step below.</p></li>
     </ol>
 
-    <p>A <a href="#media-element">media element</a> is said to <dfn id="have-selected-key-system">have a selected Key System</dfn> when one of the following has occurred:</p>
-    <ul>
-      <li>The media source was selected from a <coderef>HTMLSourceElement</coderef>.
-      <p>In this case, the selected key system is the <coderef>keySystem</coderef> attribute of the selected <coderef>HTMLSourceElement</coderef>.</p></li>
-
-      <li>One of the <a href="#dom-htmlmediaelement">new methods</a> has been called successfully (asynchronous steps may not have completed)
-      <p>In this case, the selected key system is the <var title="true">keySystem</var> parameter for the last successful call.</p></li>
-    </ul>
-
     <h3 id="error-codes">2.1. Error Codes</h3>
     <p><videoref name="mediaerror">MediaError</videoref> is extended, and a new error type is added.</p>
     <pre class="idl">
@@ -516,9 +514,22 @@
   const unsigned short <precoderef>MEDIA_KEYERR_OUTPUT</precoderef> = 4;
   const unsigned short <precoderef>MEDIA_KEYERR_HARDWARECHANGE</precoderef> = 5;
   const unsigned short <precoderef>MEDIA_KEYERR_DOMAIN</precoderef> = 6;
+  readonly attribute unsigned short <precoderef>code</precoderef>;
+  readonly attribute unsigned long <precoderef>systemCode</precoderef>;
 };</pre>
 
-    <p>The <codedfn>code</codedfn> attribute of a <coderef>MediaError</coderef> may additionally return the following:</p>
+    <dl class="domintro">
+     <dt><var title="">session</var> . <var title="">error</var> . <coderef>code</coderef></dt>
+     <dd>
+       <p>Returns the current error's error code, from the list below.</p>
+     </dd>
+     <dt><var title="">session</var> . <var title="">error</var> . <coderef>systemCode</coderef></dt>
+     <dd>
+       <p>Returns the current error's system code.</p>
+     </dd>
+    </dl>
+
+    <p>The <codedfn prefix="mediaerror">code</codedfn> attribute of a <coderef>MediaError</coderef> may additionally return the following:</p>
     <dl>
       <dt><codedfn>MEDIA_ERR_ENCRYPTED</codedfn> (numeric value 5)</dt>
       <dd>The stream could not be played because it is encrypted and one of the following:
@@ -530,7 +541,8 @@
       </dd>
     </dl>
 
-    <p>A <coderef>MediaKeyError</coderef> may be one of the following:</p>
+    <div class="impl">
+    <p>The <codedfn>code</codedfn> attribute of a <coderef>MediaKeySession</coderef> object must return the code for the error, which must be one of the following:</p>
     <dl>
       <dt><codedfn>MEDIA_KEYERR_UNKNOWN</codedfn> (numeric value 1)</dt>
       <dd>An unspecified error occurred. This value is used for errors that don't match any of the following codes.</dd>
@@ -546,77 +558,42 @@
       <dd>An error occurred in a multi-device domain licensing configuration. <span class="non-normative">The most common error is a failure to join the domain.</span></dd>
     </dl>
 
+    <p>The <codedfn>systemCode</codedfn> attribute of a <coderef>MediaKeySession</coderef> object is a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.
+    <span class="non-normative">This allows a more granular status to be returned than the more general <coderef>errorCode</coderef>.</span>
+    It should be 0 if there is no associated status code or such status codes are not supported by the Key System.
+    </p>
+    </div>
+
 
     <h2 id="events">3. Events</h2>
 
     <h3 id="event-definitions">3.1. Event Definitions</h3>
+    <pre class="idl">
+[Constructor(DOMString type, optional <precoderef>MediaKeyMessageEventInit</precoderef> eventInitDict)]
+interface <precodedfn>MediaKeyMessageEvent</precodedfn> : <dom4ref name="event">Event</dom4ref> {
+  readonly attribute Uint8Array <precoderef>message</precoderef>;
+  readonly attribute DOMString? <precoderef>destinationURL</precoderef>;
+};
+
+dictionary <precodedfn>MediaKeyMessageEventInit</precodedfn> : <dom4ref name="eventinit">EventInit</dom4ref> {
+  Uint8Array <precoderef>message</precoderef>;
+  DOMString? <precoderef>destinationURL</precoderef>;
+};</pre>
 
     <pre class="idl">
 [Constructor(DOMString type, optional <precoderef>MediaKeyNeededEventInit</precoderef> eventInitDict)]
 interface <precodedfn>MediaKeyNeededEvent</precodedfn> : <dom4ref name="event">Event</dom4ref> {
-  readonly attribute DOMString? <precoderef>keySystem</precoderef>;
-  readonly attribute DOMString? <precoderef>sessionId</precoderef>;
   readonly attribute Uint8Array? <precoderef>initData</precoderef>;
 };
 
 dictionary <precodedfn>MediaKeyNeededEventInit</precodedfn> : <dom4ref name="eventinit">EventInit</dom4ref> {
-  DOMString? <precoderef>keySystem</precoderef>;
-  DOMString? <precoderef>sessionId</precoderef>;
   Uint8Array? <precoderef>initData</precoderef>;
 };</pre>
 
-    <pre class="idl">
-[Constructor(DOMString type, optional <precoderef>MediaKeyMessageEventInit</precoderef> eventInitDict)]
-interface <precodedfn>MediaKeyMessageEvent</precodedfn> : <dom4ref name="event">Event</dom4ref> {
-  readonly attribute DOMString <precoderef>keySystem</precoderef>;
-  readonly attribute DOMString? <precoderef>sessionId</precoderef>;
-  readonly attribute Uint8Array <precoderef>message</precoderef>;
-  readonly attribute DOMString? <precoderef>defaultURL</precoderef>;
-};
-
-dictionary <precodedfn>MediaKeyMessageEventInit</precodedfn> : <dom4ref name="eventinit">EventInit</dom4ref> {
-  DOMString <precoderef>keySystem</precoderef>;
-  DOMString? <precoderef>sessionId</precoderef>;
-  Uint8Array <precoderef>message</precoderef>;
-  DOMString? <precoderef>defaultURL</precoderef>;
-};</pre>
-
-    <pre class="idl">
-[Constructor(DOMString type, optional <precoderef>MediaKeyCompleteEventInit</precoderef> eventInitDict)]
-interface <precodedfn>MediaKeyCompleteEvent</precodedfn> : <dom4ref name="event">Event</dom4ref> {
-  readonly attribute DOMString <precoderef>keySystem</precoderef>;
-  readonly attribute DOMString? <precoderef>sessionId</precoderef>;
-};
-
-dictionary <precodedfn>MediaKeyCompleteEventInit</precodedfn> : <dom4ref name="eventinit">EventInit</dom4ref> {
-  DOMString <precoderef>keySystem</precoderef>;
-  DOMString? <precoderef>sessionId</precoderef>;
-};</pre>
-
-    <pre class="idl">
-[Constructor(DOMString type, optional <precoderef>MediaKeyErrorEventInit</precoderef> eventInitDict)]
-interface <precodedfn>MediaKeyErrorEvent</precodedfn> : <dom4ref name="event">Event</dom4ref> {
-  readonly attribute DOMString <precoderef>keySystem</precoderef>;
-  readonly attribute DOMString? <precoderef>sessionId</precoderef>;
-  readonly attribute <precoderef>MediaKeyError</precoderef> <precoderef>errorCode</precoderef>;
-  readonly attribute unsigned short <precoderef>systemCode</precoderef>;
-};
-
-dictionary <precodedfn>MediaKeyErrorEventInit</precodedfn> : <dom4ref name="eventinit">EventInit</dom4ref> {
-  DOMString <precoderef>keySystem</precoderef>;
-  DOMString? <precoderef>sessionId</precoderef>;
-  <precoderef>MediaKeyError</precoderef> <precoderef>errorCode</precoderef>;
-  unsigned short <precoderef>systemCode</precoderef>;
-};</pre>
-
     <dl class="domintro">
-     <dt><var title="">event</var> . <coderef>keySystem</coderef></dt>
+     <dt><var title="">event</var> . <coderef>destinationURL</coderef></dt>
      <dd>
-       <p>Returns the name of the <a href="#key-system">Key System</a> that generated the event.</p>
-     </dd>
-     <dt><var title="">event</var> . <coderef>sessionId</coderef></dt>
-     <dd>
-       <p>Returns the <a href="#session-id">Session ID</a> the event is related to, if applicable.</p>
+       <p>Returns the URL to send the <coderef>message</coderef> to.</p>
      </dd>
      <dt><var title="">event</var> . <coderef>initData</coderef></dt>
      <dd>
@@ -626,37 +603,22 @@
      <dd>
        <p>Returns the message <span class="non-normative">(i.e. key request)</span> to send.</p>
      </dd>
-     <dt><var title="">event</var> . <coderef>defaultURL</coderef></dt>
-     <dd>
-       <p>Returns the default key exchange URL.</p>
-     </dd>
-     <dt><var title="">event</var> . <coderef>errorCode</coderef></dt>
-     <dd>
-       <p>Returns the <coderef>MediaKeyError</coderef> for the error that occurred.</p>
-     </dd>
-     <dt><var title="">event</var> . <coderef>systemCode</coderef></dt>
-     <dd>
-       <p>Returns a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.</p>
-     </dd>
     </dl>
     <div class="impl">
-    <p>The <codedfn>keySystem</codedfn> attribute is an identifier for the <a href="#key-system">Key System</a> that generated the event.
-    It may be null in the <coderef>needkey</coderef> event if the media element does not <a href="#have-selected-key-system">have a selected Key System</a>.
-    </p>
-    <p>The <codedfn>sessionId</codedfn> attribute is the <a href="#session-id">Session ID</a> for the key or license that this event refers to. It may be null.</p>
     <p>The <codedfn>initData</codedfn> attribute contains <a href="#initialization-data">Initialization Data</a> specific to the event.</p>
     <p>The <codedfn>message</codedfn> attribute contains a message from the CDM. Messages are Key System-specific. <span class="non-normative">In most cases, it should be sent to a key server.</span></p>
-    <p>The <codedfn>defaultURL</codedfn> is the default URL to send the key request to as provided by the <videoanchor name="media-data">media data</videoanchor>. It may be null.</p>
-    <p>The <codedfn>errorCode</codedfn> attribute contains the <coderef>MediaKeyError</coderef> code for the error that occurred.</p>
-    <p>The <codedfn>systemCode</codedfn> attribute contains a <a href="#key-system">Key System</a>-dependent status code for the error that occurred.
-    <span class="non-normative">This allows a more granular status to be returned than the more general <coderef>errorCode</coderef>.</span>
-    It should be 0 if there is no associated status code or such status codes are not supported by the Key System.
+    <p>The <codedfn>destinationURL</codedfn> is the URL to send the <coderef>message</coderef> to.
+       An application <em>may</em> override this.
+       <span class="non-normative">In some cases, it may have been provided by the <videoanchor name="media-data">media data</videoanchor>.</span>
+       It may be null.
     </p>
 
     <p>If a response (i.e. a license) is necessary, applications should use one of the <a href="#dom-htmlmediaelement">new methods</a> to provide the response.</p>
     </div>
 
     <h3 id="event-summary">3.2. Event Summary</h3>
+
+    <p>The following events are fired at <coderef>MediaKeySession</coderef>.</p>
     <table>
       <thead>
         <tr>
@@ -669,26 +631,40 @@
       <tbody>
         <tr>
           <td><codedfn>keyadded</codedfn></td>
-          <td><coderef>MediaKeyCompleteEvent</coderef></td>
+          <td><code><dom4ref name="event">Event</dom4ref></code></td>
           <td>A key has been added as the result of a <methodref>addKey</methodref> call.
           </td>
           <td><!-- No Preconditions. --></td>
         </tr>
         <tr>
           <td><codedfn>keyerror</codedfn></td>
-          <td><coderef>MediaKeyErrorEvent</coderef></td>
-          <td>An error occurs in one of the <a href="#dom-htmlmediaelement">new methods</a> or <a href="#cdm">CDM</a>.</td>
+          <td><code><dom4ref name="event">Event</dom4ref></code></td>
+          <td>An error occurs in the session.</td>
           <td><!-- No Preconditions. --></td>
         </tr>
         <tr>
           <td><codedfn>keymessage</codedfn></td>
           <td><coderef>MediaKeyMessageEvent</coderef></td>
           <td>
-            A message has been generated <span class="non-normative">(and likely needs to be sent to a key server)</span>.
-            <span class="non-normative">For example, a key request has been generated as the result of a <methodref>generateKeyRequest</methodref> call or another message must be sent in response to an <methodref>addKey</methodref> call.</span>
+            A message has been generated <span class="non-normative">(and likely needs to be sent to a server)</span>.
+            <span class="non-normative">For example, a key request has been generated as the result of a <methodref>createSession</methodref> call or another message must be sent in response to an <methodref>addKey</methodref> call.</span>
           </td>
           <td><!-- No Preconditions. --></td>
         </tr>
+      </tbody>
+    </table>
+
+    <p>The following event is fired at <coderef>HTMLMediaElement</coderef>.</p>
+    <table>
+      <thead>
+        <tr>
+          <th>Event name</th>
+          <th>Interface</th>
+          <th>Dispatched when...</th>
+          <th>Preconditions</th>
+        </tr>
+      </thead>
+      <tbody>
         <tr>
           <td><codedfn>needkey</codedfn></td>
           <td><coderef>MediaKeyNeededEvent</coderef></td>
@@ -722,129 +698,6 @@
     This is because proof-of-release messages may be cached in CDMs after the associated media elements have been destroyed.
     Proof-of-key-release messages are subject to the same origin policy: they shall only be delivered to scripts with the same origin as the script which created the media element that provided the key/license.
     </p>
-    
-    <h3>4.2. Key Release Manager</h3>
-    <p>The following interface is defined for management of key release messages:</p>
-    
-    <pre class="idl" id="key-release-manager">
-    [Constructor()]
-    interface <precodedfn>KeyReleaseManager</precodedfn> : <dom4ref name="eventtarget">EventTarget</dom4ref> {
-        void <premethodref>getKeyReleases</premethodref>(in DOMString <a href="#key-system">keySystem</a>);
-        void <premethodref>addKeyReleaseCommit</premethodref>(in DOMString <a href="#key-system">keySystem</a>, in DOMString <a href="#session-id">sessionId</a>, in Uint8Array message);
-    }
-    </pre>
-    <p>The <methoddfn name="getKeyReleases">getKeyReleases(<var title="true"><a href="#key-system">keysystem</a></var>)</methoddfn> method must run the following steps:</p>
-
-    <ol>
-      <li><p>If the first argument is null, throw a <syntax-err/>.</p></li>
-      <li><p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keysystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a></dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <not-supported-err/>.</dd>
-        </dl>
-      </li>
-
-      <li><p>Schedule a task to handle the call.</p>
-        <p>The user agent will asynchronously execute the following steps in the task:</p>
-        <ol>
-          <li><p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = null<br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-          <li><p>Use <var title="true">handler</var> to generate one or more key release messages, if supported.
-            <var title="true">handler</var> should follow the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If generating a key release message is not supported</dt>
-              <dd>Let <var title="true">key release messages</var> be null</dd>
-              <dt>Otherwise</dt>
-              <dd>Let <var title="true">key release messages</var> be a set of key release messages generated by the <a href="#cdm">CDM</a> for the current origin.</dd>
-            </dl>
-          </li>
-          <li><p>For each <var title="true">key release message</var> in <var title="true">key release messages</var>, <queue-a-task/> to <fire-a-simple-event/> named <coderef>keyrelease</coderef> at the <a href="#key-release-manager">key release manager</a>.</p>
-            <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-              <coderef>sessionId</coderef> = the sessionId originally associated with the provision of the key<br></br>
-              <coderef>message</coderef> = <var title="true">key release message</var><br></br>
-              <coderef>defaultURL</coderef> = value of the default URL, if stored by the CDM.
-            </li></ul>
-          </li>
-        </ol>
-      </li>
-    </ol>
-    
-    <p>The <methoddfn name="addKeyReleaseCommit">addKeyReleaseCommit(<var title="true"><a href="#key-system">keysystem</a></var>,
-                                                                     <var title="true"><a href="#session-id">sessionId</a></var>,
-                                                                     <var title="true"><a href="#message">message</a></var>)</methoddfn>
-    method must run the following steps:
-    </p>
-
-    <ol>
-      <li><p>If the first argument is null, throw a <syntax-err/>.</p></li>
-      <li><p>Initialize <var title="true">handler</var> by following the steps for the first matching condition from the following list:</p>
-        <dl class="switch">
-          <dt>If <var title="true">keysystem</var> is one of the user agent's supported <a href="#key-system">Key Systems</a></dt>
-          <dd>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">keySystem</var>.</dd>
-          <dt>Otherwise</dt>
-          <dd>Throw a <not-supported-err/>.</dd>
-        </dl>
-      </li>
-
-      <li><p>Schedule a task to handle the call, providing <var title="true">sessionId</var> and <var title="true">message</var>.</p>
-        <p>The user agent will asynchronously execute the following steps in the task:</p>
-        <ol>
-          <li><p>Load <var title="true">handler</var> if necessary.</p>
-            <dl class="switch">
-              <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-          <li><p>Use <var title="true">handler</var> to commit the message.
-            <var title="true">handler</var> should follow the steps for the first matching condition from the following list:</p>
-            <dl class="switch">
-              <dt>If committing a key release message is supported and the <var title="true">message</var> is valid:</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyreleasecommitted</coderef> at the <a href="#key-release-manager">key release manager</a>.</p>
-                <p>The event is of type <coderef>MediaKeyCompleteEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                </li></ul>
-              </dd>
-              <dt>Otherwise</dt>
-              <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#key-release-manager">key release manager</a>.</p>
-                <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-                <ul style="list-style-type:none"><li>
-                  <coderef>keySystem</coderef> = <var title="true">keySystem</var><br></br>
-                  <coderef>sessionId</coderef> = <var title="true">sessionId</var><br></br>
-                  <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                  <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                </li></ul>
-              </dd>
-            </dl>
-          </li>
-        </ol>
-      </li>
-    </ol>
 
     <h2 id="algorithms">5. Algorithms</h2>
 
@@ -852,39 +705,19 @@
     <p>The following steps are run when the <a href="#media-element">media element</a> encounters a block <span class="non-normative">(i.e. frame)</span> of encrypted <videoanchor name="media-data">media data</videoanchor> during the <resource-fetch-algorithm/>:</p>
 
     <ol>
-      <li><p>Let <var title="">key system</var> be null.</p></li>
-      <li><p>Let <var title="">handler</var> be null.</p></li>
+      <li><p>Let <var title="">cdm</var> be null.</p></li>
       <li><p>Let <var title="">block initData</var> be null.</p></li>
       <li><p>Let <var title="">block key</var> be null.</p></li>
       <li><p>If the block (or its parent entity) has <a href="#initialization-data">Initialization Data</a>, let <var title="">block initData</var> be that initialization data.</p></li>
-      <li><p>Select the key system and handler by following the steps for the first matching condition from the following list:</p>
+      <li><p>Determine whether there is an active <a href="#cdm">CDM</a> by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If the media element <a href="#have-selected-key-system">has a selected Key System</a></dt>
-        <dd>Run the following steps:
-          <ol>
-            <li><p>Let <var title="true">key system</var> be the selected Key System.</p></li>
-            <li><p>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">key system</var>.</p></li>
-          </ol>
-        </dd>
+        <dt>If the media element's <coderef>keys</coderef> attribute is not null</dt>
+        <dd>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</dd>
         <dt>Otherwise</dt>
         <dd>Jump to the <i>Key Presence</i> step below.</dd>
       </dl>
       </li>
-      <li><p>Load <var title="true">handler</var> if necessary.</p>
-        <dl class="switch">
-          <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-          <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-            <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <coderef>keySystem</coderef> = <var title="true">key system</var><br></br>
-              <coderef>sessionId</coderef> = null<br></br>
-              <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-              <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
-          </dd>
-        </dl>
-      </li>
-      <li><p>Use <var title="true">handler</var> to select the key:</p>
+      <li><p>Use <var title="true">cdm</var> to select the key:</p>
         <ol>
           <li><p>Let <var title="">block key ID</var> be null.</p></li>
           <li><p>If <var title="">block initData</var> is not null and contains a key ID, let <var title="">block key ID</var> be that ID.</p></li>
@@ -892,23 +725,23 @@
           <dl class="switch">
             <dt>If <var title="">block key ID</var> is not null</dt>
             <dd>
-            <p>Select the key by using <var title="true">handler</var> to follow the steps for the first matching condition from the following list:</p>
+            <p>Select the key by using <var title="true">cdm</var> to follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
-              <dt>If <var title="true">handler</var>  has a key cached for <var title="">block key ID</var></dt>
+              <dt>If <var title="true">cdm</var>  has a key cached for <var title="">block key ID</var></dt>
               <dd>Let <var title="">block key</var> be the matching cached key.</dd>
-              <dt>If <var title="true">handler</var> has a key cached with no ID <span class="non-normative">(there can be one at most)</span></dt>
+              <dt>If <var title="true">cdm</var> has a key cached with no ID <span class="non-normative">(there can be one at most)</span></dt>
               <dd>Let <var title="">block key</var> be the single cached key.</dd>
-              <dt>Otherwise (<var title="true">handler</var> has no keys cached OR has one or more keys cached, none of which have a matching key ID)</dt>
+              <dt>Otherwise (<var title="true">cdm</var> has no keys cached OR has one or more keys cached, none of which have a matching key ID)</dt>
               <dd>Jump to the <i>Key Presence</i> step below.</dd>
             </dl>
             </dd>
             <dt>Otherwise</dt>
             <dd>
-            <p>Select the key by using <var title="true">handler</var> to follow the steps for the first matching condition from the following list:</p>
+            <p>Select the key by using <var title="true">cdm</var> to follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
-              <dt>If <var title="true">handler</var> has a single key cached (with or without a key ID)</dt>
+              <dt>If <var title="true">cdm</var> has a single key cached (with or without a key ID)</dt>
               <dd>Let <var title="">block key</var> be the single cached key.</dd>
-              <dt>If <var title="true">handler</var> has more than one key cached <span class="non-normative">(all would have IDs)</span></dt>
+              <dt>If <var title="true">cdm</var> has more than one key cached <span class="non-normative">(all would have IDs)</span></dt>
               <dd>Abort media element's <resource-fetch-algorithm/> and run the steps to report a <coderef>MEDIA_ERR_ENCRYPTED</coderef> error.</dd>
               <dt>Otherwise</dt>
               <dd>Jump to the <i>Key Presence</i> step below.</dd>
@@ -920,8 +753,8 @@
       </li>
       <li><p><i>Key Presence</i>: Handle the presence of a key by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If <var title="">handler</var> is not null and <var title="">block key</var> is not null.</dt>
-        <dd>Use <var title="true">handler</var> to Decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:
+        <dt>If <var title="">cdm</var> is not null and <var title="">block key</var> is not null.</dt>
+        <dd>Use <var title="true">cdm</var> to Decrypt the block using <var title="">block key</var> by following the steps for the first matching condition from the following list:
           <dl class="switch">
             <dt>If decryption fails</dt>
             <dd>Abort media element's <resource-fetch-algorithm/> and run the steps to report a <coderef>MEDIA_ERR_ENCRYPTED</coderef> error.</dd>
@@ -935,8 +768,6 @@
         <queue-a-task/> to <fire-a-simple-event/> named <coderef>needkey</coderef> at the <a href="#media-element">media element</a>.
         <p>The event is of type <coderef>MediaKeyNeededEvent</coderef> and has:</p>
         <ul style="list-style-type:none"><li>
-          <coderef>keySystem</coderef> = <var title="">key system</var><br></br>
-          <coderef>sessionId</coderef> = null<br></br>
           <coderef>initData</coderef> = <var title="">block initData</var>
         </li></ul>
         <p class="non-normative">The <a href="#media-element">media element</a> is said to be <videoref name="potentially-playing">potentially playing</videoref>
@@ -979,38 +810,18 @@
     <p>The following steps are run when the <a href="#media-element">media element</a> encounters a source that may contain encrypted blocks or streams during the <resource-fetch-algorithm/>:</p>
 
     <ol>
-      <li><p>Let <var title="">key system</var> be null.</p></li>
-      <li><p>Let <var title="">handler</var> be null.</p></li>
+      <li><p>Let <var title="">cdm</var> be null.</p></li>
       <li><p>Let <var title="">initData</var> be null.</p></li>
       <li><p>If <a href="#initialization-data">Initialization Data</a> was encountered, let <var title="">initData</var> be that initialization data.</p></li>
-      <li><p>Select the key system and handler by following the steps for the first matching condition from the following list:</p>
+      <li><p>Determine whether there is an active <a href="#cdm">CDM</a> by following the steps for the first matching condition from the following list:</p>
       <dl class="switch">
-        <dt>If the media element <a href="#have-selected-key-system">has a selected Key System</a></dt>
-        <dd>Run the following steps:
-          <ol>
-            <li><p>Let <var title="true">key system</var> be the selected Key System.</p></li>
-            <li><p>Let <var title="true">handler</var> be the <a href="#cdm">content decryption module</a> corresponding to <var title="true">key system</var>.</p></li>
-          </ol>
-        </dd>
+        <dt>If the media element's <coderef>keys</coderef> attribute is not null</dt>
+        <dd>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</dd>
         <dt>Otherwise</dt>
         <dd>Jump to the <i>Need Key</i> step below.</dd>
       </dl>
       </li>
-      <li><p>Load <var title="true">handler</var> if necessary.</p>
-        <dl class="switch">
-          <dt>If <var title="true">handler</var> fails to load or initialize</dt>
-          <dd><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <a href="#media-element">media element</a> and abort the task.</p>
-            <p>The event is of type <coderef>MediaKeyErrorEvent</coderef> and has:</p>
-            <ul style="list-style-type:none"><li>
-              <coderef>keySystem</coderef> = <var title="true">key system</var><br></br>
-              <coderef>sessionId</coderef> = null<br></br>
-              <coderef>errorCode</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-              <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-            </li></ul>
-          </dd>
-        </dl>
-      </li>
-      <li><p>Use <var title="true">handler</var> to determine whether the key is known:</p>
+      <li><p>Use <var title="true">cdm</var> to determine whether the key is known:</p>
         <ol>
           <li><p>Let <var title="">key ID</var> be null.</p></li>
           <li><p>If a key ID for the source is known at this time, let <var title="">key ID</var> be that ID.</p></li>
@@ -1044,12 +855,10 @@
       <li><p><i>Need Key</i>: <queue-a-task/> to <fire-a-simple-event/> named <coderef>needkey</coderef> at the <a href="#media-element">media element</a>.</p>
         <p>The event is of type <coderef>MediaKeyNeededEvent</coderef> and has:</p>
         <ul style="list-style-type:none"><li>
-          <coderef>keySystem</coderef> = <var title="">key system</var><br></br>
-          <coderef>sessionId</coderef> = null<br></br>
           <coderef>initData</coderef> = <var title="">initData</var>
         </li></ul>
         <p class="non-normative">Firing this event allows the application to begin acquiring the key process before it is needed.</p>
-        <p class="non-normative">Note that <readystate/> is <em>not</em> changed and no algorithms are aborted. This algorithm is merely informative.</p>
+        <p class="non-normative">Note that <readystate/> is <em>not</em> changed and no algorithms are aborted. This event is merely informative.</p>
       </li>
 
       <li><p><i>Continue Normal Flow</i>: Continue with the existing media element's <resource-fetch-algorithm/>.</p></li>
@@ -1058,8 +867,8 @@
     <h3 id="algorithms-load">5.3. Addition to Media Element Load Algorithm</h3>
     <p>The following step is added to the existing <media-element-load-algorithm/>:</p>
     <ul>
-      <li><p>Clear all cached keys for this <a href="#media-element">media element</a>.</p>
-      <p class="non-normative">This also means the keys will be cleared when the <videoref name="attr-media-src">src</videoref> attribute is set or changed per <videoanchor name="location-of-the-media-resource">Location of the media resource</videoanchor></p>
+      <li><p>Clear the <codref>keys</codref> attribute for this <a href="#media-element">media element</a>.</p>
+      <p class="non-normative">This also means the <codref>keys</codref> attribute will be cleared when the <videoref name="attr-media-src">src</videoref> attribute is set or changed per <videoanchor name="location-of-the-media-resource">Location of the media resource</videoanchor></p>
       </li>
     </ul>
 
@@ -1076,48 +885,24 @@
     Use of this Key System is described below.
     </p>
     
-    <p>The <var title="true">keySystem</var> parameter and <coderef>keySystem</coderef> attributes are always <code>"org.w3.clearkey"</code>
-    with the exception of events before the Key System <a href="#have-selected-key-system">has been selected</a>.
-    All events except <coderef>needkey</coderef> have a valid <coderef>sessionId</coderef> string, which is numerical.</p>
+    <p>The <var title="true">keySystem</var> parameter and <coderef>keySystem</coderef> attributes are always <code>"org.w3.clearkey"</code>.
+    The <coderef>sessionId</coderef> string is numerical.</p>
 
-    <p>The <coderef>initData</coderef> attribute of the <coderef>needkey</coderef> event and the <var title="true">initData</var> parameters of <methodref>generateKeyRequest</methodref> and <methodref>addKey</methodref> are the same container-specific <a href="#initialization-data">Initialization Data</a> format and values.
+    <p>The <coderef>initData</coderef> attribute of the <coderef>needkey</coderef> event and the <var title="true">initData</var> parameter of <methodref>createSession</methodref> are the same container-specific <a href="#initialization-data">Initialization Data</a> format and values.
     <span class="non-normative">
     If supported, these values should provide some type of identification of the content or key that could be used to look up the key (since there is no defined logic for parsing it).
     For containers that support a simple key ID, it should be a binary array containing the raw key ID.
     For other containers, it may be some other opaque blob or null.</span>
     </p>
 
-    <p><methodref>generateKeyRequest</methodref> may optionally be called.
-    The resulting <coderef>MediaKeyMessageEvent</coderef> has:
-    </p>
+    
+    <p>The <coderef>MediaKeyMessageEvent</coderef> generated by <methodref>createSession</methodref> has:</p>
     <ul style="list-style-type:none"><li>
-      <coderef>keySystem</coderef> = <code>"org.w3.clearkey"</code><br></br>
-      <coderef>sessionId</coderef> = a unique numerical string<br></br>
-      <coderef>message</coderef> = a container-specific unique key identifier extracted from the <var title="true">initData</var> parameter of <methodref>generateKeyRequest</methodref>. null if <var title="true">initData</var> was null or a key identifier could not be extracted.<br></br>
-      <coderef>defaultURL</coderef> = value of the default URL if present in the <videoanchor name="media-data">media data</videoanchor> and null otherwise.
+      <coderef>message</coderef> = a container-specific value extracted from the <var title="true">initData</var> parameter of <methodref>createSession</methodref>. null if <var title="true">initData</var> was null or a value could not be extracted.<br></br>
+      <coderef>destinationURL</coderef> = value of the default URL if present in the <videoanchor name="media-data">media data</videoanchor> and null otherwise.
     </li></ul>
 
-    <p>To provide a key using this Key System, pass the following to <methodref>addKey</methodref>:</p>
-    <ul>
-      <li><var title="true">keySystem</var>: <code>"org.w3.clearkey"</code></li>
-      <li><var title="true">key</var>: An array of bytes containing the key</li>
-      <li><var title="true">initData</var>:
-        <dl class="switch">
-          <dt>If <methodref>generateKeyRequest</methodref> was called:</dt>
-          <dd>The value of the <coderef>message</coderef> attribute of the resulting <coderef>MediaKeyMessageEvent</coderef></dd>
-          <dt>Otherwise</dt>
-          <dd><a href="#initialization-data">Initialization Data</a> corresponding to the <var title="true">key</var> or null.</dd>
-        </dl>
-      </li>
-      <li><var title="true">sessionId</var>:
-        <dl class="switch">
-          <dt>If <methodref>generateKeyRequest</methodref> was called:</dt>
-          <dd>The value of the <coderef>sessionId</coderef> attribute of the resulting <coderef>MediaKeyMessageEvent</coderef></dd>
-          <dt>Otherwise</dt>
-          <dd>null</dd>
-        </dl>
-      </li>
-    </ul>
+    <p>The <var title="true">key</var> parameter of <methodref>addKey</methodref> should be an array of bytes containing the key.</p>
 
 
     <h2 id="examples">7. Examples</h2>
@@ -1137,13 +922,29 @@
 &lt;script&gt;
   function load() {
     var video = document.getElementById("video");
+
+    if (!video.keys)
+      video.keys = MediaKeys("org.w3.clearkey");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession();
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<precoderef>keymessage</precoderef>="handleMessage(event)";
+  }
+
+  function handleMessage(event) {
+    var keySession = event.target;
+
     var key = new Uint8Array([ 0xaa, 0xbb, 0xcc, ... ]);
-    video.<premethodref>addKey</premethodref>("org.w3.clearkey", key, null);
+    keySession.<premethodref>addKey</premethodref>(key);
   }
 &lt;/script&gt;
 
 &lt;body onload="load()"&gt;
-  &lt;video src="foo.webm" autoplay id="video"&gt;&lt;/video&gt;
+  &lt;video src="foo.webm" autoplay id="video" on<precoderef>keymessage</precoderef>="handleMessage(event)"&gt;&lt;/video&gt;
 &lt;/body&gt;</pre>
     </div>
 
@@ -1161,20 +962,34 @@
       <pre class="code">
 &lt;script&gt;
   function handleKeyNeeded(event) {
-    if (event.<precoderef>keySystem</precoderef> &amp;&amp; event.<precoderef>keySystem</precoderef> != "org.w3.clearkey")
-      throw "Unhandled keySystem in event";
+    var video = event.target;
     var initData = event.<precoderef>initData</precoderef>;
-    var video = event.target;
+
+    if (!video.keys)
+      video.keys = MediaKeys("org.w3.clearkey");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<precoderef>keymessage</precoderef>="handleMessage(event)";
+  }
+
+  function handleMessage(event) {
+    var keySession = event.target;
+    var message = event.<precoderef>message</precoderef>;
 
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", "http://.../getkey", false);
-    xmlhttp.send(initData);
+    xmlhttp.send(message);
     var key = new Uint8Array(xmlhttp.response);
-    video.<premethodref>addKey</premethodref>("org.w3.clearkey", key, initData, event.<precoderef>sessionId</precoderef>);
+    keySession.<premethodref>addKey</premethodref>(key);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)" on<precoderef>keymessage</precoderef>="handleMessage(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h4 class="exampleheader">7.2.2. Other Content Decryption Module</h4>
@@ -1184,32 +999,36 @@
       <pre class="code">
 &lt;script&gt;
   function handleKeyNeeded(event) {
-    if (event.<precoderef>keySystem</precoderef> &amp;&amp; event.<precoderef>keySystem</precoderef> != "com.example.somesystem.1_0")
-      throw "Unhandled keySystem in event";
+    var video = event.target;
     var initData = event.<precoderef>initData</precoderef>;
-    var video = event.target;
 
-    video.<premethodref>generateKeyRequest</premethodref>("com.example.somesystem.1_0", initData);
+    if (!video.keys)
+      video.keys = MediaKeys("com.example.somesystem.1_0");
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<precoderef>keymessage</precoderef>="licenseRequestReady(event)";
   }
 
   function licenseRequestReady(event) {
-    if (event.<precoderef>keySystem</precoderef> != "com.example.somesystem.1_0")
-      throw "Unhandled keySystem in event";
+    var keySession = event.target;
     var request = event.<precoderef>message</precoderef>;
     if (!request)
       throw "Could not create license request";
 
-    var video = event.target;
-
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", "http://.../getkey", false);
     xmlhttp.send(request);
     var license = new Uint8Array(xmlhttp.response);
-    video.<premethodref>addKey</premethodref>("com.example.somesystem.1_0", license, null, event.<precoderef>sessionId</precoderef>);
+    keySession.<premethodref>addKey</premethodref>(license);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)" on<precoderef>keymessage</precoderef>="licenseRequestReady(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h3 id="examples-selecting-key-system" class="exampleheader">7.3. Selecting a Supported Key System</h3>
@@ -1239,34 +1058,38 @@
   }
 
   function handleKeyNeeded(event) {
-    var targetKeySystem = event.<precoderef>keySystem</precoderef>;  
-    if (targetKeySystem == null) {
-      selectKeySystem(video);  // See previous example for implementation.
-      targetKeySystem = keySystem;
-    }
-    var initData = event.<precoderef>initData</precoderef>;
     var video = event.target;
+    var initData = event.<precoderef>initData</precoderef>;
 
-    video.<premethodref>generateKeyRequest</premethodref>(targetKeySystem, initData);
+    if (!video.keys) {
+      selectKeySystem(video);
+      video.keys = MediaKeys(keySystem);
+    }
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = mediaKeys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<precoderef>keymessage</precoderef>="licenseRequestReady(event)";
   }
-
+  
   function licenseRequestReady(event) {
-    if (event.<precoderef>keySystem</precoderef> != keySystem)
-      throw "Message from unexpected Key System";
+    var keySession = event.target;
     var request = event.<precoderef>message</precoderef>;
     if (!request)
       throw "Could not create license request";
 
-    var video = event.target;
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("POST", licenseUrl, false);
     xmlhttp.send(request);
     var license = new Uint8Array(xmlhttp.response);
-    video.<premethodref>addKey</premethodref>(keySystem, license, null, event.<precoderef>sessionId</precoderef>);
+    keySession.<premethodref>addKey</premethodref>(license);
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)" on<precoderef>keymessage</precoderef>="licenseRequestReady(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
     <h3 class="exampleheader">7.4. Using All Events</h3>
@@ -1281,50 +1104,57 @@
 
   function handleMessageResponse() {
     var license = new Uint8Array(xmlhttp.response);
-    var video = document.getElementById(“video”);
-    video.<premethodref>addKey</premethodref>(keySystem, license, null, this.sessionId);
+    this.keySession.<premethodref>addKey</premethodref>(license);
   }
   
-  function sendMessage(message, sessionId) {
+  function sendMessage(message, keySession) {
     xmlhttp = new XMLHttpRequest();
-    xmlhttp.sessionId = sessionId;
+    xmlhttp.keySession = keySession;
     xmlhttp.onreadystatechange = handleMessageResponse;
     xmlhttp.open("POST", licenseUrl, true);
     xmlhttp.send(message);
   }
 
-  function handleKeyNeeded(event) {
-    var targetKeySystem = event.<precoderef>keySystem</precoderef>;  
-    if (targetKeySystem == null) {
-      selectKeySystem(video);  // See previous example for implementation.
-      targetKeySystem = keySystem;
-    }
-    var initData = event.<precoderef>initData</precoderef>;
-    var video = event.target;
-
-    video.<premethodref>generateKeyRequest</premethodref>(targetKeySystem, initData);
-  }
-
   function handleKeyMessage(event) {
-    if (event.<precoderef>keySystem</precoderef> != keySystem)
-      throw "Message from unexpected Key System";
+    var keySession = event.target;
     var message = event.<precoderef>message</precoderef>;
     if (!message)
       throw "Invalid key message";
   
-    sendMessage(message, event.<precoderef>sessionId</precoderef>);
+    sendMessage(message, keySession);
   }
 
   function handleKeyComplete(event) {
-    // Do some bookkeeping with event.<precoderef>sessionId</precoderef> if necessary.
+    // Do some bookkeeping with event.target.<precoderef>sessionId</precoderef> if necessary.
   }
 
   function handleKeyError(event) {
-    // Report event.<precoderef>errorCode</precoderef> and do some bookkeeping with event.<precoderef>sessionId</precoderef> if necessary.
+    // Report event.target.error.<precoderef>code</precoderef> and event.target.error.<precoderef>systeCode</precoderef>,
+    // and do some bookkeeping with event.target.<precoderef>sessionId</precoderef> if necessary.
+  }
+
+  function handleKeyNeeded(event) {
+    var video = event.target;
+    var initData = event.<precoderef>initData</precoderef>;
+
+    if (!video.keys) {
+      selectKeySystem(video);  // See previous example for implementation.
+      video.keys = MediaKeys(keySystem);
+    }
+    if (!video.keys)
+      throw "Could not create MediaKeys";
+
+    var keySession = video.keys.createSession(mimeType, initData);
+    if (!keySession)
+      throw "Could not create key session";
+
+    keySession.on<precoderef>keymessage</precoderef>="handleKeyMessage(event)";
+    keySession.on<precoderef>keyadded</precoderef>="handleKeyComplete(event)";
+    keySession.on<precoderef>keyerror</precoderef>="handleKeyError(event)";
   }
 &lt;/script&gt;
 
-&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)" on<precoderef>keymessage</precoderef>="handleKeyMessage(event)" on<precoderef>keyadded</precoderef>="handleKeyComplete(event)" on<precoderef>keyerror</precoderef>="handleKeyError(event)"&gt;&lt;/video&gt;</pre>
+&lt;video src="foo.webm" autoplay on<precoderef>needkey</precoderef>="handleKeyNeeded(event)"&gt;&lt;/video&gt;</pre>
     </div>
 
 
@@ -1341,7 +1171,7 @@
     <ul>
       <li>If adaptive streaming is handled within the user agent (Type 1), the adaptive implementation can expose the events and methods needed to provide key(s) for the streams via the APIs in this proposal.</li>
       <li>If adaptive streaming is handled in the application/JavaScript (Type 3), behavior should be very similar to the non-adaptive case.
-      For example, the proposed <a href="http://html5-mediasource-api.googlecode.com/svn/trunk/draft-spec/mediasource-draft-spec.html">MediaSource Extensions</a> allow the application to provide a dynamic <code>src</code>, which could be encrypted and handled just like a normal stream.
+      For example, the <a href="http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html">Media Source Extensions</a> allow the application to provide a dynamic <code>src</code>, which could be encrypted and handled just like a normal stream.
       </li>
     </ul>
 
@@ -1354,7 +1184,6 @@
     <h4 id="sourceelement" class="faqquestion">Can I let the user agent select the appropriate CDM using <code>&lt;source&gt;</code> elements?</h4>
     <p class="faqanswer">Yes, using the <coderef prefix="source">keySystem</coderef> attribute of the <coderef>HTMLSourceElement</coderef>.
     When used with <videoref name="attr-source-type">type</videoref> attribute, this will select the first <code>&lt;source&gt;</code> element (container, codec, and <a href="#key-system">Key System</a>) that the user agent might support.
-    The selected <a href="#cdm">CDM</a> will not be reported to the application until an event is fired.
     </p>
 
     <h4 id="faq-heartbeat" class="faqquestion">Is a heartbeat supported?</h4>
@@ -1368,7 +1197,7 @@
     <h3 id="faq-use">8.2. Use</h3>
 
     <h4 class="faqquestion">Can I send a token for the signed-in user with the license request?</h4>
-    <p class="faqanswer">Yes. The application can add this to the license request (sent via <code>XMLHttpRequest</code> in the <a href="#examples">examples</a>) or send it to the <a href="#cdm">CDM</a> via <methodref>generateKeyRequest</methodref> to be included in the license request.</p>
+    <p class="faqanswer">Yes. The application can add this to the license request (sent via <code>XMLHttpRequest</code> in the <a href="#examples">examples</a>) or send it to the <a href="#cdm">CDM</a> via <methodref>createSession</methodref> to be included in the license request.</p>
 
     <h4 class="faqquestion">How do I resume playback after receiving the <coderef>needkey</coderef> event in the <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a>?</h4>
     <p class="faqanswer">Assuming there are no other issues, playback will resume when the needed key is provided by <methodref>addKey</methodref> and processed.</p>
@@ -1377,6 +1206,9 @@
     <p class="faqanswer">Yes, this will likely be necessary to support all or a majority of user agents.
     An application could also use different <a href="#key-system">Key Systems</a> on a single user agent for different purposes.</p>
 
+    <h4 class="faqquestion">Can an <coderef>HTMLMediaElement</coderef> use multiple <a href="#key-system">Key System</a>s at the same time?</h4>
+    <p class="faqanswer">No.</p>
+
     <h4 class="faqquestion">How do I add support for a CDM to my application?</h4>
     <p id="faq-cdm-library" class="faqanswer">We envision <a href="#cdm">CDM</a> providers creating JavaScript libraries that application developers can include. <methodref>canPlayType</methodref> can then be used to select from supported libraries.</p>
 
@@ -1387,12 +1219,6 @@
     Some basic Key System feature detection may be <a href="canplaytype-capability-detection">available via canPlayType()</a>.
     </p>
 
-    <h4 class="faqquestion">How should an application handle a <coderef>needkey</coderef> event with a null <coderef>keySystem</coderef> attribute?</h4>
-    <p class="faqanswer">This is a very common scenario because it happens when the user agent encounters encrypted media and does not have an appropriate key.
-    If the application does not already know which <a href="#key-system">Key System</a> to use, it should use <methodref>canPlayType</methodref> to select an appropriate one.
-    When the <coderef>keySystem</coderef> attribute is null, the <coderef>initData</coderef> attribute is always independent of the <a href="#key-system">Key System</a>.
-    </p>
-
     <h4 class="faqquestion">What is a license URL (<code>licenseUrl</code>) in the examples?</h4>
     <p class="faqanswer">This is the URL for a server capable of providing the key for the stream, usually using the <a href="#initialization-data">Initialization Data</a> and often after verifying the requesting user.
     The URL is application- and/or <a href="#key-system">Key System</a>-specific and may be a content provider or a Key System provider depending on the solution.</p>
@@ -1441,33 +1267,24 @@
     Instead, the Key System is passed as a second parameter to <methodref>canPlayType</methodref> and as a separate attribute to the source element.
     </p>
 
-    <h4 class="faqquestion">Will I be informed if a call to one of the <a href="#dom-htmlmediaelement">new methods</a> fails?</h4>
+    <h4 id="faq-key-system-mime-type" class="faqquestion">Why isn't the <a href="#key-system">Key System</a> part of the MIME type (like codecs)?</h4>
+    <p class="faqanswer">In many cases (especially the direction the content providers and standards are moving), the stream is not specific to any one Key System or provider. Multiple Key Systems could be used to decrypt the same generic stream. Thus, the <a href="#key-system">Key System</a> is not information about the file and should not be part of the MIME type.</p>
+    <p class="faqanswer">One could argue that the encryption algorithm (e.g. AES-128) and configuration should be in the MIME type. That is not required for this proposal, so it is not addressed here.</p>
+
+    <h4 class="faqquestion">Will my application be informed if a call to one of the <a href="#dom-htmlmediaelement">new methods</a> fails?</h4>
     <p class="faqanswer">Errors that occur during synchronous portion of the algorithms will be thrown.
     For asynchronous portions (i.e. when a task is scheduled), a <coderef>MediaKeyErrorEvent</coderef> will be fired.
     </p>
 
-    <h4 id="faq-key-system-mime-type" class="faqquestion">Why isn't the <a href="#key-system">Key System</a> part of the MIME type (like codecs)?</h4>
-    <p class="faqanswer">In many cases (especially the direction the content providers and standards are moving), the stream is not specific to any one Key System or provider. Multiple Key Systems could be used to decrypt the same generic stream. Thus, the <a href="#key-system">Key System</a> is not information about the file and should not be part of the MIME type.</p>
-    <p class="faqanswer">One could argue that the encryption algorithm (e.g. AES-128) and configuration should be in the MIME type. That is not required for this proposal, so it is not addressed here.</p>
-
-    <h4 class="faqquestion">Why do we need another event?</h4>
+    <h4 class="faqquestion">Why do we need additional events?</h4>
     <p class="faqanswer">While many use case could be implemented without an additional event (by requiring the app to provide all the information up front), some use cases may be better handled by an event.</p>
 
-    <h4 class="faqquestion">Why does the event need multiple attributes?</h4>
-    <p class="faqanswer">The <coderef>keySystem</coderef> attribute ensures that the application knows which <a href="#cdm">CDM</a> caused the event so it can know how to handle the event. While the application could probably know or discover this in other ways, this makes it simple for the application.</p>
-
     <h4 class="faqquestion">Why do we need a new <coderef>MediaError</coderef> code?</h4>
     <p class="faqanswer">Without a new error code (<coderef>MEDIA_ERR_ENCRYPTED</coderef>), it is not possible for user agents to clearly indicate to an application that playback failed because the content was encrypted and user agents will likely need to fire a <code>MEDIA_ERR_DECODE</code> or <code>MEDIA_ERR_SRC_NOT_SUPPORTED</code>, which would be confusing.</p>
 
     <h4 class="faqquestion">Will adding a new error code to <coderef>MediaError</coderef> break existing applications?</h4>
     <p class="faqanswer">Applications that are not aware of the new error code (<coderef>MEDIA_ERR_ENCRYPTED</coderef>) may not correctly handle it, but they should still be able to detect that an error has occurred because a) an error event is fired and b) <var title="">media</var> . <code title="dom-media-error"><videoref name="mediaerror">error</videoref></code> is not null.</p>
 
-    <h4 class="faqquestion">Why do we need a new error type (<coderef>MediaKeyError</coderef>) and event (<coderef>MediaKeyErrorEvent</coderef>)?</h4>
-    <p class="faqanswer">While key/license exchange errors are fatal to the exchange session, most are not fatal to playback.
-    This is especially true if the <a href="#media-element">media element</a> already has a key for the current (and future) frames or, for example, the exchange was for a different stream in an <a href="#faq-adaptive-streaming">adaptive streaming</a> scenario.
-    The separation allows the <a href="#media-element">media element</a> to continue playback while the application attempts to resolve the exchange problem or until the requested key/license is actually needed.
-    </p>    
-
     <h4 class="faqquestion">What happens if a response to the <coderef>needkey</coderef> event from a <a href="#algorithms-encrypted-stream">encountering a potentially encrypted stream</a> is not received before <a href="#algorithms-enrypted-block">encountering an encrypted block</a>?</h4>
     <p class="faqanswer">The <a href="#algorithms-enrypted-block">Encrypted Block Encountered algorithm</a> will proceed as normal.
     If no appropriate key has been provided, a second <coderef>needkey</coderef> event will be fired and decoding will stop.
@@ -1476,18 +1293,8 @@
     <h4 class="faqquestion">The same <coderef>needkey</coderef> event with the same attributes is fired for both <a href="#algorithms-enrypted-block">Encrypted Block Encountered</a> and <a href="#algorithms-encrypted-stream">Potentially Encrypted Stream Encountered</a>. How can an application distinguish between the two?</h4>
     <p class="faqanswer">The same event was used intentionally to reduce the complexity of applications. Ideally, they would not need to know.</p>
 
-    <h4 class="faqquestion">What if a different [supported] <a href="#key-system">Key System</a> is passed to one of the <a href="#dom-htmlmediaelement">new methods</a> in subsequent calls to the same <coderef>HTMLMediaElement</coderef>?</h4>
-    <p class="faqquestion">(Expanding on the question, this relates to the new methods, including <methodref>generateKeyRequest</methodref> and <methodref>addKey</methodref>, that modify state and does not apply to <methodref>canPlayType</methodref>, which is explicitly intended to be called with multiple <a href="#key-system">Key System</a> strings.
-    For example, what if <methodref>generateKeyRequest</methodref> is called with one Key System then <methodref>addKey</methodref> is called with another; or if <methodref>addKey</methodref> is called twice with two different Key Systems.)
-    </p>
-    <p class="faqanswer">If a load occurs between calls with different Key Systems, then there is no problem.</p>
-    <p class="faqanswer">Otherwise, the calls will be treated separately.
-    <methodref>generateKeyRequest</methodref> will start a new session with a new <a href="#session-id">Session ID</a>.
-    <methodref>addKey</methodref> will behave as normal unless <var title="true">sessionId</var> parameter is not null and is unrecognized for the specified <var title="true">keySystem</var> parameter.
-    </p>
-
     <h4 class="faqquestion">What if a key/license for the same <a href="#initialization-data">Initialization Data</a> (i.e. key ID) is provided more than once to <methodref>addKey</methodref>?</h4>
-    <p class="faqanswer">Replace it, updating the ordering to reflect that this key ID was most recently added.
+    <p class="faqanswer">The CDM will replace previous entries, updating the overall key ordering to reflect that this key ID was most recently added.
     In other words, simply replacing the existing key data is not sufficient.
     The exact algorithm is covered in <methodref>addKey</methodref>.
     </p>
@@ -1502,7 +1309,7 @@
     <p class="faqanswer">The application must use <methodref>addKey</methodref> to indicate the stream is encrypted and provide the key before decoding starts.</p>
 
     <h4 class="faqquestion">Must the container provide Initialization Data or a content key ID?</h4>
-    <p class="faqanswer">This is ideal, but the API would also support the application sending the <a href="#initialization-data">Initialization Data</a> or ID directly to the server or providing it to the <a href="#cdm">CDM</a> via <methodref>generateKeyRequest</methodref>.</p>
+    <p class="faqanswer">This is ideal, but the API would also support the application sending the <a href="#initialization-data">Initialization Data</a> or ID directly to the server or providing it to the <a href="#cdm">CDM</a> via <methodref>createSession</methodref>.</p>
 
     <h4 class="faqquestion">What if a container/codec does not support key IDs or bit(s)?</h4>
     <p class="faqanswer">The application will need to use some other mechanism to select the appropriate key for the content.
@@ -1554,6 +1361,14 @@
       </thead>
       <tbody>
         <tr>
+          <td>16 August 2012</td>
+          <td>Converted to the object-oriented API.</td>
+        </tr>
+        <tr>
+          <td><a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html">0.1b</a></td>
+          <td>Last non-object-oriented revision.</td>
+        </tr>
+        <tr>
           <td><a href="http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1a/encrypted-media/encrypted-media.html">0.1a</a></td>
           <td>Corrects minor mistakes in 0.1.</td>
         </tr>