public bool StreamTactic <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s
                                                 , string xmlName
                                                 , ref int dbid
                                                 , IO.TagElementNodeType xmlSource = XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            const Phx.DatabaseObjectKind kDbKind = Phx.DatabaseObjectKind.Tactic;

            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = false;

            if (s.IsReading)
            {
                was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);

                if (was_streamed)
                {
                    id_name = System.IO.Path.GetFileNameWithoutExtension(id_name);

                    dbid = Database.GetId(kDbKind, id_name);
                    Contract.Assert(dbid.IsNotNone(), id_name);

                    if (PhxUtil.IsUndefinedReferenceHandle(dbid))
                    {
                        TraceUndefinedHandle(s, id_name, xmlName, dbid, kDbKind.ToString());
                    }
                }
            }
            else if (s.IsWriting)
            {
                if (dbid.IsNone())
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                id_name = Database.GetName(kDbKind, dbid);
                Contract.Assert(!string.IsNullOrEmpty(id_name));

                id_name += Phx.BTacticData.kFileExt;
                s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
            }

            return(was_streamed);
        }
        public bool StreamDBID <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s
                                               , string xmlName, List <int> dbidList
                                               , Phx.DatabaseObjectKind kind
                                               , bool isOptional = true, IO.TagElementNodeType xmlSource = XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));
            Contract.Requires(xmlSource != IO.TagElementNodeType.Attribute);

            bool was_streamed = false;

            if (s.IsReading)
            {
                XmlUtil.ReadDetermineListSize(s, dbidList);

                foreach (var n in XmlUtil.ReadGetNodes(s, xmlName, xmlSource))
                {
                    using (s.EnterCursorBookmark(n))
                    {
                        int dbid = TypeExtensions.kNone;
                        if (StreamDBID(s, xmlName, ref dbid, kind, isOptional, xmlSource))
                        {
                            was_streamed = true;
                            dbidList.Add(dbid);
                        }
                    }
                }
            }
            else if (s.IsWriting && dbidList.Count > 0)
            {
                was_streamed = true;

                foreach (int dbid in dbidList)
                {
                    int dbidCopy = dbid;
                    using (s.EnterCursorBookmark(xmlName))
                        StreamDBID(s, xmlName, ref dbidCopy, kind, isOptional, xmlSource);
                }
            }

            return(was_streamed);
        }
        protected static bool ToLowerName(Phx.DatabaseObjectKind kind)
        {
            switch (kind)
            {
#if false
            case Phx.DatabaseObjectKind.Object:
            case Phx.DatabaseObjectKind.Unit:
                return(Phx.BProtoObject.kBListXmlParams.ToLowerDataNames);

            case Phx.DatabaseObjectKind.Squad:
                return(Phx.BProtoSquad.kBListXmlParams.ToLowerDataNames);

            case Phx.DatabaseObjectKind.Tech:
                return(Phx.BProtoTech.kBListXmlParams.ToLowerDataNames);
#endif

            default:
                return(false);
            }
        }
        public bool StreamDBID <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s,
                                               string xmlName, ref int dbid,
                                               Phx.DatabaseObjectKind kind,
                                               bool isOptional = true, IO.TagElementNodeType xmlSource = XmlUtil.kSourceElement)
            where TDoc : class
            where TCursor : class
        {
            Contract.Requires(xmlSource.RequiresName() == (xmlName != XML.XmlUtil.kNoXmlName));

            string id_name      = null;
            bool   was_streamed = true;
            bool   to_lower     = ToLowerName(kind);

            if (s.IsReading)
            {
                if (isOptional)
                {
                    was_streamed = s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }

                if (was_streamed)
                {
                    dbid = Database.GetId(kind, id_name);
                    Contract.Assert(dbid.IsNotNone());
                    if (PhxUtil.IsUndefinedReferenceHandle(dbid))
                    {
                        TraceUndefinedHandle(s, id_name, xmlName, dbid, kind.ToString());
                    }
                }
                else
                {
                    dbid = TypeExtensions.kNone;
                }
            }
            else if (s.IsWriting)
            {
                if (dbid.IsNone())
                {
                    was_streamed = false;
                    return(was_streamed);
                }

                id_name = Database.GetName(kind, dbid);
                Contract.Assert(!string.IsNullOrEmpty(id_name));

                if (isOptional)
                {
                    s.StreamStringOpt(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
                else
                {
                    s.StreamString(xmlName, ref id_name, to_lower, xmlSource, intern: true);
                }
            }

            return(was_streamed);
        }