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 void GenerateClass(ObjectValue exports, dynamic klass) {
            string className = (string)klass["name"];

            List<OverloadResult> overloads = new List<OverloadResult>();
            var fixedClassName = FixClassName(className);
            dynamic signatures;
            if (klass.TryGetValue("signatures", out signatures)) {
                foreach (var sig in signatures) {
                    var parameters = GetParameters(sig["params"]);
                    var doc = ParseDocumentation((string)sig["desc"]);

                    overloads.Add(new SimpleOverloadResult(fixedClassName, doc, parameters));
                }
            }
            BuiltinFunctionValue klassValue = new ClassBuiltinFunctionValue(
                exports.ProjectEntry,
                fixedClassName,
                overloads.ToArray(),
                ParseDocumentation((string)klass["desc"])
            );

            exports.Add(klassValue);

            if (klass.ContainsKey("methods")) {
                var prototype = (PrototypeValue)klassValue.Descriptors["prototype"].Values.Types.First().Value;
                Dictionary<string, FunctionSpecializer> classSpecializations;
                _classSpecializations.TryGetValue(className, out classSpecializations);
                foreach (var method in klass["methods"]) {
                    GenerateMethod(
                        prototype,
                        classSpecializations,
                        method
                    );
                }
            }
            if (klass.ContainsKey("classMethods")) {
                foreach (var method in klass["classMethods"]) {
                    GenerateMethod(
                        klassValue,
                        null,
                        method
                    );
                }
            }

            if (klass.ContainsKey("properties")) {
                var prototype = (PrototypeValue)klassValue.Descriptors["prototype"].Values.Types.First().Value;

                GenerateProperties(klass, prototype, null);
            }
        }