def __scanNode(node, data):
    
    if node.type == "function":
        if node.functionForm == "declared_form":
            data.declared.add(node.name)
            data.modified.add(node.name)
    
    elif node.type == "declaration":
        varName = getattr(node, "name", None)
        if varName != None:
            data.declared.add(varName)
            
            if hasattr(node, "initializer"):
                data.modified.add(varName)
            
            # If the variable is used as a iterator, we need to add it to the use counter as well
            if getattr(node.parent, "rel", None) == "iterator":
                data.increment(varName)
            
        else:
            # JS 1.7 Destructing Expression
            varNames = node.names
            for identifier in node.names:
                data.declared.add(identifier.value)
                data.modified.add(identifier.value)
                
            # If the variable is used as a iterator, we need to add it to the use counter as well
            if getattr(node.parent, "rel", None) == "iterator":
                for identifier in node.names:
                    data.increment(identifier.value)
            
    elif node.type == "identifier":
        # Ignore parameter names (of inner functions, these are handled by __scanScope)
        if node.parent.type == "list" and getattr(node.parent, "rel", None) == "params":
            pass
        
        # Ignore property initialization names
        elif node.parent.type == "property_init" and node.parent[0] == node:
            pass
            
        # Ignore non first identifiers in dot-chains
        elif node.parent.type != "dot" or node.parent.index(node) == 0:
            if node.value != "arguments":
                data.increment(node.value)
            
                if node.parent.type in ("increment", "decrement"):
                    data.modified.add(node.value)
                
                elif node.parent.type == "assign" and node.parent[0] == node:
                    data.modified.add(node.value)

                # Support for package-like object access
                if node.parent.type == "dot":
                    package = __combinePackage(node)
                    if package in data.packages:
                        data.packages[package] += 1
                    else:
                        data.packages[package] = 1
                
    # Treat exception variables in catch blocks like declared
    elif node.type == "block" and node.parent.type == "catch":
        data.declared.add(node.parent.exception.value)                
    
    if node.type == "script":
        innerVariables = __scanScope(node)
        for name in innerVariables.shared:
            data.increment(name, innerVariables.shared[name])
            
            if name in innerVariables.modified:
                data.modified.add(name)
        
        for package in innerVariables.packages:
            if package in data.packages:
                data.packages[package] += innerVariables.packages[package]
            else:
                data.packages[package] = innerVariables.packages[package]
                
    else:
        for child in node:
            # None children are allowed sometimes e.g. during array_init like [1,2,,,7,8]
            if child != None:
                __scanNode(child, data)
Test the basic JSON project creation with only the required fields
dataset/ETHPy150Open zynga/jasy/jasy/js/parse/ScopeScanner.py/__scanNode--crossover with--dataset/ETHPy150Open neurodata/ndstore/test/test_json.py/Test_Project_Json.test_basic_json