function xul() {
  gExtensionsView.controllers = {
    appendController: function () {
      document.getElementById('generated').innerHTML = "hi";
    }
  }
  function stringbundle_getString(aStringKey) {
    try {
      return this.stringBundle.GetStringFromName(aStringKey);
    }
    catch (e) {
      dump("*** Failed to get string " + aStringKey + " in bundle: " + this.src + "\n");
      throw e;
    }
  }
  function stringbundle_getFormattedString(aStringKey, aStringsArray) {
    try {
      return this.stringBundle.formatStringFromName(aStringKey, aStringsArray, aStringsArray.length);
    }
    catch (e) {
      dump("*** Failed to format string " + aStringKey + " in bundle: " + this.src + "\n");
      throw e;
    }
  }

  function get_stringbundle_src() {
    return this.getAttribute("src");
  }
  function set_stringbundle_src() {
    this.setAttribute("src", val);
    refreshStringBundle();
    return val;
  }
  function get_stringbundle_appLocale() {
    try {
      return gLocaleService.getApplicationLocale();
    }
    catch (ex) {
      return null;
    }
  }
  function get_stringbundle_strings() {
    return this.stringBundle.getSimpleEnumeration();
  }
  function attachStringBundle(node) {
    node.getString = stringbundle_getString;
    node.getFormattedString = stringbundle_getFormattedString;
    node.__defineGetter__("src", get_stringbundle_src);
    node.__defineSetter__("src", set_stringbundle_src);
    node.__defineGetter__("appLocale", get_stringbundle_appLocale);
    node.__defineGetter__("strings", get_stringbundle_strings);
    function refreshStringBundle() {
      node.stringBundle = gStringBundleService.createBundle(node.src, node.appLocale);
    }
    refreshStringBundle(node);
  }
  function get_notificationbox_notificationsHidden() {
    return this.getAttribute('notificationshidden') == 'true';
  }
  function set_notificationbox_notificationsHidden(val) {
    if (val)
      this.setAttribute('notificationshidden', true);
    else this.removeAttribute('notificationshidden');
    return val;
  }
  function get_notificationbox_allNotifications() {
    return this.getElementsByTagName('notification');
  }
  function notificationbox_getNotificationWithValue(aValue) {
    var notifications = this.allNotifications;
    for (var n = notifications.length - 1; n >= 0; n--) {
      if (aValue == notifications[n].value)
        return notifications[n];
    }
    return null;
  }
  function notificationbox_appendNotification(aLabel, aValue, aImage, aPriority, aButtons) {
    if (aPriority < this.PRIORITY_INFO_LOW ||
        aPriority > this.PRIORITY_CRITICAL_BLOCK)
      throw "Invalid notification priority " + aPriority;

    // check for where the notification should be inserted according to
    // priority. If two are equal, the existing one appears on top.
    var notifications = this.allNotifications;
    var insertPos = null;
    for (var n = notifications.length - 1; n >= 0; n--) {
      if (notifications[n].priority < aPriority)
        break;
      insertPos = notifications[n];
    }

    const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    var newitem = document.createElementNS(XULNS, "notification");
    newitem.setAttribute("label", aLabel);
    newitem.setAttribute("value", aValue);
    newitem.setAttribute("image", aImage);
    if (!insertPos) {
      newitem.style.position = "fixed";
      newitem.style.top = "100%";
    }
    this.insertBefore(newitem, insertPos);

    if (aButtons) {
      for (var b = 0; b < aButtons.length; b++) {
        var button = aButtons[b];
        var buttonElem = document.createElementNS(XULNS, "button");
        buttonElem.setAttribute("label", button.label);
        buttonElem.setAttribute("accesskey", button.accessKey);

        newitem.appendChild(buttonElem);
        buttonElem.buttonInfo = button;
      }
    }

    newitem.priority = aPriority;
    if (aPriority >= this.PRIORITY_CRITICAL_LOW)
      newitem.type = "critical";
    else if (aPriority <= this.PRIORITY_INFO_HIGH)
      newitem.type = "info";
    else
      newitem.type = "warning";

    if (!insertPos)
      this._showNotification(newitem, true);

    // Fire event for accessibility APIs
    var event = document.createEvent("Events");
    event.initEvent("AlertActive", true, true);
    newitem.dispatchEvent(event);

    return newitem;
  }
  function notificationbox_removeNotification(aItem) {
    if (aItem == this.currentNotification)
      this.removeCurrentNotification();
    else
      this.removeChild(aItem);
    return aItem;
  }
  function notificationbox_removeCurrentNotification() {
    this._showNotification(this.currentNotification, false);
    return null;
  }
  function notificationbox_removeAllNotifications(aImmediate) {
    var notifications = this.allNotifications;
    for (var n = notifications.length - 1; n >= 0; n--) {
      if (aImmediate)
        this.removeChild(notifications[n]);
      else
        this.removeNotification(notifications[n]);
    }
    this.currentNotification = null;
  }
  function notificationbox__showNotification(aNotification, aSlideIn) {
    if (this._timer) {
      clearInterval(this._timer);
      if (this.currentNotification) {
        this.currentNotification.style.marginTop = "0px";
        this.currentNotification.style.opacity = 1;
      }
      if (this._closedNotification)
        this._closedNotification.parentNode.
          removeChild(this._closedNotification);
      this._SetBlockingState(this.currentNotification);
    }

    var height = aNotification.boxObject.height;
    var change = height / this.slideSteps;
    if (aSlideIn) {
      if (this.currentNotification &&
          this.currentNotification.boxObject.height > height)
        height = this.currentNotification.boxObject.height;

      this.currentNotification = aNotification;
      this._closedNotification = null;
      aNotification.style.removeProperty("position");
      aNotification.style.removeProperty("top");
      aNotification.style.marginTop = -height + "px";
      aNotification.style.opacity = 0;
    }
    else {
      change = -change;
      this._closedNotification = aNotification;
      var notifications = this.allNotifications;
      var idx = notifications.length - 2;
      if (idx >= 0)
        this.currentNotification = notifications[idx];
      else
        this.currentNotification = null;
    }
    var opacitychange = change / height;

    var self = this;
    var slide = function slideInFn()
    {
      var done = false;

      var style = window.getComputedStyle(aNotification, null);
      var margin = style.getPropertyCSSValue("margin-top").
                     getFloatValue(CSSPrimitiveValue.CSS_PX);

      if (change > 0 && margin + change >= 0) {
        aNotification.style.marginTop = "0px";
        aNotification.style.opacity = 1;
        done = true;
      }
      else if (change < 0 && margin + change <= -height) {
        aNotification.style.marginTop = -height + "px";
        done = true;
      }
      else {
        aNotification.style.marginTop = (margin + change).toFixed(4) + "px";
        if (opacitychange)
          aNotification.style.opacity =
            Number(aNotification.style.opacity) + opacitychange;
      }

      if (done) {
        clearInterval(self._timer);
        self._timer = null;
        if (self._closedNotification)
          self._closedNotification.parentNode.
            removeChild(self._closedNotification);
        self._setBlockingState(self.currentNotification);
      }
    }

    this._timer = setInterval(slide, 50);
  }
  function notificationbox__setBlockingState(aNotification) {
    var isblock = aNotification &&
                  aNotification.priority == this.PRIORITY_CRITICAL_BLOCK;
    var canvas = this._blockingCanvas;
    if (isblock) {
      if (!canvas)
        canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
      const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
      var content = this.firstChild;
      if (!content ||
           content.namespaceURI != XULNS ||
           content.localName != "browser")
        return;

      var width = content.boxObject.width;
      var height = content.boxObject.height;
      content.collapsed = true;

      canvas.setAttribute("width", width);
      canvas.setAttribute("height", height);
      canvas.setAttribute("flex", "1");

      this.appendChild(canvas);
      this._blockingCanvas = canvas;

      var bgcolor = "white";
      try {
        var prefService = Components.classes["@mozilla.org/preferences-service;1"].
                            getService(nsIPrefBranch);
        bgcolor = prefService.getCharPref("browser.display.background_color");

        var win = content.contentWindow;
        var context = canvas.getContext("2d");
        context.globalAlpha = 0.5;
        context.drawWindow(win, win.scrollX, win.scrollY,
                           width, height, bgcolor);
      }
      catch(ex) { };
    }
    else if (canvas) {
      canvas.parentNode.removeChild(canvas);
      this._blockingCanvas = null;
      var content = this.firstChild;
      if (content)
        content.collapsed = false;
    }
  }
  function attachNotificationBindings(node) {
    node.PRIORITY_INFO_LOW = 1;
    node.PRIORITY_INFO_MEDIUM = 2;
    node.PRIORITY_INFO_HIGH = 3;
    node.PRIORITY_WARNING_LOW = 4;
    node.PRIORITY_WARNING_MEDIUM = 5;
    node.PRIORITY_WARNING_HIGH = 6;
    node.PRIORITY_CRITICAL_LOW = 7;
    node.PRIORITY_CRITICAL_MEDIUM = 8;
    node.PRIORITY_CRITICAL_HIGH = 9;
    node.PRIORITY_CRITICAL_BLOCK = 10;
    node.currentNotification = null;
    node.slideSteps = 4;
    node._timer = null;
    node._closedNotification = null;
    node._blockingCanvas = null;
    node.__defineGetter__("notificationsHidden", get_notificationbox_notificationsHidden);
    node.__defineSetter__("notificationsHidden", set_notificationbox_notificationsHidden);
    node.__defineGetter__("allNotifications", get_notificationbox_allNotifications);
    node.getNotificationWithValue = notificationbox_getNotificationWithValue;
    node.appendNotification = notificationbox_appendNotification;
    node.removeNotification = notificationbox_removeNotification;
    node.removeCurrentNotification = notificationbox_removeCurrentNotification;
    node.removeAllNotifications = notificationbox_removeAllNotifications;
    node._showNotification = notificationbox__showNotification;
    node._setBlockingState = notificationbox__setBlockingState;
  }
  function nsXULTemplateQueryProcessorRDF() {
    this.mDB = null;
    this.mBuilder = null;
    this.mQueryPRocessorRDFInited = false;
    this.mGenerationStarted = false;
    this.mUpdateBatchNest = 0;
    this.mSimpleRuleMemberTest = null;
  }
  nsXULTemplateQueryProcessorRDF.prototype = {
  constructor: nsXULTemplateQueryProcessorRDF,
  initGlobals: function nsXULTemplateQueryProcessorRDF_initGlobals() {
    if (!kRDF_type)
      kRDF_type = gRDFService.GetResource(RDF_NAMESPACE_URI + "type");
  },
  GetDataSource: function nsXULTemplateQueryProcessorRDF_GetDataSource(aDataSources, root, aIsTrused, aBuilder, _aShouldDelayBuilding) {
    _aShouldDelayBuilding.value = false;
    if (!root)
      throw NS_ERROR_UNEXPECTED;
    this.initGlobals();
    var compDB = Components.classes[NS_RDF_RESOURCE_CONTRACTID_PREFIX + "composite-datasource"]
                           .createInstance(nsIRDFCompositeDataSource);
    if (root.getAttribute("coalesceduplicatearcs") == "false")
      compDB.coalesceDuplicateArcs = false;
    if (root.getAttribute("allownegativeassertions") == "false")
      compDB.allowNegativeAssertions = false;
    localstore = gRDFService.GetDataSource("rdf:local-store");
    compDB.AddDataSource(localstore);
    for (var index = 0; index < aDataSources.length; index++) {
      var uri = aDataSources[index];
      if (!uri)
        continue;
      try {
        ds = gRDFService.GetDataSource(uri.spec);
        compDB.AddDataSource(ds);
      } catch (e) {
        continue;
      }
    }
    var infer;
    if ((infer = root.getAttribute("infer"))) {
      var inferCID = NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX + infer;
      try {
        var innferDB = Components.classes[inferCID].createInstance(nsIRDFInferDataSource);
        inferDB.baseDataSource = compDB;
        var db = inferDB;
      } catch (e) {}
    }
    if (!db)
      db = compDB;
    return db;
  },
  initializeForBuilding: function nsXULTemplateQueryProcessorRDF_initializeForBuilding(aDatasource, aBuilder, aRootNode) {
    if (!this.mQueryProcessorRDFInited) {
      this.initGlobals();
      if (!this.mMemoryElementToResultMap)
        this.mMemoryElementToResultMap = {};
      if (!this.mBindingDependencies)
        this.mBindingDependencies = {};
      if (!this.mRuleToBindingsMap)
        this.mRuleToBindingsMap = {};
      this.this.mQueryProcessorRDFInited = true; 
    }
    if (this.mGenerationStarted)
      throw NS_ERROR_UNEXPECTED;
    this.mDB = aDatasource;
    this.mBuilder = aBuilder;
    try {
      this.computeContainmentProperties(aRootNode);
    } catch (e) {}
    if (this.mDB)
      this.mDB.addObserver(this);
  },
  done: function nsXULTemplateQueryProcessorRDF_done() {
    if (!this.mQueryProcessorRDFInited)
      return;
    if (this.mDB)
      this.mDB.removeObserver(this);
    this.mDB = null;
    this.mBuilder = null;
    this.mRefVariable = null;
    this.mLastRef = null;
    this.mGenerationStarted = false;
    this.mUpdatedBatchNest = 0;
    this.mContainmentProperties = [];
    this.mAllTests = [];
    this.mRDFTests = [];
    this.mQueries = [];
    this.mSimpleRuleMemberTest = null;
    this.mBindingDependencies = [];
    this.mMemoryElementToResultMap = {};
    this.mRuleToBindingsMap = {};
  },
  compileQuery: function nsXULTemplateQueryProcessorRDF_compileQuery(aBuilder, aQueryNode, aRefVariable, aMemberVariable) {
    var query = new nsRDFQuery(this);
    query.mRefVariable = aRefVariable;
    if (!this.mRefVariable)
      this.mRefVariable = aRefVariable;
    if (!aMemberVariable)
      query.mMemberVariable = "?";
    else
      query.mMemberVariable = aMemberVariable;

    var lastnode = this.compileExtendedQuery(query, content);
    query.queryNode = aQueryNode;
    var instnode = new nsInstantiationNode(this, query);
    this.mAllTests.push(instnode);
    lastnode.addChild(instnode);
    this.mQueries.push(query);
    return query;
  },
  generateResults: function nsXULTemplateQueryProcessorRDF_generateResults(aDatasource, aRef, aQuery) {
    if (!aQuery)
      throw NS_ERROR_INVALID_ARG;
    this.mGenerationSTarted = true;
    if (aRef) {
      if (aRef == this.mLastRef) {
        var results = query.useCachedResults();
      } else {
        for (var r = 0; r < this.mQueries.length; r++)
          this.mQueries[r].clearCachedResults();
      }
      if (!results) {
        if (!query.mRefVariable)
          query.mRefVariable = "?uri";
        var refResource = aRef.resource;
        if (!refResource)
          throw NS_ERROR_FAILURE;
        var root = query.root;
        if (query.isSimple && this.mSimpleRuleMemberTest) {
          root = this.mSimpleRuleMemberTest.parent;
          this.mLastRef = aRef;
        }
        if (root) {
          /* migration stopped here */
        }  
      }
    }
  }
  }
  function nsXULTemplateBuilder() {
    this.mQueriesCompiled = false;
    this.mFlags = 0;
    this.mTop = null;

    this.mListeners = [];
  }
  var gRDFContainerUtils;
  var kRDF_type;
  var gScriptSecurityManager;
  var gSystemPrincipal;
  var gRefCnt = 0;
  const NS_RDF_CONTRACTID = "@mozilla.org/rdf";
  const NS_RDF_DATASOURCE_CONTRACTID = NS_RDF_CONTRACTID + "/datasource;1";
  const NS_RDF_RESOURCE_CONTRACTID_PREFIX = NS_RDF_DATASOURCE_CONTRACTID + "?name=";
  const NS_RDF_RESOURCE_FACTORY_CONTRACTID = "@mozilla.org/rdf/resource-factory;1";
  const NS_RDF_RESOURCE_FACTORY_CONTRACTID_PREFIX = NS_RDF_RESOURCE_FACTORY_CONTRACTID + "?name=";
  const NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX = NS_RDF_CONTRACTID + "/infer-datasource;1?engine=";
  const NS_RDF_SERIALIZER = NS_RDF_CONTRACTID + "/serializer;1?format=";
  const NS_QUERY_PROCESSOR_CONTRACTID_PREFIX = "@mozilla.org/xul/xul-query-processor;1?name=";
  const RDF_NAMESPACE_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  const WEB_NAMESPACE_URI = "http://home.netscape.com/WEB-rdf#";
  const NC_NAMESPACE_URI = "http://home.netscape.com/NC-rdf#";
  const DEVMO_NAMESPACE_URI_PREFIX = "http://developer.mozilla.org/rdf/vocabulary/";

  // contract ID is in the form
  // @mozilla.org/rdf/delegate-factory;1?key=<key>&scheme=<scheme>
  const NS_RDF_DELEGATEFACTORY_CONTRACTID = "@mozilla.org/rdf/delegate-factory;1";
  const NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX = NS_RDF_DELEGATEFACTORY_CONTRACTID + "?key=";
  const NS_SCRIPTSECURITYMANAGER_CONTRACTID = "@mozilla.org/scriptsecuritymanager;1";
  const kRDFServiceCID = NS_RDF_CONTRACTID + "/rdf-service;1";
  const NS_IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";

  const nsIRDFService = Components.interfaces.nsIRDFService;
  const nsIRDFContainerUtils = Components.interfaces.nsIRDFContainerUtils;
  const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
  const nsIDOMElement = Components.interfaces.nsIDOMElement; 
  const nsISupports = Components.interfaces.nsISupports;
  const nsIXULTemplateQueryProcessor = Components.interfaces.nsIXULTemplateQueryProcessor;
  const nsIIOService = Components.interfaces.nsIIOService;
  const nsIRDFInferDataSource = Components.interfaces.nsIRDFInferDataSource;
  const nsIRDFCompositeDataSource = Components.interfaces.nsIRDFCompositeDataSource;
  const nsIStringBundleService = Components.interfaces.nsIStringBundleService;
  const nsILocaleService = Components.interfaces.nsILocaleService;
  const nsIPrefBranch = Components.interfaces.nsIPrefBranch;

  const NS_ERROR_NULL_POINTER = Components.results.NS_ERROR_NULL_POINTER;
  const NS_ERROR_FAILURE = Components.results.NS_ERROR_FAILURE;
  const NS_ERROR_UNEXPECTED = Components.results.NS_ERROR_UNEXPECTED;
  const NS_ERROR_INVALID_ARG = Components.results.NS_ERROR_INVALID_ARG;

  function NS_NewURI(spec, charset, baseURI) {
    return gIOService.newURI(spec, charset, baseURI);
  }
  function NS_MakeAbsoluteURI(spec, baseURI) {
    if (!baseURI)
      return spec;
    if (!spec)
      return baseURI.spec;
    return baseURI.resolve(spec);
  }

  nsXULTemplateBuilder.prototype = {
  constructor: nsXULTemplateBuilder,
  /* [notidl] */
  initGlobals: function nsXULTemplateBuilder_InitGlobals() {
    if (gRefCnt++)
      return;
    gScriptSecurityManager = Components.classes[NS_SCRIPTSECURITYMANAGER_CONTRACTID];
    /*[noscript]*/ // gScriptSecurityManager.getSystemPrincipal();
  },
  /* [notidl] */
  uninit: function nsXULTemplateBuilder_Uninit(aIsFinal) {
    if (this.mQueryProcessor)
      this.mQueryProcessor.done();
    this.mQuerySets = null;
    this.mMatchMap = null;
    this.mRootResult = null;
    this.mRefVariable = null;
    this.mMemberVariable = null;
    this.mQueriesCompiled = null;
  },
  get root() {
    return this.mRoot.QueryInterface(nsIDOMElement);
  },
  get database() {
    return this.mCompDB;
  },
  /* [noscript] */
  get queryProcessor() {
    return this.mQueryProcessor;
  },
  rebuild: function nsXULTemplateBuilder_rebuild() {
    for (var i = this.mListeners.length - 1; i >= 0; --i)
      this.mListeners[i].willRebuild(this);
    this.rebuildAll();
    for (var i = this.mListeners.length - 1; i >= 0; --i)
      this.mListeners[i].didRebuild(this);
  },
  rebuildAll: function nsXULTreeBuild_rebuildAll() {
    if (!this.mRoot)
      throw NS_ERROR_NOT_INITIALIZED;
    var doc = this.mRoot.ownerDocument;
    if (!doc || !this.mQuerProcessor)
      return;
    if (this.mQueriesCompiled) {
      this.uninit(false);
    } else if (this.mBoxObject) {
      var count = this.mRows.length;
      this.mRows.length = 0;
      this.mBoxObject.beginUpdateBatch();
      this.mBoxObject.rowCountChanged(0, -count);
    }
    this.compileQueries();
    if (!this.mQuerySets.length)
      return;
    var ref = this.mRoot.getAttribute("ref"); 
    if (ref) {
      this.mRootResult = this.mQueryProcessor.translateRef(this.mDataSource, ref);
      if (this.mRootResult) {
        this.openContainer(-1, this.mRootResult);
        var rootResource = this.getResultResource(this.mRootResult);
        this.mRows.rootResource = rootResource;
      }
    }
    if (this.mBoxObject)
      this.mBoxObject.endBatchUpdate();
  },
  refresh: function nsXULTemplateBuilder_refresh() {
    if (!this.mCompDB)
      throw NS_ERROR_FAILURE;
    var dslist = this.mCompDB.dataSources;
    if (!dslist)
      throw NS_ERROR_FAILURE;
    try {
      while (dslist.hasMoreElements()) {
        var next = dslist.next;
        var rds;
        if (next && (rds = next.nsIRDFRemoteDataSource))
          rds.refresh(false);
      }
    } catch (e) {}
  },
  addResult: function nsXULTemplateBuilder_addResult(aResult, aQueryNode) {
    if (!aResult || !aQueryNode)
      throw NS_ERROR_NULL_POINTER;
    this.updateResult(null, aResult, aQueryNode);
  },
  removeResult: function nsXULTemplateBuilder_removeResult(aResult) {
    if (!aResult)
      throw NS_ERROR_NULL_POINTER;
    this.updateResult(aResult, null, null);
  },
  replaceResult: function nsXULTemplateBuilder_replaceResult(aOldResult, aNewResult, aQueryNode) {
    if (!aOldResult || !aNewResult || !aQueryNode)
      throw NS_ERROR_NULL_POINTER;
    this.updateResult(aOldResult, null, null);
    this.updateResult(null, aNewResult, aQueryNode);
  },
  updateResult: function nsXULTemplateBuilder_updateResult(aOldResult, aNewResult, aQueryNode) {
    var insertionPoints = { value : [] };
    var mayReplace = this.getInsertionLocations(aOldResult || aNewResult, insertionPoints);
    if (!mayReplace)
      return;
    insertionPoints = insertionPoints.value; 
    if (aOldResult) {
      var oldId = this.getResultResource(aOldResult);
      if (this.isActivated(oldId))
        return;
    }
    if (aNewResult) {
      var newId = this.getResultResource(aNewResult);
      if (!newId)
        return;
      if (this.isActivated(newId))
        return;
      var count = this.mQuerySets.length;
      var queryset;
      for (var q = 0; q < count; q++) {
        var qs = this.mQuerySets[q];
        if (qs.mQueryNode == aQueryNode) {
          queryset = qs;
          break;
        }
      }
      if (!queryset)
        return;
    }
    if (insertionPoints) {
      count = insertionPoints.length;
      for (var t = 0; t < count; t++) {
        var insertionPoint = insertionPoints[t];
        if (insertionPoint) {
          this.updateResultInContainer(aOldResult, aNewResult, queryset,
                                       oldId, newId, insertionPoint);
        }
      }
    } else {
      try {
        this.updateResultInContainer(aOldResult, aNewResult, queryset,
                                     oldId, newId, insertionPoint);
      } catch (e) {
        /* why is this code different from the other case? */
      }
    }
  },
  updateResultInContainer:  function nsXULTemplateBuilder__updateResultInContainer(aOldResult, aNewResult, aQuerySet, aOldId, aNewId, aInsertionPoint) {
    var firstmatch;
    if (aOldResult) {
      if ((firstmatch = this.mMatchMap[aOldId])) {
        var oldmatch = firstmatch;
        var prevmatch = null;
        while (oldmatch && (oldmatch.mResult != aOldResult)) {
          prevmatch = oldmatch;
          oldmatch = oldmatch.mNext;
        }
        if (oldmatch) {
          var findmatch = oldmatch.mNext;
          var nextmatch = findmatch;
          if (oldmatch.isActive()) {
            var oldMatchWasActive = true;
            while (findmatch) {
              if (findmatch.container == aInsertionPoint) {
                var qs = this.mQuerySets[findmatch.querySetPriority];
                try {
                  var _matchedrule = {value: matchedrule};
                  var _ruleindex = {value: ruleindex};
                  this.determineMatchedRule(aInsertionPoint, findmatch.mResult,
                                            qs, _matchedrule, _ruleindex);
                } catch (e) {
                  /* why ignore nsresult ? */
                } finally {
                  matchedrule = _matchedrule.value;
                  ruleindex = _ruleindex.value;
                } 
                if (matchedrule) {
                  findmatch.ruleMAtched(qs, matchedrule, ruleindex, findmatch.mResult);
                  var acceptedmatch = findmatch;
                  break;
                }
              }
              findmatch = findmatch.next;
            }
          }
          if (oldmatch == firstmatch) {
            if (oldmatch.mNext) {
              this.mMatchMap[aOldId] = oldmatch.mNext;
            } else {
              delete this.mMatchMap[aOldId];
            }
          }
          if (prevmatch)
            prevmatch.mNext = nextmatch;
          var removedmatch = oldmatch;
        }
      }
    }
    if (aNewResult) {
      var tag = aQuerySet.tag;
      if (aInsertionPoint && tag && tag != aInsertionPoint.tag)
        return;
      var findpriority = aQuerySet.priority;
      var newmatch = new nsTemplateMatch(findpriority, aNewResult, aInsertionPoint);
      if ((firstmatch = this.mMatchMap[aNewId])) {
        var hasEarlierActiveMatch = false;
        prevmatch = null;
        oldmatch = firstmatch;
        while (oldmatch) {
          var priority = oldmatch.querySetPriority;
          if (priority > findpriority) {
            oldmatch = null;
            break;
          }
          if (oldmatch.container == aInsertionPoint) {
            if (priority == findpriority)
              break;
            if (oldmatch.isActive())
              hasEarlierActiveMatch = true;
          }
          prevmatch = oldmatch;
          oldmatch = oldmatch.mNext;
        }
        if (oldmatch)
          newmatch.mNext = oldmatch.mNext;
        else if (prevmatch)
          newmatch.mNext = prevmatch.mNext;
        else
          newmattch.mNext = firstmatch;
        if (!hasEarlierActiveMatch) {
          if (oldmatch) {
            if (oldmatch.isActive())
              var replacedmatch = oldmach;
            var replacedmatchtodelete = oldmatch;
          }
          try {
            _matchedrule = {value: matchedrule};
            _ruleindex = {value: ruleindex};
            this.determineMatchedRule(aInsertionPoint, newmatch.mResult, aQuerySet, _matchedrule, _ruleindex);
          } finally {
            matchedrule = _matchedrule.value;
            ruleindex = _ruleindex.value;
          }
          if (matchedrule) {
            newmatch.ruleMatched(aQuerySet, matchedrule, ruleindex, newmatch.mResult);
            acceptedmatch = newmatch;
            var clearmatch = newmatch.mNext;
            while (clearmatch) {
              if (clearmatch.container != aInsertionPoint &&
                clearmatch.isActive()) {
                replacedmatch = clearmatch;
                break;
              }
              clearmatch = clearmatch.mNext;
            }
          } else if (oldmatch && oldmatch.isActive()) {
            newmatch = newmatch.mNext;
            while (newmatch) {
              if (newmatch.container == aInsertionPoint) {
                try {
                  _matchedrule = {value: matchedrule};
                  _ruleindex = {value: ruleindex};
                  this.determineMatchedRule(aInsertionPoint, newmatch.mResult, aQuerySet, _matchedrule, _ruleindex);
                } finally {
                  matchedrule = _matchedrule.value;
                  ruleindex = _ruleindex.value;
                }
                if (matchedrule) {
                  newmatch.ruleMatched(aQuerySet, matchedrule, ruleindex, newmatch.mResult);
                  acceptedmatch = newmatch;
                  break;
                }
              }
              newmatch = newmatch.mNext;
            }
          }
          if (!prevmatch)
            this.mMatchMap[aNewId] = newmatch;
        }
        if (prevmatch)
          prevmatch = prevmatch.mNExt;
      } else {
        try {
          _matchedrule = {value: matchedrule};
          _ruleindex = {value: ruleindex};
          this.determineMatchedRule(aInsertionPoint, aNewResult, aQuerySet, _matchedrule, _ruleindex);
        } finally {
          matchedrule = _matchedrule.value;
          ruleindex = _ruleindex.value;
        }
        acceptedmatch = newmatch;
        this.mMatchMap[aNewId] = newmatch;
      }
    }
    try {
      if (replacedmatch)
        this.replaceMatch(replacedmatch.mResult, null, null, aInsertionPoint);
    } finally {
      if (replacedmatchtodelete)
        ;
      if (oldMatchWasActive || acceptedmatch)
        this.replacedMatch(oldMAtchWasActive && aOldResult, acceptedmatch, matchedrule, aInsertionPoint);
      if (removedmatch)
        ;
    }
  },
  
  isActivated: function nsXULTemplateBuilder__isActivated(aResource) {
    return false;
  },
  getInsertionLocations: function nsXULTreeBuilder_getInsertionLocations(aResult, aLocations) {
    aLocations.value = null;
    try {
      var ref = aResult.getBindingFor(this.mRefVariable);
    } catch (e) {}
    if (!ref)
      return false;
    try {
      var container = gRDFService.getUnicodeResource(ref);
    } catch (e) {}
    if (!ref)
      return false;
    if (container == this.mRows.rootResource)
      return true;
    if (this.mRows.findByResource(container) == this.mRows.last)
      return false;

    return item.mContainerState == eContainerState_Open;
  },
  resultBindingChanged: function nsXULTemplateBuilder_resultBindingChanged(aResult) {
    if (!aResult)
      throw NS_ERROR_NULL_POINTER;
    this.synchronizeResult(aResult);
  },
  get rootResult() {
    return this.mRootResult;
  },
  getResultForId: function nsXULTemplateBuilder_getResultForId(aId) {
    if (!aId)
      throw NS_ERROR_INVALID_ARG;
    var resource = gRDFService.getUnicodeResource(aId);
    var match;
    while ((match = this.mMatchMap[resource])) {
      if (match.isActive()) {
        var result = match;
        break;
      }
      match = match.mNext;
    }
    return result;
  },
  getResultForContent: function nsXULTemplateBuilder_getResultForContent(aElement) {
    return null;
  },
  /* [undeclared, noscript] */
  hasGeneratedContent: function nsXULTemplateBuilder_hasGeneratedContent(aNode, aTag) {
    return false;
  },
  addRuleFilter: function nsXULTemplateBuilder_addRuleFilter(aRule, aFilter) {
    if (!aRule || !aFilter)
      throw NS_ERROR_NULL_POINTER;
    var count = this.mQuerySets.length;
    for (var q = 0; q< count; q++) {
      var queryset = this.mQuerySets[q];
      var rulecount = queryset.rules.length;
      for (var r = 0; r < rulecount; r++) {
        var rule = queryset.rules[r];
        rulenode = rule.ruleNode;
        if (aRule == rulenode) {
          rule.ruleFilter = aFilter;
          return;
        }
      }
    }
  },
  /* [noscript] */
  init: function nsXULTemplateBuilder_init(aElement) {
    if (!aElement)
      throw "null ptr";
    this.mRoot = aElement;
    var doc = this.mRoot.ownerDocument;
    if (!doc)
      throw NS_ERROR_UNEXPECTED;
    var shouldDelay = this.loadDataSources(doc);
    //doc.addObserver(this);
  },
  createContents: function nsXULTemplateBuilder_createContents(aElement) {
    ;
  },
  addListener: function nsXULTemplateBuilder_addListener(aListener) {
    if (!aListener)
      throw NS_ERROR_NULL_POINTER;
    this.mListeners.push(aListener);
  },
  removeListener: function nsXULTemplateBuilder_removeListener(aListener) {
    if (!aListener)
      throw NS_ERROR_NULL_POINTER;
    for (var i = 0; i < this.mListeners.length; ++i) {
      if (this.mListeners[i] == aListener) {
        this.mListeners.splice(i, 1);
        return;
      }
    }
  },
  loadDataSources: function nsXULTemplateBuilder__loadDataSources(aDocument) {
    var isRDFQuery = false;
    this.mDB = null;
    this.mCompDB = null;
    this.mDataSource = null;
    var aShouldDelayBinding = false;
    var datasources = this.mRoot.getAttribute("datasources");
    var querytype = this.mRoot.getAttribute("querytype");
    switch (querytype) {
    case null:
      querytype == "rdf";
    case "rdf":
      isRDFQuery = true;
      this.mQueryProcessor = new nsXULTemplateQueryProcessorRDF;
      break;
    case "xml":
      this.mQueryProcessor = new nsXULTemplateQueryProcessorXML;
      break;
    default:
      var cid = NS_QUERY_PROCESSOR_CONTRACTID_PREFIX;
      cid += querytype;
      this.mQueryProcessor = Components.classes[cid].createInstance(nsIXULTemplateQueryProcessor);
    }
    aShouldDelayBinding = this.loadDataSourceUrls(aDocument, datasources, isRDFQuery);
    if (0 && aDocument) {
      /* XXX this needs to be fixed to handle non xul documents */
      aDocument.setTemplateBuilderFor(mRoot, this);
    }
    if (1) {
      this.initHTMLTemplateRoot();
    }
    return aShouldDelayBinding;
  },
  loadDataSourceUrls: function nsXULTemplateBuilder__loadDataSourceUrls(aDocument, aDataSources, aIsRDFQuery) {
    var docurl = aDocument.documentURI;
    var uriList = aDataSources.split(/\s+/);
    for (var i = uriList.length; i-- > 0; ) { 
      var uriStr = uriList[i];
      uriList.splice(i, 1);
      if (uriStr == "rdf:null")
        continue;
      if (uriStr[0] == '#') {
        var dsnode = aDocument.getElementById(uriStr.substring(1));
        continue;
      }
      uriStr = NS_MakeAbsoluteURI(uriStr, docurl);
      try {
        var uri = NS_NewURI(uriStr);
      } catch (e) {
        continue;
      }
      uriList.push(uri); 
    }
    var rootNode = this.mRoot;
    try {
      var _aShouldDelayBinding = {value: false};
      this.mDataSource = this.mQueryProcessor.GetDataSource(uriList, rootNode, true, this, _aShouldDelayBinding);
    } finally {
      var aShouldDelayBinding = _aShouldDelayBinding.value;
    }
    if (aIsRDFQuery && this.mDataSource) {
      if (this.mDataSource instanceof nsIRDFInferDataSource) {
        var ds = this.mDataSource.baseDataSource;
        if (ds)
          this.mCompDB = ds;
      }
      if (!this.mCompDB)
        this.mCompDB = this.mDataSource;
      this.mDB = this.mDataSource;
    }
    if (!this.mDB)
      this.mDB = gRDFService.GetDataSource("rdf:local-store");
    return aShouldDelayBinding;
  },
  initHTMLTemplateRoot: function nsXULTemplateBuilder__initHTMLTemplateRoot() {
    var doc = this.mRoot.ownerDocument;
    if (!doc)
      throw NS_ERROR_UNEXPECTED;
    if (this.mDB)
      this.mRoot.database = this.mDB;
    this.mRoot.builder = this;
  },
  determineMatchedRule: function nsXULTemplateBuilder__determineMatchedRule(aContainer, aResult, aQuerySet, aMAtchedRule, aRuleIndex) {
    var count = aQuerySet.rules.length;
    for (var r = 0; r < count; r++) {
      var rule = aQuerySet.rules[r];
      var tag = rule.tag;
      if ((!aContainer || !tag || tag == aContainer.tag) &&
          rule.checkMatch(aResult)) {
        aMatchedRule.value = rule;
        aRuleIndex.value = r;
        return;
      }
    }
    aMatchedRule.value = null;
    aRuleIndex.value = -1;
  }
  }
  var gStringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
                                       .getService(nsIStringBundleService);
  var gLocaleService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
                                 .getService(nsILocaleService);
  var gRDFService = Components.classes[kRDFServiceCID].getService(nsIRDFService);
  var gIOService = Components.classes[NS_IOSERVICE_CONTRACTID].getService(nsIIOService);
  var gRDFContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]
                                     .getService(Components.interfaces.nsIRDFContainerUtils);

  gExtensionsView.database =
    Components.classes[NS_RDF_RESOURCE_CONTRACTID_PREFIX + "composite-datasource"]
              .createInstance(Components.interfaces.nsIRDFCompositeDataSource);
  gExtensionsView.builder = {
    rebuild: function () {
    }
  };

  attachStringBundle(gExtensionStrings);
  attachNotificationBindings(document.getElementById("addonsMsg"));
  var builder = new nsXULTemplateBuilder;
  builder.init(gExtensionsView);
}
function foo() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var b = {};
function c() {
function accum(module, key, value) {
if (!(module in b))
 b[module] = {};
b[module][key] = value;
}
twib = function twib(module) {
 var o = '';
  var keys = b[module];
  o+="<table><tbody>";
  for (var key in keys) {
   var value = keys[key];
   if (!value)
    continue;
   if (/:\/\//.test(value))
    value = '<a href="'+value+'"><img border="0" src="'+value+'" alt="'+value+'" /></a>';
   value = value.replace(/&amp;/g,'&').replace(/&/g,'&amp;');
   o += "<tr><th>"+ key + "</th><td>" + value +"</td></tr>";
  }
  o+="</tbody></table>";
 return o;
}

function flush() {
 var o = '';
 for (var module in b) {
  o+=twib(module);
 }
 b = {};
 return o;
}
  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
var Cc=Components.classes;
var Ci=Components.interfaces;
var rdfs = Cc['@mozilla.org/rdf/rdf-service;1'].getService(Ci.nsIRDFService)
try {
  var ds=rdfs.GetDataSource('rdf:extensions');
} catch (e) {
  ds = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager).datasource;
}

var ctr = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
ctr.Init(ds, rdfs.GetResource('urn:mozilla:item:root'));

var elements = ctr.GetElements();
while (elements.hasMoreElements()) {
  var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
  var i = ds.ArcLabelsOut(e);
  var arc;
  var key = e.ValueUTF8.replace("urn:mozilla:item:","");
  while (i.hasMoreElements() && (arc = i.getNext().nsIRDFResource)) {
  var value = arc.ValueUTF8.replace(/.*#/,'');
  //var arc = rdfs.GetResource(PREFIX_NS_EM + "name");
  var target = ds.GetTarget(e, arc, true);
  name = '';
  if (target) {
    if (target instanceof Components.interfaces.nsIRDFLiteral)
      var name = target.Value;
    else if (target instanceof Components.interfaces.nsIRDFResource)
      name = target.ValueUTF8;
    else if (target instanceof Components.interfaces.nsIRDFInt)
      name = '' + target.Value;
  }

  accum(key, value, name);
  }
}
//return flush();
}

var data;
function append(text) {
 data += text;
}
function flush() {
 document.getElementById('generated').innerHTML = data; data = '';
}
function link(href, text) {
 return href && href != "none" ? "<a href='"+href.replace(/&/g,'&amp;')+"'>"+text+"</a>" : "";
}
var em = Components.classes["@mozilla.org/extensions/manager;1"].getService();
var updateItem = Components.interfaces.nsIUpdateItem;
var consts = {};
var k;
c();
for (var i in updateItem)
 if ((k=updateItem[i])+0==k)
  consts[k] = i.replace(/.*_/,'').toLowerCase();
var list = em.nsIExtensionManager.getItemList(updateItem.TYPE_ANY, {});
append("<table border='1'><tr><th>Name</th><th>Version</th><th>Range</th></tr><tr><th colspan='3'>More</th></tr>");
for (i = 0; i < list.length; ++i) {
var item=list[i];
append("<tr><td><img class='"+consts[item.type]+"' alt='"+consts[item.type]+"'/><img src='"+item.iconURL+"' alt=' (unavailable) '/>"
+item.name+"</td><td>"+item.version+"</td><td>"+item.minAppVersion+"/"+item.maxAppVersion+
"</td></tr><tr><td colspan='3'>"+link(item.xpiURL, "origin")+
link(item.updateRDF, "update information")+
"</td></tr><tr><td colspan='3'>"+twib(item.id)+"</td></tr>");
}
append("</table>");
flush();
}

