docs: function(node, parent) {
      var keep = false;
      var search = false;
  
      // Track selector heirarchy while drilling into the tree:
      if (node.type === NodeType.SELECTOR) {
        this.selector.push(Node.toString(node).trim());
      }
  
      // Track derivitive locals created by control-flow loops:
      else if (node.type === NodeType.LOOP) {
        this._mapNodeLocalVars(node);
        search = true;
      }
  
      // Keep variable declarations and overrides:
      else if (node.type === NodeType.VARIABLE && parent) {
        var varName = normalizeVarName(Node.toString(node));
        // Test if the var belongs to the set of theme vars:
        var isThemeVar = this.vars.hasOwnProperty(varName);
        // Test if the variable is keepable (includes local derivatives)
        var isKeepableVar = isThemeVar || this.locals.hasOwnProperty(varName);
        // Check usage context to determin if variable is being referenced (versus declared):
        var isRefContext = (parent.type === NodeType.VALUE ||
                            parent.type === NodeType.INTERPOLATION ||
                            parent.type === NodeType.PARENTHESIS ||
                            parent.type === NodeType.ARGUMENTS ||
                            parent.type === NodeType.LOOP);
  
        // Transform theme variables into fields when rendering to template:
        if (this._template && isThemeVar && isRefContext) {
          this._validateFieldContext(parent);
  
          var id = Node.first(node, NodeType.IDENTIFIER);
          node.type = id.type;
          node.content = this.fieldOpen + id.content + this.fieldClose;
          this._addFieldUsage(id.content);
        }
  
        // Keep if the variable is being declared (ie, `$banana: yellow;`),
        // or if the variable is keepable and being referenced (ie, `color: $banana;`).
        return (parent.type === NodeType.PROPERTY) || (isRefContext && isKeepableVar);
      }
  
      // Keep "____field-name____" template field identifiers:
      else if (node.type === NodeType.IDENTIFIER && this.isValidFieldName(node.content) && parent) {
        this._validateFieldContext(parent);
        this._addFieldUsage(node.content.replace(this.fieldRegex, '$1'));
        return true;
      }
  
      // Keep "@extend class-name;" statements for keepable extensions:
      else if (node.type === NodeType.EXTEND) {
        var target = Node.first(node, NodeType.SELECTOR);
        if (this.extend.hasOwnProperty(target)) return true;
      }
  
      // Keep "@include mixin-name;" statements for keepable mixins:
      else if (node.type === NodeType.INCLUDE) {
        var target = Node.first(node, NodeType.SELECTOR);
        if (this.mixin.hasOwnProperty(target)) return true;
      }
  
      // Drop all vars stylesheet includes:
      // This removes the overrideable variables from the compilation entirely.
      else if (node.type === NodeType.STYLE_SHEET && node.file === this.varsFile && this._varsRemoval) {
        return this._removeNode(node, 'varsfile');
      }
  
      // Keep framework helper functions while compiling templates:
      else if (node.type === NodeType.FUNCTION && /^sass-thematic/.test(Node.toString(node))) {
        return !!this._template;
      }
  
      // Keep node trees with a "// @sass-thematic-keep" comment flag:
      else if (node.type === NodeType.COMMENT && node.content.trim() === '@sass-thematic-keep') {
        return true;
      }
  
      // Deep search all other node types:
      else {
        search = true;
      }
  
      // Extend filter to all child nodes...
      if (Array.isArray(node.content) && search) {
        // Recursively filter on all node children:
        for (var i=0; i < node.content.length; i++) {
          keep = this._parseNode(node.content[i], node) || keep;
        }
      }
  
      // Track mixin names that contain keepable variables:
      if (node.type === NodeType.MIXIN && keep) {
        var ident = Node.first(node, NodeType.IDENTIFIER);
        if (ident && typeof ident.content === 'string') {
          this.mixin[ ident.content ] = 1;
        }
      }
  
      // Track valid rulesets for future use by @extend:
      // Remove last selector after traversing a ruleset.
      else if (node.type === NodeType.RULESET) {
        //console.log(this.selector);
        // Retain all selector names that are being kept:
        if (keep && this.selector.length) {
          this.extend[ this.selector.join(' ') ] = 1;
        }
        //console.log(this.selector);
        this.selector.pop();
      }
  
      // Clear local variables after completing a loop:
      else if (node.type === NodeType.LOOP) {
        this.locals = {};
      }
  
      // If we don't need to keep the node and it's a removable type, then drop it:
      // Also check the renderer to see if destructive operations are enabled.
      if (!keep && !!RemovableTypes[node.type] && this._treeRemoval) {
        return this._removeNode(node);
      }
  
      return keep;
    }