internal RegisteredFormat(string name, TagElementStreamFormat baseFormat)
            {
                Name       = name;
                BaseFormat = baseFormat;

                GetExtension = null;
                Open         = null;
            }
        public static dynamic Open(System.IO.Stream sourceStream, TagElementStreamFormat format,
                                   FileAccess permissions = FileAccess.ReadWrite, object owner = null)
        {
            Contract.Requires <ArgumentNullException>(sourceStream != null);
            Contract.Requires <ArgumentException>(sourceStream.HasPermissions(permissions));

            var registration = GetRegistration(format, "open");

            return(registration.Open(format, sourceStream, permissions, owner));
        }
        static string YamlGetExtension(TagElementStreamFormat format)
        {
            Contract.Requires(format.GetBaseFormat() == TagElementStreamFormat.Yaml);

            if (format.IsText())
            {
                return(".yaml");
            }
            else if (format.IsBinary())             // Yaml doesn't support binary formats
            {
                return(null);
            }

            throw new Debug.UnreachableException(format.ToString());
        }
        static string JsonGetExtension(TagElementStreamFormat format)
        {
            Contract.Requires(format.GetBaseFormat() == TagElementStreamFormat.Json);

            if (format.IsText())
            {
                return(".json");
            }
            else if (format.IsBinary())
            {
                return(".bson");
            }

            throw new Debug.UnreachableException(format.ToString());
        }
        static string XmlGetExtension(TagElementStreamFormat format)
        {
            Contract.Requires(format.GetBaseFormat() == TagElementStreamFormat.Xml);

            if (format.IsText())
            {
                return(".xml");
            }
            else if (format.IsBinary())             // haven't decided on a standard to use yet
            {
                throw new NotImplementedException("General binary XML files not yet implemented");
            }

            throw new Debug.UnreachableException(format.ToString());
        }
        static RegisteredFormat GetRegistration(TagElementStreamFormat format, string operation)
        {
            Contract.Requires(!string.IsNullOrEmpty(operation));

            var base_format = format.GetBaseFormat();

            if (!gRegisteredFormats.TryGetValue(base_format, out RegisteredFormat registration))
            {
                throw new ArgumentException(string.Format(Util.InvariantCultureInfo,
                                                          "Format {0} ({1}) is not registered, can't {2}",
                                                          base_format, format, operation));
            }

            return(registration);
        }
        static dynamic YamlOpenFromStream(TagElementStreamFormat format, System.IO.Stream sourceStream,
                                          FileAccess permissions, object owner)
        {
            Contract.Requires(format.GetBaseFormat() == TagElementStreamFormat.Yaml);

            if (format.IsText())
            {
                throw new NotImplementedException();
            }
            else if (format.IsBinary())
            {
                throw new NotSupportedException("Yaml doesn't support binary streams");
            }

            throw new Debug.UnreachableException(format.ToString());
        }
        public static RegisteredFormat Register(TagElementStreamFormat baseFormat, string name = null)
        {
            Contract.Requires <ArgumentException>(baseFormat != TagElementStreamFormat.Undefined);
            Contract.Requires <ArgumentException>(baseFormat.GetTypeFlags() == 0,
                                                  "Format should exclude any type flags when registering");
            Contract.Requires <ArgumentException>((baseFormat >= TagElementStreamFormat.kCustomStart || baseFormat <= TagElementStreamFormat.kCustomEnd) || !string.IsNullOrEmpty(name),
                                                  "Custom formats require an explicit name");

            if (string.IsNullOrEmpty(name))
            {
                name = baseFormat.ToString();
            }

            var registration = new RegisteredFormat(name, baseFormat);

            gRegisteredFormats.Add(baseFormat, registration);

            return(registration);
        }
        static dynamic XmlOpenFromStream(TagElementStreamFormat format, System.IO.Stream sourceStream,
                                         FileAccess permissions, object owner)
        {
            Contract.Requires(format.GetBaseFormat() == TagElementStreamFormat.Xml);

            if (format.IsText())
            {
                var stream = new XmlElementStream(sourceStream, permissions, owner);
                stream.InitializeAtRootElement();

                return(stream);
            }
            else if (format.IsBinary())             // haven't decided on a standard to use yet
            {
                throw new NotImplementedException("General binary XML files not yet implemented");
            }

            throw new Debug.UnreachableException(format.ToString());
        }