/// <summary>Outputs the RDF dataset found in the given JSON-LD object.</summary>
        /// <remarks>Outputs the RDF dataset found in the given JSON-LD object.</remarks>
        /// <param name="input">the JSON-LD input.</param>
        /// <param name="callback"></param>
        /// <param name="options"></param>
        /// <exception cref="JsonLdError"></exception>
        public static async Task <object> ToRdfAsync(JToken input,
                                                     IJsonLdTripleCallback callback,
                                                     JsonLdOptions options)
        {
            JToken expandedInput = await ExpandAsync(input, options);

            var api = await JsonLdApi.CreateAsync(expandedInput, options);

            var dataset = api.ToRdf();

            // generate namespaces from context
            if (options.useNamespaces)
            {
                JArray _input;
                if (input is JArray array)
                {
                    _input = array;
                }
                else
                {
                    _input = new JArray();
                    _input.Add((JObject)input);
                }

                foreach (var e in _input)
                {
                    if (((JObject)e).ContainsKey("@context"))
                    {
                        dataset.ParseContext((JObject)e["@context"]);
                    }
                }
            }

            if (callback != null)
            {
                return(callback.Call(dataset));
            }
            if (options.format != null)
            {
                if ("application/nquads".Equals(options.format))
                {
                    return(new NQuadTripleCallback().Call(dataset));
                }
                else
                {
                    if ("text/turtle".Equals(options.format))
                    {
                        return(new TurtleTripleCallback().Call(dataset));
                    }
                    throw new JsonLdError(JsonLdError.Error.UnknownFormat, options.format);
                }
            }

            return(dataset);
        }
        /// <exception cref="JsonLdError"></exception>
        public static async Task <JObject> FrameAsync(JToken input,
                                                      JToken frame,
                                                      JsonLdOptions options)
        {
            if (frame is JObject)
            {
                frame = JsonLdUtils.Clone((JObject)frame);
            }

            // TODO string/IO input
            JToken expandedInput = await ExpandAsync(input, options);

            var expandedFrame = await ExpandAsync(frame, options);

            var api = await JsonLdApi.CreateAsync(expandedInput, options);

            var framed    = api.Frame(expandedInput, expandedFrame);
            var activeCtx = await api.context.ParseAsync(frame["@context"
                                                         ]);

            var compacted = api.Compact(activeCtx, null, framed);

            if (!(compacted is JArray))
            {
                compacted = new JArray {
                    compacted
                };
            }

            var alias = activeCtx.CompactIri("@graph");
            var rval  = activeCtx.Serialize();

            rval[alias] = compacted;
            JsonLdUtils.RemovePreserve(activeCtx, rval, options);
            return(rval);
        }