private void GenerateGlobal(ObjectValue exports, dynamic klass) {
            string name = FixClassName((string)klass["name"]);
            ObjectValue value = new BuiltinObjectValue(
                exports.ProjectEntry,
                ParseDocumentation((string)klass["desc"])
            );

            exports.Add(name, value.Proxy);

            if (klass.ContainsKey("methods")) {
                foreach (var method in klass["methods"]) {
                    GenerateMethod(
                        value,
                        null,
                        method
                    );
                }
            }

            Dictionary<string, PropertySpecializer> specializers;
            _propertySpecializations.TryGetValue(name, out specializers);

            GenerateProperties(klass, value, specializers);
        }
        private void GenerateProperties(dynamic klass, ObjectValue value, Dictionary<string, PropertySpecializer> specializers) {
            if (klass.ContainsKey("properties")) {
                foreach (var prop in klass["properties"]) {
                    string propName = prop["name"];
                    string desc = ParseDocumentation(prop["desc"]);

                    string textRaw = "";
                    if (prop.ContainsKey("textRaw")) {
                        textRaw = prop["textRaw"];
                    }

                    PropertySpecializer specializer;
                    AnalysisValue propValue = null;
                    if (specializers != null &&
                        specializers.TryGetValue(propName, out specializer)) {
                        propValue = specializer.Specialize(value.ProjectEntry, propName);
                    } else if (desc.IndexOf("<code>Boolean</code>") != -1) {
                        propValue = value.ProjectEntry.Analyzer._trueInst;
                    } else if (desc.IndexOf("<code>Number</code>") != -1) {
                        propValue = value.ProjectEntry.Analyzer._zeroIntValue;
                    } else if (desc.IndexOf("<code>Readable Stream</code>") != -1) {
                        propValue = _readableStream;
                    } else if (desc.IndexOf("<code>Writable Stream</code>") != -1 || textRaw == "process.stderr") {
                        propValue = _writableStream;
                    } else if (!String.IsNullOrWhiteSpace(textRaw)) {
                        int start, end;
                        if ((start = textRaw.IndexOf('{')) != -1 && (end = textRaw.IndexOf('}')) != -1 &&
                            start < end) {
                            string typeName = textRaw.Substring(start, end - start);
                            switch (typeName) {
                                case "Boolean":
                                    propValue = value.ProjectEntry.Analyzer._trueInst;
                                    break;
                                case "Number":
                                    propValue = value.ProjectEntry.Analyzer._zeroIntValue;
                                    break;
                            }
                        }
                    }

                    if (propValue == null) {
                        propValue = new BuiltinObjectValue(value.ProjectEntry);
                    }

                    value.Add(
                        new MemberAddInfo(
                            propName,
                            propValue,
                            desc,
                            true
                        )
                    );
                }
            }
        }
        private ObjectValue MakeJSONObject() {
            var builtinEntry = _analyzer._builtinEntry;

            // TODO: Should we see if we have something that we should parse?
            // TODO: Should we have a per-node value for the result of parse?
            var parseResult = new BuiltinObjectValue(builtinEntry);
            return new BuiltinObjectValue(builtinEntry) { 
                ReturningFunction(
                    "parse", 
                    parseResult,
                    "Converts a JavaScript Object Notation (JSON) string into an object.",
                    Parameter("text", "A valid JSON string."),
                    Parameter("reviver", @"A function that transforms the results. This function is called for each member of the object. 
If a member contains nested objects, the nested objects are transformed before the parent object is.", isOptional:true)
                ),
                ReturningFunction(
                    "stringify", 
                    _analyzer._emptyStringValue,
                    "Converts a JavaScript value to a JavaScript Object Notation (JSON) string.",
                    Parameter("value", "A JavaScript value, usually an object or array, to be converted.")
                ),
            };
        }
 private BuiltinFunctionValue BooleanFunction(out AnalysisValue booleanPrototype) {
     var builtinEntry = _analyzer._builtinEntry;
     var prototype = new BuiltinObjectValue(builtinEntry) {
             BuiltinFunction("constructor"),
             ReturningFunction("toString", _analyzer._emptyStringValue),
             BuiltinFunction("valueOf"),
     };
     booleanPrototype = prototype;
     return new BuiltinFunctionValue(builtinEntry, "Boolean", null, prototype);
 }
        private BuiltinFunctionValue ArrayFunction(out ExpandoValue arrayPrototype) {
            var builtinEntry = _analyzer._builtinEntry;

            return new SpecializedFunctionValue(
                builtinEntry,
                "Array",
                NewArray,
                null,
                arrayPrototype = new BuiltinObjectValue(builtinEntry) {
                        SpecializedFunction(
                            "concat",
                            ArrayConcat,
                            "Combines two or more arrays.",
                            Parameter("item"),
                            Parameter("item...")
                        ),
                        BuiltinFunction("constructor"),
                        ReturningFunction(
                            "every",
                            _analyzer._trueInst,
                            "Determines whether all the members of an array satisfy the specified test.",
                            Parameter("callbackfn", "A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array."),
                            Parameter("thisArg", "An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.", isOptional:true)
                        ),
                        BuiltinFunction(
                            "filter",
                            "Returns the elements of an array that meet the condition specified in a callback function.",
                            Parameter("callbackfn", "A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array."),
                            Parameter("thisArg", "An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.", isOptional:true)
                        ),
                        SpecializedFunction(
                            "forEach", 
                            ArrayForEach,
                            "Performs the specified action for each element in an array.",
                            Parameter("callbackfn", "A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array."),
                            Parameter("thisArg", "An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.")
                        ),
                        ReturningFunction(
                            "indexOf",
                            _analyzer._zeroIntValue,
                            "Returns the index of the first occurrence of a value in an array.",
                            Parameter("searchElement", "The value to locate in the array."),
                            Parameter("fromIndex", "The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.", isOptional: true)
                        ),
                        ReturningFunction(
                            "join",
                            _analyzer._emptyStringValue,
                            "Adds all the elements of an array separated by the specified separator string.",
                            Parameter("separator", "A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.", isOptional: true)
                        ),
                        ReturningFunction(
                            "lastIndexOf",
                            _analyzer._zeroIntValue,
                            "Returns the index of the last occurrence of a specified value in an array.",
                            Parameter("searchElement", "The value to locate in the array."),
                            Parameter("fromIndex", "The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.", isOptional: true)
                        ),
                        BuiltinProperty(
                            "length", 
                            _analyzer._zeroIntValue,
                            "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array."
                        ),
                        BuiltinFunction(
                            "map",
                            "Calls a defined callback function on each element of an array, and returns an array that contains the results.",
                            Parameter("callbackfn", "A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array."),
                            Parameter("thisArg", "An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.")
                        ),
                        SpecializedFunction(
                            "pop",
                            ArrayPopFunction,
                            "Removes the last element from an array and returns it"
                        ),                        
                        SpecializedFunction(
                            "push",
                            ArrayPushFunction,
                            "Appends new elements to an array, and returns the new length of the array.",
                            Parameter("item", "New element of the Array."),
                            Parameter("item...",  "New element of the Array.", isOptional: true)
                        ),
                        BuiltinFunction(
                            "reduce",
                            "Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.",
                            Parameter("callbackfn", "A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array."),
                            Parameter("initialValue", "If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.", isOptional: true)
                        ),
                        BuiltinFunction(
                            "reduceRight",
                            "Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.",
                            Parameter("callbackfn", "A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array."),
                            Parameter("initialValue", "If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.", isOptional: true)
                        ),
                        BuiltinFunction(
                            "reverse", 
                            "Reverses the elements in an Array."
                        ),
                        BuiltinFunction(
                            "shift", 
                            "Removes the first element from an array and returns it."
                        ),
                        SpecializedFunction(
                            "slice",
                            ArraySliceFunction,
                            "Returns a section of an array.",
                            Parameter("start", "The beginning of the specified portion of the array.", isOptional: true),
                            Parameter("end", "end The end of the specified portion of the array.", isOptional: true)
                        ),
                        ReturningFunction(
                            "some",
                            _analyzer._trueInst,
                            "Determines whether the specified callback function returns true for any element of an array.",
                            Parameter("callbackfn", "A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array."),
                            Parameter("thisArg", "An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.", isOptional:true)
                        ),
                        BuiltinFunction(
                            "sort",
                            "Sorts an array.",
                            Parameter("compareFn", "The function used to determine the order of the elements. If omitted, the elements are sorted in ascending, ASCII character order.")
                        ),
                        BuiltinFunction(
                            "splice", 
                            "Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.",
                            Parameter("start", "The zero-based location in the array from which to start removing elements.")
                        ),
                        BuiltinFunction("toLocaleString"),
                        ReturningFunction(
                            "toString", 
                            _analyzer._emptyStringValue,
                            "Returns a string representation of an array."
                        ),
                        BuiltinFunction(
                            "unshift",
                            "Inserts new elements at the start of an array.",
                            Parameter("item...", "Element to insert at the start of the Array.")
                        ),
                }) { 
                new ReturningFunctionValue(builtinEntry, "isArray", _analyzer._falseInst.Proxy)
            };
        }
        private BuiltinFunctionValue StringFunction(out AnalysisValue stringPrototype) {
            var builtinEntry = _analyzer._builtinEntry;
            var prototype = new BuiltinObjectValue(builtinEntry) {
                    ReturningFunction(
                        "anchor",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with an <a name=...> tag.",
                        Parameter("name", "the name attribute for the anchor")
                    ),
                    ReturningFunction(
                        "big",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <big> tag."
                    ),
                    ReturningFunction(
                        "blink",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <blink> tag."
                    ),
                    ReturningFunction(
                        "bold",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <bold> tag."
                    ),
                    ReturningFunction(
                        "charAt", 
                        _analyzer._emptyStringValue,
                        "Returns the character at the specified index.", 
                        Parameter("pos", "The zero-based index of the desired character.")
                    ),
                    ReturningFunction(
                        "charCodeAt", 
                        _analyzer._zeroIntValue,
                        "Returns the Unicode value of the character at the specified location.", 
                        Parameter("index", "The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.")
                    ),
                    BuiltinFunction("concat", 
                        "Returns a string that contains the concatenation of two or more strings.", 
                        Parameter("...")
                    ),
                    BuiltinFunction("constructor"),
                    ReturningFunction(
                        "fixed",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <tt> tag."
                    ),
                    ReturningFunction(
                        "fontcolor",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <font color=...> tag.",
                        Parameter("color", "the color attribute for the font tag")
                    ),
                    ReturningFunction(
                        "fontsize",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <font size=...> tag.",
                        Parameter("size", "the size attribute for the font tag")
                    ),
                    BuiltinFunction("indexOf", 
                        "Returns the position of the first occurrence of a substring.", 
                        Parameter("searchString", "The substring to search for in the string"), 
                        Parameter("position", "The index at which to begin searching the String object. If omitted, search starts at the beginning of the string.", true)
                    ),
                    ReturningFunction(
                        "italics",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with an <i> tag."
                    ),
                    BuiltinFunction(
                        "lastIndexOf", 
                        "Returns the last occurrence of a substring in the string.", 
                        Parameter("searchString", "The substring to search for."), 
                        Parameter("position", "The index at which to begin searching. If omitted, the search begins at the end of the string.", true)
                    ),
                    BuiltinProperty("length", _analyzer._zeroIntValue),
                    ReturningFunction(
                        "link",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with an <a href=...> tag.",
                        Parameter("href", "the href attribute for the tag")
                    ),
                    BuiltinFunction(
                        "localeCompare", 
                        "Determines whether two strings are equivalent in the current locale.",
                        Parameter("that", "String to compare to target string")
                    ),
                    BuiltinFunction(
                        "match",
                        "Matches a string with a regular expression, and returns an array containing the results of that search.",
                        Parameter("regexp", "A string containing the regular expression pattern and flags or a RegExp.")

                    ),
                    BuiltinFunction(
                        "replace",
                        "Replaces text in a string, using a regular expression or search string.",
                        Parameter("searchValue", "A string that represents the regular expression or a RegExp"),
                        Parameter("replaceValue", "A string containing the text replacement text or a function which returns it.")
                    ),
                    BuiltinFunction(
                        "search",
                        "Finds the first substring match in a regular expression search.",
                        Parameter("regexp", "The regular expression pattern and applicable flags.")
                    ),
                    BuiltinFunction(
                        "slice",
                        "Returns a section of a string.",
                        Parameter("start", "The index to the beginning of the specified portion of stringObj."),
                        Parameter("end", "The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end.  If this value is not specified, the substring continues to the end of stringObj.")
                    ),
                    ReturningFunction(
                        "small",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <small> tag."
                    ),
                    BuiltinFunction(
                        "split",
                        "Split a string into substrings using the specified separator and return them as an array.",
                        Parameter("separator", "A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned. "),
                        Parameter("limit", "A value used to limit the number of elements returned in the array.", isOptional: true)
                    ),
                    ReturningFunction(
                        "strike",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <strike> tag."
                    ),
                    ReturningFunction(
                        "sub",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <sub> tag."
                    ),
                    BuiltinFunction("substr"),
                    BuiltinFunction(
                        "substring",
                        "Returns the substring at the specified location within a String object. ",
                        Parameter("start", "The zero-based index number indicating the beginning of the substring."),
                        Parameter("end", "Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end.  If end is omitted, the characters from start through the end of the original string are returned.")
                    ),
                    ReturningFunction(
                        "sup",
                        _analyzer._emptyStringValue,
                        "Surrounds the provided string with a <sup> tag."
                    ),
                    BuiltinFunction(
                        "toLocaleLowerCase",
                        "Converts all alphabetic characters to lowercase, taking into account the host environment's current locale."
                    ),
                    BuiltinFunction(
                        "toLocaleUpperCase",
                        "Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale."
                    ),
                    SpecializedFunction(
                        "toLowerCase",
                        StringToLowerCase,
                        "Converts all the alphabetic characters in a string to lowercase."
                    ),
                    BuiltinFunction(
                        "toString",
                        "Returns a string representation of a string."
                    ),
                    SpecializedFunction(
                        "toUpperCase",
                        StringToUpperCase,
                        "Converts all the alphabetic characters in a string to uppercase."
                    ),
                    BuiltinFunction(
                        "trim",
                        "Removes the leading and trailing white space and line terminator characters from a string."
                    ),
                    BuiltinFunction(
                        "trimLeft",
                        "Removes the leading white space and line terminator characters from a string."
                    ),
                    BuiltinFunction(
                        "trimRight",
                        "Removes the trailing white space and line terminator characters from a string."
                    ),
                    BuiltinFunction("valueOf"),
            };
            stringPrototype = prototype;

            return new BuiltinFunctionValue(builtinEntry, "String", null, prototype) { 
                ReturningFunction("fromCharCode", _analyzer.GetConstant(String.Empty)),
            };
        }
        private BuiltinFunctionValue NumberFunction(out AnalysisValue numberPrototype) {
            var builtinEntry = _analyzer._builtinEntry;

            var prototype = new BuiltinObjectValue(builtinEntry) {
                    BuiltinFunction("constructor"),
                    ReturningFunction(
                        "toExponential",
                        _analyzer._emptyStringValue,
                        "Returns a string containing a number represented in exponential notation."
                    ),
                    ReturningFunction(
                        "toFixed",
                        _analyzer._emptyStringValue,
                        "Returns a string representing a number in fixed-point notation."
                    ),
                    BuiltinFunction("toLocaleString"),
                    BuiltinFunction(
                        "toPrecision",
                        "Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.",
                        Parameter("precision", "Number of significant digits. Must be in the range 1 - 21, inclusive.", isOptional: true)
                    ),
                    ReturningFunction(
                        "toString",
                        _analyzer._emptyStringValue,
                        "Returns a string representation of an object.",
                        Parameter("radix", "Specifies a radix for converting numeric values to strings. This value is only used for numbers.", isOptional: true)
                    ),
                    BuiltinFunction("valueOf"),
            };
            numberPrototype = prototype;

            return new BuiltinFunctionValue(builtinEntry, "Number", null, prototype) { 
                Member("length", _analyzer.GetConstant(1.0)),
                Member("name", _analyzer.GetConstant("Number")),
                Member("arguments", _analyzer._nullInst),
                Member("caller", _analyzer._nullInst),
                Member("MAX_VALUE", _analyzer.GetConstant(Double.MaxValue)),
                Member("MIN_VALUE", _analyzer.GetConstant(Double.MinValue)),
                Member("NaN", _analyzer.GetConstant(Double.NaN)),
                Member("NEGATIVE_INFINITY", _analyzer.GetConstant(Double.NegativeInfinity)),
                Member("POSITIVE_INFINITY", _analyzer.GetConstant(Double.PositiveInfinity)),
                ReturningFunction(
                    "isFinite", 
                    _analyzer._trueInst,
                    "Determines whether a supplied number is finite."
                ),
                ReturningFunction(
                    "isNaN", 
                    _analyzer._falseInst,
                    "Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number)."
                ),
            };
        }