text: "use strict";
  
  const conversions = require("webidl-conversions");
  const utils = require("./utils.js");
  const Node = require("./Node.js");
  const impl = utils.implSymbol;
  const mixin = utils.mixin;
  const GlobalEventHandlers = require("./GlobalEventHandlers.js");
  const NonElementParentNode = require("./NonElementParentNode.js");
  const ParentNode = require("./ParentNode.js");
  
  function Document() {
    const args = [];
    for (let i = 0; i < arguments.length && i < 0; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
  
    module.exports.setup(this, args);
  }
  Document.prototype = Object.create(Node.interface.prototype);
  Document.prototype.constructor = Document;
  
  mixin(Document.prototype, GlobalEventHandlers.interface.prototype);
  GlobalEventHandlers.mixedInto.push(Document);
  mixin(Document.prototype, NonElementParentNode.interface.prototype);
  NonElementParentNode.mixedInto.push(Document);
  mixin(Document.prototype, ParentNode.interface.prototype);
  ParentNode.mixedInto.push(Document);
  
  Document.prototype.getElementsByTagName = function getElementsByTagName(localName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'getElementsByTagName' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].getElementsByTagName.apply(this[impl], args));
  };
  
  Document.prototype.getElementsByTagNameNS = function getElementsByTagNameNS(namespace, localName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 2) {
      throw new TypeError("Failed to execute 'getElementsByTagNameNS' on 'Document': 2 arguments required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] === null || args[0] === undefined) {
      args[0] = null;
    } else {
    args[0] = conversions["DOMString"](args[0]);
    }
    args[1] = conversions["DOMString"](args[1]);
    return utils.tryWrapperForImpl(this[impl].getElementsByTagNameNS.apply(this[impl], args));
  };
  
  Document.prototype.getElementsByClassName = function getElementsByClassName(classNames) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'getElementsByClassName' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].getElementsByClassName.apply(this[impl], args));
  };
  
  Document.prototype.createElement = function createElement(localName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createElement' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].createElement.apply(this[impl], args));
  };
  
  Document.prototype.createElementNS = function createElementNS(namespace, qualifiedName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 2) {
      throw new TypeError("Failed to execute 'createElementNS' on 'Document': 2 arguments required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] === null || args[0] === undefined) {
      args[0] = null;
    } else {
    args[0] = conversions["DOMString"](args[0]);
    }
    args[1] = conversions["DOMString"](args[1]);
    return utils.tryWrapperForImpl(this[impl].createElementNS.apply(this[impl], args));
  };
  
  Document.prototype.createDocumentFragment = function createDocumentFragment() {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 0; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    return utils.tryWrapperForImpl(this[impl].createDocumentFragment.apply(this[impl], args));
  };
  
  Document.prototype.createTextNode = function createTextNode(data) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createTextNode' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].createTextNode.apply(this[impl], args));
  };
  
  Document.prototype.createComment = function createComment(data) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createComment' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].createComment.apply(this[impl], args));
  };
  
  Document.prototype.createProcessingInstruction = function createProcessingInstruction(target, data) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 2) {
      throw new TypeError("Failed to execute 'createProcessingInstruction' on 'Document': 2 arguments required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    args[1] = conversions["DOMString"](args[1]);
    return utils.tryWrapperForImpl(this[impl].createProcessingInstruction.apply(this[impl], args));
  };
  
  Document.prototype.importNode = function importNode(node) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'importNode' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[1] !== undefined) {
    args[1] = conversions["boolean"](args[1]);
    } else {
      args[1] = false;
    }
    return utils.tryWrapperForImpl(this[impl].importNode.apply(this[impl], args));
  };
  
  Document.prototype.adoptNode = function adoptNode(node) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'adoptNode' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    return utils.tryWrapperForImpl(this[impl].adoptNode.apply(this[impl], args));
  };
  
  Document.prototype.createAttribute = function createAttribute(localName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createAttribute' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].createAttribute.apply(this[impl], args));
  };
  
  Document.prototype.createAttributeNS = function createAttributeNS(namespace, qualifiedName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 2) {
      throw new TypeError("Failed to execute 'createAttributeNS' on 'Document': 2 arguments required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] === null || args[0] === undefined) {
      args[0] = null;
    } else {
    args[0] = conversions["DOMString"](args[0]);
    }
    args[1] = conversions["DOMString"](args[1]);
    return utils.tryWrapperForImpl(this[impl].createAttributeNS.apply(this[impl], args));
  };
  
  Document.prototype.createEvent = function createEvent(_interface) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createEvent' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].createEvent.apply(this[impl], args));
  };
  
  Document.prototype.createTreeWalker = function createTreeWalker(root) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'createTreeWalker' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 3; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[1] !== undefined) {
    args[1] = conversions["unsigned long"](args[1]);
    } else {
      args[1] = 4294967295;
    }
    if (args[2] === null || args[2] === undefined) {
      args[2] = null;
    } else {
    }
    return utils.tryWrapperForImpl(this[impl].createTreeWalker.apply(this[impl], args));
  };
  
  Document.prototype.getElementsByName = function getElementsByName(elementName) {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    if (arguments.length < 1) {
      throw new TypeError("Failed to execute 'getElementsByName' on 'Document': 1 argument required, but only " + arguments.length + " present.");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 1; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    args[0] = conversions["DOMString"](args[0]);
    return utils.tryWrapperForImpl(this[impl].getElementsByName.apply(this[impl], args));
  };
  
  Document.prototype.open = function open() {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 2; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] !== undefined) {
    args[0] = conversions["DOMString"](args[0]);
    } else {
      args[0] = "text/html";
    }
    if (args[1] !== undefined) {
    args[1] = conversions["DOMString"](args[1]);
    } else {
      args[1] = "";
    }
    return utils.tryWrapperForImpl(this[impl].open.apply(this[impl], args));
  };
  
  Document.prototype.close = function close() {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    const args = [];
    for (let i = 0; i < arguments.length && i < 0; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    return utils.tryWrapperForImpl(this[impl].close.apply(this[impl], args));
  };
  
  Document.prototype.write = function write() {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    const args = [];
    for (let i = 0; i < arguments.length; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] !== undefined) {
    args[0] = conversions["DOMString"](args[0]);
    }
    return utils.tryWrapperForImpl(this[impl].write.apply(this[impl], args));
  };
  
  Document.prototype.writeln = function writeln() {
    if (!this || !module.exports.is(this)) {
      throw new TypeError("Illegal invocation");
    }
    const args = [];
    for (let i = 0; i < arguments.length; ++i) {
      args[i] = utils.tryImplForWrapper(arguments[i]);
    }
    if (args[0] !== undefined) {
    args[0] = conversions["DOMString"](args[0]);
    }
    return utils.tryWrapperForImpl(this[impl].writeln.apply(this[impl], args));
  };
  
  Document.prototype.toString = function () {
    if (this === Document.prototype) {
      return "[object DocumentPrototype]";
    }
    return Node.interface.prototype.toString.call(this);
  };
  Object.defineProperty(Document.prototype, "implementation", {
    get() {
      return utils.tryWrapperForImpl(this[impl].implementation);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "URL", {
    get() {
      return utils.tryWrapperForImpl(this[impl].URL);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "documentURI", {
    get() {
      return utils.tryWrapperForImpl(this[impl].documentURI);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "origin", {
    get() {
      return utils.tryWrapperForImpl(this[impl].origin);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "compatMode", {
    get() {
      return utils.tryWrapperForImpl(this[impl].compatMode);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "characterSet", {
    get() {
      return utils.tryWrapperForImpl(this[impl].characterSet);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "charset", {
    get() {
      return utils.tryWrapperForImpl(this[impl].charset);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "inputEncoding", {
    get() {
      return utils.tryWrapperForImpl(this[impl].inputEncoding);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "contentType", {
    get() {
      return utils.tryWrapperForImpl(this[impl].contentType);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "doctype", {
    get() {
      return utils.tryWrapperForImpl(this[impl].doctype);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "documentElement", {
    get() {
      return utils.tryWrapperForImpl(this[impl].documentElement);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "referrer", {
    get() {
      return utils.tryWrapperForImpl(this[impl].referrer);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "cookie", {
    get() {
      return utils.tryWrapperForImpl(this[impl].cookie);
    },
    set(V) {
      V = conversions["DOMString"](V);
      this[impl].cookie = utils.tryImplForWrapper(V);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "lastModified", {
    get() {
      return utils.tryWrapperForImpl(this[impl].lastModified);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "readyState", {
    get() {
      return utils.tryWrapperForImpl(this[impl].readyState);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "title", {
    get() {
      return utils.tryWrapperForImpl(this[impl].title);
    },
    set(V) {
      V = conversions["DOMString"](V);
      this[impl].title = utils.tryImplForWrapper(V);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "body", {
    get() {
      return utils.tryWrapperForImpl(this[impl].body);
    },
    set(V) {
      if (V === null || V === undefined) {
        V = null;
      } else {
      }
      this[impl].body = utils.tryImplForWrapper(V);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "head", {
    get() {
      return utils.tryWrapperForImpl(this[impl].head);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "images", {
    get() {
      return utils.tryWrapperForImpl(this[impl].images);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "links", {
    get() {
      return utils.tryWrapperForImpl(this[impl].links);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "forms", {
    get() {
      return utils.tryWrapperForImpl(this[impl].forms);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "currentScript", {
    get() {
      return utils.tryWrapperForImpl(this[impl].currentScript);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "defaultView", {
    get() {
      return utils.tryWrapperForImpl(this[impl].defaultView);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "activeElement", {
    get() {
      return utils.tryWrapperForImpl(this[impl].activeElement);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "onreadystatechange", {
    get() {
      return utils.tryWrapperForImpl(this[impl].onreadystatechange);
    },
    set(V) {
      this[impl].onreadystatechange = utils.tryImplForWrapper(V);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "anchors", {
    get() {
      return utils.tryWrapperForImpl(this[impl].anchors);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "applets", {
    get() {
      return utils.tryWrapperForImpl(this[impl].applets);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "styleSheets", {
    get() {
      return utils.tryWrapperForImpl(this[impl].styleSheets);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "hidden", {
    get() {
      return utils.tryWrapperForImpl(this[impl].hidden);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "visibilityState", {
    get() {
      return utils.tryWrapperForImpl(this[impl].visibilityState);
    },
    enumerable: true,
    configurable: true
  });
  
  Object.defineProperty(Document.prototype, "onvisibilitychange", {
    get() {
      return utils.tryWrapperForImpl(this[impl].onvisibilitychange);
    },
    set(V) {
      this[impl].onvisibilitychange = utils.tryImplForWrapper(V);
    },
    enumerable: true,
    configurable: true
  });
  
  
  module.exports = {
    mixedInto: [],
    is(obj) {
      if (obj) {
        if (obj[impl] instanceof Impl.implementation) {
          return true;
        }
        for (let i = 0; i < module.exports.mixedInto.length; ++i) {
          if (obj instanceof module.exports.mixedInto[i]) {
            return true;
          }
        }
      }
      return false;
    },
    isImpl(obj) {
      if (obj) {
        if (obj instanceof Impl.implementation) {
          return true;
        }
  
        const wrapper = utils.wrapperForImpl(obj);
        for (let i = 0; i < module.exports.mixedInto.length; ++i) {
          if (wrapper instanceof module.exports.mixedInto[i]) {
            return true;
          }
        }
      }
      return false;
    },
    create(constructorArgs, privateData) {
      let obj = Object.create(Document.prototype);
      this.setup(obj, constructorArgs, privateData);
      return obj;
    },
    createImpl(constructorArgs, privateData) {
      let obj = Object.create(Document.prototype);
      this.setup(obj, constructorArgs, privateData);
      return utils.implForWrapper(obj);
    },
    _internalSetup(obj) {
      Node._internalSetup(obj);
  
      Object.defineProperty(obj, "location", {
        get() {
          return utils.tryWrapperForImpl(obj[impl].location);
        },
        set(V) {
          this.location.href = V;
        },
        enumerable: true,
        configurable: false
      });
      
      
    },
    setup(obj, constructorArgs, privateData) {
      if (!privateData) privateData = {};
      privateData.wrapper = obj;
  
      this._internalSetup(obj);
  
      obj[impl] = new Impl.implementation(constructorArgs, privateData);
      obj[impl][utils.wrapperSymbol] = obj;
    },
    interface: Document,
    expose: {
      Window: { Document: Document }
    }
  };
  
  
  const Impl = require("../nodes/Document-impl.js");
  