public static Vocabulary Create()
        {
            var vocab = new Vocabulary();

            vocab.AddTermHandler <OpenApiDocument, string>("swagger", (s, o) =>
            {
                s.Version = o;
            });
            vocab.AddTermHandler <OpenApiDocument, string>("schemes", (s, o) =>
            {
                if (s.Schemes == null)
                {
                    s.Schemes = new List <String>();
                }
                s.Schemes.Add(o);
            });

            vocab.AddTermHandler("info", (c, o) =>
            {
                var sdoc  = (OpenApiDocument)c.Subject;
                sdoc.Info = new Info();
                return(new Context()
                {
                    Subject = sdoc.Info, Term = "info"
                });
            });

            vocab.AddTermHandler("paths", (c, o) =>
            {
                return(new Context()
                {
                    Subject = c.Subject, Term = "paths"
                });
            });

            vocab.AddDefaultTermHandler("paths", (s, o) =>
            {
                var sdoc = (OpenApiDocument)s.Subject;
                var path = sdoc.AddPath((string)o);
                return(new Context()
                {
                    Subject = path, Term = "_path"
                });
            });

            vocab.AddTermHandler("_path", "get", (c, o) =>
            {
                return(new Context()
                {
                    Subject = (c.Subject as Path)?.AddOperation("get", ""),
                    Term = "_operation"
                });
            });
            vocab.AddTermHandler("_path", "post", (s, o) =>
            {
                return(new Context()
                {
                    Subject = (s.Subject as Path)?.AddOperation("post", ""),
                    Term = "_operation"
                });
            });

            vocab.AddSimpleStringTermHandler("description", "Description");
            vocab.AddSimpleStringTermHandler("title", "Title");
            vocab.AddSimpleStringTermHandler("operationId", "Id");
            vocab.AddSimpleStringTermHandler("x-controller", "XController");
            return(vocab);
        }
        public static void ParseStream(Stream stream, object rootSubject, Vocabulary termHandlers)
        {
            var     reader          = new JsonTextReader(new StreamReader(stream));
            var     ostack          = new Stack <Context>();
            Context currentContext  = null;
            string  currentProperty = "";

            Func <Context, object, Context> termHandler = null;

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                case JsonToken.StartObject:

                    if (currentContext == null)
                    {
                        currentContext = new Context()
                        {
                            Subject = rootSubject,
                            Term    = ""
                        };
                    }
                    else
                    {
                        ostack.Push(currentContext);
                        if (termHandler != null)
                        {
                            var newContext = termHandler(currentContext, currentProperty);
                            if (newContext != null)      // Not an array
                            {
                                currentContext = newContext;
                            }
                        }
                    }
                    DiagSource?.Write("Tavis.JsonStreamingParser.NewObject", currentContext.Term);
                    break;

                case JsonToken.StartArray:
                    break;

                case JsonToken.EndArray:
                    break;

                case JsonToken.EndObject:
                    DiagSource?.Write("Tavis.JsonStreamingParser.EndObject", currentContext.Term);
                    if (ostack.Count > 0)
                    {
                        currentContext = ostack.Pop();
                    }
                    break;

                case JsonToken.PropertyName:
                    currentProperty = reader.Value.ToString();
                    termHandler     = termHandlers.FindHandler(currentContext.Term, currentProperty);
                    break;

                case JsonToken.Integer:
                case JsonToken.Boolean:
                case JsonToken.String:
                    if (termHandler != null)
                    {
                        termHandler(currentContext, reader.Value);
                    }
                    else
                    {
                        DiagSource?.Write("Tavis.JsonStreamingParser.MissingTermHandler", new { Context = currentContext, Property = currentProperty });
                    }
                    break;
                }
            }
        }