public ProtoDataObjectSource(ProtoDataObjectSourceKind kind, Engine.XmlFileInfo fileReference)
        {
            Contract.Requires(kind != ProtoDataObjectSourceKind.None);
            Contract.Requires(!kind.RequiresFileReference() || fileReference != null);

            SourceKind    = kind;
            FileReference = fileReference;
        }
        public bool TryStreamData <TContext>(
            Engine.XmlFileInfo xfi, FA mode,
            Action <IO.XmlElementStream, TContext> streamProc, TContext ctxt,
            string ext = null)
        {
            Contract.Requires(xfi != null);
            Contract.Requires(streamProc != null);

            bool result = false;

            if (mode == FA.Read)
            {
                result = true;
                System.IO.FileInfo file;
                var xml_or_xmb = GameEngine.Directories.TryGetXmlOrXmbFile(xfi.Location, xfi.Directory, xfi.FileName, out file, ext);

                if (xml_or_xmb == Engine.GetXmlOrXmbFileResult.FileNotFound)
                {
                    GameEngine.UpdateFileLoadStatus(xfi, Engine.XmlFileLoadState.FileDoesNotExist);
                    throw new System.IO.FileNotFoundException("Neither XML or XMB exists: " + file.FullName);
                }

                try
                {
                    if (result)
                    {
                        using (var s = GameEngine.OpenXmlOrXmbForRead(xml_or_xmb, file.FullName))
                        {
                            SetupStream(s, mode, this);
                            streamProc(s, ctxt);

                            GameEngine.UpdateFileLoadStatus(xfi, Engine.XmlFileLoadState.Loaded);
                        }
                    }
                } catch (Exception ex)
                {
                    ex.UnusedExceptionVar();
                    GameEngine.UpdateFileLoadStatus(xfi, Engine.XmlFileLoadState.Failed);
                    throw;
                }
            }
            else if (mode == FA.Write)
            {
                System.IO.FileInfo file;
                result = GameEngine.Directories.TryGetFile(xfi.Location, xfi.Directory, xfi.FileName, out file, ext);

                if (Engine.XmlFileInfo.RespectWritableFlag)
                {
                    result = result && xfi.Writable;
                }

                if (result)
                {
                    using (var s = IO.XmlElementStream.CreateForWrite(xfi.RootName))
                    {
                        SetupStream(s, mode, this);
                        streamProc(s, ctxt);
                        s.Document.Save(file.FullName);
                    }
                }
            }

            return(result);
        }