using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace PosStart
{
    /// <summary>
    /// Implements FXS (Framework Xml Schema) Protocol.
    /// <para>(FXS (Framework Xml Schema) Protocol를 구현합니다.)</para>
    /// </summary>
    public class CmMessage : Hashtable
    {
        private static string m_strLock = "";
        /// Name of top tag of Message Object and Object name
        /// <para>(Message객체의 최상위 태크의 이름, 객체의 이름)</para>
        private string m_strName;

        /// List of key values by which input sequence of Message Objects is observed
        /// <para>(Message객체의 입력순서가 지켜지는 key 값의 리스트)</para>
        private ArrayList m_aryKeyList;

        /// Depth for intention of XML when it is output on string, file and screen
        /// <para>(스트링, 파일, 화면에 출력할때 XML의 인텐션을 위한 Depth)</para>
        private int m_intDepth = 0;

        /// It is assembled and stored to output Message Objects
        /// <para>(Message 객체를 출력하기 위하여 조립하여 보관)</para>
        private StringBuilder m_stbMessage;

        private const int STDOUT = 1;
        private const int BUFFER = 2;
        private const String XMLSCHEMA = "";  // pfxs:
        private const String CrLf = "\r\n";

        /// <summary>
        /// Constructor, initializes new instance of CmMessage Class.
        /// <para>(Constructor, CmMessage 클래스의 새 인스턴스를 초기화합니다.)</para>
        /// </summary>
        public CmMessage()
        {
            m_strName = "message";
            m_aryKeyList = new ArrayList();
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Constructor, initializes new instance of CmMessage Class.
        /// <para>(Constructor, CmMessage 클래스의 새 인스턴스를 초기화합니다.)</para>
        /// </summary>
        /// <param name="pStrName">Name of Message Object
        ///                  <para>(Message객체의 이름)</para></param>
        /* --------------------------------------------------------------------------------- */
        public CmMessage(string pStrName)
        {
            m_strName = pStrName;
            m_aryKeyList = new ArrayList();
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// After reading and parsing a file, stores it into CmMessage
        /// <para>(파일을 읽어서 Parsing한후 CmMessage에 보관)</para>
        /// </summary>
        /// <param name="sFileName">Name of Objective File
        ///                   <para>(대상 파일명)</para></param>
        /// <returns>File Content
        ///     <para>(파일 내용)</para></returns>
        /* --------------------------------------------------------------------------------- */
        public static CmMessage MakeMessageFromFile(string sFileName)
        {
            RestoreMessageFile(sFileName);      // 설정파일 복구

            // 파일이 없으면 null 리턴
            if (!File.Exists(sFileName))
            {
                return null;
            }

            Encoding encEncoding = null;									// 파일의 Encoding 정보 체크
            FileStream fs = null;											// 파일을 Stream으로 OPEN
            try
            {
                fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                encEncoding = GetDetectEncodedInfo(fs);
            }
            catch (Exception e)
            {
                //ConsoleNx.WriteLine("Message  Class Error : FileStream e !!!"+e.ToString());

                // 에러난 상태에서 파일을 체크하여 OPEN이면 종료
                try
                {
                    if (fs != null) fs.Close();
                    return null;
                }
                catch (Exception ee)
                {
                    //ConsoleNx.WriteLine("Message  Class Error : FileStream ee !!!"+ee.ToString());
                }
            }


            // 파일의 데이타를 읽어서 sbInput에 보관
            //**************************************************************************************
            StringBuilder sbInput = new StringBuilder("");
            try
            {
                // Do your file operations here, such as getting a string from the byte array that is the file
                int intSize = 0;
                string strBuffer = "";
                byte[] bytBuffer = new byte[16384];									// A good buffer size; should always be base2 in case of Unicode
                char[] chrBuffer = new char[16384];
                do
                {
                    intSize = fs.Read(bytBuffer, 0, 16384);
                    if (encEncoding == Encoding.Unicode)							// Unicode로 변환합니다.
                    {
                        strBuffer = encEncoding.GetString(bytBuffer, 0, intSize);	// Uses the encoding we defined above
                        sbInput.Append(strBuffer);
                    }
                    else															// ANSI로 변환합니다.
                    {
                        Array.Copy(bytBuffer, 0, chrBuffer, 0, intSize);
                        sbInput.Append(chrBuffer, 0, intSize);
                    }
                }
                while (intSize != 0);
                bytBuffer = null;
                chrBuffer = null;
            }
            catch (Exception e)
            {
                //ConsoleNx.WriteLine("Message  Class Error : ReadByte !!!"+e.ToString()); 
            }
            fs.Close();


            try
            {
                // 읽은 데이타를 Parsing 하여 CmMessage Hashtable에 보관
                //**************************************************************************************
                XmlBase p = new XmlBase(sbInput.ToString());
                return p.ParserStart();
            }
            catch
            {
                return null;
            }
        }
        //////#if GLOBAL
        //////        /* --------------------------------------------------------------------------------- */
        //////        /// <summary>
        //////        /// After reading and parsing a file, stores it into CmMessage
        //////        /// <para>(파일을 읽어서 Parsing한후 CmMessage에 보관)</para>
        //////        /// </summary>
        //////        /// <param name="sInStr">Name of Objective File
        //////        ///                   <para>(대상 파일명)</para></param>
        //////        /// <returns>File Content
        //////        ///     <para>(파일 내용)</para></returns>
        //////        /* --------------------------------------------------------------------------------- */
        //////        public static CmMessage MakeMessageFromStr(string sInStr)
        //////        {
        //////            try
        //////            {
        //////                // 읽은 데이타를 Parsing 하여 CmMessage Hashtable에 보관
        //////                //**************************************************************************************
        //////                XmlBase p = new XmlBase(sInStr);
        //////                return p.ParserStart();
        //////            }
        //////            catch
        //////            {
        //////                return null;
        //////            }
        //////        }
        //////#endif
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Reads initial 4 bytes of file to derive encoding information and returns it
        /// <para>(파일의 초기 4바이트를 읽어서 인코딩 정보를 산출하여 리턴)</para>
        /// </summary>
        /// <param name="fisFile">File</param>
        /// <returns>Encoding Information
        ///    <para>(인코딩 정보)</para></returns>
        /* --------------------------------------------------------------------------------- */
        private static Encoding GetDetectEncodedInfo(FileStream fisFile)
        {
            Encoding encEncoding = null;
            if (fisFile.CanSeek)
            {
                byte[] bom = new byte[4]; // Get the byte-order mark, if there is one
                fisFile.Read(bom, 0, 4);
                if ((bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf))
                {
                    encEncoding = Encoding.Unicode;							// utf-8
                    fisFile.Seek(0, System.IO.SeekOrigin.Begin);
                    fisFile.Read(bom, 0, 3);
                }
                else if ((bom[0] == 0xff && bom[1] == 0xfe))
                {
                    encEncoding = Encoding.Unicode;							// ucs-2le, ucs-4le, and ucs-16le
                    fisFile.Seek(0, System.IO.SeekOrigin.Begin);
                    fisFile.Read(bom, 0, 2);
                }
                else if ((bom[0] == 0xfe && bom[1] == 0xff))
                {
                    encEncoding = Encoding.Unicode;							// utf-16 and ucs-2
                    fisFile.Seek(0, System.IO.SeekOrigin.Begin);
                    fisFile.Read(bom, 0, 2);
                }
                else if ((bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff))
                {
                    encEncoding = Encoding.Unicode;							// ucs-4
                    fisFile.Seek(0, System.IO.SeekOrigin.Begin);
                }
                else
                {
                    encEncoding = Encoding.Default;							// ascii (seek o)
                    fisFile.Seek(0, System.IO.SeekOrigin.Begin);
                }
            }
            else
            {
                encEncoding = Encoding.Default;
            }
            return encEncoding;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Message Making
        /// <para>(Messsage 제작)</para>
        /// </summary>
        /// <param name="pMessage">Message Content
        ///                  <para>(메세지 내용)</para></param>
        /// <returns>Number of elements of ArrayList having key of CmMessage Object as Key
        ///    <para>(CmMessage객체에 key를 키로 하는 ArrayList의 요소의 수)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public int MakeMessage(CmMessage pMessage)
        {
            return MakeMessage(pMessage.MessageName, pMessage);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Adds value to ArrayList having key of CmMessage Object as Key.
        /// <para>(CmMessage객체에 key를 키로 하는 ArrayList에 value를 추가한다.)</para>
        /// </summary>
        /// <param name="sKey">String format Key of Message
        ///              <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <param name="oVal">CmMessage or string type value to be added
        ///              <para>(추가할 CmMessage 또는 string타입의 value)</para>
        /// </param>
        /// <returns>Number of elements of ArrayList having key of CmMessage Object as Key
        /// <para>(CmMessage객체에 key를 키로 하는 ArrayList의 요소의 수)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public int MakeMessage(string sKey, object oVal)
        {
            ArrayList aTempList = new ArrayList();
            try
            {
                // Key의 값이 중복되어 있으면 기존의 값도 삭제
                if (this.ContainsKey(sKey) && m_aryKeyList.Contains(sKey))
                {
                    try
                    {
                        aTempList = (ArrayList)this[sKey];
                        this.MakeMessageRemove(sKey);
                    }
                    catch (NullReferenceException e)
                    {
                        //ConsoleNx.WriteLine("Message  Class Error : MakeMessage 1 !!!"+e.ToString());
                        return -1;
                    }
                }

                // Key의 값을 ArrayList의 m_aryKeyList에 Key 값을 추가
                m_aryKeyList.Add(sKey);


                // oVol이 ArrayList이면 입력된 ArrayList를 복사하여 
                if (oVal is ArrayList)
                {
                    aTempList = (ArrayList)((ArrayList)oVal).Clone();
                }
                else
                {
                    aTempList.Add(oVal);
                }

                // CmMessage의 Hashtable에 Key와 Value 값을 추가
                this.Add(sKey, aTempList);
            }
            catch (ArgumentNullException e)
            {
                //ConsoleNx.WriteLine("Message  Class Error : MakeMessage 2 !!!"+e.ToString());
                return -1;
            }
            return aTempList.Count;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Makes and adds Body.Return Tag to CmMessage requesting control.
        /// <para>(제어를 요청한 CmMessage의 Body.Return Tag를 만들어 추가합니다.)</para>
        /// </summary>
        /// <param name="pStrName">Service Name
        ///                  <para>(서비스명)</para></param>
        /// <param name="pStrArgument">Parameters
        ///                      <para>(매개변수)</para></param>
        /// <returns>CmMessage Object
        ///    <para>(CmMessage 객체)</para></returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage MakeMessageBodyReturn(string pStrName, string pStrArgument)
        {
            CmMessage msgReturn = new CmMessage("return");
            msgReturn.MakeMessage("name", pStrName);
            msgReturn.MakeMessage("argument", pStrArgument);
            MakeMessageBody(msgReturn);
            return this;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Changes CmMessage to String and outputs it into a file
        /// <para>(CmMessage를 String로 바꾸어 파일로 출력)</para> 
        /// </summary>
        /// <param name="sFileName">FileName</param>
        /* --------------------------------------------------------------------------------- */
        public void MakeFileFromMessage(string sFileName)
        {
            //다중 쓰레드에서의 동시접근제어를 위해 수정(2017.09.12)
            //lock (this)
            lock (m_strLock)
            {
                string sMsgString = this.ToString();

                // 파일이 있으면 기존파일을 삭제
                //try
                //{
                //    if (File.Exists(sFileName)) 
                //    {
                //        File.Delete(sFileName);
                //    }
                //}
                //catch (Exception e)
                //{
                //    //ConsoleNx.WriteLine("Message  Class Error : MakeFileFromMessage() 1 !!!"+e.ToString());
                //}


                // 새로 파일을 생성하기 위하여 파일오픈
                FileStream fs = null;
                try
                {
                    fs = new FileStream(sFileName, FileMode.Create, FileAccess.Write);
                }
                catch (Exception e)
                {
                    //ComLog.WriteLog(ComLog.Level.Exception, "CmMessage.MakeFileFromMessage()", e.ToString());
                    try
                    {
                        if (fs != null) fs.Close();
                        return;
                    }
                    catch (Exception ee)
                    {
                        //ComLog.WriteLog(ComLog.Level.Exception, "CmMessage.MakeFileFromMessage()", e.ToString());
                    }
                }


                // 새로운 파일에 유니코드 정보를 출력
                try
                {
                    byte[] header = { 0xff, 0xfe };
                    fs.WriteByte(header[0]);
                    fs.WriteByte(header[1]);
                }
                catch (Exception e)
                {
                    //ConsoleNx.WriteLine("Message  Class Error : MakeFileFromMessage() 4 !!!"+e.ToString());
                    //BaseLog.WriteLogFile(BaseCom.LOG_ERROR, "Cosmos.BaseFrame", "CmMessage.MakeFileFromMessage()", e.ToString());
                    //ComLog.WriteLog(ComLog.Level.Exception, "CmMessage.MakeFileFromMessage()", e.ToString());

                }


                // 새로운 파일에 CmMessage의 String데이타를 출력
                try
                {
                    UnicodeEncoding encEncoding = new UnicodeEncoding(false, false);
                    byte[] wByte = encEncoding.GetBytes(sMsgString);
                    for (int i = 0; i < wByte.Length; i++)
                    {
                        fs.WriteByte(wByte[i]);
                    }
                    fs.Flush();
                    fs.Close();

                    //설정파일 백업 기능 주석 처리(20170927)
                    //BackUpMessageFile(sFileName);       // 설정파일 백업
                }
                catch (Exception e)
                {
                    fs.Close();

                    //BaseLog.WriteLogFile(BaseCom.LOG_ERROR, "Cosmos.BaseFrame", "CmMessage.MakeFileFromMessage()", e.ToString());
                    //ComLog.WriteLog(ComLog.Level.Exception, "CmMessage.MakeFileFromMessage()", e.ToString());
                }
            }
        }


        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets CmMessage Object as string format XML Message
        /// <para>(CmMessage객체를 string형태의 XML Message로 얻는다.)</para>
        ///
        /// </summary>
        /// <returns>String format Message of Message Object
        ///    <para>(Message객체를 string형태의 Message)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public override string ToString()
        {
            try
            {
                m_stbMessage = new StringBuilder();
                // 2010.6.14 YSR ADD
                if (m_strName.LastIndexOf(XMLSCHEMA) < 0)
                {
                    m_stbMessage.Append("<" + XMLSCHEMA + m_strName + ">" + CrLf);
                    MessagePrint(this);
                    m_stbMessage.Append("</" + XMLSCHEMA + m_strName + ">" + CrLf);
                }
                else
                {
                    m_stbMessage.Append("<" + m_strName + ">" + CrLf);
                    MessagePrint(this);
                    m_stbMessage.Append("</" + m_strName + ">" + CrLf);
                }

                return m_stbMessage.ToString();
            }
            catch (Exception e)
            {
                //ConsoleNx.WriteLine("Message Error : ToString Exception !!!"+e.ToString());
                return "";
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receives input of CmMessage and outputs it classified by Object
        /// <para>(CmMessage를 입력받아서 Object에 따라 구분하여 출력)</para>
        /// </summary>
        /// <param name="msg">CmMessage Object to be output
        ///             <para>(출력할 CmMessage객체)</para>
        /// </param>
        /* --------------------------------------------------------------------------------- */
        private void MessagePrint(CmMessage msg)
        {
            try
            {
                m_intDepth++;
                String curKey = "";
                int size = 0;

                for (int index = 0; index < msg.m_aryKeyList.Count; index++)
                {
                    curKey = (string)msg.m_aryKeyList[index];
                    ArrayList tmpAL = (ArrayList)msg[curKey];
                    size = tmpAL.Count;

                    for (int i = 0; i < size; i++)
                    {
                        Object obj = msg.GetMessageObject(curKey, i);
                        // 보관된 자료가 CmMessage이면 재귀호출하여 처리
                        if (obj is CmMessage)
                        {
                            // 2010.6.14 YSR ADD
                            if (curKey.LastIndexOf(XMLSCHEMA) < 0)
                            {
                                MessagePrint("<" + XMLSCHEMA + ((CmMessage)obj).m_strName + ">");
                                MessagePrint((CmMessage)obj);
                                MessagePrint("</" + XMLSCHEMA + curKey + ">");
                            }
                            else
                            {
                                MessagePrint("<" + ((CmMessage)obj).m_strName + ">");
                                MessagePrint((CmMessage)obj);
                                MessagePrint("</" + curKey + ">");
                            }

                        }
                        // 보관된 자료가 String이면 화면또는 버퍼로 출력
                        else if (obj is string)
                        {
                            // 2010.6.14 YSR ADD
                            if (curKey.LastIndexOf(XMLSCHEMA) < 0)
                            {
                                MessagePrint("<" + XMLSCHEMA + curKey + ">" + (String)obj + "</" + XMLSCHEMA + curKey + ">");
                            }
                            else
                            {
                                MessagePrint("<" + curKey + ">" + (String)obj + "</" + curKey + ">");
                            }
                        }
                        // 보관된 자료가 그외이면 에러처리
                        else
                        {
                            if (obj == null)
                                MessagePrint("<Error>" + curKey + "'s value is null</Error>");
                            else
                                MessagePrint("<Error>Return Object is not Message or String. this is " + obj.ToString() + "</Error>");
                        }
                    }
                }
                m_intDepth--;
            }
            catch (Exception e)
            {
                //ConsoleNx.WriteLine("Message  Class Error : MessagePrint(Message, int) !!!"+e.ToString()); 
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Receives input of String and outputs it to the screen and buffer
        /// <para>(String를 입력받아서 화면, 버퍼로 출력)</para>
        /// </summary>
        /// <param name="pString">String Object to be output
        ///                 <para>(출력할 string객체)</para>
        /// </param>
        /* --------------------------------------------------------------------------------- */
        private void MessagePrint(string pString)
        {
            try
            {
                // 버퍼로 데이타를 출력하여 보관
                for (int i = 0; i < m_intDepth; i++)
                {
                    m_stbMessage.Append("\t");
                }
                m_stbMessage.Append(pString + "" + CrLf);
            }
            catch (Exception e)
            {
                //ConsoleNx.WriteLine("Message  Class Error : MessagePrint(string, int) !!!"+e.ToString());
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets ArrayList Object having key of CmMessage Object as Key.
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        ///             <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <returns>ArrayList Object having key of CmMessage Object as Key
        ///    <para>(Message객체의 key를 키로 가진 ArrayList객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public ArrayList GetMessageArrayList(string key)
        {
            if (this[key] != null)
                return (ArrayList)this[key];
            else
                return null;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets the (index)th object of ArrayList having key of CmMessage Object as Key.
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList의 index번째의 object객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        ///             <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <param name="index">Index on ArrayList of the desired object
        ///               <para>(원하는 object객체의 ArrayList에서의 인덱스)</para>
        /// </param>
        /// <returns>The (index)th object of ArrayList having key of CmMessage Object as Key
        ///    <para>(Message객체의 key를 키로 가진 ArrayList의 index번째의 object객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public object GetMessageObject(string key, int index)
        {
            object obj = null;
            try
            {
                obj = ((ArrayList)(this[key]))[index];
            }
            catch (Exception)
            {
                obj = null;
            }
            return obj;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Changes of the (index)th value of ArrayList having key of CmMessage Object as Key
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList의 index번째의 값을 변경한다.)</para>
        /// </summary>
        /// <param name="key">Key Value<para></para></param>
        /// <param name="index">Index<para></para></param>
        /// <param name="sValue">Changing Value
        ///                <para>(변경 값)</para></param>
        /// <returns>Processing Result
        ///    <para>(처리 결과)</para></returns>
        /* --------------------------------------------------------------------------------- */
        public bool MakeMessageOverWrite(string key, int index, string sValue)
        {
            try
            {
                ((ArrayList)(this[key]))[index] = sValue;
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get the 0th string object of ArrayList having key of CmMessage Object as Key.
        ///	<para>(CmMessage객체의 key를 키로 가진 ArrayList의 0번째의 string객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        ///             <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <returns>The 0th string object of ArrayList having key of CmMessage Object as Key
        ///    <para>(Message객체의 key를 키로 가진 ArrayList의 0번째의 string객체)</para>
        /// </returns>		
        /* --------------------------------------------------------------------------------- */
        public string GetMessageValue(string key)
        {
            //2014.02.19 YSR UPD
            try
            {
                object obj = GetMessageObject(key, 0);
                if (obj == null)
                {
                    return null;
                }
                else
                {
                    return (string)obj;
                }
            }
            catch
            {
                return null;
            }
            //return (string) GetMessageObject(key, 0);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets the (index)th string object of ArrayList having key of CmMessage Object as Key.
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList의 index번째의 string객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        /// <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <param name="index">Index in ArrayList of desired string Object
        /// <para>(원하는 string객체의 ArrayList에서의 인덱스)</para>
        /// </param>
        /// <returns>The (index)th string object of ArrayList having key of CmMessage Object as Key
        /// <para>(Message객체의 key를 키로 가진 ArrayList의 index번째의 string객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageValue(string key, int index)
        {
            //2014.02.19 YSR UPD
            try
            {
                object obj = GetMessageObject(key, index);
                if (obj == null)
                {
                    return null;
                }
                else
                {
                    return (string)obj;
                }
            }
            catch
            {
                return null;
            }
            //return (string)GetMessageObject(key, index);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets the 0th sub-Message object of ArrayList having key of CmMessage Object as Key.
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList의 0번째의 sub-Message객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        /// <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <returns>the 0th sub-Message object of ArrayList having key of CmMessage Object as Key
        /// <para>(Message객체의 key를 키로 가진 ArrayList의 0번째의 sub-Message객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessage(string key)
        {
            try
            {
                // 2013.11.12 YSR UPD
                key = key.Trim();
                object obj = GetMessageObject(key, 0);
                if (obj == null && (key != FxsAttr.RECORD && key != FxsAttr.HEADER && key != FxsAttr.AGENT && key != FxsAttr.BODY && key != FxsAttr.RETURN && key != FxsAttr.SERVICE && key != FxsAttr.DEST))
                {
                    CmMessage msgTemp = new CmMessage(key);
                    MakeMessage(key, msgTemp);
                }
                return (CmMessage)GetMessageObject(key, 0);
            }
            catch
            {
                return null;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets the (index)th sub-Message object of ArrayList having key of CmMessage Object as Key.
        /// <para>(CmMessage객체의 key를 키로 가진 ArrayList의 index번째의 sub-Message객체를 얻는다.)</para>
        /// </summary>
        /// <param name="key">String format Key of Message
        /// <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <param name="index">Index in ArrayList of desired sub-Message Object
        /// <para>(원하는 sub-Message객체의 ArrayList에서의 인덱스)</para>
        /// </param>
        /// <returns>The (index)th sub-Message object of ArrayList having key of CmMessage Object as Key
        /// <para>(Message객체의 key를 키로 가진 ArrayList의 index번째의 sub-Message객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessage(string key, int index)
        {
            try
            {
                return (CmMessage)GetMessageObject(key, index);
            }
            catch
            {
                return null;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets body subMessage Object from CmMessage Object.
        /// <para>(CmMessage객체에서 body subMessage객체를 얻는다.)</para>
        /// </summary>
        /// <returns>CmMessage Object of which body tag is the top level tag
        /// <para>(body태크가 최상위 태그인 CmMessage객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessageHeader()
        {
            return GetMessage("header");
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets a value having given key out of header subMessage of Message as Key.
        /// <para>(Messsage객체의 header subMessage중 주어진 key를 키로 갖는 값을 얻는다.)</para>
        /// </summary>
        /// <param name="pStrKey">String format Key of the value to be found from header subMessage
        ///                 <para>(header subMessage에서 찾을 값의 string형태의 키)</para>
        /// </param>
        /// <returns>Value having given key out of header subMessage of Message as Key
        ///    <para>(header subMessage중 주어진 key를 키로가지는 값)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageHeader(string pStrKey)
        {
            return GetMessageHeader().GetMessageValue(pStrKey);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Gets body subMessage Object from CmMessage Object.
        /// <para>(CmMessage객체에서 body subMessage객체를 얻는다.)</para>
        /// </summary>
        /// <returns>CmMessage Object of which body tag is the top level tag
        ///    <para>(body태크가 최상위 태그인 CmMessage객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessageBody()
        {
            return GetMessage("body");
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Message Information for the Agent under Body of CmMessage
        /// <para>(CmMessage의 Body아래의 Agent에 대한 Message 정보 가져오기)</para>
        /// </summary>
        /// <returns>CmMessage Object of which Agent tag is the top level tag
        ///    <para>(Agent태크가 최상위 태그인 CmMessage객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessageBodyAgent()
        {
            CmMessage msgReturn = GetMessageBody();
            if (msgReturn != null)
            {
                msgReturn = msgReturn.GetMessage("agent");
            }
            return msgReturn;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Value information of Key value under Body.Agent of CmMessage
        /// <para>(CmMessage의 Body.Agent아래의 Key값에 대한 Value정보 가져오기)</para>
        /// </summary>
        /// <param name="pStrKey"></param>
        /// <returns>Value having given key out of Agent subMessage as Key
        ///    <para>(Agent subMessage중 주어진 key를 키로가지는 값)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageBodyAgent(string pStrKey)
        {
            CmMessage msgReturn = GetMessageBodyAgent();
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue(pStrKey);
            }
            return null;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Message information for Service under Body.Agent of CmMessage
        /// <para>(CmMessage의 Body.Agent아래의 Service에 대한 Message 정보 가져오기)</para>
        /// </summary>
        /// <returns>CmMessage Object of which service tag is the top level tag
        ///    <para>(service태크가 최상위 태그인 CmMessage객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage GetMessageBodyAgentService()
        {
            CmMessage msgReturn = GetMessageBodyAgent();
            if (msgReturn != null)
            {
                msgReturn = msgReturn.GetMessage("service");
            }
            return msgReturn;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Message information for Service under Body.Agent of CmMessage
        /// <para>(CmMessage의 Body.Agent.Service아래의 Key값에 대한 Value정보 가져오기)</para>
        /// </summary>
        /// <param name="pStrKey">Key Value</param>
        /// <returns>Value of the respective Key
        ///    <para>(해당 Key에대한 값)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageBodyAgentService(string pStrKey)
        {
            CmMessage msgReturn = GetMessageBodyAgentService();
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue(pStrKey);
            }
            return null;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Name information under Body.Return of CmMessage
        /// <para>(CmMessage의 Body.Return아래의 Name 정보 가져오기)</para>
        /// </summary>
        /// <returns>Value having given name out of Return subMessage
        ///    <para>(Return subMessage중 주어진 name를 키로가지는 값)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageBodyReturn()
        {
            CmMessage msgReturn = GetMessageBody().GetMessage("return");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("name");
            }
            else
            {
                return "";
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get argument information under Body.Return of CmMessage
        /// <para>(CmMessage의 Body.Return아래의 arguement정보 가져오기)</para>
        /// </summary>
        /// <returns>Value having given argument out of Return subMessage as Key
        ///    <para>(Return subMessage중 주어진 argument를 키로가지는 값)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageBodyReturnValue()
        {
            CmMessage msgReturn = GetMessageBody().GetMessage("return");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("argument");
            }
            else
            {
                return "";
            }
        }
        ///
        /// <summary>
        /// Get UID of Device set to be used
        /// <para>(사용하기로 설정된 장비의 UID 가져오기)</para>
        /// </summary>
        /// <returns>UID</returns>
        ///
        public string GetMessageDeviceUid(string pDeviceType)
        {
            CmMessage msgReturn = GetMessage(pDeviceType).GetMessage("device");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uid");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get UID NAME of Device set to be used
        /// <para>(사용하기로 설정된 장비의 UID  NAME 가져오기)</para>
        /// </summary>
        /// <returns>Uidname</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageDeviceUidname(string pDeviceType)
        {
            CmMessage msgReturn = GetMessage(pDeviceType).GetMessage("device");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uidname");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get UID of Network set to be used
        /// <para>(사용하기로 설정된 Network의 UID 가져오기)</para>
        /// </summary>
        /// <returns>UID</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageNetworkUid(string pNetworkType)
        {
            CmMessage msgReturn = GetMessage(pNetworkType).GetMessage("network");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uid");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get UID NAME of Network set to be used
        /// <para>(사용하기로 설정된 Network의 UID  NAME 가져오기)</para>
        /// </summary>
        /// <returns>Uidname</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageNetworkUidname(string pNetworkType)
        {
            CmMessage msgReturn = GetMessage(pNetworkType).GetMessage("network");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uidname");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get UID of Database set to be used
        /// <para>(사용하기로 설정된 Database의 UID 가져오기)</para>
        /// </summary>
        /// <returns>UID</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageDatabaseUid(string pDatabaseType)
        {
            CmMessage msgReturn = GetMessage(pDatabaseType).GetMessage("database");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uid");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get UID NAME of Database set to be used
        /// <para>(사용하기로 설정된 Database의 UID  NAME 가져오기)</para>
        /// </summary>
        /// <returns>Uidname</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetMessageDatabaseUidname(string pDatabaseType)
        {
            CmMessage msgReturn = GetMessage(pDatabaseType).GetMessage("database");
            if (msgReturn != null)
            {
                return msgReturn.GetMessageValue("uidname");
            }
            else
            {
                return "";
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates information if there is no Header information or changes information if it exists.
        /// <para>(Header의 정보가 없으면 생성하고, 있으면 정보를 변경합니다.)</para>
        /// </summary>
        /// <example>
        /// <code>
        ///    string sUid   = BaseCom.NetUseConf.GetMessageNetworkUid(Classify.UseAgentList.VAN);
        ///    string sUidnm = BaseCom.NetUseConf.GetMessageNetworkUidname(Classify.UseAgentList.VAN);
        /// 
        ///    CmMessage msgSend1 = new CmMessage();
        /// 
        ///    msgSend1.MakeMessageHeaderInfo("NetworkManager", "protocol", "true");
        ///    msgSend1.MakeMessageBodyAgentInfo(sUid, sUidnm);
        ///    msgSend1.MakeMessageBodyAgentServiceInfo("CardApproval", "", "020244040040402039", "");
        /// </code>
        /// </example>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageHeaderInfo(string pStrDest, string pStrTpye, string pStrFeedback)
        {
            CmMessage msgHeader = GetMessage("header");
            if (msgHeader == null)
            {
                msgHeader = new CmMessage("header");
                MakeMessage("header", msgHeader);
            }
            if (pStrDest != null) msgHeader.MakeMessageOverWrite("dest", pStrDest);
            if (pStrTpye != null) msgHeader.MakeMessageOverWrite("type", pStrTpye);
            if (pStrFeedback != null) msgHeader.MakeMessageOverWrite("feedback", pStrFeedback);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body, and adds Name and Message of pMessage under Body
        /// <para>(Body를 생성하고, Body아래에 pMessage의 Name과 Message를 추가합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBody(CmMessage pMessage)
        {
            CmMessage msgBody = GetMessage("body");
            if (msgBody == null)
            {
                msgBody = new CmMessage("body");
                MakeMessage("body", msgBody);
            }
            if (pMessage != null) msgBody.MakeMessage(pMessage.MessageName, pMessage);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body and Agent and adds Name and Message of pMessage under Body.Agent.
        /// <para>(Body와 Agent를 생성하고, Body.Agent아래에 pMessage의 Name과 Message를 추가합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgent(CmMessage pMessage)
        {
            MakeMessageBodyAgent(pMessage.MessageName, pMessage);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body and Agent and adds Key and Value under Body.Agent.
        /// <para>(Body와 Agent를 생성하고, Body.Agent아래에 Key, Value를 추가합니다.)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgent(string pStrKey, object pObjValue)
        {
            CmMessage msgBody = GetMessage("body");
            if (msgBody == null)
            {
                msgBody = new CmMessage("body");
                MakeMessage("body", msgBody);
            }
            CmMessage msgDevice = msgBody.GetMessage("agent");
            if (msgDevice == null)
            {
                msgDevice = new CmMessage("agent");
                msgBody.MakeMessage("agent", msgDevice);
            }
            if (pStrKey != null) msgDevice.MakeMessage(pStrKey, pObjValue);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Agent and adds uid and uidname under Body.
        /// <para>(Body를 생성하고, Body아래에 Agent를 생성한후 uid, uidname을 추가한다.)</para>
        /// </summary>
        /// <param name="pStrUid"></param>
        /// <param name="pStrUidname"></param>
        /// <example>It is an example edit Protocol to acquire Uid and UidName information from Protocol CmMessage and send them to Controller.
        /// <para>(CmMessage 객체에서 Uid, UidName 정보를 취득한 후 Controller로 전송할 Protocol을 편집하는 예제입니다.</para>
        /// <code>
        /// 
        ///    string sUid   = BaseCom.NetUseConf.GetMessageNetworkUid(Classify.UseAgentList.VAN);
        ///    string sUidnm = BaseCom.NetUseConf.GetMessageNetworkUidname(Classify.UseAgentList.VAN);
        /// 
        ///    CmMessage msgSend1 = new CmMessage();
        /// 
        ///    msgSend1.MakeMessageHeaderInfo("NetworkManager", "protocol", "true");
        ///    msgSend1.MakeMessageBodyAgentInfo(sUid, sUidnm);
        ///    msgSend1.MakeMessageBodyAgentServiceInfo("CardApproval", "", "020244040040402039", "");
        /// </code>
        /// </example>
        /// 
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgentInfo(string pStrUid, string pStrUidname)
        {
            if (pStrUid != null) MakeMessageBodyAgent("uid", pStrUid);
            if (pStrUidname != null) MakeMessageBodyAgent("uidname", pStrUidname);
        }

        /*
                public void MakeMessageBodyAgentDongHo(string pStrDong, string pStrHo)
                {
                    if (pStrDong != null) MakeMessageBodyAgent("dong", pStrDong);
                    if (pStrHo != null)	  MakeMessageBodyAgent("ho",   pStrHo);
                }
        */
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body, Agent and Service and adds Name and Message of pMessage under Body.Agent.Service.
        /// <para>(Body, Agent, Service를 생성하고, Body.Agent.Service아래에 pMessage의 Name과 Message를 추가합니다.)</para>
        /// </summary>
        /// <param name="pMessage"></param>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgentService(CmMessage pMessage)
        {
            MakeMessageBodyAgentService(pMessage.MessageName, pMessage);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body, Agent and Service and adds Key and Value under Body.Agent.Service.
        /// <para>(Body, Agent, Service를 생성하고, Body.Agent.Service아래에 Key, Value를 추가합니다.)</para>
        /// </summary>
        /// <param name="pStrKey">추가할 Key  <para>Key to be added</para></param>
        /// <param name="pObjValue">추가할 Value <para>Value to be added</para></param>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgentService(string pStrKey, object pObjValue)
        {
            CmMessage msgBody = GetMessage("body");
            if (msgBody == null)
            {
                msgBody = new CmMessage("body");
                MakeMessage("body", msgBody);
            }
            CmMessage msgDevice = msgBody.GetMessage("agent");
            if (msgDevice == null)
            {
                msgDevice = new CmMessage("agent");
                msgBody.MakeMessage("agent", msgDevice);
            }
            CmMessage msgService = msgDevice.GetMessage("service");
            if (msgService == null)
            {
                msgService = new CmMessage("service");
                msgDevice.MakeMessage("service", msgService);
            }
            if (pStrKey != null) msgService.MakeMessage(pStrKey, pObjValue);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Body, Agent and Service and adds Name, Argument, Explicit, Comment under Body.Agent.Service.
        /// <para>(Body, Agent, Service를 생성하고, Body.Agent.Service아래에 Name, Arguement, Explicit, Comment를 추가합니다.)</para>
        /// </summary>
        /// <param name="pStrName">Service Name
        ///                  <para>(서비스명)</para></param>
        /// <param name="pStrArgument">Parameter
        ///                      <para>(매개변수)</para></param>
        /// <param name="pStrExplicit">Additional Description
        ///                      <para>(부가설명)</para></param>
        /// <param name="pStrComment">Description
        ///                     <para>(설명)</para></param>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageBodyAgentServiceInfo(string pStrName, string pStrArgument, string pStrExplicit, string pStrComment)
        {
            CmMessage msgService = new CmMessage("service");				// 서비스
            if (pStrName != null) msgService.MakeMessage("name", pStrName);		// Name
            if (pStrArgument != null) msgService.MakeMessage("argument", pStrArgument);	// Argument
            if (pStrExplicit != null) msgService.MakeMessage("explicit", pStrExplicit);	// 부가설명
            if (pStrComment != null) msgService.MakeMessage("comment", pStrComment);	// 설명
            MakeMessageBodyAgent(msgService);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Makes and returns Network Socket Connection Stop Message. (Negotiates with other party later.)
        /// <para>(네트워크 소켓 연결 종료 메시지를 만들어 반환한다. (나중에 상대측과 협의한다.))</para>
        /// </summary>
        /// <returns>Network Socket Connection Stop CmMessage Object
        /// <para>(네트워크 소켓 연결 종료 CmMessage객체)</para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        public static CmMessage MakeMessageQuit()
        {
            CmMessage msgReturn = new CmMessage("message");
            msgReturn.MakeMessageHeaderInfo("DeviceCtrl", "response", "false");
            msgReturn.MakeMessageBodyAgentServiceInfo("socket", "close", null, null);
            return msgReturn;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Inputs new value pObjValue with given pStrKey as Key. The previous value is cleared.
        /// <para>(주어진 pStrKey를 키로해서 새로운 값 pObjValue을 넣는다. 이전 값은 지워진다.)</para>
        /// </summary>
        /// <param name="pStrKey">String format Key of Message
        /// <para>(Message의 string형태의 키)</para>
        /// </param>
        /// <param name="pObjValue">New value of Message in object format
        /// <para>(Message의 object형태의 새로운 값)</para>
        /// </param>
        /// <returns>pStrKey를 키로 하는 값(ArrayList)의 요소의 갯수
        /// <para></para>
        /// </returns>
        /* --------------------------------------------------------------------------------- */
        //public void MakeMessageOverWrite(string pStrKey, object pObjValue)
        public void MakeMessageOverWrite(string pStrKey, string pObjValue)
        {
            MakeMessageRemove(pStrKey.Trim());
            MakeMessage(pStrKey.Trim(), pObjValue);
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Delete elements having given key as Key. Deletes it on keyList.
        /// <para>(주어진 key를 키로 가진 요소을 지운다. keyList에서도 삭제한다.)</para>
        /// </summary>
        /// <param name="key">It is a string type Key of the element to be deleted.
        /// <para>(제거할 요소의 string타입의 키입니다.)</para>
        /// </param>
        /* --------------------------------------------------------------------------------- */
        public void MakeMessageRemove(string key)
        {
            base.Remove(key);
            m_aryKeyList.Remove(key);
        }

        /* -------------------------------------------------------------------------------------------- */
        /// <summary>
        /// Creates Components.INI file to be output
        /// <para>(출력할 Components.INI 파일 생성)</para>
        /// </summary>
        /// <param name="filePath">Module Name
        ///               <para>(파일결오)</para></param>
        /// <param name="sName">Module Name
        ///               <para>(모듈명)</para></param>
        /// <param name="sVersion">Version
        ///                  <para>(버젼)</para></param>
        /// <param name="sStatus">Status
        ///                 <para>(상태)</para></param>
        /* -------------------------------------------------------------------------------------------- */
        public static void MakeComponentsInfo(string filePath, string sName, string sVersion, string sStatus)
        {
            // 출력할 Components.INI 파일의 위치를 산출
            //**************************************************************************************
            //string sFileName = BaseCom.NxIniPath + @"Components.INI";
            string sFileName = Path.Combine(filePath, "Components.INI");

            lock (m_strLock)
            {
                // 출력할 Components.INI 파일을 읽어서 CmMessage로 만듭니다
                //**************************************************************************************
                CmMessage msgLog = CmMessage.MakeMessageFromFile(sFileName);

                if (msgLog == null)
                {
                    // Components 파일없는경우에만 Components 파일을 생성합니다.
                    //**********************************************************************************
                    CmMessage msgComponents = new CmMessage();
                    msgComponents.MessageName = "components";
                    //msgComponents.MakeFileFromMessage(BaseCom.NxIniPath + @"Components.INI");
                    msgComponents.MakeFileFromMessage(sFileName);

                    msgLog = CmMessage.MakeMessageFromFile(sFileName);
                }
                CmMessage mSubCompLog = new CmMessage("" + (msgLog.Count + 1));


                // 로드한 프로그램명, 버젼, 상태를 보관합니다.
                //**************************************************************************************
                mSubCompLog.MakeMessage("name", sName);
                mSubCompLog.MakeMessage("version", sVersion);
                mSubCompLog.MakeMessage("status", sStatus);


                // CmMessage에 subMessage를 추가하고, Components.INI 파일에 출력합니다.
                //**************************************************************************************
                msgLog.MakeMessage(mSubCompLog.MessageName, mSubCompLog);
                msgLog.MakeFileFromMessage(sFileName);
                //ConsoleNx.WriteLine("Message Message : " + sName + " ComponentInfo Maked !!!");                
            }
        }

        /* -------------------------------------------------------------------------------------------- */
        /// <summary>
        /// Service.INI File Creation
        /// <para>(Service.INI 파일 생성)</para>
        /// </summary>
        /// <param name="pFilePath">File Name</param>
        /// <param name="pFilename">File Name</param>
        /// <returns>Processing Result
        ///    <para>(처리 결과)</para>
        /// </returns>
        /* -------------------------------------------------------------------------------------------- */
        public static bool MakeServiceInfo(string pFilePath, string pFilename)
        {
            // 출력할 Service.INI 파일의 위치를 산출
            //**************************************************************************************
            string sFileName = pFilename;

            lock (m_strLock)
            {
                // 출력할 Service.INI 파일을 읽어서 CmMessage로 만듭니다
                //**************************************************************************************
                CmMessage msgService = CmMessage.MakeMessageFromFile(sFileName);

                //if (msgService != null)
                //{
                // 항상 Service.ini 파일을 신규 생성합니다.
                //**********************************************************************************
                CmMessage msgTemp = new CmMessage();
                msgTemp.MessageName = "message";
                msgTemp.MakeFileFromMessage(sFileName);

                msgService = CmMessage.MakeMessageFromFile(sFileName);
                //}

                CmMessage msgProcess = new CmMessage("assembly");
                // Detail Service 파일 가져오기
                //string[] strLoadFiles = Directory.GetFiles(BaseCom.NxIniPath, "*Config.INI");
                string[] strLoadFiles = Directory.GetFiles(pFilePath, "*Config.INI");

                string strFileName = "";
                int intStartPos, intEndPos1, intEndPos2;
                // INI폴더내의 파일
                foreach (string strFile in strLoadFiles)
                {
                    intStartPos = strFile.LastIndexOf(@"\") + 1;
                    intEndPos1 = strFile.LastIndexOf("Config.INI");
                    intEndPos2 = strFile.LastIndexOf("Service");
                    strFileName = strFile.Substring(intStartPos, strFile.Length - intStartPos);
                    // Service파일인 경우만 처리
                    if (strFileName.Length > 0 && (intEndPos1 > 0 && intEndPos2 > 0))
                    {
                        msgProcess = CmMessage.MakeMessageFromFile(strFile);
                        ArrayList arrAssembly = msgProcess.GetMessageArrayList(("assembly"));
                        if (arrAssembly.Count > 1)
                        {
                            foreach (CmMessage msgTemp2 in arrAssembly)
                            {
                                string Assemblyname = msgTemp2.GetMessageValue("name");

                                //CmMessage msgAssembly = msgProcess.GetMessage("assembly");
                                msgService.MakeMessage(msgTemp2.MessageName, msgTemp2);
                            }
                        }
                        else
                        {
                            CmMessage msgAssembly = msgProcess.GetMessage("assembly");
                            msgService.MakeMessage(msgAssembly.MessageName, msgAssembly);
                        }
                    }
                }
                // Message에 subMessage를 추가하고, Service.INI 파일에 출력합니다.
                //**************************************************************************************

                msgService.MakeFileFromMessage(sFileName);
                return true;
                //ConsoleNx.WriteLine("Message Message : " + sName + " ComponentInfo Maked !!!");
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Returns a copy of same CmMessage.
        /// <para>(동일한 CmMessage의 복사본을 리턴합니다.)</para>
        /// </summary>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public CmMessage MessageClone()
        {
            XmlBase parMessgae = new XmlBase(this.ToString());
            return parMessgae.ParserStart();
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Message Name
        /// <para>(메세지 명)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public string MessageName
        {
            get
            {
                return m_strName;
            }
            set
            {
                m_strName = value;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Whether or not Network Socket Connection Stop Message
        /// <para>(네트워크 소켓 연결 종료 메시지인지 여부)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public bool MessageIsQuit
        {
            get
            {
                CmMessage msgReturn = GetMessageBody().GetMessage("agent").GetMessage("service");
                if (msgReturn != null)
                {
                    string strSocket = msgReturn.GetMessageValue("name");
                    string strClose = msgReturn.GetMessageValue("argument");
                    if (strSocket == "socket" && strClose == "close")
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Key Values of CmMessage. Difference from Key Property of Hashtable is observation of input order
        /// <para>(CmMessage의 key값들. Hashtable의 Keys속성과의 차이점은 입력된 순서가 지켜진다)</para>
        /// </summary>
        /* --------------------------------------------------------------------------------- */
        public ArrayList MessageKeyList
        {
            get
            {
                return m_aryKeyList;
            }
        }

        // =========================================================================================================
        // private void Print(Message msg, int target)
        // private void Print(string msg, int target)
        // =========================================================================================================
        #region private 멤버
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="target"></param>
        /* --------------------------------------------------------------------------------- */
        private void Print(CmMessage msg, int target)
        {
            try
            {
                m_intDepth++;
                String curKey = "";
                int size = 0;
                for (int index = 0; index < msg.m_aryKeyList.Count; index++)
                {
                    curKey = (string)msg.m_aryKeyList[index];
                    ArrayList tmpAL = (ArrayList)msg[curKey];
                    size = tmpAL.Count;
                    for (int i = 0; i < size; i++)
                    {
                        Object obj = msg.GetObject(curKey, i);
                        if (obj is CmMessage)
                        {
                            Print("<" + ((CmMessage)obj).m_strName + ">", target);
                            Print((CmMessage)obj, target);
                            Print("</" + curKey + ">", target);
                        }
                        else
                        {
                            Print("<" + curKey + ">" + obj.ToString() + "</" + curKey + ">", target);
                        }
                    }
                }
                m_intDepth--;
            }
            catch (Exception e)
            {
                Print("<Error>" + e.ToString() + "</Error>", target);
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        ///
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="target"></param>
        /* --------------------------------------------------------------------------------- */
        private void Print(string msg, int target)
        {
            try
            {
                if (target == STDOUT)
                {
                    for (int i = 0; i < m_intDepth; i++)
                    {
                        Console.WriteLine("\t");
                    }

                    Console.WriteLine(msg);
                }
                else if (target == BUFFER)
                {
                    for (int i = 0; i < m_intDepth; i++)
                    {
                        this.m_stbMessage.Append("\t");
                    }
                    this.m_stbMessage.Append(msg + "" + CrLf);
                }
                else
                {

                }
            }
            catch (Exception e)
            {
                Print("<Error>" + e.ToString() + "</Error>", target);
            }
        }


        #endregion private 멤버
        /* =========================================================================================================

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Returns the No. of nodes of tag key value
        /// <para>(태그 key값 노드의 개수 리턴)</para>
        /// </summary>
        /// <param name="key">Tag Name</param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public int GetObjectCount(string key)
        {
            int nCount = 0;
            try
            {
                nCount = ((ArrayList)(this[key])).Count;
            }
            catch
            {
                nCount = 0;
            }
            return nCount;
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public object GetObject(string key, int index)
        {
            object obj = null;
            try
            {
                obj = ((ArrayList)(this[key]))[index];
            }
            catch (System.NullReferenceException)
            {
                obj = null;
            }
            return obj;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public static Encoding DetectFileEncoding(string filePath)
        {
            Encoding enc = null;
            FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            if (file.CanSeek)
            {
                byte[] bom = new byte[4];
                file.Read(bom, 0, 4);
                if ((bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf))
                {
                    enc = System.Text.Encoding.Unicode;
                }
                else if ((bom[0] == 0xff && bom[1] == 0xfe))
                {
                    enc = System.Text.Encoding.Unicode;
                }
                else if ((bom[0] == 0xfe && bom[1] == 0xff))
                {
                    enc = System.Text.Encoding.Unicode;
                }
                else if ((bom[0] == 0 && bom[1] == 0 && bom[2] == 0xfe && bom[3] == 0xff))
                {
                    enc = System.Text.Encoding.Unicode;
                }
                else
                {
                    enc = System.Text.Encoding.ASCII;
                }

                file.Seek(0, System.IO.SeekOrigin.Begin);
            }
            else
            {
                enc = Encoding.ASCII;
            }
            file.Close();
            return enc;
        }

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// 
        /// </summary>
        /// <param name="abstractFilename"></param>
        /// <returns></returns>
        /* --------------------------------------------------------------------------------- */
        public static CmMessage FromFile(string abstractFilename)
        {
            CmMessage rMessage = null;

            if (!File.Exists(abstractFilename))
            {
                return null;
            }

            Encoding enc = CmMessage.DetectFileEncoding(abstractFilename);

            FileStream fs = null;
            try
            {
                fs = new FileStream(abstractFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            catch (Exception e)
            {
                Console.WriteLine("Message.FromFileUnicode() FileStream e - " + e.ToString());

                try
                {
                    if (fs != null) fs.Close();
                    return null;
                }
                catch (Exception ee)
                {
                    Console.WriteLine("Message.FromFileUnicode() FileStream ee - " + ee.ToString());
                }
            }

            StringBuilder sbInput = new StringBuilder("");
            try
            {
                byte rbyte;
                rbyte = (byte)fs.ReadByte();
                rbyte = (byte)fs.ReadByte();

                byte[] buffer = new byte[4096];

                int rByteSize = 0;
                do
                {
                    rByteSize = fs.Read(buffer, 0, 4096);
                    string line = enc.GetString(buffer, 0, rByteSize);
                    sbInput.Append(line);
                }
                while (rByteSize != 0);
            }
            catch (Exception e)
            {
                Console.WriteLine("Message.FromFileUnicode() ReadByte - " + e.ToString());
            }

            fs.Close();

            XmlBase p = new XmlBase(sbInput.ToString());
            rMessage = p.ParserStart();

            return rMessage;
        }


        /* --------------------------------------------------------------------------------- */
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="key"></param>
        ///// <param name="val"></param>
        ///// <returns></returns>
        /* --------------------------------------------------------------------------------- */ 
        //public int Put(string key, object val) 
        //{
        //    ArrayList tmpList = new ArrayList();
        //    try 
        //    {
        //        if (this.ContainsKey(key) && this.m_aryKeyList.Contains(key)) 
        //        {
        //            try 
        //            {
        //                tmpList = (ArrayList)this[key];
        //                base.Remove(key);
        //            } 
        //            catch (NullReferenceException nre) 
        //            {
        //                Console.Write(nre);
        //                return -1;
        //            }
        //        } 
        //        else 
        //        {
        //            this.m_aryKeyList.Add(key);
        //        }

        //        if (val is ArrayList)
        //        {
        //            tmpList = (ArrayList)((ArrayList)val).Clone();
        //        }
        //        else
        //        {
        //            tmpList.Add(val);
        //        }
        //        this.Add(key, tmpList);
        //    } 
        //    catch (ArgumentNullException ane) 
        //    {
        //        Console.WriteLine(ane.ToString());
        //        return -1;
        //    }
        //    return tmpList.Count;
        //}

        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Value for a Specific Key
        /// <para>(특정 Key에 대한 값 가져오기)</para>
        /// </summary>
        /// <param name="key">Key</param>
        /// <returns>반환값</returns>
        /* --------------------------------------------------------------------------------- */
        public string GetValue(string key)
        {
            try
            {
                if (this.Contains(key))
                    return (string)this.GetObject(key, 0);
                else
                    return null;
            }
            catch
            {
                return null;
            }
        }
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Get Value for specific Key, Index
        /// <para>(특정 Key, Index에 대한 값 가져오기)</para>
        /// </summary>
        /// <param name="key">인덱스</param>
        /// <param name="index">(Key)</param>
        /// <returns>Return Value
        ///    <para>(반환값)</para></returns>
        /* --------------------------------------------------------------------------------- */
        public string GetValue(string key, int index)
        {
            try
            {
                return (string)this.GetObject(key, index);
            }
            catch
            {
                return null;
            }
        }

        /*
                public Message GetMessage(string key) 
                {
                    try
                    {
                        return (Message) this.GetObject(key, 0);
                    }
                    catch
                    {
                        return null;
                    }
			
                }
                public Message GetMessage(string key, int index) 
                {
                    try
                    {
                        return (Message) this.GetObject(key, index);
                    }
                    catch
                    {
                        return null;
                    }			
                }
        */
        /* --------------------------------------------------------------------------------- */
        /// <summary>
        /// Saves contents of CmMessage Object as a file
        /// <para>(CmMessage 객체의 내용을 파일로 저장)</para>
        /// </summary>
        /// <param name="abstractFilename">Save Filename
        ///                          <para>(저장할 파일명)</para></param>
        /* --------------------------------------------------------------------------------- */
        public void ToFile(string abstractFilename)
        {
            string messageStr = this.ToString();

            if (File.Exists(abstractFilename))
            {
                File.Delete(abstractFilename);
            }
            FileStream fs = null;
            try
            {
                fs = new FileStream(abstractFilename, FileMode.Create, FileAccess.Write);
            }
            catch
            {
                try
                {
                    if (fs != null) fs.Close();
                    return;
                }
                catch { }
            }

            byte[] header = { 0xff, 0xfe };
            fs.WriteByte(header[0]);
            fs.WriteByte(header[1]);


            UnicodeEncoding enc = new UnicodeEncoding(false, false);
            byte[] wByte = enc.GetBytes(messageStr);
            for (int i = 0; i < wByte.Length; i++)
            {
                fs.WriteByte(wByte[i]);
            }
            fs.Close();
        }

        /// <summary>
        /// INI 파일 백업 처리
        /// </summary>
        /// <param name="sFileName"></param>
        /// 2017.09.13 Edit
        private static void BackUpMessageFile(string sFileName)
        {
            try
            {
                if (File.Exists(sFileName) == true)
                {
                    string sFirstLine = ReadFileFirstLine(sFileName);
                    //if (sFirstLine.Trim() == "<message>" || sFirstLine.Trim() == "<components>")
                    if (sFirstLine.Trim() == "<MESSAGE>" || sFirstLine.Trim() == "<COMPONENTS>")
                    {
                        try
                        {
                            File.Move(sFileName + ".bak", sFileName + ".ba1");
                        }
                        catch { }
                        try
                        {
                            File.Copy(sFileName, sFileName + ".bak", true);
                        }
                        catch { }
                    }
                }
            }
            catch { }
        }
        /// <summary>
        /// INI 파일 복구 처리
        /// </summary>
        /// <param name="sFileName"></param>
        /// 2017.09.13 Edit
        private static void RestoreMessageFile(string sFileName)
        {
            try
            {
                string sFirstLine = ReadFileFirstLine(sFileName);
                //if (sFirstLine.Trim() == "<message>" || sFirstLine.Trim() == "<components>") return;
                if (sFirstLine.Trim() == "<MESSAGE>" || sFirstLine.Trim() == "<COMPONENTS>") return;

                try
                {
                    if (File.Exists(sFileName + ".bak") == true)
                    {
                        string sBackLine = ReadFileFirstLine(sFileName + ".bak");
                        //if (sBackLine.Trim() == "<message>" || sBackLine.Trim() == "<components>")
                        if (sBackLine.Trim() == "<MESSAGE>" || sBackLine.Trim() == "<COMPONENTS>")
                        {
                            File.Copy(sFileName + ".bak", sFileName, true);
                            //BaseLog.WriteLogFile(BaseCom.LOG_ERROR, "Cosmos.BaseFrame", "CmMessage.RestoreMessageFile()", "백업파일 복구 => " + sFileName);
                            //ComLog.WriteLog(ComLog.Level.Error, "CmMessage.RestoreMessageFile()", "백업파일 복구 => " + sFileName);
                        }
                    }

                    sFirstLine = ReadFileFirstLine(sFileName);
                    //if (sFirstLine.Trim() == "<message>" || sFirstLine.Trim() == "<components>") return;
                    if (sFirstLine.Trim() == "<MESSAGE>" || sFirstLine.Trim() == "<COMPONENTS>") return;
                    if (File.Exists(sFileName + ".ba1") == true)
                    {
                        string sBackLine = ReadFileFirstLine(sFileName + ".ba1");
                        //if (sBackLine.Trim() == "<message>" || sBackLine.Trim() == "<components>")
                        if (sBackLine.Trim() == "<MESSAGE>" || sBackLine.Trim() == "<COMPONENTS>")
                        {
                            File.Copy(sFileName + ".ba1", sFileName, true);
                            //BaseLog.WriteLogFile(BaseCom.LOG_ERROR, "Cosmos.BaseFrame", "CmMessage.RestoreMessageFile()", "백업파일 복구1 => " + sFileName);
                            //ComLog.WriteLog(ComLog.Level.Error, "CmMessage.RestoreMessageFile()", "백업파일 복구1 => " + sFileName);
                        }
                    }
                }
                catch { }
            }
            catch { }
        }

        /// <summary>
        /// 텍스트 파일의 첫 라인 읽기
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        private static string ReadFileFirstLine(string sFileName)
        {
            string sReadLine = "";

            try
            {
                if (File.Exists(sFileName))
                {
                    FileStream fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read);
                    StreamReader sr = new StreamReader(fs, Encoding.Default);

                    try
                    {
                        sr.BaseStream.Seek(0, SeekOrigin.Begin);

                        while (sr.Peek() > -1)
                        {
                            string sLine = sr.ReadLine();
                            if (sLine.Trim().Length == 0) continue;

                            sReadLine = sLine;
                            break;
                        }
                    }
                    catch { }
                    finally
                    {
                        sr.Close();
                        fs.Close();
                    }
                }
            }
            catch { }

            return sReadLine;
        }
    }


}

/// <summary>
/// FXS Protocol Attribute DEFINITION
/// </summary>
public class FxsAttr
{
    /// <summary>
    /// header
    /// </summary>
    public const string HEADER = "header";
    /// <summary>
    /// dest
    /// </summary>
    public const string DEST = "dest";
    /// <summary>
    /// type
    /// </summary>
    public const string TYPE = "type";
    /// <summary>
    /// body
    /// </summary>
    public const string BODY = "body";
    /// <summary>
    /// agent
    /// </summary>
    public const string AGENT = "agent";
    /// <summary>
    /// feedback
    /// </summary>
    public const string FEEDBACK = "feedback";
    /// <summary>
    /// uid
    /// </summary>
    public const string UID = "uid";
    /// <summary>
    /// uidname
    /// </summary>
    public const string UIDNAME = "uidname";
    /// <summary>
    /// service
    /// </summary>
    public const string SERVICE = "service";
    /// <summary>
    /// name
    /// </summary>
    public const string NAME = "name";
    /// <summary>
    /// arguement
    /// </summary>
    public const string ARGUEMENT = "arguement";
    /// <summary>
    /// explicit
    /// </summary>
    public const string EXPLICIT = "explicit";
    /// <summary>
    /// comment
    /// </summary>
    public const string COMMENT = "comment";
    /// <summary>
    /// return
    /// </summary>
    public const string RETURN = "return";
    /// <summary>
    /// record
    /// </summary>
    public const string RECORD = "records";
}