public bool AddSchema(string schemaText, string filename, out string error)
        {
            filename = Path.ChangeExtension(filename, null);
            string[] lvls         = filename.Split('\\');
            string   category     = lvls[lvls.Length - 2];
            string   endpointname = lvls[lvls.Length - 1];

            endpointname = char.ToUpper(endpointname[0]) + endpointname.Substring(1);
            category     = char.ToUpper(category[0]) + category.Substring(1);
            RedoxJsonSchema rs = new RedoxJsonSchema(category, endpointname, schemaText);

            schemaTextList.Add(rs);
            error = ParseSchemaDefinitions(rs);
            return(string.IsNullOrEmpty(error));
        }
        private string ParseSchemaDefinitions(RedoxJsonSchema rs)
        {
            string tokenName;
            string typeName;
            string error;

            try
            {
                JObject   tokenItems;
                JToken    token;
                JProperty tokenParent;
                var       sroot       = new JObject();
                var       objs        = sroot.Descendants();
                var       comparer    = new JTokenEqualityComparer();
                var       objectToken = JToken.FromObject("object");
                sroot = rs.Schema;
                objs  = sroot.Descendants()
                        .OfType <JObject>()
                        .Where(t => comparer.Equals(t["type"], objectToken))
                        .ToList();
                foreach (JObject o in objs)
                {
                    AllObjects.Add(o);
                    tokenParent = (JProperty)o.Parent;
                    tokenName   = tokenParent.Name;
                    if (tokenName == "items")
                    {
                        continue;
                    }
                    token = o;
                    if (!IsSimpleObject(o, out error))
                    {
                        continue;
                    }
                    if (!string.IsNullOrEmpty(error))
                    {
                        return(error);
                    }
                    if (!ObjectTypeDict.ContainsKey(tokenName))
                    {
                        ObjectTypeDict.Add(tokenName, token.Parent.ToString());
                        token["title"] = tokenName;
                        defs.Add(new JProperty(tokenName, token));
                    }
                    else if (!ObjectTypeDict.ContainsValue(token.Parent.ToString()))
                    {
                        tokenName = GetNewName(tokenName, ObjectTypeDict);
                        ObjectTypeDict.Add(tokenName, token.Parent.ToString());
                        token["title"] = tokenName;
                        defs.Add(new JProperty(tokenName, token));
                    }
                    else
                    {
                        token["title"] = tokenName;
                    }
                }
                var arrayToken = JToken.FromObject("array");
                var arrObjs    = sroot.Descendants()
                                 .OfType <JObject>()
                                 .Where(t => comparer.Equals(t["type"], arrayToken))
                                 .ToList();
                foreach (JToken a in arrObjs)
                {
                    tokenName  = ((JProperty)a.Parent).Name;
                    tokenItems = (JObject)a["items"];
                    typeName   = tokenName + "Item";
                    if (!ObjectTypeDict.ContainsKey(typeName))
                    {
                        if (IsSimpleObject(tokenItems, out error))
                        {
                            defs.Add(new JProperty(typeName, tokenItems));
                            ObjectTypeDict.Add(typeName, tokenItems.Parent.ToString());
                        }
                        if (!string.IsNullOrEmpty(error))
                        {
                            return(error);
                        }
                        tokenItems["title"] = typeName;
                    }
                    else if (!ObjectTypeDict.ContainsValue(tokenItems.Parent.ToString()))
                    {
                        typeName = GetNewName(typeName, ObjectTypeDict);
                        if (IsSimpleObject(tokenItems, out error))
                        {
                            defs.Add(new JProperty(typeName, tokenItems));
                            ObjectTypeDict.Add(typeName, tokenItems.Parent.ToString());
                        }
                        if (!string.IsNullOrEmpty(error))
                        {
                            return(error);
                        }
                        tokenItems["title"] = typeName;
                    }
                    else
                    {
                        tokenItems["title"] = typeName;
                    }
                }
                foreach (JObject o in objs)
                {
                    tokenParent = (JProperty)o.Parent;
                    tokenName   = tokenParent.Name;
                    if (tokenName == "items")
                    {
                        continue;
                    }
                    if (!IsSimpleObject(o, out error))
                    {
                        if (!string.IsNullOrEmpty(error))
                        {
                            return(error);
                        }
                        if (!ComplexObjectDict.ContainsKey(tokenName) && !ObjectTypeDict.ContainsKey(tokenName))
                        {
                            if (ComplexObjectDict.ContainsValue(o.Parent.ToString()))
                            {
                                tokenName = GetNewName(tokenName, ComplexObjectDict);
                            }
                            ComplexObjectDict.Add(tokenName, o.Parent.ToString());
                            ComplexObjectLists.Add(tokenName, new List <JObject>());
                            ComplexObjectLists[tokenName].Add(o);
                        }
                        else
                        {
                            if (ComplexObjectDict.ContainsValue(o.Parent.ToString()))
                            {
                                if (ComplexObjectLists[tokenName] == null)
                                {
                                    ComplexObjectLists[tokenName] = new List <JObject>();
                                }
                                ComplexObjectLists[tokenName].Add(o);
                            }
                            else
                            {
                                tokenName = GetNewName(tokenName, ComplexObjectDict);
                                ComplexObjectDict.Add(tokenName, o.Parent.ToString());
                                ComplexObjectLists.Add(tokenName, new List <JObject>());
                                ComplexObjectLists[tokenName].Add(o);
                            }
                        }
                        o["title"] = tokenName;
                    }
                    if (!string.IsNullOrEmpty(error))
                    {
                        return(error);
                    }
                }
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
            return("");
        }