From 933806a04438f19311bafbd3fc0b69b2526a71ac Mon Sep 17 00:00:00 2001
From: robocoder <anthon.pang@gmail.com>
Date: Mon, 7 Mar 2011 01:22:39 +0000
Subject: [PATCH] fixes #2156

git-svn-id: http://dev.piwik.org/svn/trunk@4044 59fd770c-687e-43c8-a1e3-f5a4ff64c105
---
 js/piwik.js                           |  43 +-
 piwik.js                              |   4 +-
 tests/javascript/jslint/fulljslint.js | 862 +++++++++++++++-----------
 3 files changed, 535 insertions(+), 374 deletions(-)

diff --git a/js/piwik.js b/js/piwik.js
index 9c06ff8b4e..4162eab6b6 100644
--- a/js/piwik.js
+++ b/js/piwik.js
@@ -30,6 +30,12 @@
  ************************************************************/
 /*jslint evil: true, strict: true, regexp: false */
 /*global JSON2 */
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON2, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
 
 // Create a JSON object only if one does not already exist. We create the
 // methods in a closure to avoid creating global variables.
@@ -358,6 +364,39 @@ if (!this.JSON2) {
 
 /*jslint browser:true, forin:true, plusplus:false, onevar:false, strict:true, evil:true */
 /*global window unescape ActiveXObject _paq:true */
+/*members encodeURIComponent, decodeURIComponent,
+	shift, unshift,
+	addEventListener, attachEvent, removeEventListener, detachEvent,
+	cookie, domain, readyState, documentElement, doScroll, title,
+	location, top, document, referrer, parent, links, href, protocol, GearsFactory,
+	event, which, button, srcElement, type, target,
+	parentNode, tagName, hostname, className,
+	userAgent, cookieEnabled, platform, mimeTypes, enabledPlugin, javaEnabled,
+	XMLHttpRequest, ActiveXObject, open, setRequestHeader, send,
+	getTime, setTime, toGMTString, getHours, getMinutes, getSeconds,
+	toLowerCase, charAt, indexOf, split,
+	onLoad, src,
+	round, random,
+	exec,
+	res, width, height,
+	pdf, qt, realp, wma, dir, fla, java, gears, ag,
+	hook, getHook, getVisitorId, setTrackerUrl, setSiteId,
+	setCustomData, getCustomData,
+	setCustomVariable, getCustomVariable, deleteCustomVariable,
+	setDownloadExtensions, addDownloadExtensions,
+	setDomains, setIgnoreClasses, setRequestMethod,
+	setReferrerUrl, setCustomUrl, setDocumentTitle,
+	setDownloadClasses, setLinkClasses,
+	discardHashTag,
+	setCookieNamePrefix, setCookieDomain, setCookiePath,
+	setVisitorCookieTimeout, setSessionCookieTimeout, setReferralCookieTimeout
+	setConversionAttributionFirstReferrer,
+	doNotTrack, setDoNotTrack,
+	addListener, enableLinkTracking, setLinkTrackingTimer,
+	setHeartBeatTimer, killFrame, redirectFile,
+	trackGoal, trackLink, trackPageView,
+	addPlugin, getTracker, getAsyncTracker
+*/
 var
 	// asynchronous tracker (or proxy)
 	_paq = _paq || [],
@@ -526,6 +565,8 @@ var
 		 * Add onload or DOM ready handler
 		 */
 		function addReadyListener() {
+			var _timer;
+
 			if (documentAlias.addEventListener) {
 				addEventListener(documentAlias, 'DOMContentLoaded', function ready() {
 					documentAlias.removeEventListener('DOMContentLoaded', ready, false);
@@ -556,7 +597,7 @@ var
 
 			// sniff for older WebKit versions
 			if ((new RegExp('WebKit')).test(navigatorAlias.userAgent)) {
-				var _timer = setInterval(function () {
+				_timer = setInterval(function () {
 					if (hasLoaded || /loaded|complete/.test(documentAlias.readyState)) {
 						clearInterval(_timer);
 						loadHandler();
diff --git a/piwik.js b/piwik.js
index 6e2c4070b6..a75f21d544 100644
--- a/piwik.js
+++ b/piwik.js
@@ -10,8 +10,8 @@
 if(!this.JSON2){this.JSON2={}}(function(){function d(f){return f<10?"0"+f:f}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(f){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+d(this.getUTCMonth()+1)+"-"+d(this.getUTCDate())+"T"+d(this.getUTCHours())+":"+d(this.getUTCMinutes())+":"+d(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(f){return this.valueOf()}}var c=new RegExp("[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]","g"),g=new RegExp('[\\\\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]',"g"),h,b,j={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},i;
 function a(f){g.lastIndex=0;return g.test(f)?'"'+f.replace(g,function(k){var l=j[k];return typeof l==="string"?l:"\\u"+("0000"+k.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+f+'"'}function e(r,o){var m,l,s,f,p=h,n,q=o[r];if(q&&typeof q==="object"&&typeof q.toJSON==="function"){q=q.toJSON(r)}if(typeof i==="function"){q=i.call(o,r,q)}switch(typeof q){case"string":return a(q);case"number":return isFinite(q)?String(q):"null";case"boolean":case"null":return String(q);case"object":if(!q){return"null"}h+=b;n=[];if(Object.prototype.toString.apply(q)==="[object Array]"){f=q.length;for(m=0;m<f;m+=1){n[m]=e(m,q)||"null"}s=n.length===0?"[]":h?"[\n"+h+n.join(",\n"+h)+"\n"+p+"]":"["+n.join(",")+"]";h=p;return s}if(i&&typeof i==="object"){f=i.length;for(m=0;m<f;m+=1){if(typeof i[m]==="string"){l=i[m];s=e(l,q);if(s){n.push(a(l)+(h?": ":":")+s)}}}}else{for(l in q){if(Object.prototype.hasOwnProperty.call(q,l)){s=e(l,q);if(s){n.push(a(l)+(h?": ":":")+s)}}}}s=n.length===0?"{}":h?"{\n"+h+n.join(",\n"+h)+"\n"+p+"}":"{"+n.join(",")+"}";
 h=p;return s}}if(typeof JSON2.stringify!=="function"){JSON2.stringify=function(m,k,l){var f;h="";b="";if(typeof l==="number"){for(f=0;f<l;f+=1){b+=" "}}else{if(typeof l==="string"){b=l}}i=k;if(k&&typeof k!=="function"&&(typeof k!=="object"||typeof k.length!=="number")){throw new Error("JSON.stringify")}return e("",{"":m})}}if(typeof JSON2.parse!=="function"){JSON2.parse=function(m,f){var l;function k(q,p){var o,n,r=q[p];if(r&&typeof r==="object"){for(o in r){if(Object.prototype.hasOwnProperty.call(r,o)){n=k(r,o);if(n!==undefined){r[o]=n}else{delete r[o]}}}}return f.call(q,p,r)}m=String(m);c.lastIndex=0;if(c.test(m)){m=m.replace(c,function(n){return"\\u"+("0000"+n.charCodeAt(0).toString(16)).slice(-4)})}if((new RegExp("^[\\],:{}\\s]*$")).test(m.replace(new RegExp('\\\\(?:["\\\\/bfnrt]|u[0-9a-fA-F]{4})',"g"),"@").replace(new RegExp('"[^"\\\\\n\r]*"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?',"g"),"]").replace(new RegExp("(?:^|:|,)(?:\\s*\\[)+","g"),""))){l=eval("("+m+")");
-return typeof f==="function"?k({"":l},""):l}throw new SyntaxError("JSON.parse")}}}());var _paq=_paq||[],Piwik=Piwik||(function(){var m,w={},d=document,j=navigator,v=screen,G=window,h=false,B=[],e=G.encodeURIComponent,H=G.decodeURIComponent,F,C;function b(i){return typeof i!=="undefined"}function a(i){return typeof i==="function"}function n(i){return typeof i==="object"}function q(i){return typeof i==="string"||i instanceof String}function z(I){var i=I.shift();if(q(i)){F[i].apply(F,I)}else{i.apply(F,I)}}function t(K,J,I,i){if(K.addEventListener){K.addEventListener(J,I,i);return true}if(K.attachEvent){return K.attachEvent("on"+J,I)}K["on"+J]=I}function g(J,M){var I="",L,K;for(L in w){K=w[L][J];if(a(K)){I+=K(M)}}return I}function A(){var i;g("unload");if(m){do{i=new Date()}while(i.getTime()<m)}}function k(){var I;if(!h){h=true;g("load");for(I=0;I<B.length;I++){B[I]()}}return true}function x(){if(d.addEventListener){t(d,"DOMContentLoaded",function I(){d.removeEventListener("DOMContentLoaded",I,false);
-k()})}else{if(d.attachEvent){d.attachEvent("onreadystatechange",function I(){if(d.readyState==="complete"){d.detachEvent("onreadystatechange",I);k()}});if(d.documentElement.doScroll&&G===G.top){(function I(){if(!h){try{d.documentElement.doScroll("left")}catch(J){setTimeout(I,0);return}k()}}())}}}if((new RegExp("WebKit")).test(j.userAgent)){var i=setInterval(function(){if(h||/loaded|complete/.test(d.readyState)){clearInterval(i);k()}},10)}t(G,"load",k,false)}function f(){var i="";try{i=G.top.document.referrer}catch(J){if(G.parent){try{i=G.parent.document.referrer}catch(I){i=""}}}if(i===""){i=d.referrer}return i}function y(i){var J=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),I=J.exec(i);return I?I[1]:i}function p(J,I){var M=new RegExp("^(?:https?|ftp)(?::/*(?:[^?]+)[?])([^#]+)"),L=M.exec(J),K=new RegExp("(?:^|&)"+I+"=([^&]*)"),i=L?K.exec(L[1]):0;return i?H(i[1]):""}function s(N,K,J,M,I,L){var i;if(J){i=new Date();i.setTime(i.getTime()+J)}d.cookie=N+"="+e(K)+(J?";expires="+i.toGMTString():"")+";path="+(M?M:"/")+(I?";domain="+I:"")+(L?";secure":"")
+return typeof f==="function"?k({"":l},""):l}throw new SyntaxError("JSON.parse")}}}());var _paq=_paq||[],Piwik=Piwik||(function(){var m,w={},d=document,j=navigator,v=screen,G=window,h=false,B=[],e=G.encodeURIComponent,H=G.decodeURIComponent,F,C;function b(i){return typeof i!=="undefined"}function a(i){return typeof i==="function"}function n(i){return typeof i==="object"}function q(i){return typeof i==="string"||i instanceof String}function z(I){var i=I.shift();if(q(i)){F[i].apply(F,I)}else{i.apply(F,I)}}function t(K,J,I,i){if(K.addEventListener){K.addEventListener(J,I,i);return true}if(K.attachEvent){return K.attachEvent("on"+J,I)}K["on"+J]=I}function g(J,M){var I="",L,K;for(L in w){K=w[L][J];if(a(K)){I+=K(M)}}return I}function A(){var i;g("unload");if(m){do{i=new Date()}while(i.getTime()<m)}}function k(){var I;if(!h){h=true;g("load");for(I=0;I<B.length;I++){B[I]()}}return true}function x(){var I;if(d.addEventListener){t(d,"DOMContentLoaded",function i(){d.removeEventListener("DOMContentLoaded",i,false);
+k()})}else{if(d.attachEvent){d.attachEvent("onreadystatechange",function i(){if(d.readyState==="complete"){d.detachEvent("onreadystatechange",i);k()}});if(d.documentElement.doScroll&&G===G.top){(function i(){if(!h){try{d.documentElement.doScroll("left")}catch(J){setTimeout(i,0);return}k()}}())}}}if((new RegExp("WebKit")).test(j.userAgent)){I=setInterval(function(){if(h||/loaded|complete/.test(d.readyState)){clearInterval(I);k()}},10)}t(G,"load",k,false)}function f(){var i="";try{i=G.top.document.referrer}catch(J){if(G.parent){try{i=G.parent.document.referrer}catch(I){i=""}}}if(i===""){i=d.referrer}return i}function y(i){var J=new RegExp("^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)"),I=J.exec(i);return I?I[1]:i}function p(J,I){var M=new RegExp("^(?:https?|ftp)(?::/*(?:[^?]+)[?])([^#]+)"),L=M.exec(J),K=new RegExp("(?:^|&)"+I+"=([^&]*)"),i=L?K.exec(L[1]):0;return i?H(i[1]):""}function s(N,K,J,M,I,L){var i;if(J){i=new Date();i.setTime(i.getTime()+J)}d.cookie=N+"="+e(K)+(J?";expires="+i.toGMTString():"")+";path="+(M?M:"/")+(I?";domain="+I:"")+(L?";secure":"")
 }function E(J){var i=new RegExp("(^|;)[ ]*"+J+"=([^;]*)"),I=i.exec(d.cookie);return I?H(I[2]):0}function r(i){return unescape(e(i))}function u(Y){var K=function(W,i){return(W<<i)|(W>>>(32-i))},Z=function(af){var ae="",ad,W;for(ad=7;ad>=0;ad--){W=(af>>>(ad*4))&15;ae+=W.toString(16)}return ae},N,ab,aa,J=[],R=1732584193,P=4023233417,O=2562383102,M=271733878,L=3285377520,X,V,U,T,S,ac,I,Q=[];Y=r(Y);I=Y.length;for(ab=0;ab<I-3;ab+=4){aa=Y.charCodeAt(ab)<<24|Y.charCodeAt(ab+1)<<16|Y.charCodeAt(ab+2)<<8|Y.charCodeAt(ab+3);Q.push(aa)}switch(I&3){case 0:ab=2147483648;break;case 1:ab=Y.charCodeAt(I-1)<<24|8388608;break;case 2:ab=Y.charCodeAt(I-2)<<24|Y.charCodeAt(I-1)<<16|32768;break;case 3:ab=Y.charCodeAt(I-3)<<24|Y.charCodeAt(I-2)<<16|Y.charCodeAt(I-1)<<8|128;break}Q.push(ab);while((Q.length&15)!==14){Q.push(0)}Q.push(I>>>29);Q.push((I<<3)&4294967295);for(N=0;N<Q.length;N+=16){for(ab=0;ab<16;ab++){J[ab]=Q[N+ab]}for(ab=16;ab<=79;ab++){J[ab]=K(J[ab-3]^J[ab-8]^J[ab-14]^J[ab-16],1)}X=R;V=P;U=O;T=M;S=L;
 for(ab=0;ab<=19;ab++){ac=(K(X,5)+((V&U)|(~V&T))+S+J[ab]+1518500249)&4294967295;S=T;T=U;U=K(V,30);V=X;X=ac}for(ab=20;ab<=39;ab++){ac=(K(X,5)+(V^U^T)+S+J[ab]+1859775393)&4294967295;S=T;T=U;U=K(V,30);V=X;X=ac}for(ab=40;ab<=59;ab++){ac=(K(X,5)+((V&U)|(V&T)|(U&T))+S+J[ab]+2400959708)&4294967295;S=T;T=U;U=K(V,30);V=X;X=ac}for(ab=60;ab<=79;ab++){ac=(K(X,5)+(V^U^T)+S+J[ab]+3395469782)&4294967295;S=T;T=U;U=K(V,30);V=X;X=ac}R=(R+X)&4294967295;P=(P+V)&4294967295;O=(O+U)&4294967295;M=(M+T)&4294967295;L=(L+S)&4294967295}ac=Z(R)+Z(P)+Z(O)+Z(M)+Z(L);return ac.toLowerCase()}function o(J,i,I){if(J==="translate.googleusercontent.com"){if(I===""){I=i}i=p(i,"u");J=y(i)}else{if(J==="cc.bingj.com"||J==="webcache.googleusercontent.com"||J.slice(0,5)==="74.6."){i=d.links[0].href;J=y(i)}}return[J,i,I]}function l(I){var i=I.length;if(I.charAt(--i)==="."){I=I.slice(0,i)}if(I.slice(0,2)==="*."){I=I.slice(1)}return I}function D(ay,aw){var aj=o(d.domain,G.location.href,f()),W=l(aj[0]),T=aj[1],az=aj[2],K="GET",aa=ay||"",aQ=aw||"",aJ,aP=d.title,af="7z|aac|ar[cj]|as[fx]|avi|bin|csv|deb|dmg|doc|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|ms[ip]|od[bfgpst]|og[gv]|pdf|phps|png|ppt|qtm?|ra[mr]?|rpm|sea|sit|tar|t?bz2?|tgz|torrent|txt|wav|wm[av]|wpd||xls|xml|z|zip",aB=[W],M=[],aC=[],aF=[],Z=500,J,ah,ai,au,aD="_pk_",P,ax,L,aq,aR=63072000000,ad=1800000,Y=15768000000,aG=false,R=100,al={},ap=false,Q=false,X,aN,an,aI=u,av;
 function aK(aT){var aS;if(ai){aS=new RegExp("#.*");return aT.replace(aS,"")}return aT}function ao(aV){var aT,aS,aU;for(aT=0;aT<aB.length;aT++){aS=l(aB[aT].toLowerCase());if(aV===aS){return true}if(aS.slice(0,1)==="."){if(aV===aS.slice(1)){return true}aU=aV.length-aS.length;if((aU>0)&&(aV.slice(aU)===aS)){return true}}}return false}function i(aS){var aT=new Image(1,1);aT.onLoad=function(){};aT.src=aa+(aa.indexOf("?")<0?"?":"&")+aS}function V(aS){try{var aU=G.XMLHttpRequest?new G.XMLHttpRequest():G.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;aU.open("POST",aa,true);aU.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");aU.send(aS)}catch(aT){i(aS)}}function aM(aU,aT){var aS=new Date();if(!L){if(K==="POST"){V(aU)}else{i(aU)}m=aS.getTime()+aT}}function N(aS){return aD+aS+"."+aQ+"."+av}function at(){var aS=N("testcookie");if(!b(j.cookieEnabled)){s(aS,"1");return E(aS)==="1"?"1":"0"}return j.cookieEnabled?"1":"0"}function ag(){av=aI((P||W)+(ax||"/")).slice(0,4)
diff --git a/tests/javascript/jslint/fulljslint.js b/tests/javascript/jslint/fulljslint.js
index 778c4e60f8..aa75dce729 100644
--- a/tests/javascript/jslint/fulljslint.js
+++ b/tests/javascript/jslint/fulljslint.js
@@ -1,5 +1,5 @@
 // jslint.js
-// 2011-02-24
+// 2011-03-05
 
 /*
 Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
@@ -45,7 +45,7 @@ SOFTWARE.
     If it checks out, JSLINT returns true. Otherwise, it returns false.
 
     If false, you can inspect JSLINT.errors to find out the problems.
-    JSLINT.errors is an array of objects containing these members:
+    JSLINT.errors is an array of objects containing these properties:
 
     {
         line      : The line (relative to 0) at which the lint was found
@@ -67,9 +67,9 @@ SOFTWARE.
     implied global variables and other problems. The report is in HTML and
     can be inserted in an HTML <body>.
 
-        var myReport = JSLINT.report(limited);
+        var myReport = JSLINT.report(errors_only);
 
-    If limited is true, then the report will be limited to only errors.
+    If errors_only is true, then the report will be limited to only errors.
 
     You can request a data structure which contains JSLint's results.
 
@@ -152,69 +152,123 @@ SOFTWARE.
 
 */
 
+/*
+    JSLint provides three directives. They look like slashstar comments, and
+    allow for setting options, declaring global variables, and establishing a
+    set of allowed property names.
+
+    These directives respect function scope.
+*/
+
+/*
+    The jslint directive is a special comment that can set one or more options.
+    The current option set is
+
+    adsafe     true, if ADsafe rules should be enforced
+    bitwise    true, if bitwise operators should not be allowed
+    browser    true, if the standard browser globals should be predefined
+    cap        true, if upper case HTML should be allowed
+    'continue' true, if the continuation statement should be tolerated
+    css        true, if CSS workarounds should be tolerated
+    debug      true, if debugger statements should be allowed
+    devel      true, if logging should be allowed (console, alert, etc.)
+    es5        true, if ES5 syntax should be allowed
+    evil       true, if eval should be allowed
+    forin      true, if for in statements need not filter
+    fragment   true, if HTML fragments should be allowed
+    indent     the indentation factor
+    maxerr     the maximum number of errors to allow
+    maxlen     the maximum length of a source line
+    newcap     true, if constructor names must be capitalized
+    nomen      true, if names should be checked
+    on         true, if HTML event handlers should be allowed
+    onevar     true, if only one var statement per function should be allowed
+    passfail   true, if the scan should stop on first error
+    plusplus   true, if increment/decrement should not be allowed
+    regexp     true, if the . should not be allowed in regexp literals
+    rhino      true, if the Rhino environment globals should be predefined
+    undef      true, if variables should be declared before used
+    safe       true, if use of some browser features should be restricted
+    windows    true, if MS Windows-specigic globals should be predefined
+    strict     true, require the "use strict"; pragma
+    sub        true, if all forms of subscript notation are tolerated
+    white      true, if strict whitespace rules apply
+    widget     true  if the Yahoo Widgets globals should be predefined
+
+    For example:
+*/
+
+
 /*jslint
     evil: true, nomen: false, onevar: false, regexp: false, strict: true
 */
 
-/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "'",
-    "(begin)", "(breakage)", "(context)", "(end)", "(error)", "(global)",
-    "(identifier)", "(line)", "(loopage)", "(name)", "(onevar)",
-    "(params)", "(scope)", "(statement)", "(token)", "(verb)", ")", "*",
-    "+", "-", "/", ";", "<", "</", "<=", "==", "===", ">", ">=", ADSAFE,
-    ActiveXObject, Array, Boolean, COM, CScript, Canvas, CustomAnimation,
-    Date, Debug, E, Enumerator, Error, EvalError, FadeAnimation, Flash,
-    FormField, Frame, Function, HotKey, Image, JSON, LN10, LN2, LOG10E,
-    LOG2E, MAX_VALUE, MIN_VALUE, Math, MenuItem, MoveAnimation,
-    NEGATIVE_INFINITY, Number, Object, Option, PI, POSITIVE_INFINITY, Point,
-    RangeError, Rectangle, ReferenceError, RegExp, ResizeAnimation,
-    RotateAnimation, SQRT1_2, SQRT2, ScrollBar, String, Style, SyntaxError,
-    System, Text, TextArea, Timer, TypeError, URIError, URL, VBArray,
-    WScript, Web, Window, XMLDOM, XMLHttpRequest, "\\", a, a_function,
-    a_label, a_not_allowed, a_not_defined, a_scope, abbr, acronym,
-    activeborder, activecaption, address, adsafe, adsafe_a,
-    adsafe_autocomplete, adsafe_bad_id, adsafe_div, adsafe_fragment,
-    adsafe_go, adsafe_html, adsafe_id, adsafe_id_go, adsafe_lib,
-    adsafe_lib_second, adsafe_missing_id, adsafe_name_a, adsafe_placement,
-    adsafe_prefix_a, adsafe_script, adsafe_source, adsafe_subscript_a,
-    adsafe_tag, alert, aliceblue, all, already_defined, and, animator,
-    antiquewhite, appleScript, applet, apply, approved, appworkspace, aqua,
-    aquamarine, area, arguments, arity, article, aside, assign,
-    assign_exception, assignment_function_expression, at, attribute_case_a,
-    audio, autocomplete, avoid_a, azure, b, background,
-    "background-attachment", "background-color", "background-image",
-    "background-position", "background-repeat", bad_assignment, bad_color_a,
-    bad_constructor, bad_entity, bad_html, bad_id_a, bad_in_a,
-    bad_invocation, bad_name_a, bad_new, bad_number, bad_operand, bad_type,
-    bad_url, bad_wrap, base, bdo, beep, beige, big, bisque, bitwise, black,
-    blanchedalmond, block, blockquote, blue, blueviolet, body, border,
-    "border-bottom", "border-bottom-color", "border-bottom-style",
-    "border-bottom-width", "border-collapse", "border-color", "border-left",
-    "border-left-color", "border-left-style", "border-left-width",
-    "border-right", "border-right-color", "border-right-style",
-    "border-right-width", "border-spacing", "border-style", "border-top",
-    "border-top-color", "border-top-style", "border-top-width",
-    "border-width", bottom, br, braille, brown, browser, burlywood, button,
-    buttonface, buttonhighlight, buttonshadow, buttontext, bytesToUIString,
-    c, cadetblue, call, callee, caller, canvas, cap, caption,
-    "caption-side", captiontext, case, center, charAt, charCodeAt,
-    character, chartreuse, chocolate, chooseColor, chooseFile, chooseFolder,
-    cite, clear, clearInterval, clearTimeout, clip, closeWidget, closure,
-    cm, code, col, colgroup, color, combine_var, command, comments, concat,
-    conditional_assignment, confirm, confusing_a, confusing_regexp, console,
-    constructor, constructor_name_a, content, continue, control_a,
-    convertPathToHFS, convertPathToPlatform, coral, cornflowerblue,
-    cornsilk, "counter-increment", "counter-reset", create, crimson, css,
-    cursor, cyan, d, dangerous_comment, dangling_a, darkblue, darkcyan,
-    darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta,
+/*
+    The properties directive declares an exclusive list of property names.
+    Any properties named in the program that are not in the list will
+    produce a warning.
+
+    For example:
+*/
+
+/*properties "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "'",
+    "(begin)", "(breakage)", "(context)", "(error)", "(global)",
+    "(identifier)", "(line)", "(loopage)", "(name)", "(onevar)", "(params)",
+    "(scope)", "(statement)", "(token)", "(verb)", ")", "*", "+", "-", "\/",
+    ";", "<", "<=", "==", "===", ">", ">=", ADSAFE, ActiveXObject,
+    Array, Boolean, COM, CScript, Canvas, CustomAnimation, Date, Debug, E,
+    Enumerator, Error, EvalError, FadeAnimation, Flash, FormField, Frame,
+    Function, HotKey, Image, JSON, LN10, LN2, LOG10E, LOG2E, MAX_VALUE,
+    MIN_VALUE, Math, MenuItem, MoveAnimation, NEGATIVE_INFINITY, Number,
+    Object, Option, PI, POSITIVE_INFINITY, Point, RangeError, Rectangle,
+    ReferenceError, RegExp, ResizeAnimation, RotateAnimation, SQRT1_2,
+    SQRT2, ScrollBar, String, Style, SyntaxError, System, Text, TextArea,
+    Timer, TypeError, URIError, URL, VBArray, WScript, Web, Window, XMLDOM,
+    XMLHttpRequest, "\\", a, a_function, a_label, a_not_allowed,
+    a_not_defined, a_scope, abbr, acronym, activeborder, activecaption,
+    address, adsafe, adsafe_a, adsafe_autocomplete, adsafe_bad_id,
+    adsafe_div, adsafe_fragment, adsafe_go, adsafe_html, adsafe_id,
+    adsafe_id_go, adsafe_lib, adsafe_lib_second, adsafe_missing_id,
+    adsafe_name_a, adsafe_placement, adsafe_prefix_a, adsafe_script,
+    adsafe_source, adsafe_subscript_a, adsafe_tag, alert, aliceblue, all,
+    already_defined, and, animator, antiquewhite, appleScript, applet,
+    apply, approved, appworkspace, aqua, aquamarine, area, arguments, arity,
+    article, aside, assign, assign_exception,
+    assignment_function_expression, at, attribute_case_a, audio,
+    autocomplete, avoid_a, azure, b, background, "background-attachment",
+    "background-color", "background-image", "background-position",
+    "background-repeat", bad_assignment, bad_color_a, bad_constructor,
+    bad_entity, bad_html, bad_id_a, bad_in_a, bad_invocation, bad_name_a,
+    bad_new, bad_number, bad_operand, bad_type, bad_url, bad_wrap, base,
+    bdo, beep, beige, big, bisque, bitwise, black, blanchedalmond, block,
+    blockquote, blue, blueviolet, body, border, "border-bottom",
+    "border-bottom-color", "border-bottom-style", "border-bottom-width",
+    "border-collapse", "border-color", "border-left", "border-left-color",
+    "border-left-style", "border-left-width", "border-right",
+    "border-right-color", "border-right-style", "border-right-width",
+    "border-spacing", "border-style", "border-top", "border-top-color",
+    "border-top-style", "border-top-width", "border-width", bottom, br,
+    braille, brown, browser, burlywood, button, buttonface, buttonhighlight,
+    buttonshadow, buttontext, bytesToUIString, c, cadetblue, call, callee,
+    caller, canvas, cap, caption, "caption-side", captiontext, center,
+    charAt, charCodeAt, character, chartreuse, chocolate, chooseColor,
+    chooseFile, chooseFolder, cite, clear, clearInterval, clearTimeout,
+    clip, closeWidget, closure, cm, code, col, colgroup, color, combine_var,
+    command, comments, concat, conditional_assignment, confirm, confusing_a,
+    confusing_regexp, console, constructor, constructor_name_a, content,
+    continue, control_a, convertPathToHFS, convertPathToPlatform, coral,
+    cornflowerblue, cornsilk, "counter-increment", "counter-reset", create,
+    crimson, css, cursor, cyan, d, dangerous_comment, dangling_a, darkblue,
+    darkcyan, darkgoldenrod, darkgray, darkgreen, darkkhaki, darkmagenta,
     darkolivegreen, darkorange, darkorchid, darkred, darksalmon,
     darkseagreen, darkslateblue, darkslategray, darkturquoise, darkviolet,
     data, datalist, dd, debug, decodeURI, decodeURIComponent, deeppink,
-    deepskyblue, default, defineClass, del, deleted, deserialize, details,
-    devel, dfn, dialog, dimgray, dir, direction, display, disrupt, div, dl,
-    do, document, dodgerblue, dt, duplicate_a, edge, edition, else, em,
-    embed, embossed, empty, "empty-cells", empty_block, empty_case,
-    empty_class, encodeURI, encodeURIComponent, entityify, errors, es5,
-    escape, eval, event, evidence, evil, ex, exception, exec, expected_a,
+    deepskyblue, defineClass, del, deleted, deserialize, details, devel,
+    dfn, dialog, dimgray, dir, direction, display, disrupt, div, dl,
+    document, dodgerblue, dt, duplicate_a, edge, edition, else, em, embed,
+    embossed, empty, "empty-cells", empty_block, empty_case, empty_class,
+    encodeURI, encodeURIComponent, entityify, errors, es5, escape, eval,
+    event, evidence, evil, ex, exception, exec, expected_a,
     expected_a_at_b_c, expected_a_b, expected_a_b_from_c_d, expected_at_a,
     expected_attribute_a, expected_attribute_value_a, expected_class_a,
     expected_fraction_a, expected_id_a, expected_identifier_a,
@@ -224,10 +278,10 @@ SOFTWARE.
     expected_positive_a, expected_pseudo_a, expected_selector_a,
     expected_small_a, expected_space_a_b, expected_string_a,
     expected_style_attribute, expected_style_pattern, expected_tagname_a,
-    fieldset, figure, filesystem, firebrick, first, float, floor,
+    fieldset, figure, filesystem, filter, firebrick, first, float, floor,
     floralwhite, focusWidget, font, "font-family", "font-size",
     "font-size-adjust", "font-stretch", "font-style", "font-variant",
-    "font-weight", footer, for, for_if, forestgreen, forin, form, fragment,
+    "font-weight", footer, for_if, forestgreen, forin, form, fragment,
     frame, frames, frameset, from, fromCharCode, fuchsia, fud, funct,
     function, function_block, function_eval, function_loop,
     function_statement, function_strict, functions, g, gainsboro, gc,
@@ -237,12 +291,12 @@ SOFTWARE.
     honeydew, hotpink, hr, "hta:application", html, html_confusion_a,
     html_handlers, i, iTunes, id, identifier, identifier_function, iframe,
     img, immed, implied_evil, implieds, in, inactiveborder, inactivecaption,
-    inactivecaptiontext, include, indent, indexOf, indianred, indigo, infix_in,
-    infobackground, infotext, init, input, ins, insecure_a, isAlpha,
-    isApplicationRunning, isArray, isDigit, isFinite, isNaN, ivory, join,
-    jslint, json, kbd, keygen, keys, khaki, konfabulatorVersion, label,
-    label_a_b, labeled, lang, lavender, lavenderblush, lawngreen, lbp,
-    leading_decimal_a, led, left, legend, lemonchiffon, length,
+    inactivecaptiontext, include, indent, indexOf, indianred, indigo,
+    infix_in, infobackground, infotext, init, input, ins, insecure_a,
+    isAlpha, isApplicationRunning, isArray, isDigit, isFinite, isNaN, ivory,
+    join, jslint, json, kbd, keygen, keys, khaki, konfabulatorVersion,
+    label, label_a_b, labeled, lang, lavender, lavenderblush, lawngreen,
+    lbp, leading_decimal_a, led, left, legend, lemonchiffon, length,
     "letter-spacing", li, lib, lightblue, lightcoral, lightcyan,
     lightgoldenrodyellow, lightgreen, lightpink, lightsalmon, lightseagreen,
     lightskyblue, lightslategray, lightsteelblue, lightyellow, lime,
@@ -269,7 +323,7 @@ SOFTWARE.
     palegreen, paleturquoise, palevioletred, papayawhip, param,
     parameter_a_get_b, parameter_set_a, paren, parent, parseFloat, parseInt,
     passfail, pc, peachpuff, peru, pink, play, plum, plusplus, pop,
-    popupMenu, position, postcomments, powderblue, pre, predef,
+    popupMenu, position, postcomments, postscript, powderblue, pre, predef,
     preferenceGroups, preferences, prev, print, progress, projection,
     prompt, prototype, pt, purple, push, px, q, quit, quote, quotes, radix,
     random, range, raw, readFile, readUrl, read_only, reason, red,
@@ -281,30 +335,35 @@ SOFTWARE.
     select, serialize, setInterval, setTimeout, shift,
     showWidgetPreferences, sienna, silver, skyblue, slash_equal, slateblue,
     slategray, sleep, slice, small, snow, sort, source, span, spawn, speak,
-    speech, split, springgreen, src, stack, statement, statement_block,
-    steelblue, stopping, strange_loop, strict, strong, style, styleproperty,
-    sub, subscript, substr, sup, supplant, suppressUpdates, switch, sync,
-    system, table, "table-layout", tag_a_in_b, tan, tbody, td, teal,
-    tellWidget, test, "text-align", "text-decoration", "text-indent",
-    "text-shadow", "text-transform", textarea, tfoot, th, thead, third,
-    thistle, threeddarkshadow, threedface, threedhighlight,
-    threedlightshadow, threedshadow, thru, time, title, toLowerCase,
-    toString, toUpperCase, toint32, token, tomato, too_long, too_many, top,
-    tr, trailing_decimal_a, tree, tt, tty, turquoise, tv, type, u, ul,
-    unclosed, unclosed_comment, unclosed_regexp, undef, unescape,
-    unescaped_a, unexpected_a, unexpected_char_a_b, unexpected_comment,
-    unexpected_member_a, unexpected_space_a_b, "unicode-bidi",
-    unnecessary_initialize, unnecessary_use, unreachable_a_b,
-    unrecognized_style_attribute_a, unrecognized_tag_a, unsafe, unused,
-    unwatch, updateNow, url, urls, use_array, use_braces, use_object,
-    used_before_a, value, valueOf, var, var_a_not, version,
-    "vertical-align", video, violet, visibility, was, watch,
-    weird_assignment, weird_condition, weird_new, weird_program,
-    weird_relation, weird_ternary, wheat, while, white, "white-space",
-    whitesmoke, widget, width, window, windowframe, windows, windowtext,
-    "word-spacing", "word-wrap", wrap, wrap_immediate, wrap_regexp,
-    write_is_wrong, yahooCheckLogin, yahooLogin, yahooLogout, yellow,
-    yellowgreen, "z-index", "}"
+    speech, split, springgreen, src, stack, statement_block, steelblue,
+    stopping, strange_loop, strict, strong, style, styleproperty, sub,
+    subscript, substr, sup, supplant, suppressUpdates, sync, system, table,
+    "table-layout", tag_a_in_b, tan, tbody, td, teal, tellWidget, test,
+    "text-align", "text-decoration", "text-indent", "text-shadow",
+    "text-transform", textarea, tfoot, th, thead, third, thistle,
+    threeddarkshadow, threedface, threedhighlight, threedlightshadow,
+    threedshadow, thru, time, title, toLowerCase, toString, toUpperCase,
+    toint32, token, tomato, too_long, too_many, top, tr, trailing_decimal_a,
+    tree, tt, tty, turquoise, tv, type, u, ul, unclosed, unclosed_comment,
+    unclosed_regexp, undef, unescape, unescaped_a, unexpected_a,
+    unexpected_char_a_b, unexpected_comment, unexpected_member_a,
+    unexpected_space_a_b, "unicode-bidi", unnecessary_initialize,
+    unnecessary_use, unreachable_a_b, unrecognized_style_attribute_a,
+    unrecognized_tag_a, unsafe, unused, unwatch, updateNow, url, urls,
+    use_array, use_braces, use_object, used_before_a, value, valueOf, var,
+    var_a_not, version, "vertical-align", video, violet, visibility, was,
+    watch, weird_assignment, weird_condition, weird_new, weird_program,
+    weird_relation, weird_ternary, wheat, white, "white-space", whitesmoke,
+    widget, width, window, windowframe, windows, windowtext, "word-spacing",
+    "word-wrap", wrap, wrap_immediate, wrap_regexp, write_is_wrong,
+    yahooCheckLogin, yahooLogin, yahooLogout, yellow, yellowgreen,
+    "z-index"
+*/
+
+/*
+    The global directive is used to declare global variables that can
+    be accessed by the program. If a declaration is true, then the variable
+    is writeable. Otherwise, it is read-only.
 */
 
 // We build the application inside a function so that we produce only a single
@@ -317,6 +376,7 @@ var JSLINT = (function () {
 
     var adsafe_id,      // The widget's ADsafe id.
         adsafe_may,     // The widget may load approved scripts.
+        adsafe_top,     // At the top of the widget script.
         adsafe_went,    // ADSAFE.go has been called.
         anonname,       // The guessed name for anonymous functions.
         approved,       // ADsafe approved urls.
@@ -341,7 +401,7 @@ var JSLINT = (function () {
 
 // These are property names that should not be permitted in the safe subset.
 
-        banned = {              // the member names that ADsafe prohibits.
+        banned = {
             'arguments'     : true,
             callee          : true,
             caller          : true,
@@ -354,41 +414,9 @@ var JSLINT = (function () {
             watch           : true
         },
 
-
-// These are the JSLint boolean options.
-
-        bool_options = {
-            adsafe     : true, // if ADsafe should be enforced
-            bitwise    : true, // if bitwise operators should not be allowed
-            browser    : true, // if the standard browser globals should be predefined
-            cap        : true, // if upper case HTML should be allowed
-            'continue' : true, // if the continuation statement should be tolerated
-            css        : true, // if CSS workarounds should be tolerated
-            debug      : true, // if debugger statements should be allowed
-            devel      : true, // if logging should be allowed (console, alert, etc.)
-            es5        : true, // if ES5 syntax should be allowed
-            evil       : true, // if eval should be allowed
-            forin      : true, // if for in statements need not filter
-            fragment   : true, // if HTML fragments should be allowed
-            newcap     : true, // if constructor names must be capitalized
-            nomen      : true, // if names should be checked
-            on         : true, // if HTML event handlers should be allowed
-            onevar     : true, // if only one var statement per function should be allowed
-            passfail   : true, // if the scan should stop on first error
-            plusplus   : true, // if increment/decrement should not be allowed
-            regexp     : true, // if the . should not be allowed in regexp literals
-            rhino      : true, // if the Rhino environment globals should be predefined
-            undef      : true, // if variables should be declared before used
-            safe       : true, // if use of some browser features should be restricted
-            windows    : true, // if MS Windows-specigic globals should be predefined
-            strict     : true, // require the "use strict"; pragma
-            sub        : true, // if all forms of subscript notation are tolerated
-            white      : true, // if strict whitespace rules apply
-            widget     : true  // if the Yahoo Widgets globals should be predefined
-        },
-
-// browser contains a set of global names which are commonly provided by a
-// web browser environment.
+// browser contains a set of global names that are commonly provided by a
+// web browser environment. self and window are intentially excluded because
+// of the high likelihood for misue.
 
         browser = {
             clearInterval   : false,
@@ -408,6 +436,9 @@ var JSLINT = (function () {
             setTimeout      : false,
             XMLHttpRequest  : false
         },
+
+// bundle contains the text messages.
+
         bundle = {
             a_function: "'{a}' is a function.",
             a_label: "'{a}' is a statement label.",
@@ -562,7 +593,7 @@ var JSLINT = (function () {
             unexpected_a: "Unexpected '{a}'.",
             unexpected_char_a_b: "Unexpected character '{a}' in {b}.",
             unexpected_comment: "Unexpected comment.",
-            unexpected_member_a: "Unexpected /*member {a}.",
+            unexpected_member_a: "Unexpected property '{a}'.",
             unexpected_space_a_b: "Unexpected space between '{a}' and '{b}'.",
             unnecessary_initialize: "It is not necessary to initialize '{a}' to 'undefined'.",
             unnecessary_use: "Unnecessary \"use strict\".",
@@ -804,8 +835,7 @@ var JSLINT = (function () {
         funct,          // The current function
 
         functionicity = [
-            'closure', 'exception', 'global', 'label',
-            'outer', 'unused', 'var'
+            'closure', 'exception', 'global', 'label', 'outer', 'unused', 'var'
         ],
 
         functions,      // All of the functions
@@ -936,19 +966,9 @@ var JSLINT = (function () {
         lines,
         lookahead,
         member,
-        members_only,
+        properties,
         nexttoken,
         option,
-        postscript = {
-            '(end)':    true,
-            '(error)':  true,
-            '</':       true,
-            '}':        true,
-            '"':        true,
-            '\'':       true,
-            'case':     true,
-            'default':  true
-        },
         predefined,     // Global variables defined by option
         prereg,
         prevtoken,
@@ -1153,7 +1173,7 @@ var JSLINT = (function () {
 // unsafe characters that are silently deleted by one or more browsers
         cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,
 // token
-        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
+        tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jslint|properties|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,
 // html token
         hx = /^\s*(['"=>\/&#]|<(?:\/|\!(?:--)?)?|[a-zA-Z][a-zA-Z0-9_\-:]*|[0-9]+|--)/,
 // characters in strings that need escapement
@@ -1193,6 +1213,19 @@ var JSLINT = (function () {
 
 // Provide critical ES5 functions to ES3.
 
+    if (typeof Array.prototype.filter !== 'function') {
+        Array.prototype.filter = function (f) {
+            var i, length = this.length, result = [];
+            for (i = 0; i < length; i += 1) {
+                try {
+                    result.push(f(this[i]));
+                } catch (ignore) {
+                }
+            }
+            return result;
+        };
+    }
+
     if (typeof Array.isArray !== 'function') {
         Array.isArray = function (o) {
             return Object.prototype.toString.apply(o) === '[object Array]';
@@ -1375,6 +1408,16 @@ var JSLINT = (function () {
         }
     }
 
+    function aint(it, name, expected) {
+
+        if (it[name] !== expected) {
+            warn(bundle.expected_a_b, it, expected, it[name]);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
 
 
 // lexical analysis and token construction
@@ -1384,7 +1427,7 @@ var JSLINT = (function () {
 
 // Private lex methods
 
-        function collect_comment(comment) {
+        function collect_comment(comment, quote,  at) {
             if (older_token.line !== line) {
                 if (comments) {
                     comments.push(comment);
@@ -1537,15 +1580,7 @@ var JSLINT = (function () {
                 function string(x) {
                     var c, j, r = '';
 
-                    if (json_mode && x !== '"') {
-                        warn_at(bundle.expected_a, line, character, '"');
-                    }
-
-                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
-                        return it('(punctuator)', x);
-                    }
-
-                    function esc(n) {
+                    function hex(n) {
                         var i = parseInt(source_row.substr(j + 1, n), 16);
                         j += n;
                         if (i >= 32 && i <= 126 &&
@@ -1555,6 +1590,15 @@ var JSLINT = (function () {
                         character += n;
                         c = String.fromCharCode(i);
                     }
+
+                    if (json_mode && x !== '"') {
+                        warn_at(bundle.expected_a, line, character, '"');
+                    }
+
+                    if (xquote === x || (xmode === 'scriptstring' && !xquote)) {
+                        return it('(punctuator)', x);
+                    }
+
                     j = 0;
                     for (;;) {
                         while (j >= source_row.length) {
@@ -1631,7 +1675,7 @@ var JSLINT = (function () {
                                     c = '\t';
                                     break;
                                 case 'u':
-                                    esc(4);
+                                    hex(4);
                                     break;
                                 case 'v':
                                     if (json_mode) {
@@ -1643,7 +1687,7 @@ var JSLINT = (function () {
                                     if (json_mode) {
                                         warn_at(bundle.unexpected_a, line, character, '\\x');
                                     }
-                                    esc(2);
+                                    hex(2);
                                     break;
                                 default:
                                     warn_at(bundle.unexpected_a, line, character, '\\');
@@ -2191,7 +2235,10 @@ klass:                                  do {
         }
         funct[t] = type;
         if (funct['(global)']) {
-            global[t] = funct;
+            if (global[t] === false) {
+                warn(bundle.read_only);
+            }
+            global[t] = true;
             if (Object.prototype.hasOwnProperty.call(implied, t)) {
                 warn(bundle.used_before_a, nexttoken, t);
                 delete implied[t];
@@ -2202,31 +2249,6 @@ klass:                                  do {
     }
 
 
-    function discard() {
-
-// The token will not be included in the parse tree, so move the comments
-// that are attached to the token to tokens that are in the tree.
-
-        if (token.comments) {
-            nexttoken.comments = nexttoken.comments ?
-                nexttoken.comments.concat(token.comments) :
-                token.comments;
-        }
-        if (token.postcomments) {
-            var prev = prevtoken;
-            while (prev.postcomments === null) {
-                prev = prev.prev;
-            }
-            if (prev.postcomments) {
-                prev.comments = prev.postcomments.concat(token.postcomments);
-            } else {
-                prev.postcomments = token.postcomments;
-            }
-            token.postcomments = null;
-        }
-    }
-
-
     function peek(distance) {
 
 // Peek ahead to a future token. The distance is how far ahead to look. The
@@ -2246,6 +2268,35 @@ klass:                                  do {
     }
 
 
+    function discard(it) {
+
+// The token will not be included in the parse tree, so move the comments
+// that are attached to the token to tokens that are in the tree.
+
+        var next, prev;
+        it = it || token;
+        if (it.postcomments) {
+            next = it.next || peek();
+            next.comments = next.comments ?
+                next.comments.concat(it.postcomments) :
+                it.postcomments;
+        }
+        if (it.comments) {
+            prev = it.prev;
+            while (prev.postcomments === null) {
+                prev = prev.prev;
+            }
+            if (prev.postcomments) {
+                prev.postcomments = prev.postcomments.concat(it.comments);
+            } else {
+                prev.postcomments = it.comments;
+            }
+        }
+        it.comments = null;
+        it.postcomments = null;
+    }
+
+
     function advance(id, match) {
 
 // Produce the next token, also looking for programming errors.
@@ -2340,14 +2391,15 @@ klass:                                  do {
         prevtoken = token;
         token = nexttoken;
         nexttoken = lookahead.shift() || lex.token();
+        if (token.id === '(end)') {
+            discard();
+        }
     }
 
 
-    function do_option() {
+    function directive() {
         var command = this.id,
-            filter,
             name,
-            object,
             old_comments_off = comments_off,
             old_option_white = option.white,
             value;
@@ -2357,26 +2409,23 @@ klass:                                  do {
             warn(bundle.unexpected_a, this);
         }
         switch (command) {
+        case '/*properties':
         case '/*members':
         case '/*member':
-            command = '/*members';
-            if (!members_only) {
-                members_only = {};
+            command = '/*properties';
+            if (!properties) {
+                properties = {};
             }
-            object = members_only;
             break;
         case '/*jslint':
             if (option.safe) {
                 warn(bundle.adsafe_a, this);
             }
-            filter = bool_options;
-            object = option;
             break;
         case '/*global':
             if (option.safe) {
                 warn(bundle.adsafe_a, this);
             }
-            object = predefined;
             break;
         default:
             fail("What?");
@@ -2394,61 +2443,102 @@ loop:   for (;;) {
             if (nexttoken.arity !== 'string' && !nexttoken.identifier) {
                 fail(bundle.unexpected_a, nexttoken);
             }
-            name = nexttoken;
+            name = nexttoken.value;
             advance();
-            if (nexttoken.id === ':') {
-                advance(':');
-                if (object === members_only) {
-                    fail(bundle.expected_a_b, name, '*/', ':');
+            switch (command) {
+            case '/*global':
+                if (nexttoken.id === ':') {
+                    advance(':');
+                    switch (nexttoken.id) {
+                    case 'true':
+                        if (typeof scope[name] === 'object' ||
+                                global[name] === false) {
+                            fail(bundle.unexpected_a);
+                        }
+                        global[name] = true;
+                        advance('true');
+                        break;
+                    case 'false':
+                        if (typeof scope[name] === 'object') {
+                            fail(bundle.unexpected_a);
+                        }
+                        global[name] = false;
+                        advance('false');
+                        break;
+                    default:
+                        fail(bundle.unexpected_a);
+                    }
+                } else {
+                    if (typeof scope[name] === 'object') {
+                        fail(bundle.unexpected_a);
+                    }
+                    global[name] = false;
                 }
-                if (name.value === 'indent' && command === '/*jslint') {
+                break;
+            case '/*jslint':
+                if (nexttoken.id !== ':') {
+                    fail(bundle.expected_a_b, nexttoken, ':', nexttoken.value);
+                }
+                advance(':');
+                switch (name) {
+                case 'indent':
                     value = +nexttoken.value;
-                    if (typeof value !== 'number' || !isFinite(value) || value < 0 ||
+                    if (typeof value !== 'number' ||
+                            !isFinite(value) || value < 0 ||
                             Math.floor(value) !== value) {
                         fail(bundle.expected_small_a);
                     }
                     if (value > 0) {
                         old_option_white = true;
                     }
-                    object.indent = value;
-                } else if (name.value === 'maxerr' && command === '/*jslint') {
+                    option.indent = value;
+                    break;
+                case 'maxerr':
                     value = +nexttoken.value;
-                    if (typeof value !== 'number' || !isFinite(value) || value <= 0 ||
+                    if (typeof value !== 'number' ||
+                            !isFinite(value) ||
+                            value <= 0 ||
                             Math.floor(value) !== value) {
                         fail(bundle.expected_small_a, nexttoken);
                     }
-                    object.maxerr = value;
-                } else if (name.value === 'maxlen' && command === '/*jslint') {
+                    option.maxerr = value;
+                    break;
+                case 'maxlen':
                     value = +nexttoken.value;
                     if (typeof value !== 'number' || !isFinite(value) || value < 0 ||
                             Math.floor(value) !== value) {
                         fail(bundle.expected_small_a);
                     }
-                    object.maxlen = value;
-                } else if (nexttoken.id === 'true') {
-                    if (name.value === 'white' && command === '/*jslint') {
-                        old_option_white = object.white = true;
+                    option.maxlen = value;
+                    break;
+                case 'white':
+                    if (nexttoken.id === 'true') {
+                        old_option_white = true;
+                    } else if (nexttoken.id === 'false') {
+                        old_option_white = false;
                     } else {
-                        object[name.value] = true;
+                        fail(bundle.unexpected_a);
                     }
-                } else if (nexttoken.id === 'false') {
-                    if (name.value === 'white' && command === '/*jslint') {
-                        old_option_white = object.white = false;
+                    break;
+                default:
+                    if (nexttoken.id === 'true') {
+                        option[name] = true;
+                    } else if (nexttoken.id === 'false') {
+                        option[name] = false;
                     } else {
-                        object[name.value] = false;
+                        fail(bundle.unexpected_a);
                     }
-                } else {
-                    fail(bundle.unexpected_a);
                 }
                 advance();
-            } else {
-                if (command === '/*jslint') {
-                    fail(bundle.missing_option, nexttoken);
-                }
-                object[name.value] = false;
+                break;
+            case '/*properties':
+                properties[name] = true;
+                break;
+            default:
+                fail(bundle.unexpected_a);
             }
         }
-        if (filter) {
+        if (command === '/*jslint') {
             assume();
         }
         comments_off = old_comments_off;
@@ -2735,6 +2825,11 @@ loop:   for (;;) {
     }
 
 
+    function postscript(x) {
+        x.postscript = true;
+        return x;
+    }
+
     function ultimate(s) {
         var x = symbol(s, 0);
         x.from = 1;
@@ -2742,7 +2837,7 @@ loop:   for (;;) {
         x.line = 0;
         x.edge = true;
         s.value = s;
-        return x;
+        return postscript(x);
     }
 
 
@@ -2934,8 +3029,7 @@ loop:   for (;;) {
                 warn(bundle.unexpected_a, that);
             }
             that.first = left;
-            if (predefined[left.value] === false &&
-                    scope[left.value]['(global)'] === true) {
+            if (funct[left.value] === false) {
                 warn(bundle.read_only, left);
             } else if (left['function']) {
                 warn(bundle.a_function, left);
@@ -3057,7 +3151,9 @@ loop:   for (;;) {
             edge('label');
             label = nexttoken;
             advance();
+            discard();
             advance(':');
+            discard();
             scope = Object.create(old_scope);
             add_label(label.value, 'label');
             if (nexttoken.labeled !== true) {
@@ -3113,70 +3209,13 @@ loop:   for (;;) {
     }
 
 
-    function statements(begin) {
-        var adsafe_function, adsafe_params, array = [], disruptor, the_statement;
-        if (option.adsafe) {
-            switch (begin) {
-            case 'script':
-
-// JSLint is also the static analyzer for ADsafe. See www.ADsafe.org.
-
-                if (!adsafe_may) {
-                    if (nexttoken.value !== 'ADSAFE' || peek(0).id !== '.' ||
-                            (peek(1).value !== 'id' && peek(1).value !== 'go')) {
-                        fail(bundle.adsafe_id_go);
-                    }
-                }
-                if (nexttoken.value === 'ADSAFE' && peek(0).id === '.' &&
-                        peek(1).value === 'id') {
-                    if (adsafe_may) {
-                        fail(bundle.adsafe, nexttoken);
-                    }
-                    advance('ADSAFE');
-                    advance('.');
-                    advance('id');
-                    advance('(');
-                    if (nexttoken.value !== adsafe_id) {
-                        fail(bundle.adsafe_id, nexttoken);
-                    }
-                    advance('(string)');
-                    advance(')');
-                    semicolon();
-                    adsafe_may = true;
-                }
-                break;
-            case 'lib':
-                if (nexttoken.value === 'ADSAFE') {
-                    advance('ADSAFE');
-                    advance('.');
-                    advance('lib');
-                    advance('(');
-                    advance('(string)');
-                    comma();
-                    adsafe_function = expression(0);
-                    if (adsafe_function.id !== 'function') {
-                        fail(bundle.adsafe_lib_second, adsafe_function);
-                    }
-                    adsafe_params = adsafe_function.funct['(params)'];
-                    adsafe_params = adsafe_params && adsafe_params.join(', ');
-                    if (adsafe_params && adsafe_params !== 'lib') {
-                        fail(bundle.expected_a_b, adsafe_function, '(lib)',
-                            '(' + adsafe_params + ')');
-                    }
-                    advance(')');
-                    semicolon();
-                    return array;
-                } else {
-                    fail(bundle.adsafe_lib);
-                }
-                break;
-            }
-        }
+    function statements() {
+        var array = [], disruptor, the_statement;
 
 // A disrupt statement may not be followed by any other statement.
 // If the last statement is disrupt, then the sequence is disrupt.
 
-        while (postscript[nexttoken.id] !== true) {
+        while (nexttoken.postscript !== true) {
             if (nexttoken.id === ';') {
                 warn(bundle.unexpected_a, nexttoken);
                 semicolon();
@@ -3244,7 +3283,7 @@ loop:   for (;;) {
 
 
     function tally_member(name) {
-        if (members_only && typeof members_only[name] !== 'boolean') {
+        if (properties && typeof properties[name] !== 'boolean') {
             warn(bundle.unexpected_member_a, token, name);
         }
         if (typeof member[name] === 'number') {
@@ -3276,41 +3315,35 @@ loop:   for (;;) {
         lbp: 0,
         identifier: true,
         nud: function () {
-            var v = this.value,
-                s = scope[v],
-                f;
-            if (typeof s === 'function') {
-
-// Protection against accidental inheritance.
-
-                s = undefined;
-            } else if (typeof s === 'boolean') {
-                f = funct;
-                funct = functions[0];
-                add_label(v, 'var');
-                s = funct;
-                funct = f;
+            var variable = this.value,
+                site = scope[variable];
+            if (typeof site === 'function') {
+                site = undefined;
             }
 
 // The name is in scope and defined in the current function.
 
-            if (funct === s) {
+            if (funct === site) {
 
 //      Change 'unused' to 'var', and reject labels.
 
-                switch (funct[v]) {
+                switch (funct[variable]) {
+                case 'error':
+                    warn(bundle.unexpected_a, token);
+                    funct[variable] = 'var';
+                    break;
                 case 'unused':
-                    funct[v] = 'var';
+                    funct[variable] = 'var';
                     break;
                 case 'unction':
-                    funct[v] = 'function';
+                    funct[variable] = 'function';
                     this['function'] = true;
                     break;
                 case 'function':
                     this['function'] = true;
                     break;
                 case 'label':
-                    warn(bundle.a_label, token, v);
+                    warn(bundle.a_label, token, variable);
                     break;
                 }
 
@@ -3318,64 +3351,71 @@ loop:   for (;;) {
 // then we have an undefined variable.
 
             } else if (funct['(global)']) {
-                if (option.undef && typeof predefined[v] !== 'boolean') {
-                    warn(bundle.a_not_defined, token, v);
+                if (typeof global[variable] === 'boolean') {
+                    funct[variable] = global[variable];
+                } else {
+                    if (option.undef) {
+                        warn(bundle.a_not_defined, token, variable);
+                    } else {
+                        note_implied(token);
+                    }
                 }
-                note_implied(token);
 
 // If the name is already defined in the current
 // function, but not as outer, then there is a scope error.
 
             } else {
-                switch (funct[v]) {
+                switch (funct[variable]) {
                 case 'closure':
                 case 'function':
                 case 'var':
                 case 'unused':
-                    warn(bundle.a_scope, token, v);
+                    warn(bundle.a_scope, token, variable);
                     break;
                 case 'label':
-                    warn(bundle.a_label, token, v);
+                    warn(bundle.a_label, token, variable);
                     break;
                 case 'outer':
-                case 'global':
+                case true:
+                case false:
                     break;
                 default:
 
 // If the name is defined in an outer function, make an outer entry, and if
 // it was unused, make it var.
 
-                    if (s === true) {
-                        funct[v] = true;
-                    } else if (s === null) {
-                        warn(bundle.a_not_allowed, token, v);
+                    if (typeof site === 'boolean') {
+                        funct[variable] = site;
+                        functions[0][variable] = true;
+                    } else if (site === null) {
+                        warn(bundle.a_not_allowed, token, variable);
                         note_implied(token);
-                    } else if (typeof s !== 'object') {
+                    } else if (typeof site !== 'object') {
                         if (option.undef) {
-                            warn(bundle.a_not_defined, token, v);
+                            warn(bundle.a_not_defined, token, variable);
                         } else {
-                            funct[v] = true;
+                            funct[variable] = true;
                         }
                         note_implied(token);
                     } else {
-                        switch (s[v]) {
+                        switch (site[variable]) {
                         case 'function':
                         case 'unction':
                             this['function'] = true;
-                            s[v] = 'closure';
-                            funct[v] = s['(global)'] ? 'global' : 'outer';
+                            site[variable] = 'closure';
+                            funct[variable] = site['(global)'] ? false : 'outer';
                             break;
                         case 'var':
                         case 'unused':
-                            s[v] = 'closure';
-                            funct[v] = s['(global)'] ? 'global' : 'outer';
+                            site[variable] = 'closure';
+                            funct[variable] = site['(global)'] ? true : 'outer';
                             break;
                         case 'closure':
                         case 'parameter':
-                            funct[v] = s['(global)'] ? 'global' : 'outer';
+                            funct[variable] = site['(global)'] ? true : 'outer';
                             break;
                         case 'label':
-                            warn(bundle.a_label, token, v);
+                            warn(bundle.a_label, token, variable);
                             break;
                         }
                     }
@@ -3399,15 +3439,15 @@ loop:   for (;;) {
     ultimate('(begin)');
     ultimate('(end)');
     ultimate('(error)');
-    delim('</');
+    postscript(delim('</'));
     delim('<!');
     delim('<!--');
     delim('-->');
-    delim('}');
+    postscript(delim('}'));
     delim(')');
     delim(']');
-    delim('"');
-    delim('\'');
+    postscript(delim('"'));
+    postscript(delim('\''));
     delim(';');
     delim(':');
     delim(',');
@@ -3415,9 +3455,9 @@ loop:   for (;;) {
     delim('@');
     delim('*/');
     reserve('else');
-    reserve('case');
+    postscript(reserve('case'));
     reserve('catch');
-    reserve('default');
+    postscript(reserve('default'));
     reserve('finally');
     reservevar('arguments', function (x) {
         if (strict_mode && funct['(global)']) {
@@ -3464,6 +3504,7 @@ loop:   for (;;) {
         that.second = expression(0);
         spaces();
         advance(':');
+        discard();
         spaces();
         that.third = expression(10);
         that.arity = 'ternary';
@@ -3542,12 +3583,14 @@ loop:   for (;;) {
             }
         }
         if (left.arity === right.arity &&
-                (left.arity === 'string' && left.arity === 'number')) {
+                (left.arity === 'string' || left.arity === 'number')) {
             left.value += right.value;
             left.thru = right.thru;
             if (left.arity === 'string' && jx.test(left.value)) {
                 warn(bundle.url, left);
             }
+            discard(right);
+            discard(that);
             return left;
         }
         that.first = left;
@@ -3578,6 +3621,8 @@ loop:   for (;;) {
         if (left.arity === right.arity && left.arity === 'number') {
             left.value -= right.value;
             left.thru = right.thru;
+            discard(right);
+            discard(that);
             return left;
         }
         that.first = left;
@@ -3608,6 +3653,8 @@ loop:   for (;;) {
         if (left.arity === right.arity && left.arity === 'number') {
             left.value *= right.value;
             left.thru = right.thru;
+            discard(right);
+            discard(that);
             return left;
         }
         that.first = left;
@@ -3625,6 +3672,8 @@ loop:   for (;;) {
         if (left.arity === right.arity && left.arity === 'number') {
             left.value /= right.value;
             left.thru = right.thru;
+            discard(right);
+            discard(that);
             return left;
         }
         that.first = left;
@@ -3642,6 +3691,8 @@ loop:   for (;;) {
         if (left.arity === right.arity && left.arity === 'number') {
             left.value %= right.value;
             left.thru = right.thru;
+            discard(right);
+            discard(that);
             return left;
         }
         that.first = left;
@@ -3717,6 +3768,7 @@ loop:   for (;;) {
                             warn(bundle.use_array, token);
                         }
                         advance(')', p);
+                        discard();
                         return p;
                     }
                     warn(bundle.use_array, token);
@@ -3867,7 +3919,7 @@ loop:   for (;;) {
                 (m === 'write' || m === 'writeln')) {
             warn(bundle.write_is_wrong, left);
         } else if (option.adsafe) {
-            if (left && left.value === 'ADSAFE') {
+            if (!adsafe_top && left.value === 'ADSAFE') {
                 if (m === 'id' || m === 'lib') {
                     warn(bundle.adsafe, that);
                 } else if (m === 'go') {
@@ -3883,6 +3935,7 @@ loop:   for (;;) {
                     adsafe_may = false;
                 }
             }
+            adsafe_top = false;
         }
         if (!option.evil && (m === 'eval' || m === 'execScript')) {
             warn(bundle.evil);
@@ -3962,6 +4015,7 @@ loop:   for (;;) {
             while (nexttoken.id === ',') {
                 warn(bundle.unexpected_a, nexttoken);
                 advance(',');
+                discard();
             }
             if (nexttoken.id === ']') {
                 break;
@@ -4037,8 +4091,10 @@ loop:   for (;;) {
 
 
     function do_function(func, name) {
-        var s = scope;
-        scope = Object.create(s);
+        var old_properties = properties,
+            old_option     = option,
+            old_global     = global,
+            old_scope      = scope;
         funct = {
             '(name)'     : name || '"' + anonname + '"',
             '(line)'     : nexttoken.line,
@@ -4048,6 +4104,10 @@ loop:   for (;;) {
             '(scope)'    : scope,
             '(token)'    : func
         };
+        properties  = Object.create(old_properties);
+        option      = Object.create(old_option);
+        global      = Object.create(old_global);
+        scope       = Object.create(old_scope);
         token.funct = funct;
         functions.push(funct);
         if (name) {
@@ -4057,10 +4117,11 @@ loop:   for (;;) {
         func.first = funct['(params)'] = function_params();
         one_space();
         func.block = block(false);
-
-        scope = s;
-        funct = funct['(context)'];
-        return func;
+        funct      = funct['(context)'];
+        properties = old_properties;
+        option     = old_option;
+        global     = old_global;
+        scope      = old_scope;
     }
 
 
@@ -4158,10 +4219,11 @@ loop:   for (;;) {
         return this;
     });
 
-    stmt('/*members', do_option);
-    stmt('/*member', do_option);
-    stmt('/*jslint', do_option);
-    stmt('/*global', do_option);
+    stmt('/*properties', directive);
+    stmt('/*members', directive);
+    stmt('/*member', directive);
+    stmt('/*jslint', directive);
+    stmt('/*global', directive);
 
 
 
@@ -4189,7 +4251,7 @@ loop:   for (;;) {
             if (funct['(global)'] && predefined[id] === false) {
                 warn(bundle.redefinition_a, token, id);
             }
-            add_label(id, 'unused');
+            add_label(id, 'error');
 
             if (nexttoken.id === '=') {
                 assign = nexttoken;
@@ -4209,6 +4271,7 @@ loop:   for (;;) {
             } else {
                 this.first.push(name);
             }
+            funct[id] = 'unused';
             if (nexttoken.id !== ',') {
                 break;
             }
@@ -4305,6 +4368,7 @@ loop:   for (;;) {
         if (nexttoken.id === 'catch') {
             one_space();
             advance('catch');
+            discard();
             one_space();
             t = nexttoken;
             advance('(');
@@ -4564,6 +4628,11 @@ loop:   for (;;) {
                             filter.first.first.value === the_in.second.value &&
                             filter.first.second.value === 'hasOwnProperty' &&
                             filter.second[0].value === the_in.first.value
+                        ) || (
+                            filter.first.first.value === 'ADSAFE' &&
+                            filter.first.second.value === 'has' &&
+                            filter.second[0].value === the_in.second.value &&
+                            filter.second[1].value === the_in.first.value
                         ) || (
                             filter.first.first.id === '.' &&
                             filter.first.first.first.id === '.' &&
@@ -5735,7 +5804,7 @@ loop:   for (;;) {
     }
 
     function do_tag(n, a) {
-        var i, t = html_tag[n], x;
+        var i, t = html_tag[n], script, x;
         src = false;
         if (!t) {
             fail(
@@ -5786,13 +5855,49 @@ loop:   for (;;) {
                     warn(bundle.type, token);
                 }
             } else {
-                if (adsafe_went) {
-                    fail(bundle.adsafe_script, token);
-                }
                 step_in(nexttoken.from);
                 edge();
                 use_strict();
-                statements('script');
+                adsafe_top = true;
+                script = statements();
+
+// JSLint is also the static analyzer for ADsafe. See www.ADsafe.org.
+
+                if (option.adsafe) {
+                    if (adsafe_went) {
+                        fail(bundle.adsafe_script, token);
+                    }
+                    if (script.length !== 1 ||
+                            aint(script[0],             'id',    '(') ||
+                            aint(script[0].first,       'id',    '.') ||
+                            aint(script[0].first.first, 'value', 'ADSAFE') ||
+                            aint(script[0].second[0],   'value', adsafe_id)) {
+                        fail(bundle.adsafe_id_go);
+                    }
+                    switch (script[0].first.second.value) {
+                    case 'id':
+                        if (adsafe_may || script[0].second.length !== 1) {
+                            fail(bundle.adsafe_id, nexttoken);
+                        }
+                        adsafe_may = true;
+                        break;
+                    case 'go':
+                        if (!adsafe_may) {
+                            fail(bundle.adsafe_id);
+                        }
+                        if (script[0].second.length !== 2 ||
+                                aint(script[0].second[1], 'id', 'function') ||
+                                script[0].second[1].first.length !== 2 ||
+                                aint(script[0].second[1].first[0], 'value', 'dom') ||
+                                aint(script[0].second[1].first[1], 'value', 'lib')) {
+                            fail(bundle.adsafe_go, nexttoken);
+                        }
+                        adsafe_went = true;
+                        break;
+                    default:
+                        fail(bundle.adsafe_id_go);
+                    }
+                }
                 indent = null;
             }
             xmode = 'html';
@@ -5936,7 +6041,7 @@ loop:   for (;;) {
                         option.white = false;
                         advance(q);
                         use_strict();
-                        statements('on');
+                        statements();
                         option.white = wmode;
                         if (nexttoken.id !== q) {
                             fail(bundle.expected_a_b, nexttoken, q, nexttoken.value);
@@ -6094,12 +6199,12 @@ loop:   for (;;) {
                     option.forin   =
                     option.on      =
                     option.rhino   =
-                    option.windows =
                     option.sub     =
-                    option.widget  = false;
+                    option.widget  =
+                    option.windows = false;
 
                 option.nomen       =
-                    option.safe    =
+                    option.strict  =
                     option.undef   = true;
 
                 predefined.Date         =
@@ -6116,8 +6221,7 @@ loop:   for (;;) {
         option.indent = +option.indent || 0;
         option.maxerr = option.maxerr || 50;
         adsafe_id = '';
-        adsafe_may = false;
-        adsafe_went = false;
+        adsafe_may = adsafe_top = adsafe_went = false;
         approved = {};
         if (option.approved) {
             for (i = 0; i < option.approved.length; i += 1) {
@@ -6149,7 +6253,7 @@ loop:   for (;;) {
         json_mode = false;
         lookahead = [];
         member = {};
-        members_only = null;
+        properties = null;
         prereg = true;
         src = false;
         stack = null;
@@ -6219,7 +6323,18 @@ loop:   for (;;) {
                         warn(bundle.function_strict);
                         use_strict();
                     }
-                    JSLINT.tree = statements('lib');
+                    adsafe_top = true;
+                    JSLINT.tree = statements();
+                    if (option.adsafe && (JSLINT.tree.length !== 1 ||
+                            aint(JSLINT.tree[0], 'id', '(') ||
+                            aint(JSLINT.tree[0].first, 'id', '.') ||
+                            aint(JSLINT.tree[0].first.first, 'value', 'ADSAFE') ||
+                            aint(JSLINT.tree[0].first.second, 'value', 'lib') ||
+                            JSLINT.tree[0].second.length !== 2 ||
+                            JSLINT.tree[0].second[0].arity !== 'string' ||
+                            aint(JSLINT.tree[0].second[1], 'id', 'function'))) {
+                        fail(bundle.adsafe_lib);
+                    }
                     if (JSLINT.tree.disrupt) {
                         warn(bundle.weird_program, prevtoken);
                     }
@@ -6249,11 +6364,11 @@ loop:   for (;;) {
             i,
             implieds = [],
             j,
+            kind,
             members = [],
             name,
             the_function,
-            unused = [],
-            variable;
+            unused = [];
         if (itself.errors.length) {
             data.errors = itself.errors;
         }
@@ -6278,7 +6393,9 @@ loop:   for (;;) {
             data.urls = urls;
         }
 
-        globals = Object.keys(scope);
+        globals = Object.keys(functions[0]).filter(function (value) {
+            return value.charAt(0) !== '(' ? value : undefined;
+        });
         if (globals.length > 0) {
             data.globals = globals;
         }
@@ -6292,13 +6409,15 @@ loop:   for (;;) {
             for (name in the_function) {
                 if (Object.prototype.hasOwnProperty.call(the_function, name)) {
                     if (name.charAt(0) !== '(') {
-                        variable = the_function[name];
-                        if (variable === 'unction') {
-                            variable = 'unused';
+                        kind = the_function[name];
+                        if (kind === 'unction') {
+                            kind = 'unused';
+                        } else if (typeof kind === 'boolean') {
+                            kind = 'global';
                         }
-                        if (Array.isArray(function_data[variable])) {
-                            function_data[variable].push(name);
-                            if (variable === 'unused') {
+                        if (Array.isArray(function_data[kind])) {
+                            function_data[kind].push(name);
+                            if (kind === 'unused') {
                                 unused.push({
                                     name: name,
                                     line: the_function['(line)'],
@@ -6335,7 +6454,8 @@ loop:   for (;;) {
         return data;
     };
 
-    itself.report = function (option) {
+
+    itself.report = function (errors_only) {
         var data = itself.data();
 
         var err, evidence, i, j, key, keys, length, mem = '', name, names,
@@ -6399,7 +6519,7 @@ loop:   for (;;) {
             output.push('</div>');
         }
 
-        if (!option) {
+        if (!errors_only) {
 
             output.push('<br><div id=functions>');
 
@@ -6441,8 +6561,8 @@ loop:   for (;;) {
                 keys = Object.keys(data.member);
                 if (keys.length) {
                     keys = keys.sort();
-                    mem = '<br><pre id=members>/*members ';
-                    length = 10;
+                    mem = '<br><pre id=properties>/*properties ';
+                    length = 13;
                     for (i = 0; i < keys.length; i += 1) {
                         key = keys[i];
                         name = key.name();
@@ -6469,7 +6589,7 @@ loop:   for (;;) {
     };
     itself.jslint = itself;
 
-    itself.edition = '2011-02-24';
+    itself.edition = '2011-03-05';
 
     return itself;
 
-- 
GitLab