src/main/java/com/bazaarvoice/jless/ast/node/ScopeNode.java
private void setAdditionVisitor() {
        setAdditionVisitor(new InclusiveNodeVisitor() {
            /**
             * Add parameter set as a child for printing input, but also add each defined value to the variable map.
             */
            @Override
            public boolean add(ParametersNode node) {
                for (VariableDefinitionNode variable : NodeTreeUtils.getChildren(node, VariableDefinitionNode.class)) {
                    _parameterDefinitions.add(variable);
                    add(variable);
                }
                return super.add(node);
            }

            /**
             * Store the rule set's scope by selector group
             */
            @Override
            public boolean add(RuleSetNode node) {
                SelectorGroupNode selectorGroup = NodeTreeUtils.getFirstChild(node, SelectorGroupNode.class);
                for (SelectorNode selectorNode : NodeTreeUtils.getChildren(selectorGroup, SelectorNode.class)) {
                    StringBuilder sb = new StringBuilder();
                    for (Node selectorChild : selectorNode.getChildren()) {
                        sb.append(selectorChild.toString());
                    }
                    String selector = sb.toString();
                    // Mixins lock on first definition
                    if (!_selectorToRuleSetMap.containsKey(selector)) {
                        _selectorToRuleSetMap.put(selector, node);
                    }
                }
                return super.add(node);
            }

            /**
             * Absorb all children of the given scope. This assumes that cloning is not necessary.
             */
            @Override
            public boolean add(ScopeNode node) {
                NodeTreeUtils.moveChildren(node, ScopeNode.this);
                return false; // Don't add the original scope itself
            }

            /**
             * Store variable definitions in a map by name
             */
            @Override
            public boolean add(VariableDefinitionNode node) {
                String name = node.getName();
                // "Variables" lock on first definition
                if (!_variableNameToValueMap.containsKey(name)) {
                    _variableNameToValueMap.put(name, NodeTreeUtils.getFirstChild(node, ExpressionGroupNode.class));
                }
                return super.add(node);
            }

            /**
             * Store property nodes by name. If there are multiple properties for a given name, only retain the last one.
             */
            @Override
            public boolean add(PropertyNode node) {
                String name = node.getName();

                // If this is the IE-specific "filter" property, always add it
                if (name.equals(FILTER_PROPERTY)) {
                    return super.add(node);
                }

                // If the value of this property node is a vendor-specific keyword, always add it
                if (node.getChildren().get(0).toString().startsWith("-")) {
                    return super.add(node);
                }

                // Check if this property has been seen before
                if (_propertyNameToNodeMap.containsKey(name)) {
                    PropertyNode oldPropertyNode = _propertyNameToNodeMap.get(name);
                    int oldPropertyIndex = getChildren().indexOf(oldPropertyNode);

                    if (oldPropertyNode.isVisible()) {
                        // Hide the unneeded property
                        oldPropertyNode.setVisible(false);

                        // Attempt to hide one surrounding white space node
                        if (!hideWhiteSpaceNode(oldPropertyIndex - 1)) {
                            hideWhiteSpaceNode(oldPropertyIndex + 1);
                        }
                    }
                }

                // Store the property as the latest for this name
                _propertyNameToNodeMap.put(name, node);

                return super.add(node);
            }
        });
    }
private void setAdditionVisitor() {
        setAdditionVisitor(new InclusiveNodeVisitor() {
            /**
             * Add parameter set as a child for printing input, but also add each defined value to the variable map.
             */
            @Override
            public boolean add(ParametersNode node) {
                for (VariableDefinitionNode variable : NodeTreeUtils.getChildren(node, VariableDefinitionNode.class)) {
                    _parameterDefinitions.add(variable);
                    add(variable);
                }
                return super.add(node);
            }

            /**
             * Store the rule set's scope by selector group
             */
            @Override
            public boolean add(RuleSetNode node) {
                SelectorGroupNode selectorGroup = NodeTreeUtils.getFirstChild(node, SelectorGroupNode.class);
                for (SelectorNode selectorNode : NodeTreeUtils.getChildren(selectorGroup, SelectorNode.class)) {
                    StringBuilder sb = new StringBuilder();
                    for (Node selectorChild : selectorNode.getChildren()) {
                        sb.append(selectorChild.toString());
                    }
                    String selector = sb.toString();
                    // Mixins lock on first definition
                    if (!_selectorToRuleSetMap.containsKey(selector)) {
                        _selectorToRuleSetMap.put(selector, node);
                    }
                }
                return super.add(node);
            }

            /**
             * Absorb all children of the given scope. This assumes that cloning is not necessary.
             */
            @Override
            public boolean add(ScopeNode node) {
                NodeTreeUtils.moveChildren(node, ScopeNode.this);
                return false; // Don't add the original scope itself
            }

            /**
             * Store variable definitions in a map by name
             */
            @Override
            public boolean add(VariableDefinitionNode node) {
                String name = node.getName();
                // "Variables" lock on first definition
                if (!_variableNameToValueMap.containsKey(name)) {
                    _variableNameToValueMap.put(name, NodeTreeUtils.getFirstChild(node, ExpressionGroupNode.class));
                }
                return super.add(node);
            }

            /**
             * Store property nodes by name. If there are multiple properties for a given name, only retain the last one.
             */
            @Override
            public boolean add(PropertyNode node) {
                String name = node.getName();

                // If this is the IE-specific "filter" property, always add it
                if (name.equals(FILTER_PROPERTY)) {
                    return super.add(node);
                }

                // If the value of this property node is a vendor-specific keyword, always add it
                if (node.getChildren().get(0).toString().startsWith("-")) {
                    return super.add(node);
                }

                // Check if this property has been seen before
                if (_propertyNameToNodeMap.containsKey(name)) {
                    PropertyNode oldPropertyNode = _propertyNameToNodeMap.get(name);
                    int oldPropertyIndex = getChildren().indexOf(oldPropertyNode);

                    if (oldPropertyNode.isVisible()) {
                        // Hide the unneeded property
                        oldPropertyNode.setVisible(false);

                        // Attempt to hide one surrounding white space node
                        if (!hideWhiteSpaceNode(oldPropertyIndex - 1)) {
                            hideWhiteSpaceNode(oldPropertyIndex + 1);
                        }
                    }
                }

                // Store the property as the latest for this name
                _propertyNameToNodeMap.put(name, node);

                return super.add(node);
            }
        });
    }
Some nodes are captured in additional structures to aid later resolution.