private static Type Parse(TypeStringNode nodes)
        {
            string typeStr = nodes.Name;

            if (nodes.Children.Length == 0)
            {
                return(Type.GetType(typeStr));
            }

            typeStr += "`" + nodes.Children.Length;
            Type mainType = Type.GetType(typeStr);

            if (mainType == null)
            {
                return(null);
            }

            Type[] subTypes = nodes.Children.Select((child) => Parse(child)).ToArray();
            if (subTypes.Any((t) => t == null))
            {
                return(null);
            }

            return(mainType.MakeGenericType(subTypes));
        }
        private static TypeStringNode Parse(string str)
        {
            str = str.Trim();
            int openIndex = str.IndexOfAny(searchChars);

            if (openIndex == -1)
            {
                return(new TypeStringNode()
                {
                    Name = str
                });
            }

            if (str[openIndex] != '<')
            { // Opened with something weird
                throw new ArgumentException(str + " was malformed.");
            }

            int closeIndex = str.LastIndexOf('>', openIndex);

            if (closeIndex == -1)
            { // No closing index
                throw new ArgumentException(str + " was malformed.");
            }

            if (closeIndex != str.Length - 1)
            { // Closing index had things afterwards
                throw new ArgumentException(str + " was malformed.");
            }

            string content = str.Substring(openIndex + 1, closeIndex - openIndex - 1);

            if (content.Length == 0)
            { // No generic content
                throw new ArgumentException(str + " was malformed.");
            }

            string[] commaSplit = content.Split(',');

            var ret = new TypeStringNode()
            {
                Name = str.Substring(0, openIndex).Trim()
            };

            if (commaSplit.Length > 0)
            {
                ret.Children = commaSplit.Select((t) => Parse(str)).ToArray();
            }
            return(ret);
        }
        public static TryGet <Type> TryGetType(string name)
        {
            if (!cache.TryGetValue(name, out Type t))
            {
                try
                {
                    TypeStringNode node = Parse(name);
                    throw new NotImplementedException();
                }
                catch
                {
                    cache[name] = null;
                    return(TryGet <Type> .Failure);
                }
            }

            return(TryGet <Type> .Create(t != null, t));
        }