docs: function MirroredDocument() {
  // private
      var originalDoc;
      var reflectionDoc;
      var namespaceResolver;
      var finderBuilder = new FinderBuilder();
      var pastReflections = new BoundedCache(50);
      var jQuery = new JQueryWrapper();
  
      /**
       * Appends elements represented by the given HTML to the given parent
       * element. All <script> elements are omitted.
       */
      function appendHTML(html, parentNode) {
          var scripts = jQuery.clean([ html ], null, parentNode);
      }
  
      function getHeadHtml(doc) {
          return doc.getElementsByTagName('head')[0].innerHTML;
      }
  
      function getBodyHtml(doc) {
          return doc.body.innerHTML;
      }
  
      /**
       * Copies the given HTML as the content of the current document's <head>
       * element. If the current document's head already contains identical
       * markup, copying is skipped. <script> elements are omitted.
       */
      function copyHead(headHtml, doc) {
          var head = doc.getElementsByTagName('head')[0];
  
          if (head.innerHTML == headHtml) {
              // the content is already correct
              return;
          }
  
          jQuery.init(head).empty();
  
          appendHTML(headHtml, head);
      }
  
      /**
       * Copies the given HTML as the content of the current document's <body>
       * element. If the current document's body already contains identical
       * markup, copying is skipped. <script> elements are omitted.
       */
      function copyBody(bodyHtml, doc) {
          if (doc.body.innerHTML == bodyHtml) {
              return;
          }
  
          jQuery.init(doc.body).empty();
  
          appendHTML(bodyHtml, doc.body);
      }
  
  // public
      this.setOriginal = function(newOriginalDoc) {
          originalDoc = newOriginalDoc;
          return this;
      };
  
      this.getOriginal = function() {
          return originalDoc;
      };
  
      this.setReflection = function(newReflectionDoc) {
          reflectionDoc = newReflectionDoc;
          return this;
      }
  
      this.getReflection = function() {
          return reflectionDoc;
      };
  
      this.setNamespaceResolver = function(newNamespaceResolver) {
          namespaceResolver = newNamespaceResolver;
          return this;
      };
  
      /**
       * Makes sure the reflected document reflects the original. Returns this
       * object.
       */
      this.reflect = function() {
          if (reflectionDoc == originalDoc) {
              // the reflection and the original are one and the same
              return this;
          }
  
          var originalHtml = originalDoc.documentElement.innerHTML;
          var pastReflectionHtml = pastReflections.get(originalHtml);
  
          if (pastReflectionHtml != null &&
              pastReflectionHtml == reflectionDoc.documentElement.innerHTML) {
              // the reflection is already accurate
              return this;
          }
  
          var headHtml = getHeadHtml(originalDoc);
          var bodyHtml = getBodyHtml(originalDoc);
  
          try {
              copyHead(headHtml, reflectionDoc);
              copyBody(bodyHtml, reflectionDoc);
  
              pastReflections.put(originalHtml,
                  reflectionDoc.documentElement.innerHTML);
          }
          catch (e) {
              safe_log('warn', 'Document reflection failed: ' + e.message);
          }
  
          return this;
      };
  
      /**
       * Returns the node in the reflection that corresponds to node in the
       * original document. Returns null if the reflected node can't be found.
       */
      this.getReflectedNode = function(originalNode) {
          if (reflectionDoc == originalDoc) {
              // the reflection and the original are one and the same
              return originalNode;
          }
  
          if (originalNode == originalDoc) {
              return reflectionDoc;
          }
  
          var finder = finderBuilder.setDocument(originalDoc).build(originalNode);
  
          return finder(reflectionDoc) || null;
      };
  }