docs: function cleanTree ( node, preserveWS ) {
      var children = node.childNodes,
          nonInlineParent, i, l, child, nodeName, nodeType, rewriter, childLength,
          startsWithWS, endsWithWS, data, sibling;
  
      nonInlineParent = node;
      while ( isInline( nonInlineParent ) ) {
        nonInlineParent = nonInlineParent.parentNode;
      }
      walker.root = nonInlineParent;
  
      for ( i = 0, l = children.length; i < l; i += 1 ) {
        child = children[i];
        nodeName = child.nodeName;
        nodeType = child.nodeType;
        rewriter = stylesRewriters[ nodeName ];
        if ( nodeType === ELEMENT_NODE ) {
          childLength = child.childNodes.length;
          if ( rewriter ) {
            child = rewriter( child, node );
          } else if ( blacklist.test( nodeName ) ) {
            node.removeChild( child );
            i -= 1;
            l -= 1;
            continue;
          } else if ( !allowedBlock.test( nodeName ) && !isInline( child ) ) {
            i -= 1;
            l += childLength - 1;
            node.replaceChild( empty( child ), child );
            continue;
          }
          if ( childLength ) {
            cleanTree( child, preserveWS || ( nodeName === 'PRE' ) );
          }
        } else {
          if ( nodeType === TEXT_NODE ) {
            data = child.data;
            startsWithWS = !notWS.test( data.charAt( 0 ) );
            endsWithWS = !notWS.test( data.charAt( data.length - 1 ) );
            if ( preserveWS || ( !startsWithWS && !endsWithWS ) ) {
              continue;
            }
            // Iterate through the nodes; if we hit some other content
            // before the start of a new block we don't trim
            if ( startsWithWS ) {
              walker.currentNode = child;
              while ( sibling = walker.previousPONode() ) {
                nodeName = sibling.nodeName;
                if ( nodeName === 'IMG' ||
                     ( nodeName === '#text' &&
                       notWS.test( sibling.data ) ) ) {
                  break;
                }
                if ( !isInline( sibling ) ) {
                  sibling = null;
                  break;
                }
              }
              data = data.replace( /^[ \t\r\n]+/g, sibling ? ' ' : '' );
            }
            if ( endsWithWS ) {
              walker.currentNode = child;
              while ( sibling = walker.nextNode() ) {
                if ( nodeName === 'IMG' ||
                     ( nodeName === '#text' &&
                       notWS.test( sibling.data ) ) ) {
                  break;
                }
                if ( !isInline( sibling ) ) {
                  sibling = null;
                  break;
                }
              }
              data = data.replace( /[ \t\r\n]+$/g, sibling ? ' ' : '' );
            }
            if ( data ) {
              child.data = data;
              continue;
            }
          }
          node.removeChild( child );
          i -= 1;
          l -= 1;
        }
      }
      return node;
    }