Re-write of Section 7: Service Discovery according to feedback @ http://lists.w3.org/Archives/Public/public-device-apis/2012Aug/0017.html
authorRich Tibbett <richt@opera.com>
Tue, 25 Sep 2012 12:48:42 +0200
changeset 230 3c13dc93cfb1
parent 229 2c38f7223615
child 231 a0e6b501258d
Re-write of Section 7: Service Discovery according to feedback @ http://lists.w3.org/Archives/Public/public-device-apis/2012Aug/0017.html
discovery-api/Overview.html
discovery-api/Overview.src.html
--- a/discovery-api/Overview.html	Tue Sep 25 11:20:35 2012 +0200
+++ b/discovery-api/Overview.html	Tue Sep 25 12:48:42 2012 +0200
@@ -204,17 +204,17 @@
   </p>
   <h1 class="title" id="title">Networked Service Discovery and Messaging</h1>
 
-  <h2 id="w3c-editor-s-draft-22-august-2012"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft 22 August 2012</h2>
+  <h2 id="w3c-editor-s-draft-25-september-2012"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft 25 September 2012</h2>
   <dl>
 
       <dt>This version:</dt>
-      <dd><a href="http://w3c-test.org/dap/discovery-api/">http://w3c-test.org/dap/discovery-api/</a></dd>
+      <dd><a href="http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html">http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html</a></dd>
       <dt>Latest published version:</dt>
       <dd><a href="http://www.w3.org/TR/discovery-api/">http://www.w3.org/TR/discovery-api/</a></dd>
 
 
       <dt>Latest editor's draft:</dt>
-      <dd><a href="http://w3c-test.org/dap/discovery-api/">http://w3c-test.org/dap/discovery-api/</a></dd>
+      <dd><a href="http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html">http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html</a></dd>
 
 
 
@@ -312,7 +312,7 @@
 
 
 
-</section><section id="toc"><h2 class="introductory">Table of Contents</h2><ul class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#conformance" class="tocxref"><span class="secno">2. </span>Conformance</a><ul class="toc"><li class="tocline"><a href="#dependencies" class="tocxref"><span class="secno">2.1 </span>Dependencies</a></li></ul></li><li class="tocline"><a href="#terminology" class="tocxref"><span class="secno">3. </span>Terminology</a></li><li class="tocline"><a href="#requesting-networked-services" class="tocxref"><span class="secno">4. </span>Requesting networked services</a><ul class="toc"><li class="tocline"><a href="#methods" class="tocxref"><span class="secno">4.1 </span>Methods</a></li><li class="tocline"><a href="#error-handling" class="tocxref"><span class="secno">4.2 </span>Error Handling</a></li></ul></li><li class="tocline"><a href="#obtaining-networked-services" class="tocxref"><span class="secno">5. </span>Obtaining networked services</a><ul class="toc"><li class="tocline"><a href="#attributes" class="tocxref"><span class="secno">5.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-1" class="tocxref"><span class="secno">5.2 </span>Methods</a></li><li class="tocline"><a href="#events" class="tocxref"><span class="secno">5.3 </span>Events</a></li></ul></li><li class="tocline"><a href="#communicating-with-a-networked-service" class="tocxref"><span class="secno">6. </span>Communicating with a networked service</a><ul class="toc"><li class="tocline"><a href="#attributes-1" class="tocxref"><span class="secno">6.1 </span>Attributes</a></li><li class="tocline"><a href="#states" class="tocxref"><span class="secno">6.2 </span>States</a></li><li class="tocline"><a href="#events-1" class="tocxref"><span class="secno">6.3 </span>Events</a></li></ul></li><li class="tocline"><a href="#service-discovery" class="tocxref"><span class="secno">7. </span>Service Discovery</a><ul class="toc"><li class="tocline"><a href="#zeroconf-mdns-dns-sd" class="tocxref"><span class="secno">7.1 </span>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</a></li><li class="tocline"><a href="#universal-plug-and-play-upnp" class="tocxref"><span class="secno">7.2 </span>Universal Plug-and-Play (<abbr title="Universal Plug-and-Play">UPnP</abbr>)</a></li><li class="tocline"><a href="#network-topology-monitoring" class="tocxref"><span class="secno">7.3 </span>Network Topology Monitoring</a></li></ul></li><li class="tocline"><a href="#garbage-collection" class="tocxref"><span class="secno">8. </span>Garbage collection</a></li><li class="tocline"><a href="#use-cases-and-requirements" class="tocxref"><span class="secno">9. </span>Use Cases and Requirements</a></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">A. </span>Examples</a></li><li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">B. </span>Acknowledgements</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">C. </span>References</a><ul class="toc"><li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">C.1 </span>Normative references</a></li><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">C.2 </span>Informative references</a></li></ul></li></ul></section>
+</section><section id="toc"><h2 class="introductory">Table of Contents</h2><ul class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#conformance" class="tocxref"><span class="secno">2. </span>Conformance</a><ul class="toc"><li class="tocline"><a href="#dependencies" class="tocxref"><span class="secno">2.1 </span>Dependencies</a></li></ul></li><li class="tocline"><a href="#terminology" class="tocxref"><span class="secno">3. </span>Terminology</a></li><li class="tocline"><a href="#requesting-networked-services" class="tocxref"><span class="secno">4. </span>Requesting networked services</a><ul class="toc"><li class="tocline"><a href="#methods" class="tocxref"><span class="secno">4.1 </span>Methods</a></li><li class="tocline"><a href="#error-handling" class="tocxref"><span class="secno">4.2 </span>Error Handling</a></li></ul></li><li class="tocline"><a href="#obtaining-networked-services" class="tocxref"><span class="secno">5. </span>Obtaining networked services</a><ul class="toc"><li class="tocline"><a href="#attributes" class="tocxref"><span class="secno">5.1 </span>Attributes</a></li><li class="tocline"><a href="#methods-1" class="tocxref"><span class="secno">5.2 </span>Methods</a></li><li class="tocline"><a href="#events" class="tocxref"><span class="secno">5.3 </span>Events</a></li></ul></li><li class="tocline"><a href="#communicating-with-a-networked-service" class="tocxref"><span class="secno">6. </span>Communicating with a networked service</a><ul class="toc"><li class="tocline"><a href="#attributes-1" class="tocxref"><span class="secno">6.1 </span>Attributes</a></li><li class="tocline"><a href="#states" class="tocxref"><span class="secno">6.2 </span>States</a></li><li class="tocline"><a href="#events-1" class="tocxref"><span class="secno">6.3 </span>Events</a></li></ul></li><li class="tocline"><a href="#service-discovery" class="tocxref"><span class="secno">7. </span>Service Discovery</a><ul class="toc"><li class="tocline"><a href="#zeroconf-mdns-dns-sd" class="tocxref"><span class="secno">7.1 </span>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</a></li><li class="tocline"><a href="#universal-plug-and-play-upnp" class="tocxref"><span class="secno">7.2 </span>Universal Plug-and-Play (<abbr title="Universal Plug-and-Play">UPnP</abbr>)</a></li><li class="tocline"><a href="#network-topology-monitoring" class="tocxref"><span class="secno">7.3 </span>Network Topology Monitoring</a></li></ul></li><li class="tocline"><a href="#garbage-collection" class="tocxref"><span class="secno">8. </span>Garbage collection</a></li><li class="tocline"><a href="#use-cases-and-requirements" class="tocxref"><span class="secno">9. </span>Use Cases and Requirements</a></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">A. </span>Examples</a></li><li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">B. </span>Acknowledgements</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">C. </span>References</a><ul class="toc"><li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">C.1 </span>Normative references</a></li></ul></li></ul></section>
 
 
 
@@ -465,10 +465,17 @@
       <p>
         A <dfn id="dfn-valid-service-type">valid service type</dfn> is a string that begins with <code>upnp:</code> or <code>zeroconf:</code> followed by one or more characters in the ranges U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E.
       </p>
+      <p></p>
 
       <p>
-        A <a href="#dfn-valid-service-type" class="internalDFN">valid service type</a> provided in the <code>type</code> attribute of the <code>getNetworkServices()</code> method will be matched against the services currently contained in the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> according to the algorithms defined in this specification.
+        A <a href="#dfn-valid-service-type" class="internalDFN">valid service type</a> provided in the <code>type</code> attribute of the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method will be matched against the services currently contained in the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> according to the algorithms defined in this specification.
       </p>
+
+      <p>
+        A <dfn id="dfn-user-agent-generated-callback-url">user-agent generated callback url</dfn> is a Local-network accessible <abbr title="Uniform Resource Locator">URL</abbr> endpoint that a <a href="#dfn-user-agent" class="internalDFN">user agent</a> must generate and maintain for receiving <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY requests from <abbr title="Universal Plug-and-Play">UPnP</abbr> Event sources. It is only required when the user agent implements <abbr title="Universal Plug-and-Play">UPnP</abbr> Service Discovery as defined in
+        this specification.
+      </p>
+
     </section>
 
     <section id="requesting-networked-services">
@@ -670,7 +677,7 @@
             </li>
 
             <li>
-              Store the set of <var>services</var> as <dfn id="current_authorized_services">current authorized services</dfn> internally against the newly created <var>services manager</var> object.
+              Add the set of <var>services</var> to the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> internally against the newly created <var>services manager</var> object.
             </li>
 
             <li>
@@ -788,7 +795,7 @@
           </dt>
           <dd>
             <p>
-              Returns the current number of services in the respective object's <a href="#current_authorized_services" class="internalDFN">current authorized services</a>.
+              Returns the current number of services belonging in the respective object's <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a>.
             </p>
           </dd>
           <dt>
@@ -805,7 +812,7 @@
 
         <div>
            <p>
-              The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute <em class="rfc2119" title="must">must</em> return the number of services represented in the object's corresponding <a href="#current_authorized_services" class="internalDFN">current authorized services</a> list at the time of getting.
+              The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute <em class="rfc2119" title="must">must</em> return the number of services represented in the object's corresponding <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> at the time of getting.
            </p>
 
            <p>
@@ -869,24 +876,24 @@
       </dl>
 
       <p>
-        A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of zero or more <a href="#current_authorized_services" class="internalDFN">current authorized services</a>, of which zero or more can be available at a time. Each item in <a href="#current_authorized_services" class="internalDFN">current authorized services</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object. The list of <a href="#current_authorized_services" class="internalDFN">current authorized services</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
+        A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of one or more current authorized services - the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a>. Each item in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object. The <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
       </p>
 
       <div class="note"><div class="note-title"><span>Note</span></div><p class="">
-        Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one. If the <a href="#dfn-user-agent" class="internalDFN">user agent</a> dynamically adds or removes network services for any reason, then the indices of the services in <a href="#current_authorized_services" class="internalDFN">current authorized services</a> will change dynamically. If the set of network services changes entirely, then all the previous services will be removed from <a href="#current_authorized_services" class="internalDFN">current authorized services</a> and replaced with new services.
+        Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one.
       </p></div>
 
       <p>
-        The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in <a href="#current_authorized_services" class="internalDFN">current authorized services</a> represented by the respective object minus one, if any services are represented in <a href="#current_authorized_services" class="internalDFN">current authorized services</a>. If a <a href="#networkservices"><code>NetworkServices</code></a> object represents no <a href="#current_authorized_services" class="internalDFN">current authorized services</a>, it has no <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a>.
+        The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> represented by the respective object minus one, if any services are represented in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a>.
       </p>
 
       <p>
-        To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a href="#current_authorized_services" class="internalDFN">current authorized services</a>, the user agent <em class="rfc2119" title="must">must</em> return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in <a href="#current_authorized_services" class="internalDFN">current authorized services</a>.
+        To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a>, the user agent <em class="rfc2119" title="must">must</em> return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a>.
       </p>
 
       <p>
-        The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class="rfc2119" title="must">must</em> return the first <a href="#networkservice"><code>NetworkService</code></a> object in <a href="#current_authorized_services" class="internalDFN">current authorized services</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
-        When no services in <a href="#current_authorized_services" class="internalDFN">current authorized services</a> match the given argument, the method <em class="rfc2119" title="must">must</em> return null.
+        The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method <em class="rfc2119" title="must">must</em> return the first <a href="#networkservice"><code>NetworkService</code></a> object in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
+        When no services in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> match the given argument, the method <em class="rfc2119" title="must">must</em> return null.
       </p>
 
       <p>
@@ -1156,7 +1163,7 @@
       </p>
       <p>
          This section presents how the results of these two service discovery
-         mechanisms will be matched to requested service types and how their properties will be applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
+         mechanisms will be matched to requested service types, how the user agent stores available and active services, how their properties are applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
       </p>
 
       <p>
@@ -1166,12 +1173,155 @@
       </p>
 
       <p>
-         The <dfn id="dfn-list-of-available-service-records">list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the current services available in the network at any given time.
+         The <dfn id="dfn-list-of-available-service-records">list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track all the  services that have been discovered and are available in the current network at any given time.
          At any point during the running of either of the two service discovery mechanisms then existing entries within this table can be updated, entries can be added and entries can be removed as the status of networked
-         services changes. Each record contained within this table contains the attributes: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code> and <code>config</code>.
+         services changes according to the rules defined in this specification. <!--Each record contained within this table contains the attributes: <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code> and <code>expiryTimestamp</code>.-->
       </p>
 
-            <section id="zeroconf-mdns-dns-sd">
+      <p>
+        The <dfn id="dfn-list-of-authorized-service-records">list of authorized service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the
+        current services that are being shared with web pages at any given time from the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>. Each record in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> is associated with a <var>services manager</var> object that is assigned as part of the
+         <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> algorithm.
+      </p>
+
+      <p>
+        The rule for <dfn id="dfn-adding-an-available-service">adding an available service</dfn> is the process of adding a new service or updating an existing service in the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> that is generally available on the user's current network. This rule takes one argument, <var>network service record</var>, and consists of
+        running the following steps:
+      </p>
+
+      <ol class="rule">
+
+        <li>
+          Let <var>new service registration flag</var> be <code>true</code>.
+        </li>
+
+        <li>
+           For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, run the following sub-steps:
+           <ol class="rule">
+
+             <li>
+              If the <var>existing service record</var>'s <code>id</code> property does not equal <var>network service record</var>'s <code>id</code>
+               property then abort any remaining sub-steps and continue at the next available <var>existing service record</var>.
+             </li>
+
+             <li>
+              Set <var>new service registration flag</var> to <code>false</code>.
+             </li>
+
+             <li>
+               Replace the value of <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> with the value of
+              <var>network service record</var>.
+             </li>
+           </ol>
+        </li>
+
+        <li>
+           If <var>new service registration flag</var> is set to <code>true</code> then add <var>network service record</var> to the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> as a new entry.
+        </li>
+
+        <li>
+          For each <var>active service</var> in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> run the following steps:
+
+          <ol class="rule">
+
+            <li>
+               If <var>network service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
+                <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
+            </li>
+
+            <li>
+               If the <var>new service registration flag</var> is set to <code>true</code> then increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <var>services manager</var> associated with
+               the current <var>active service</var>
+                object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
+                 to dispatch a newly created event with the name <a href="#dom-networkservices-onserviceavailable"><code>serviceavailable</code></a> that uses the <code>Event</code> interface,
+                 which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
+                 the current <var>active service</var> object.
+            </li>
+
+            <li>
+               <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
+                to dispatch a newly created event with the name <a href="#dom-networkservice-onserviceonline"><code>serviceonline</code></a> that uses the <code>Event</code> interface, which
+                 does not bubble, is not cancellable, and has no default action, at the current
+                <var>active service</var> object.
+            </li>
+
+          </ol>
+
+        </li>
+
+      </ol>
+
+
+      <p>
+        The rule for <dfn id="dfn-removing-an-available-service">removing an available service</dfn> is the general process of removing a service from the
+        <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>
+         that has left the user's current network or has otherwise expired. This rule takes one argument, <var>service identifier</var>, and consists of running the following steps:</p>
+
+      <ol class="rule">
+
+        <li>
+           For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, run the following sub-steps:
+           <ol class="rule">
+
+             <li>
+              If the <var>existing service record</var>'s <code>id</code> property does not match <var>service identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
+             </li>
+
+             <li>
+               If the <var>existing service record</var>'s <code>type</code> property begins with the DOMString "<code>upnp:</code>" and
+               <var>existing service record</var>'s <code>eventsURL</code> property is set then run the rule to
+               <a href="#dfn-terminate-an-existing-upnp-events-subscription" class="internalDFN">terminate an existing <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</a>, if one is currently active (as a result of having previously called
+               <a href="#dfn-setup-a-upnp-events-subscription" class="internalDFN">setup a <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</a> against the current <var>existing service record</var>).
+             </li>
+
+             <li>
+               For each <var>active service</var> in <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> run the following steps:
+
+               <ol class="rule">
+
+                 <li>
+                    If <var>existing service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
+                     <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
+                 </li>
+
+                 <li>
+                    Decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the
+                    <var>services manager</var> associated with the current <var>active service</var>
+                     object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
+                      to dispatch a newly created event with the name <a href="#dom-networkservices-onserviceunavailable"><code>serviceunavailable</code></a> that uses the <code>Event</code> interface,
+                      which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
+                      the current <var>active service</var> object.
+                 </li>
+
+                 <li>
+                    <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
+                     to dispatch a newly created event with the name <a href="#dom-networkservice-onserviceoffline"><code>serviceoffline</code></a> that uses the <code>Event</code> interface, which
+                      does not bubble, is not cancellable, and has no default action, at the current
+                     <var>active service</var> object.
+                 </li>
+
+               </ol>
+
+             </li>
+
+             <li>
+               Remove <var>existing service record</var> from the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>.
+             </li>
+
+           </ol>
+        </li>
+
+      </ol>
+
+      <p>
+       User agents <em class="ct"><em class="rfc2119" title="should">should</em></em> expire a service record from the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> when its
+       <code>expiryTimestamp</code> attribute exceeds the current UTC timestamp. When this condition is met the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="should">should</em>
+       run the rule for <a href="#dfn-removing-an-available-service" class="internalDFN">removing an available service</a>, passing in the expired service record's <code>id</code> attribute as the
+       only argument.
+      </p>
+
+
+      <section id="zeroconf-mdns-dns-sd">
          <h3><span class="secno">7.1 </span>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</h3>
 
          <p>
@@ -1187,7 +1337,7 @@
                <ol>
 
                   <li>
-                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>.
+                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>, <code>expiryTimestamp</code>.
                   </li>
 
                   <li>
@@ -1211,45 +1361,14 @@
                   </li>
 
                   <li>
-                     For each Object <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, run the following sub-steps:
-                     <ol class="rule">
-
-                       <li>
-                        If the <var>existing service record</var>'s <code>id</code> property matches the value of the <var>network service record</var>'s <code>id</code>, then set the
-                        value of <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>  to the value of the
-                        <var>network service record</var> and skip the next step.
-                       </li>
-                     </ol>
-                  </li>
-
-                  <li>
-                     Add <var>network service record</var> to the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>.
+                     Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus a value of <code>120</code> seconds.
                   </li>
 
                   <li>
-                     For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
+                     Run the general rule for <a href="#dfn-adding-an-available-service" class="internalDFN">adding an available service</a>, passing in the current <var>network service record</var> as the
+                     only argument.
+                  </li>
 
-                     <ol class="rule">
-                        <li>
-                           If the <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
-                           current <a>network service record</a>'s <code>type</code> property then continue at the next available active
-                           <a href="#networkservice"><code>NetworkService</code></a> object.
-                        </li>
-                        <li>
-                           Increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a> object by <code>1</code>.
-                        </li>
-                        <li>
-                          <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                           to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                            <a href="#networkservices"><code>NetworkServices</code></a> object.
-                        </li>
-                        <li>
-                          <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                           to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                           <a href="#networkservice"><code>NetworkService</code></a> object.
-                        </li>
-                     </ol>
-                  </li>
             </ol>
            </li>
          </ol>
@@ -1260,126 +1379,165 @@
          <h3><span class="secno">7.2 </span>Universal Plug-and-Play (<abbr title="Universal Plug-and-Play">UPnP</abbr>)</h3>
 
          <p>
-            For each <acronym title="Simple Service Discovery Protocol">SSDP</acronym> Presence Announcement [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] - a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request - received from a user-agent-initiated <acronym title="Simple Service Discovery Protocol">SSDP</acronym> Discovery Request [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>], the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> run the following steps:
+          A user agent that implements <abbr title="Universal Plug-and-Play">UPnP</abbr> service discovery must issue an <dfn id="dfn-advertisement-for-upnp-root-devices">advertisement for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</dfn> against the user's
+          current local network according to the full normative text and timing provided in 'Section 1.3.2: Search request with M-SEARCH' detailed in [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
+          </p>
+
+          <p>
+            The user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> issue all <a title="advertisement for UPnP root devices" href="#dfn-advertisement-for-upnp-root-devices" class="internalDFN">advertisements for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</a> with a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> request line equal to <code>M-SEARCH * <abbr title="Hypertext Transfer Protocol">HTTP</abbr>/1.1</code>, with a HOST header equal to the reserved multicast address and port of <code>239.255.255.250:1900</code>, a MAN header equal to <code>ssdp:discover</code>, an ST header equal to <code>upnp:rootdevice</code> and a user-agent defined MX header equal to a <dfn id="dfn-maximum-upnp-advertisement-response-wait-time">maximum <abbr title="Universal Plug-and-Play">UPnP</abbr> advertisement response wait time</dfn> value between <code>1</code> and <code>5</code> seconds.
+         </p>
+
+         <p>
+          The user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> listen for incoming requests and process any incoming responses to any <a href="#dfn-advertisement-for-upnp-root-devices" class="internalDFN">advertisement for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</a> on the <dfn id="dfn-standard-upnp-address-and-port">standard <abbr title="Universal Plug-and-Play">UPnP</abbr> address and port</dfn>, on all current local network interface addresses with the port <code>1900</code>, according to the rules defined in this section.
+         </p>
+
+         <p>
+          For each <dfn id="dfn-http-response"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</dfn> following an initial <a href="#dfn-advertisement-for-upnp-root-devices" class="internalDFN">advertisement for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</a> sent on a <a href="#dfn-standard-upnp-address-and-port" class="internalDFN">standard <abbr title="Universal Plug-and-Play">UPnP</abbr> address
+            and port</a> the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the following steps:
          </p>
 
          <ol class="rule">
-            <li>
-               Let <var>ssdp device</var> be an Object with a property for each <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header received in the received <acronym title="Simple Service Discovery Protocol">SSDP</acronym> Presence Announcement, with each key being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header and its
-               value being that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header's accompanying value.
-            </li>
-
-            <li>
-               If <var>ssdp device</var> does not contain at least one <var>NTS</var>, <var>USN</var> and <var>Location</var> parameter, then the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> abort these steps.
-            </li>
-
-            <li>
-               If the first occurrence of <var>NTS</var> has a value other than <code>ssdp:alive</code>, then continue to the step labeled <var>update service monitor</var> below.
-            </li>
-
-            <li>
-               Let <var>root device descriptor file</var> contain the contents of the file located at the <abbr title="Uniform Resource Locator">URL</abbr> provided in the first occurrence of <var>Location</var> obtained according to the rules
-               defined in the section 'Retrieving a description using <abbr title="Hypertext Transfer Protocol">HTTP</abbr>' [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
-            </li>
-
-            <li>
-               If <var>root device descriptor file</var> is empty, then the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> abort these steps.
-            </li>
-
-            <li>
-               Let <var>advertised services</var> be a <a>list of all advertised services</a> obtained from the <var>root device descriptor file</var> containing all sub-nodes of the <code>serviceList</code> node as described in
-               the section 'Device Description' [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
-            </li>
-
-            <li>
-               For each Object <var>advertised service</var> in <var>advertised services</var> run the following steps:
-               <ol class="rule">
-
-                  <li>
-                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>id</code> property to the string value of the first occurrence of <var>ssdp device</var>'s <var>USN</var> parameter.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>service</var>'s <code>serviceId</code> property.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>service</var>'s <code>serviceType</code> property.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>service</var>'s <code>controlURL</code> property.
-                  </li>
+          <li>
+            If the <a href="#dfn-http-response" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is not a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response then this response is invalid and the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> discard this response, abort any remaining steps and return. The user agent <em class="ct"><em class="rfc2119" title="may">may</em></em> issue a new <a href="#dfn-advertisement-for-upnp-root-devices" class="internalDFN">advertisement for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</a> as a result of this error occurring.
+          </li>
 
-                  <li>
-                     Set <var>network service record</var>'s <code>config</code> property to the string value of the first occurrence of the <var>device</var> property.
-                  </li>
-
-                  <li>
-                     If <var>service</var>'s <code>eventSubURL</code> property is empty, then continue to the step labeled <em>register</em> below.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>service</var>'s <code>eventSubURL</code> property.
-                  </li>
-
-                  <li>
-                     <em>Register</em>: For each Object <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, run the following sub-steps:
-                     <ol class="rule">
-
-                       <li>
-                        If the <var>existing service record</var>'s <var>id</var> property matches the value of the first occurrence of <var>USN</var> and the
-                        <var>existing service record</var>'s <code>type</code> property matches the value of <var>network service record</var>'s <code>type</code>, then set the
-                        value of <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>  to the value of the
-                        <var>network service record</var> and skip the next step.
-                       </li>
-                     </ol>
-                  </li>
-
-                  <li>
-                     Add <var>network service record</var> to the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>.
-                  </li>
+          <li>
+            If the <a href="#dfn-maximum-upnp-advertisement-response-wait-time" class="internalDFN">maximum <abbr title="Universal Plug-and-Play">UPnP</abbr> advertisement response wait time</a> has been exceeded since the initial <a href="#dfn-advertisement-for-upnp-root-devices" class="internalDFN">advertisement for <abbr title="Universal Plug-and-Play">UPnP</abbr> root devices</a> was sent then the <a href="#dfn-http-response" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> discard this response, abort any remaining steps and return.
+          </li>
 
-               </ol>
-            </li>
-            <li>
-               <em>Update Service Monitor</em>: For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
+          <li>
+             Let <var>ssdp device</var> be an Object with a property for each <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-response" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a>, with each key being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header and each value being that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> response header's value.
+          </li>
 
-               <ol class="rule">
-                  <li>
-                     If this <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
-                     current <a>network service record</a>'s <code>type</code> property then continue at the next available active
-                     <a href="#networkservice"><code>NetworkService</code></a> object.
-                  </li>
-                  <li>
-                     If the <var>announcement type</var> equals <code>ssdp:alive</code> then increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
-                     object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                      to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                      <a href="#networkservice"><code>NetworkServices</code></a> object. Otherwise, decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
-                     object by <code>1</code> and then  <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                       to dispatch a newly created event with the name <code>serviceunavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                       <a href="#networkservice"><code>NetworkServices</code></a> object.
-                  </li>
-                  <li>
-                     If the <var>announcement type</var> equals <code>ssdp:alive</code> then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                      to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                      <a href="#networkservice"><code>NetworkService</code></a> object. Otherwise, <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                       to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                       <a href="#networkservice"><code>NetworkService</code></a> object.
-                  </li>
-               </ol>
-            </li>
+          <li>
+            If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>ST</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>ST</var> entry is not <code>upnp:rootdevice</code>, then the <a href="#dfn-http-response" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> discard this response, abort any remaining steps and return.
+          </li>
+
+          <li>
+            The user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the rule for <a href="#dfn-processing-a-upnp-device-description-file" class="internalDFN">processing a <abbr title="Universal Plug-and-Play">UPnP</abbr> Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var> argument
+          </li>
+
+        </ol>
+
+        <p>
+          For each <dfn id="dfn-http-request"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</dfn> received on a <a href="#dfn-standard-upnp-address-and-port" class="internalDFN">standard <abbr title="Universal Plug-and-Play">UPnP</abbr> address and port</a> the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the following steps:
+         </p>
+
+        <ol class="rule">
+
+          <li>
+            If the <a href="#dfn-http-request" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> is not a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY request then it is not a valid <abbr title="Universal Plug-and-Play">UPnP</abbr> Request and the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> return a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> 200 OK response, discard this request, abort any remaining steps and return.
+          </li>
+
+          <li>
+             Let <var>ssdp device</var> be an Object with a property for each <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header received in the <a href="#dfn-http-request" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a>, with each key being the name of a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header and each value being that <abbr title="Hypertext Transfer Protocol">HTTP</abbr> header's value.
+          </li>
+
+          <li>
+            If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>NT</var> entry, at least one <var>NTS</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>NT</var> entry is not <code>upnp:rootdevice</code>, then the <a href="#dfn-http-request" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Request</a> is a malformed <abbr title="Universal Plug-and-Play">UPnP</abbr> Request and the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> return a 400 Bad Request response, discard this request, abort any remaining steps and return.
+          </li>
+
+          <li>
+            If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> or <code>ssdp:update</code> then the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the rule for <a href="#dfn-processing-a-upnp-device-description-file" class="internalDFN">processing a <abbr title="Universal Plug-and-Play">UPnP</abbr> Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var>. <br><br>Otherwise, if <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:byebye</code> then the user agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the rule for <a href="#dfn-removing-all-services-from-a-registered-upnp-device" class="internalDFN">removing all services from a registered <abbr title="Universal Plug-and-Play">UPnP</abbr> Device</a> passing in the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument.
+          </li>
+
+        </ol>
+
+      <p>
+        The rule for <dfn id="dfn-processing-a-upnp-device-description-file">processing a <abbr title="Universal Plug-and-Play">UPnP</abbr> Device Description File</dfn> is the process of parsing the contents of a standard <abbr title="Universal Plug-and-Play">UPnP</abbr> Device Description [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] and
+        registering the <abbr title="Universal Plug-and-Play">UPnP</abbr> services contained therein within the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>.
+      </p>
+
+      <p>The rule for <a href="#dfn-processing-a-upnp-device-description-file" class="internalDFN">processing a <abbr title="Universal Plug-and-Play">UPnP</abbr> Device Description File</a> takes three arguments - <var>device descriptor</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the user
+         agent <em class="ct"><em class="rfc2119" title="must">must</em></em> run the following steps:</p>
+
+      <ol class="rule">
+
+          <li>
+             Let <var>root device descriptor file</var> contain the contents of the file located at the <abbr title="Uniform Resource Locator">URL</abbr> provided in <var>device descriptor</var> obtained according to the rules
+             defined in 'Section 2.11: Retrieving a description using <abbr title="Hypertext Transfer Protocol">HTTP</abbr>' in [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]. If the value provided in <var>device descriptor</var> cannot be resolved as a <abbr title="Uniform Resource Locator">URL</abbr> on the current network or the <var>root device descriptor file</var> remains empty then the <a href="#dfn-http-response" class="internalDFN"><abbr title="Hypertext Transfer Protocol">HTTP</abbr> Response</a> is invalid and the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> discard this response, abort any remaining steps and return.
+          </li>
+
+          <li>
+             Let <var>advertised services</var> be a <a>list of all advertised services</a> obtained from the <var>root device descriptor file</var> containing the value of the first occurrence of the <code>&lt;serviceList&gt;</code> element as it is defined in 'Section 2.3: Device Description' in [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>].
+          </li>
+
+          <li>
+             For each <code>&lt;service&gt;</code> element - known as an <var>advertised service</var> - in <var>advertised services</var> run the following steps:
+
+             <ol class="rule">
+
+                <li>
+                   Let <var>network service record</var> be a new Object consisting of the following empty properties: <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>, <code>expiryTimestamp</code>.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>id</code> property to the concatenated string value of <var>device identifier</var> with the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>deviceId</code> property to the value of <var>device identifier</var>.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceType&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;controlURL&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>config</code> property to the string value of the contents of the first occurrence of the <code>&lt;device&gt;</code> element in the <var>root device descriptor file</var>.
+                </li>
+
+                <li>
+                   If <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element is not empty, then set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element. Otherwise, do not set <var>network service record</var>'s <code>eventsUrl</code> property.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus the value of <var>device expiry</var>.
+                </li>
+
+                <li>
+                  Run the general rule for <a href="#dfn-adding-an-available-service" class="internalDFN">adding an available service</a>, passing in the current <var>network service record</var> as the only argument.
+                </li>
+
+              </ol>
+
+          </li></ol>
+
+         <p>
+           The rule for <dfn id="dfn-removing-all-services-from-a-registered-upnp-device">removing all services from a registered <abbr title="Universal Plug-and-Play">UPnP</abbr> Device</dfn> is the process of removing all services associated with a
+           device from the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a> that has left the user's current network or has otherwise timed out or expired.
+           This rule takes one argument, <var>device identifier</var>, and consists of running the following steps:
+        </p>
+
+         <ol class="rule">
+
+           <li>
+              For each <var>existing service record</var> in the current <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, run the following sub-steps:
+              <ol class="rule">
+
+                <li>
+                 If the <var>existing service record</var>'s <code>deviceId</code> property does not match <var>device identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
+                </li>
+
+                <li>
+                  Run the general rule for <a href="#dfn-removing-an-available-service" class="internalDFN">removing an available service</a> passing in <var>existing service record</var>'s <code>id</code>
+                  property as the only argument.
+                </li>
+
+              </ol>
+           </li>
+
          </ol>
 
-         <p>
-            A <dfn id="dfn-user-agent-generated-callback-url">user-agent generated callback url</dfn> is a Local-network accessible <abbr title="Uniform Resource Locator">URL</abbr> endpoint that a <a href="#dfn-user-agent" class="internalDFN">user agent</a> must generate and maintain for receiving <abbr title="Hypertext Transfer Protocol">HTTP</abbr> NOTIFY requests from <abbr title="Universal Plug-and-Play">UPnP</abbr> Event sources.
-         </p>
-
-         <p>When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> is to <dfn id="dfn-setup-a-upnp-events-subscription">setup a <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object:</p>
+         <p>When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> is to <dfn id="dfn-setup-a-upnp-events-subscription">setup a <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object as defined in 'Section 4.1.2: SUBSCRIBE with NT and CALLBACK' in [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>]:</p>
 
          <ol class="rule">
             <li>
@@ -1391,8 +1549,7 @@
             </li>
 
             <li>
-               Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with an integer value ofÆ’
-               <code>86400</code> and a <em>CALLBACK</em> header
+               Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with a user-agent defined timeout value (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) and a <em>CALLBACK</em> header
                with a string value of <var>callback <abbr title="Uniform Resource Locator">URL</abbr></var> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
             </li>
 
@@ -1408,7 +1565,7 @@
                      Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it exists.
                   </li>
                   <li>
-                     Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header, if it exists.
+                     Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header (minus the leading string of <code>Second-</code>), if it exists.
                   </li>
                   <li>
                      Run the following steps aynchronously and continue to the step labeled <em>listen</em> below.
@@ -1424,8 +1581,7 @@
                            If <var>current date</var> is less than the <var>timeout date</var> then continue to the step labeled <em>refresh subscription</em> above.
                         </li>
                         <li>
-                           Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a <em>TIMEOUT</em> header
-                           with an integer value of <code>86400</code> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
+                           Send a <abbr title="Hypertext Transfer Protocol">HTTP</abbr> SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a user-agent defined <em>TIMEOUT</em> header (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) towards the <var>network service record</var>'s <code>eventsUrl</code> property.
                         </li>
                         <li>
                            On receiving a valid 200 OK, update <var>callback ID</var> with the string value of the first included <em>SID</em> header, if it exists. All other <abbr title="Hypertext Transfer Protocol">HTTP</abbr>
@@ -1461,6 +1617,10 @@
             </li>
          </ol>
 
+         <p>
+           A <a href="#dfn-user-agent" class="internalDFN">user agent</a> can <dfn id="dfn-terminate-an-existing-upnp-events-subscription">terminate an existing <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</dfn> at any time for any <var>active service</var> in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> by sending an <abbr title="Hypertext Transfer Protocol">HTTP</abbr> UNSUBSCRIBE request - as defined in 'Section 4.1.4: Canceling a subscription with UNSUBSCRIBE' in [<cite><a class="bibref" href="#bib-UPNP-DEVICEARCH11">UPNP-DEVICEARCH11</a></cite>] - with a HOST header set to that <var>active service</var>'s <code>eventsUrl</code> property and a SID header set to the <var>callback ID</var> obtained when the initial <a href="#dfn-setup-a-upnp-events-subscription" class="internalDFN">setup a <abbr title="Universal Plug-and-Play">UPnP</abbr> Events Subscription</a> action occurred.
+         </p>
+
          </section>
 
          <section id="network-topology-monitoring">
@@ -1468,53 +1628,18 @@
 
                   <div>
                      <p>
-                        When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> detects that the user has dropped from their connected network, then it <em class="rfc2119" title="must">must</em> run the following steps:
-                     </p>
-
-                     <ol class="rule">
-                        <li>
-                           Flush all entries from the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>.
-                        </li>
-                        <li>
-                           For each <a href="#networkservice"><code>NetworkService</code></a> object currently active in the <a href="#dfn-user-agent" class="internalDFN">user agent</a> perform the following steps:
-
-                           <ol class="rule">
-                              <li>
-                                 Set the <a href="#dom-networkservice-online"><code>online</code></a> attribute to <code>false</code>.
-                              </li>
-                              <li>
-                                 <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                                                      to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                                                      <a href="#networkservice"><code>NetworkService</code></a> object.
-                           </li></ol>
-                        </li>
-                        <li>
-                          For each <a href="#networkservices"><code>NetworkServices</code></a> object currently active in the <a href="#dfn-user-agent" class="internalDFN">user agent</a> perform the following steps:
-
-                          <ol class="rule">
-                            <li>
-                              Let <var>number of available services</var> equal the value of <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute.
-                            </li>
-                            <li>
-                              Set the <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to zero (<code>0</code>).
-                            </li>
-                            <li>
-                              For each <var>available service</var> in <var>number of available services</var> the <a href="#dfn-user-agent" class="internalDFN">user agent</a> <em class="rfc2119" title="must">must</em> fire a new simple event with the name <code>serviceunavailable</code> that has no default action, does not bubble and is not cancellable, at the current <a href="#networkservices"><code>NetworkServices</code></a> object.
-                            </li>
-                          </ol>
-                        </li>
-
-                     </ol>
+                        When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> detects that the user has dropped from their connected network then, for each <var>existing service record</var> in the <a href="#dfn-list-of-available-service-records" class="internalDFN">list of available service records</a>, the user agent
+                        <em class="ct"><em class="rfc2119" title="must">must</em></em>
+                            run the general rule for <a href="#dfn-removing-an-available-service" class="internalDFN">removing an available service</a> passing in each <var>existing service record</var>'s
+                            <code>id</code> property as the only argument for each call.
+                    </p>
 
                      <p>
-                        When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> detects that the user has connected to a new network, then it <em class="rfc2119" title="should">should</em> run the following steps:
+                        When the <a href="#dfn-user-agent" class="internalDFN">user agent</a> detects that the user has connected to a new network or reconnected to an existing network, then it
+                        <em class="ct"><em class="rfc2119" title="should">should</em></em> restart its discovery
+                         mechanisms as defined in the <a href="#service-discovery">Service Discovery</a> section of this specification, maintaining
+                         the existing <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> currently in use.
                      </p>
-
-                     <ol class="rule">
-                        <li>
-                           Re-issue an <abbr title="Multicast DNS">mDNS</abbr> search and <acronym title="Simple Service Discovery Protocol">SSDP</acronym> discovery search using all of the <a href="#dfn-valid-service-type" class="internalDFN">valid service type</a> tokens initially provided to all active <a href="#networkservices"><code>NetworkServices</code></a> objects and handle all discovery responses according to the processing defined in <a href="#service-discovery">Section 7: Service Discovery</a>.
-                        </li>
-                     </ol>
                   </div>
          </section>
       </section>
@@ -1523,11 +1648,7 @@
       <!--OddPage--><h2><span class="secno">8. </span>Garbage collection</h2>
 
       <p>
-         A <a href="#networkservice" class="internalDFN"><code>NetworkService</code></a> object containing a <code>url</code> parameter currently in the <a href="#dfn-entry-script-origin-s-url-whitelist" class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a> <em class="rfc2119" title="must not">must not</em> be garbage collected.
-      </p>
-
-      <p>
-         Only when the user navigates away from the current browsing context can <a href="#networkservice" class="internalDFN"><code>NetworkService</code></a> objects be garbage-collected and records in the <a href="#dfn-entry-script-origin-s-url-whitelist" class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a> be removed.
+         Only when the user navigates away from the current browsing context can <a href="#networkservice" class="internalDFN"><code>NetworkService</code></a> objects be garbage-collected, its records in the <a href="#dfn-entry-script-origin-s-url-whitelist" class="internalDFN">entry script origin's <abbr title="Uniform Resource Locator">URL</abbr> whitelist</a> be removed and its corresponding entry in the <a href="#dfn-list-of-authorized-service-records" class="internalDFN">list of authorized service records</a> be removed.
       </p>
 
    </section>
@@ -1806,4 +1927,4 @@
 </dd><dt id="bib-RFC2119">[RFC2119]</dt><dd>S. Bradner. <a href="http://www.ietf.org/rfc/rfc2119.txt"><cite>Key words for use in RFCs to Indicate Requirement Levels.</cite></a> March 1997. Internet RFC 2119.  URL: <a href="http://www.ietf.org/rfc/rfc2119.txt">http://www.ietf.org/rfc/rfc2119.txt</a>
 </dd><dt id="bib-UPNP-DEVICEARCH11">[UPNP-DEVICEARCH11]</dt><dd><a href="http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf"><cite>UPnP Device Architecture 1.1</cite></a>. 15 October 2008. UPnP Forum. PDF document. URL: <a href="http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf">http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf</a>
 </dd><dt id="bib-WEBIDL">[WEBIDL]</dt><dd>Cameron McCormack. <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/"><cite>Web IDL.</cite></a> 27 September 2011. W3C Working Draft. (Work in progress.) URL: <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/">http://www.w3.org/TR/2011/WD-WebIDL-20110927/</a>
-</dd></dl></section><section id="informative-references"><h3><span class="secno">C.2 </span>Informative references</h3><p>No informative references.</p></section></section></body></html>
\ No newline at end of file
+</dd></dl></section></section></body></html>
\ No newline at end of file
--- a/discovery-api/Overview.src.html	Tue Sep 25 11:20:35 2012 +0200
+++ b/discovery-api/Overview.src.html	Tue Sep 25 12:48:42 2012 +0200
@@ -8,7 +8,7 @@
           specStatus:   "ED",
           //publishDate:  "2012-08-22",
           shortName:    "discovery-api",
-          edDraftURI:   "http://w3c-test.org/dap/discovery-api/",
+          edDraftURI:   "http://dvcs.w3.org/hg/dap/raw-file/tip/discovery-api/Overview.html",
           previousMaturity: "WD",
           previousPublishDate: "2012-08-07",
           editors: [
@@ -218,10 +218,17 @@
       <p>
         A <dfn>valid service type</dfn> is a string that begins with <code>upnp:</code> or <code>zeroconf:</code> followed by one or more characters in the ranges U+0021, U+0023 to U+0027, U+002A to U+002B, U+002D to U+002E, U+0030 to U+0039, U+0041 to U+005A, U+005E to U+007E.
       </p>
+      <p></p>
 
       <p>
-        A <a>valid service type</a> provided in the <code>type</code> attribute of the <code>getNetworkServices()</code> method will be matched against the services currently contained in the <a>list of available service records</a> according to the algorithms defined in this specification.
+        A <a>valid service type</a> provided in the <code>type</code> attribute of the <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> method will be matched against the services currently contained in the <a>list of available service records</a> according to the algorithms defined in this specification.
       </p>
+
+      <p>
+        A <dfn>user-agent generated callback url</dfn> is a Local-network accessible URL endpoint that a <a>user agent</a> must generate and maintain for receiving HTTP NOTIFY requests from UPnP Event sources. It is only required when the user agent implements UPnP Service Discovery as defined in
+        this specification.
+      </p>
+
     </section>
 
     <section>
@@ -423,7 +430,7 @@
             </li>
 
             <li>
-              Store the set of <var>services</var> as <dfn id="current_authorized_services">current authorized services</dfn> internally against the newly created <var>services manager</var> object.
+              Add the set of <var>services</var> to the <a>list of authorized service records</a> internally against the newly created <var>services manager</var> object.
             </li>
 
             <li>
@@ -542,7 +549,7 @@
           </dt>
           <dd>
             <p>
-              Returns the current number of services in the respective object's <a>current authorized services</a>.
+              Returns the current number of services belonging in the respective object's <a>list of authorized service records</a>.
             </p>
           </dd>
           <dt>
@@ -559,7 +566,7 @@
 
         <div>
            <p>
-              The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute MUST return the number of services represented in the object's corresponding <a>current authorized services</a> list at the time of getting.
+              The <dfn id="dom-networkservices-length"><code>length</code></dfn> attribute MUST return the number of services represented in the object's corresponding <a>list of authorized service records</a> at the time of getting.
            </p>
 
            <p>
@@ -623,24 +630,24 @@
       </dl>
 
       <p>
-        A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of zero or more <a>current authorized services</a>, of which zero or more can be available at a time. Each item in <a>current authorized services</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object. The list of <a>current authorized services</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
+        A <a href="#networkservices"><code>NetworkServices</code></a> object represents the current list of one or more current authorized services - the <a>list of authorized service records</a>. Each item in the <a>list of authorized service records</a> is represented by a <a href="#networkservice"><code>NetworkService</code></a> object. The <a>list of authorized service records</a> is <span>immutable</span> meaning that it cannot be modified for the lifetime of a <a href="#networkservices"><code>NetworkServices</code></a> object.
       </p>
 
       <p class="note">
-        Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one. If the <a>user agent</a> dynamically adds or removes network services for any reason, then the indices of the services in <a>current authorized services</a> will change dynamically. If the set of network services changes entirely, then all the previous services will be removed from <a>current authorized services</a> and replaced with new services.
+        Each service in a <a href="#networkservices"><code>NetworkServices</code></a> object thus has an index; the first has the index 0, and each subsequent service is numbered one higher than the previous one.
       </p>
 
       <p>
-        The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in <a>current authorized services</a> represented by the respective object minus one, if any services are represented in <a>current authorized services</a>. If a <a href="#networkservices"><code>NetworkServices</code></a> object represents no <a>current authorized services</a>, it has no <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a>.
+        The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#supported-property-indices" class="externalDFN">supported property indices</a> of <a href="#networkservices"><code>NetworkServices</code></a> objects at any instant are the numbers from zero to the number of items in the <a>list of authorized service records</a> represented by the respective object minus one, if any services are represented in the <a>list of authorized service records</a>.
       </p>
 
       <p>
-        To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a>current authorized services</a>, the user agent MUST return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in <a>current authorized services</a>.
+        To <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#determine-the-value-of-an-indexed-property" class="externalDFN">determine the value of an indexed property</a> for a given index <var>index</var> in a <a href="#networkservices"><code>NetworkServices</code></a> object's <a>list of authorized service records</a>, the user agent MUST return the <a href="#networkservice"><code>NetworkService</code></a> object that represents the <var>index</var>th service in the <a>list of authorized service records</a>.
       </p>
 
       <p>
-        The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method MUST return the first <a href="#networkservice"><code>NetworkService</code></a> object in <a>current authorized services</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
-        When no services in <a>current authorized services</a> match the given argument, the method MUST return null.
+        The <dfn id="dom-networkservices-getservicebyid"><code>getServiceById(id)</code></dfn> method MUST return the first <a href="#networkservice"><code>NetworkService</code></a> object in the <a>list of authorized service records</a> represented by the respective object whose <a href="#dom-networkservice-id"><code>id</code></a> attribute is equal to the value of the <var>id</var> argument.
+        When no services in the <a>list of authorized service records</a> match the given argument, the method MUST return null.
       </p>
 
       <p>
@@ -911,7 +918,7 @@
       </p>
       <p>
          This section presents how the results of these two service discovery
-         mechanisms will be matched to requested service types and how their properties will be applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
+         mechanisms will be matched to requested service types, how the user agent stores available and active services, how their properties are applied to any resulting <a href="#networkservice"><code>NetworkService</code></a> objects.
       </p>
 
       <p>
@@ -921,12 +928,155 @@
       </p>
 
       <p>
-         The <dfn>list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the current services available in the network at any given time.
+         The <dfn>list of available service records</dfn> is a single dynamic internal lookup table within user agents that is used to track all the  services that have been discovered and are available in the current network at any given time.
          At any point during the running of either of the two service discovery mechanisms then existing entries within this table can be updated, entries can be added and entries can be removed as the status of networked
-         services changes. Each record contained within this table contains the attributes: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code> and <code>config</code>.
+         services changes according to the rules defined in this specification. <!--Each record contained within this table contains the attributes: <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code> and <code>expiryTimestamp</code>.-->
       </p>
 
-            <section>
+      <p>
+        The <dfn>list of authorized service records</dfn> is a single dynamic internal lookup table within user agents that is used to track the
+        current services that are being shared with web pages at any given time from the <a>list of available service records</a>. Each record in the <a>list of authorized service records</a> is associated with a <var>services manager</var> object that is assigned as part of the
+         <a href="#dom-navigator-getnetworkservices"><code>getNetworkServices()</code></a> algorithm.
+      </p>
+
+      <p>
+        The rule for <dfn>adding an available service</dfn> is the process of adding a new service or updating an existing service in the <a>list of available service records</a> that is generally available on the user's current network. This rule takes one argument, <var>network service record</var>, and consists of
+        running the following steps:
+      </p>
+
+      <ol class="rule">
+
+        <li>
+          Let <var>new service registration flag</var> be <code>true</code>.
+        </li>
+
+        <li>
+           For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
+           <ol class="rule">
+
+             <li>
+              If the <var>existing service record</var>'s <code>id</code> property does not equal <var>network service record</var>'s <code>id</code>
+               property then abort any remaining sub-steps and continue at the next available <var>existing service record</var>.
+             </li>
+
+             <li>
+              Set <var>new service registration flag</var> to <code>false</code>.
+             </li>
+
+             <li>
+               Replace the value of <var>existing service record</var> in the current <a>list of available service records</a> with the value of
+              <var>network service record</var>.
+             </li>
+           </ol>
+        </li>
+
+        <li>
+           If <var>new service registration flag</var> is set to <code>true</code> then add <var>network service record</var> to the <a>list of available service records</a> as a new entry.
+        </li>
+
+        <li>
+          For each <var>active service</var> in the <a>list of authorized service records</a> run the following steps:
+
+          <ol class="rule">
+
+            <li>
+               If <var>network service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
+                <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
+            </li>
+
+            <li>
+               If the <var>new service registration flag</var> is set to <code>true</code> then increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <var>services manager</var> associated with
+               the current <var>active service</var>
+                object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
+                 to dispatch a newly created event with the name <a href="#dom-networkservices-onserviceavailable"><code>serviceavailable</code></a> that uses the <code>Event</code> interface,
+                 which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
+                 the current <var>active service</var> object.
+            </li>
+
+            <li>
+               <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
+                to dispatch a newly created event with the name <a href="#dom-networkservice-onserviceonline"><code>serviceonline</code></a> that uses the <code>Event</code> interface, which
+                 does not bubble, is not cancellable, and has no default action, at the current
+                <var>active service</var> object.
+            </li>
+
+          </ol>
+
+        </li>
+
+      </ol>
+
+
+      <p>
+        The rule for <dfn>removing an available service</dfn> is the general process of removing a service from the
+        <a>list of available service records</a>
+         that has left the user's current network or has otherwise expired. This rule takes one argument, <var>service identifier</var>, and consists of running the following steps:</p>
+
+      <ol class="rule">
+
+        <li>
+           For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
+           <ol class="rule">
+
+             <li>
+              If the <var>existing service record</var>'s <code>id</code> property does not match <var>service identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
+             </li>
+
+             <li>
+               If the <var>existing service record</var>'s <code>type</code> property begins with the DOMString "<code>upnp:</code>" and
+               <var>existing service record</var>'s <code>eventsURL</code> property is set then run the rule to
+               <a>terminate an existing UPnP Events Subscription</a>, if one is currently active (as a result of having previously called
+               <a>setup a UPnP Events Subscription</a> against the current <var>existing service record</var>).
+             </li>
+
+             <li>
+               For each <var>active service</var> in <a>list of authorized service records</a> run the following steps:
+
+               <ol class="rule">
+
+                 <li>
+                    If <var>existing service record</var>'s <code>type</code> property does not equal the current <var>active service</var>'s
+                     <code>type</code> attribute then abort any remaining sub-steps for this <var>active service</var> and continue at the next available <var>active service</var>.
+                 </li>
+
+                 <li>
+                    Decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the
+                    <var>services manager</var> associated with the current <var>active service</var>
+                     object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
+                      to dispatch a newly created event with the name <a href="#dom-networkservices-onserviceunavailable"><code>serviceunavailable</code></a> that uses the <code>Event</code> interface,
+                      which does not bubble, is not cancellable, and has no default action, at the <var>services manager</var> associated with
+                      the current <var>active service</var> object.
+                 </li>
+
+                 <li>
+                    <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
+                     to dispatch a newly created event with the name <a href="#dom-networkservice-onserviceoffline"><code>serviceoffline</code></a> that uses the <code>Event</code> interface, which
+                      does not bubble, is not cancellable, and has no default action, at the current
+                     <var>active service</var> object.
+                 </li>
+
+               </ol>
+
+             </li>
+
+             <li>
+               Remove <var>existing service record</var> from the current <a>list of available service records</a>.
+             </li>
+
+           </ol>
+        </li>
+
+      </ol>
+
+      <p>
+       User agents <em class="ct">SHOULD</em> expire a service record from the <a>list of available service records</a> when its
+       <code>expiryTimestamp</code> attribute exceeds the current UTC timestamp. When this condition is met the <a>user agent</a> SHOULD
+       run the rule for <a>removing an available service</a>, passing in the expired service record's <code>id</code> attribute as the
+       only argument.
+      </p>
+
+
+      <section>
          <h4>Zeroconf (<abbr title="Multicast DNS">mDNS</abbr> + <abbr title="Domain Name System">DNS</abbr>-<abbr title="Service Discovery">SD</abbr>)</h4>
 
          <p>
@@ -942,7 +1092,7 @@
                <ol>
 
                   <li>
-                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>.
+                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>config</code>, <code>expiryTimestamp</code>.
                   </li>
 
                   <li>
@@ -966,45 +1116,14 @@
                   </li>
 
                   <li>
-                     For each Object <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
-                     <ol class="rule">
-
-                       <li>
-                        If the <var>existing service record</var>'s <code>id</code> property matches the value of the <var>network service record</var>'s <code>id</code>, then set the
-                        value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
-                        <var>network service record</var> and skip the next step.
-                       </li>
-                     </ol>
-                  </li>
-
-                  <li>
-                     Add <var>network service record</var> to the <a>list of available service records</a>.
+                     Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus a value of <code>120</code> seconds.
                   </li>
 
                   <li>
-                     For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
+                     Run the general rule for <a>adding an available service</a>, passing in the current <var>network service record</var> as the
+                     only argument.
+                  </li>
 
-                     <ol class="rule">
-                        <li>
-                           If the <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
-                           current <a>network service record</a>'s <code>type</code> property then continue at the next available active
-                           <a href="#networkservice"><code>NetworkService</code></a> object.
-                        </li>
-                        <li>
-                           Increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a> object by <code>1</code>.
-                        </li>
-                        <li>
-                          <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                           to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                            <a href="#networkservices"><code>NetworkServices</code></a> object.
-                        </li>
-                        <li>
-                          <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                           to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                           <a href="#networkservice"><code>NetworkService</code></a> object.
-                        </li>
-                     </ol>
-                  </li>
             </ol>
            </li>
          </ol>
@@ -1015,126 +1134,165 @@
          <h5>Universal Plug-and-Play (<abbr title="Universal Plug-and-Play">UPnP</abbr>)</h5>
 
          <p>
-            For each SSDP Presence Announcement [[!UPNP-DEVICEARCH11]] - a HTTP NOTIFY request - received from a user-agent-initiated SSDP Discovery Request [[!UPNP-DEVICEARCH11]], the <a>user agent</a> MUST run the following steps:
+          A user agent that implements UPnP service discovery must issue an <dfn>advertisement for UPnP root devices</dfn> against the user's
+          current local network according to the full normative text and timing provided in 'Section 1.3.2: Search request with M-SEARCH' detailed in [[!UPNP-DEVICEARCH11]].
+          </p>
+
+          <p>
+            The user agent <em class="ct">MUST</em> issue all <a title="advertisement for UPnP root devices">advertisements for UPnP root devices</a> with a HTTP request line equal to <code>M-SEARCH * HTTP/1.1</code>, with a HOST header equal to the reserved multicast address and port of <code>239.255.255.250:1900</code>, a MAN header equal to <code>ssdp:discover</code>, an ST header equal to <code>upnp:rootdevice</code> and a user-agent defined MX header equal to a <dfn>maximum UPnP advertisement response wait time</dfn> value between <code>1</code> and <code>5</code> seconds.
+         </p>
+
+         <p>
+          The user agent <em class="ct">MUST</em> listen for incoming requests and process any incoming responses to any <a>advertisement for UPnP root devices</a> on the <dfn>standard UPnP address and port</dfn>, on all current local network interface addresses with the port <code>1900</code>, according to the rules defined in this section.
+         </p>
+
+         <p>
+          For each <dfn>HTTP Response</dfn> following an initial <a>advertisement for UPnP root devices</a> sent on a <a>standard UPnP address
+            and port</a> the user agent <em class="ct">MUST</em> run the following steps:
          </p>
 
          <ol class="rule">
-            <li>
-               Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the received SSDP Presence Announcement, with each key being the name of a HTTP header and its
-               value being that HTTP header's accompanying value.
-            </li>
-
-            <li>
-               If <var>ssdp device</var> does not contain at least one <var>NTS</var>, <var>USN</var> and <var>Location</var> parameter, then the <a>user agent</a> MUST abort these steps.
-            </li>
-
-            <li>
-               If the first occurrence of <var>NTS</var> has a value other than <code>ssdp:alive</code>, then continue to the step labeled <var>update service monitor</var> below.
-            </li>
-
-            <li>
-               Let <var>root device descriptor file</var> contain the contents of the file located at the URL provided in the first occurrence of <var>Location</var> obtained according to the rules
-               defined in the section 'Retrieving a description using HTTP' [[!UPNP-DEVICEARCH11]].
-            </li>
-
-            <li>
-               If <var>root device descriptor file</var> is empty, then the <a>user agent</a> MUST abort these steps.
-            </li>
-
-            <li>
-               Let <var>advertised services</var> be a <a>list of all advertised services</a> obtained from the <var>root device descriptor file</var> containing all sub-nodes of the <code>serviceList</code> node as described in
-               the section 'Device Description' [[!UPNP-DEVICEARCH11]].
-            </li>
-
-            <li>
-               For each Object <var>advertised service</var> in <var>advertised services</var> run the following steps:
-               <ol class="rule">
-
-                  <li>
-                     Let <var>network service record</var> be an Object consisting of the following empty properties: <code>id</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>id</code> property to the string value of the first occurrence of <var>ssdp device</var>'s <var>USN</var> parameter.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>service</var>'s <code>serviceId</code> property.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>service</var>'s <code>serviceType</code> property.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>service</var>'s <code>controlURL</code> property.
-                  </li>
+          <li>
+            If the <a>HTTP Response</a> is not a HTTP 200 OK response then this response is invalid and the user agent <em class="ct">MUST</em> discard this response, abort any remaining steps and return. The user agent <em class="ct">MAY</em> issue a new <a>advertisement for UPnP root devices</a> as a result of this error occurring.
+          </li>
 
-                  <li>
-                     Set <var>network service record</var>'s <code>config</code> property to the string value of the first occurrence of the <var>device</var> property.
-                  </li>
-
-                  <li>
-                     If <var>service</var>'s <code>eventSubURL</code> property is empty, then continue to the step labeled <em>register</em> below.
-                  </li>
-
-                  <li>
-                     Set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>service</var>'s <code>eventSubURL</code> property.
-                  </li>
-
-                  <li>
-                     <em>Register</em>: For each Object <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
-                     <ol class="rule">
-
-                       <li>
-                        If the <var>existing service record</var>'s <var>id</var> property matches the value of the first occurrence of <var>USN</var> and the
-                        <var>existing service record</var>'s <code>type</code> property matches the value of <var>network service record</var>'s <code>type</code>, then set the
-                        value of <var>existing service record</var> in the current <a>list of available service records</a>  to the value of the
-                        <var>network service record</var> and skip the next step.
-                       </li>
-                     </ol>
-                  </li>
-
-                  <li>
-                     Add <var>network service record</var> to the <a>list of available service records</a>.
-                  </li>
+          <li>
+            If the <a>maximum UPnP advertisement response wait time</a> has been exceeded since the initial <a>advertisement for UPnP root devices</a> was sent then the <a>HTTP Response</a> is invalid and the user agent <em class="ct">MUST</em> discard this response, abort any remaining steps and return.
+          </li>
 
-               </ol>
-            </li>
-            <li>
-               <em>Update Service Monitor</em>: For each non-garbage collected <a href="#networkservice"><code>NetworkService</code></a> object run the following steps:
+          <li>
+             Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP Response</a>, with each key being the name of a HTTP response header and each value being that HTTP response header's value.
+          </li>
 
-               <ol class="rule">
-                  <li>
-                     If this <a href="#networkservice"><code>NetworkService</code></a> object's <code>type</code> attribute does not equal the
-                     current <a>network service record</a>'s <code>type</code> property then continue at the next available active
-                     <a href="#networkservice"><code>NetworkService</code></a> object.
-                  </li>
-                  <li>
-                     If the <var>announcement type</var> equals <code>ssdp:alive</code> then increment the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
-                     object by <code>1</code> and then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                      to dispatch a newly created event with the name <code>serviceavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                      <a href="#networkservice"><code>NetworkServices</code></a> object. Otherwise, decrement the <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute of the <a href="#networkservices"><code>NetworkServices</code></a>
-                     object by <code>1</code> and then  <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                       to dispatch a newly created event with the name <code>serviceunavailable</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                       <a href="#networkservice"><code>NetworkServices</code></a> object.
-                  </li>
-                  <li>
-                     If the <var>announcement type</var> equals <code>ssdp:alive</code> then <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                      to dispatch a newly created event with the name <code>serviceonline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                      <a href="#networkservice"><code>NetworkService</code></a> object. Otherwise, <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">queue a task</a>
-                       to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                       <a href="#networkservice"><code>NetworkService</code></a> object.
-                  </li>
-               </ol>
-            </li>
+          <li>
+            If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>ST</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>ST</var> entry is not <code>upnp:rootdevice</code>, then the <a>HTTP Response</a> is invalid and the <a>user agent</a> MUST discard this response, abort any remaining steps and return.
+          </li>
+
+          <li>
+            The user agent <em class="ct">MUST</em> run the rule for <a>processing a UPnP Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var> argument
+          </li>
+
+        </ol>
+
+        <p>
+          For each <dfn>HTTP Request</dfn> received on a <a>standard UPnP address and port</a> the user agent <em class="ct">MUST</em> run the following steps:
+         </p>
+
+        <ol class="rule">
+
+          <li>
+            If the <a>HTTP Request</a> is not a HTTP NOTIFY request then it is not a valid UPnP Request and the user agent <em class="ct">MUST</em> return a HTTP 200 OK response, discard this request, abort any remaining steps and return.
+          </li>
+
+          <li>
+             Let <var>ssdp device</var> be an Object with a property for each HTTP header received in the <a>HTTP Request</a>, with each key being the name of a HTTP header and each value being that HTTP header's value.
+          </li>
+
+          <li>
+            If <var>ssdp device</var> does not contain at least one <var>CACHE-CONTROL</var> entry, at least one <var>USN</var> entry, at least one <var>NT</var> entry, at least one <var>NTS</var> entry and at least one <var>LOCATION</var> entry or the value of its <var>NT</var> entry is not <code>upnp:rootdevice</code>, then the <a>HTTP Request</a> is a malformed UPnP Request and the <a>user agent</a> MUST return a 400 Bad Request response, discard this request, abort any remaining steps and return.
+          </li>
+
+          <li>
+            If <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:alive</code> or <code>ssdp:update</code> then the user agent <em class="ct">MUST</em> run the rule for <a>processing a UPnP Device Description File</a> passing in the first occurrence of <var>LOCATION</var> from <var>ssdp device</var> as the <var>device descriptor</var> argument and the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument and the first occurrence of <var>CACHE-CONTROL</var> from <var>ssdp device</var> as the <var>device expiry</var>. <br/><br/>Otherwise, if <var>ssdp device</var>'s <var>NTS</var> entry is equal to <code>ssdp:byebye</code> then the user agent <em class="ct">MUST</em> run the rule for <a>removing all services from a registered UPnP Device</a> passing in the first occurrence of <var>USN</var> from <var>ssdp device</var> as the <var>device identifier</var> argument.
+          </li>
+
+        </ol>
+
+      <p>
+        The rule for <dfn>processing a UPnP Device Description File</dfn> is the process of parsing the contents of a standard UPnP Device Description [[!UPNP-DEVICEARCH11]] and
+        registering the UPnP services contained therein within the <a>list of available service records</a>.
+      </p>
+
+      <p>The rule for <a>processing a UPnP Device Description File</a> takes three arguments - <var>device descriptor</var>, <var>device identifier</var> and <var>device expiry</var> - and when called the user
+         agent <em class="ct">MUST</em> run the following steps:</p>
+
+      <ol class="rule">
+
+          <li>
+             Let <var>root device descriptor file</var> contain the contents of the file located at the URL provided in <var>device descriptor</var> obtained according to the rules
+             defined in 'Section 2.11: Retrieving a description using HTTP' in [[!UPNP-DEVICEARCH11]]. If the value provided in <var>device descriptor</var> cannot be resolved as a URL on the current network or the <var>root device descriptor file</var> remains empty then the <a>HTTP Response</a> is invalid and the <a>user agent</a> MUST discard this response, abort any remaining steps and return.
+          </li>
+
+          <li>
+             Let <var>advertised services</var> be a <a>list of all advertised services</a> obtained from the <var>root device descriptor file</var> containing the value of the first occurrence of the <code>&lt;serviceList&gt;</code> element as it is defined in 'Section 2.3: Device Description' in [[!UPNP-DEVICEARCH11]].
+          </li>
+
+          <li>
+             For each <code>&lt;service&gt;</code> element - known as an <var>advertised service</var> - in <var>advertised services</var> run the following steps:
+
+             <ol class="rule">
+
+                <li>
+                   Let <var>network service record</var> be a new Object consisting of the following empty properties: <code>id</code>, <code>deviceId</code>, <code>name</code>, <code>type</code>, <code>url</code>, <code>eventsUrl</code>, <code>config</code>, <code>expiryTimestamp</code>.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>id</code> property to the concatenated string value of <var>device identifier</var> with the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>deviceId</code> property to the value of <var>device identifier</var>.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>name</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceId&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>type</code> property to the concatenation of the string <code>upnp:</code> followed by the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;serviceType&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>url</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;controlURL&gt;</code> sub-element.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>config</code> property to the string value of the contents of the first occurrence of the <code>&lt;device&gt;</code> element in the <var>root device descriptor file</var>.
+                </li>
+
+                <li>
+                   If <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element is not empty, then set <var>network service record</var>'s <code>eventsUrl</code> property to the string value of the first occurrence of the <var>advertised service</var>'s <code>&lt;eventSubURL&gt;</code> sub-element. Otherwise, do not set <var>network service record</var>'s <code>eventsUrl</code> property.
+                </li>
+
+                <li>
+                   Set <var>network service record</var>'s <code>expiryTimestamp</code> property to the value of the current date, in UTC timestamp format, plus the value of <var>device expiry</var>.
+                </li>
+
+                <li>
+                  Run the general rule for <a>adding an available service</a>, passing in the current <var>network service record</var> as the only argument.
+                </li>
+
+              </ol>
+
+          </ol>
+
+         <p>
+           The rule for <dfn>removing all services from a registered UPnP Device</dfn> is the process of removing all services associated with a
+           device from the <a>list of available service records</a> that has left the user's current network or has otherwise timed out or expired.
+           This rule takes one argument, <var>device identifier</var>, and consists of running the following steps:
+        </p>
+
+         <ol class="rule">
+
+           <li>
+              For each <var>existing service record</var> in the current <a>list of available service records</a>, run the following sub-steps:
+              <ol class="rule">
+
+                <li>
+                 If the <var>existing service record</var>'s <code>deviceId</code> property does not match <var>device identifier</var> then skip any remaining sub-steps for the current <var>existing service record</var> and continue at the next available <var>existing service record</var>.
+                </li>
+
+                <li>
+                  Run the general rule for <a>removing an available service</a> passing in <var>existing service record</var>'s <code>id</code>
+                  property as the only argument.
+                </li>
+
+              </ol>
+           </li>
+
          </ol>
 
-         <p>
-            A <dfn>user-agent generated callback url</dfn> is a Local-network accessible URL endpoint that a <a>user agent</a> must generate and maintain for receiving HTTP NOTIFY requests from UPnP Event sources.
-         </p>
-
-         <p>When the <a>user agent</a> is to <dfn>setup a UPnP Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object:</p>
+         <p>When the <a>user agent</a> is to <dfn>setup a UPnP Events Subscription</dfn>, it is to run the following steps with the current <var>network service record</var> object as defined in 'Section 4.1.2: SUBSCRIBE with NT and CALLBACK' in [[!UPNP-DEVICEARCH11]]:</p>
 
          <ol class="rule">
             <li>
@@ -1146,8 +1304,7 @@
             </li>
 
             <li>
-               Send a HTTP SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with an integer value ofÆ’
-               <code>86400</code> and a <em>CALLBACK</em> header
+               Send a HTTP SUBSCRIBE request with a <em>NT</em> header with a string value of <code>upnp:event</code>, a <em>TIMEOUT</em> header with a user-agent defined timeout value (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) and a <em>CALLBACK</em> header
                with a string value of <var>callback URL</var> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
             </li>
 
@@ -1163,7 +1320,7 @@
                      Let <var>callback ID</var> equal the string value of the first included <em>SID</em> header, if it exists.
                   </li>
                   <li>
-                     Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header, if it exists.
+                     Let <var>timeout date</var> equal the sum of the current UTC date value plus the integer value of the first included <em>TIMEOUT</em> header (minus the leading string of <code>Second-</code>), if it exists.
                   </li>
                   <li>
                      Run the following steps aynchronously and continue to the step labeled <em>listen</em> below.
@@ -1179,8 +1336,7 @@
                            If <var>current date</var> is less than the <var>timeout date</var> then continue to the step labeled <em>refresh subscription</em> above.
                         </li>
                         <li>
-                           Send a HTTP SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a <em>TIMEOUT</em> header
-                           with an integer value of <code>86400</code> towards the <var>network service record</var>'s <code>eventsUrl</code> property.
+                           Send a HTTP SUBSCRIBE request with a <em>SID</em> header with the string value of <var>callback ID</var> and a user-agent defined <em>TIMEOUT</em> header (in the form <code>Second-XX</code> where <code>XX</code> is the user-agent defined timeout value in seconds) towards the <var>network service record</var>'s <code>eventsUrl</code> property.
                         </li>
                         <li>
                            On receiving a valid 200 OK, update <var>callback ID</var> with the string value of the first included <em>SID</em> header, if it exists. All other HTTP
@@ -1216,6 +1372,10 @@
             </li>
          </ol>
 
+         <p>
+           A <a>user agent</a> can <dfn>terminate an existing UPnP Events Subscription</dfn> at any time for any <var>active service</var> in the <a>list of authorized service records</a> by sending an HTTP UNSUBSCRIBE request - as defined in 'Section 4.1.4: Canceling a subscription with UNSUBSCRIBE' in [[!UPNP-DEVICEARCH11]] - with a HOST header set to that <var>active service</var>'s <code>eventsUrl</code> property and a SID header set to the <var>callback ID</var> obtained when the initial <a>setup a UPnP Events Subscription</a> action occurred.
+         </p>
+
          </section>
 
          <section>
@@ -1223,53 +1383,18 @@
 
                   <div>
                      <p>
-                        When the <a>user agent</a> detects that the user has dropped from their connected network, then it MUST run the following steps:
-                     </p>
-
-                     <ol class="rule">
-                        <li>
-                           Flush all entries from the <a>list of available service records</a>.
-                        </li>
-                        <li>
-                           For each <a href="#networkservice"><code>NetworkService</code></a> object currently active in the <a>user agent</a> perform the following steps:
-
-                           <ol class="rule">
-                              <li>
-                                 Set the <a href="#dom-networkservice-online"><code>online</code></a> attribute to <code>false</code>.
-                              </li>
-                              <li>
-                                 <a href="http://www.whatwg.org/specs/web-apps/current-work/complete/webappapis.html#queue-a-task" class="externalDFN">Queue a task</a>
-                                                      to dispatch a newly created event with the name <code>serviceoffline</code> that uses the <code>Event</code> interface, which does not bubble, is not cancellable, and has no default action, at the current
-                                                      <a href="#networkservice"><code>NetworkService</code></a> object.
-                           </ol>
-                        </li>
-                        <li>
-                          For each <a href="#networkservices"><code>NetworkServices</code></a> object currently active in the <a>user agent</a> perform the following steps:
-
-                          <ol class="rule">
-                            <li>
-                              Let <var>number of available services</var> equal the value of <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute.
-                            </li>
-                            <li>
-                              Set the <a href="#networkservices"><code>NetworkServices</code></a>'s <a href="#dom-networkservices-servicesavailable"><code>servicesAvailable</code></a> attribute to zero (<code>0</code>).
-                            </li>
-                            <li>
-                              For each <var>available service</var> in <var>number of available services</var> the <a>user agent</a> MUST fire a new simple event with the name <code>serviceunavailable</code> that has no default action, does not bubble and is not cancellable, at the current <a href="#networkservices"><code>NetworkServices</code></a> object.
-                            </li>
-                          </ol>
-                        </li>
-
-                     </ol>
+                        When the <a>user agent</a> detects that the user has dropped from their connected network then, for each <var>existing service record</var> in the <a>list of available service records</a>, the user agent
+                        <em class="ct">MUST</em>
+                            run the general rule for <a>removing an available service</a> passing in each <var>existing service record</var>'s
+                            <code>id</code> property as the only argument for each call.
+                    </p>
 
                      <p>
-                        When the <a>user agent</a> detects that the user has connected to a new network, then it SHOULD run the following steps:
+                        When the <a>user agent</a> detects that the user has connected to a new network or reconnected to an existing network, then it
+                        <em class="ct">SHOULD</em> restart its discovery
+                         mechanisms as defined in the <a href="#service-discovery">Service Discovery</a> section of this specification, maintaining
+                         the existing <a>list of authorized service records</a> currently in use.
                      </p>
-
-                     <ol class="rule">
-                        <li>
-                           Re-issue an mDNS search and SSDP discovery search using all of the <a>valid service type</a> tokens initially provided to all active <a href="#networkservices"><code>NetworkServices</code></a> objects and handle all discovery responses according to the processing defined in <a href="#service-discovery">Section 7: Service Discovery</a>.
-                        </li>
-                     </ol>
                   </div>
          </section>
       </section>
@@ -1278,11 +1403,7 @@
       <h3>Garbage collection</h3>
 
       <p>
-         A <a><code>NetworkService</code></a> object containing a <code>url</code> parameter currently in the <a>entry script origin's URL whitelist</a> MUST NOT be garbage collected.
-      </p>
-
-      <p>
-         Only when the user navigates away from the current browsing context can <a><code>NetworkService</code></a> objects be garbage-collected and records in the <a>entry script origin's URL whitelist</a> be removed.
+         Only when the user navigates away from the current browsing context can <a><code>NetworkService</code></a> objects be garbage-collected, its records in the <a>entry script origin's URL whitelist</a> be removed and its corresponding entry in the <a>list of authorized service records</a> be removed.
       </p>
 
    </section>