private static DocItem DocumentEnum(BindEnum enu, string prefix)
        {
            string name       = enu.Name;
            string fullName   = prefix + name;
            string definition = fullName;
            string copy       = definition;
            var    nextPrefix = prefix + name + ".";

            string documentation = enu.Documentation ?? "";
            string example       = enu.Example ?? "";

            var doc = new DocItem(DocItemType.Enum, enu.EnumType, name, fullName, definition, copy, documentation, example)
            {
                DataType = enu.EnumType
            };

            for (int i = 0; i < enu.EnumVals.Count; i++)
            {
                var field = enu.EnumVals[i];
                var iobj  = DocumentInstanceObject(typeof(int), field.Key, nextPrefix, 0, enu.EnumType, enu.FieldDocumentations[i], enu.FieldExamples[i]);
                doc.SubDocs.Add(iobj);
            }
            return(doc);
        }
        /// <summary>
        /// CAN RETURN NULL
        /// </summary>
        private static DocItem DocumentInstanceObject(Type type, string name, string prefix, int curLevel, Type declType = null, string documentation = "", string example = "")
        {
            string fullName   = prefix + name;
            var    nextPrefix = prefix + name + ".";

            if (type.IsPrimitive || type == typeof(string))
            {
                //Stop recursing
                return(new DocItem(DocItemType.InstanceObject, declType ?? type, name, fullName, fullName, fullName, documentation, example, name, name, name)
                {
                    DataType = type
                });
            }
            else if (!UserData.IsTypeRegistered(type))
            {
                return(null);
            }

            DocItem doc = new DocItem(DocItemType.InstanceObject, type, name, fullName, fullName, fullName, documentation, example, name, name, name)
            {
                DataType = type
            };

            if (curLevel > MaxRecursion)
            {
                doc.SubDocs.Add(new DocItem(DocItemType.None, typeof(void), "Max Recursion Reached", "Max Recursion Reached", "Max Recursion Reached", "", "", "")
                {
                    DataType = typeof(string)
                });
                return(doc);
            }


            var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Where(a => !a.IsSpecialName && a.Name != "ToString" && a.Name != "GetHashCode" && a.Name != "GetType" && a.Name != "Equals" && a.Name != "GetTypeCode")
                         .Where(x => !x.CustomAttributes.Any(y => y.AttributeType == typeof(MoonSharpHiddenAttribute) || y.AttributeType == typeof(MoonSharpHideMemberAttribute) || y.AttributeType == typeof(LunarBindHideAttribute)));
            var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(a => !a.IsSpecialName && a.Name != "ToString" && a.Name != "GetHashCode" && a.Name != "GetType" && a.Name != "Equals" && a.Name != "GetTypeCode")
                             .Where(x => !x.CustomAttributes.Any(y => y.AttributeType == typeof(MoonSharpHiddenAttribute) || y.AttributeType == typeof(MoonSharpHideMemberAttribute) || y.AttributeType == typeof(LunarBindHideAttribute)));
            var funcs = type.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(a => !a.IsSpecialName && a.Name != "ToString" && a.Name != "GetHashCode" && a.Name != "GetType" && a.Name != "Equals" && a.Name != "GetTypeCode")
                        .Where(x => !x.CustomAttributes.Any(y => y.AttributeType == typeof(MoonSharpHiddenAttribute) || y.AttributeType == typeof(MoonSharpHideMemberAttribute) || y.AttributeType == typeof(LunarBindHideAttribute)));

            //TODO: events
            //var events = type.GetEvents(BindingFlags.Instance | BindingFlags.Public)
            //    .Where(x => !x.CustomAttributes.Any(y => y.AttributeType == typeof(MoonSharpHiddenAttribute) || y.AttributeType == typeof(MoonSharpHideMemberAttribute) || y.AttributeType == typeof(LunarBindHideAttribute)));

            foreach (var field in fields)
            {
                if (field.FieldType.IsEnum)
                {
                    BindEnum bindEnum = new BindEnum(field.Name, field.FieldType);
                    doc.SubDocs.Add(DocumentEnum(bindEnum, prefix));
                }
                else
                {
                    string docu = "";
                    string ex   = "";

                    var docAttrib = field.GetCustomAttribute <LunarBindDocumentationAttribute>();
                    if (docAttrib != null)
                    {
                        docu = docAttrib.Data;
                    }
                    var exampleAttrib = field.GetCustomAttribute <LunarBindExampleAttribute>();
                    if (exampleAttrib != null)
                    {
                        ex = exampleAttrib.Data;
                    }


                    var fdoc = DocumentInstanceObject(field.FieldType, field.Name, nextPrefix, curLevel + 1, type, docu, ex);
                    if (fdoc != null)
                    {
                        doc.SubDocs.Add(fdoc);
                    }
                }
            }

            foreach (var property in properties)
            {
                string docu = "";
                string ex   = "";

                var docAttrib = property.GetCustomAttribute <LunarBindDocumentationAttribute>();
                if (docAttrib != null)
                {
                    docu = docAttrib.Data;
                }
                var exampleAttrib = property.GetCustomAttribute <LunarBindExampleAttribute>();
                if (exampleAttrib != null)
                {
                    ex = exampleAttrib.Data;
                }

                var pdoc = DocumentInstanceObject(property.PropertyType, property.Name, nextPrefix, curLevel + 1, type, docu, ex);
                if (pdoc != null)
                {
                    doc.SubDocs.Add(pdoc);
                }
            }

            foreach (var func in funcs)
            {
                var pdoc = DocumentFunction(func, nextPrefix);
                if (pdoc != null)
                {
                    doc.SubDocs.Add(pdoc);
                }
            }

            return(doc);
        }