/// <summary>
        /// Saves a Store in TriG (Turtle with Named Graphs) format.
        /// </summary>
        /// <param name="store">Store to save.</param>
        /// <param name="writer">Writer to save to.</param>
        /// <param name="leaveOpen">Boolean flag indicating if <paramref name="writer"/> should be left open after the store is saved.</param>
        public void Save(ITripleStore store, TextWriter writer, bool leaveOpen)
        {
            if (store == null)
            {
                throw new RdfOutputException("Cannot output a null Triple Store");
            }
            if (writer == null)
            {
                throw new RdfOutputException("Cannot output to a null writer");
            }

            TriGWriterContext context = new TriGWriterContext(store, writer, _prettyprint, _allowHiSpeed, _compressionLevel, _n3compat);

            // Check there's something to do
            if (context.Store.Graphs.Count == 0)
            {
                if (!leaveOpen)
                {
                    context.Output.Close();
                }
                return;
            }

            // Write the Header of the File
            foreach (var g in context.Store.Graphs)
            {
                context.NamespaceMap.Import(g.NamespaceMap);
            }
            if (context.CompressionLevel > WriterCompressionLevel.None)
            {
                // Only add @prefix declarations if compression is enabled
                context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap);
                foreach (string prefix in context.NamespaceMap.Prefixes)
                {
                    if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                    {
                        context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                    }
                }
                context.Output.WriteLine();
            }
            else
            {
                context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true));
            }

            if (_useMultiThreading)
            {
                // Standard Multi-Threaded Writing

                // Queue the Graphs to be written
                foreach (IGraph g in context.Store.Graphs)
                {
                    context.Add(g.BaseUri);
                }

                // Start making the async calls
                var workers = new Task[_threads];
                for (int i = 0; i < _threads; i++)
                {
                    workers[i] = Task.Factory.StartNew(() => SaveGraphs(context));
                }

                try
                {
                    Task.WaitAll(workers);
                }
                catch (AggregateException ex)
                {
                    var outputException =
                        new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG"));
                    foreach (var innerException in ex.InnerExceptions)
                    {
                        outputException.AddException(innerException);
                    }
                }
                finally
                {
                    // Make sure to close the output
                    if (!leaveOpen)
                    {
                        context.Output.Close();
                    }
                }
            }
            else
            {
                try
                {
                    // Optional Single Threaded Writing
                    foreach (IGraph g in store.Graphs)
                    {
                        TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted);
                        if (context.CompressionLevel > WriterCompressionLevel.None)
                        {
                            graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper);
                        }
                        else
                        {
                            graphContext.NodeFormatter = new UncompressedTurtleFormatter();
                        }
                        context.Output.WriteLine(GenerateGraphOutput(context, graphContext));
                    }

                    // Make sure to close the output
                    if (!leaveOpen)
                    {
                        context.Output.Close();
                    }
                }
                catch
                {
                    try
                    {
                        // Close the output
                        if (!leaveOpen)
                        {
                            context.Output.Close();
                        }
                    }
                    catch
                    {
                        // No catch actions, just cleaning up the output stream
                    }
                    throw;
                }
            }
        }
        /// <summary>
        /// Saves a Store in TriG (Turtle with Named Graphs) format
        /// </summary>
        /// <param name="store">Store to save</param>
        /// <param name="writer">Writer to save to</param>
        public void Save(ITripleStore store, TextWriter writer)
        {
            if (store == null)
            {
                throw new RdfOutputException("Cannot output a null Triple Store");
            }
            if (writer == null)
            {
                throw new RdfOutputException("Cannot output to a null writer");
            }

            TriGWriterContext context = new TriGWriterContext(store, writer, this._prettyprint, this._allowHiSpeed, this._compressionLevel, this._n3compat);

            //Check there's something to do
            if (context.Store.Graphs.Count == 0)
            {
                context.Output.Close();
                return;
            }

            //Write the Header of the File
            foreach (IGraph g in context.Store.Graphs)
            {
                context.NamespaceMap.Import(g.NamespaceMap);
            }
            if (context.CompressionLevel > WriterCompressionLevel.None)
            {
                //Only add @prefix declarations if compression is enabled
                context.QNameMapper = new ThreadSafeQNameOutputMapper(context.NamespaceMap);
                foreach (String prefix in context.NamespaceMap.Prefixes)
                {
                    if (TurtleSpecsHelper.IsValidQName(prefix + ":"))
                    {
                        context.Output.WriteLine("@prefix " + prefix + ": <" + context.FormatUri(context.NamespaceMap.GetNamespaceUri(prefix)) + ">.");
                    }
                }
                context.Output.WriteLine();
            }
            else
            {
                context.QNameMapper = new ThreadSafeQNameOutputMapper(new NamespaceMapper(true));
            }

            if (this._useMultiThreading)
            {
                //Standard Multi-Threaded Writing

                //Queue the Graphs to be written
                foreach (IGraph g in context.Store.Graphs)
                {
                    context.Add(g.BaseUri);
                }

                //Start making the async calls
                List <IAsyncResult> results = new List <IAsyncResult>();
                SaveGraphsDelegate  d       = new SaveGraphsDelegate(this.SaveGraphs);
                for (int i = 0; i < this._threads; i++)
                {
                    results.Add(d.BeginInvoke(context, null, null));
                }

                //Wait for all the async calls to complete
                WaitHandle.WaitAll(results.Select(r => r.AsyncWaitHandle).ToArray());
                RdfThreadedOutputException outputEx = new RdfThreadedOutputException(WriterErrorMessages.ThreadedOutputFailure("TriG"));
                foreach (IAsyncResult result in results)
                {
                    try
                    {
                        d.EndInvoke(result);
                    }
                    catch (Exception ex)
                    {
                        outputEx.AddException(ex);
                    }
                }
                //Make sure to close the output
                context.Output.Close();

                //If there were any errors we'll throw an RdfThreadedOutputException now
                if (outputEx.InnerExceptions.Any())
                {
                    throw outputEx;
                }
            }
            else
            {
                try
                {
                    //Optional Single Threaded Writing
                    foreach (IGraph g in store.Graphs)
                    {
                        TurtleWriterContext graphContext = new TurtleWriterContext(g, new System.IO.StringWriter(), context.PrettyPrint, context.HighSpeedModePermitted);
                        if (context.CompressionLevel > WriterCompressionLevel.None)
                        {
                            graphContext.NodeFormatter = new TurtleFormatter(context.QNameMapper);
                        }
                        else
                        {
                            graphContext.NodeFormatter = new UncompressedTurtleFormatter();
                        }
                        context.Output.WriteLine(this.GenerateGraphOutput(context, graphContext));
                    }

                    //Make sure to close the output
                    context.Output.Close();
                }
                catch
                {
                    try
                    {
                        //Close the output
                        context.Output.Close();
                    }
                    catch
                    {
                        //No catch actions, just cleaning up the output stream
                    }
                    throw;
                }
            }
        }