// <summary>ソースコード：ＨＹＭＣＯグループ化演算要素クラス</summary>
// <author>CommonMP</author>

using System;
using System.Collections.Generic;
using System.Text;

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;
using CommonMP.HYSSOP.CoreImpl.HSData;

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.Controller;
using CommonMP.HYMCO.Interface.Data;
using CommonMP.HYMCO.Interface.Model;
using CommonMP.HYMCO.CoreImpl.Model;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Data.FileIO;
using CommonMP.HYMCO.CoreImpl.Data.StructInfo;
using CommonMP.HYMCO.CoreImpl.Data.TranInfo;
using CommonMP.HYMCO.CoreImpl.Tool;

namespace CommonMP.HYMCO.CoreImpl.Controller
{
    /// <summary><para>class outline:</para>
    /// <para>グループ化演算要素</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>
    /// [CommonMP][ver 1.0.0][2008/10/01][新規作成]
    /// [CommonMP][ver 1.4.0][2013/12/06][修正]
    /// </para>
    /// </remarks>
    public class McGrElement : McCmnElement
    {
        /// <summary> McCmnElement.m_csCalModel をグループ化要素制御にキャストしておく(Gr化固有の処理の際、キャストする必要がなくなる) </summary>
        McGrElementCtl m_csGrElmCtl;

        /// <summary>内部要素リスト（演算操作用：演算スレッドから内部のエレメントを制御する）</summary>
        protected LinkedList<McElement> m_csElementList = new LinkedList<McElement>();
        /// <summary>
        /// 内部要素リスト（指示伝達用：演算スレッド以外から内部のエレメントを制御する）
        /// 　演算実行中に、他のスレッドが、m_csElementList を操作すると、演算制御不能となる為　別リストで同じエレメントを管理する
        /// </summary>
        protected LinkedList<McElement> m_csElementListForCommand  = new LinkedList<McElement>();

        /// <summary>接続情報リスト</summary>      
        protected LinkedList<McConnection> m_csConnectionList = new LinkedList<McConnection>();

        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCmnElement csElm = new McCmnElement()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>コンストラクターから呼ばれる</para>
        /// </remarks>
        public McGrElement()
        {
            this.Init();
        }

        /// <summary><para>method outline:</para>
        /// <para>コンストラクター</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCmnElement csElm = new McCmnElement( csID ) </para>
        /// </example>
        /// <param name="csID">識別子</param>
        /// <returns>インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McGrElement(HySIdentifier csID) : base(csID)
        {
            this.Init();
        }

        /// <summary><para>method outline:</para>
        /// <para>初期化処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Init( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>コンストラクターから呼ばれる</para>
        /// </remarks>
        protected new void Init()
        {
            base.Init();
        }

        /// <summary><para>method outline:</para>
        /// <para>内部要素追加</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>AddElement( csAddElement ) </para>
        /// </example>
        /// <param name="csAddElement">要素</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void AddElement(McElement csAddElement)
        {
            m_csElementList.AddLast(csAddElement);  // 演算制御リストに追加
            m_csElementListForCommand.AddLast(csAddElement);    // 指示制御リストに追加
        }
        /// <summary><para>method outline:</para>
        /// <para>内部要素取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McElement csEl = GetElement( csID, ref lIdx ) </para>
        /// </example>
        /// <param name="csID">要素の識別子</param>
        /// <param name="lIdx">要素の配列上の位置</param>
        /// <returns>取得可能：該当要素、取得不可：null</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McElement GetElement(HySIdentifier csID, ref long lIdx)
        {
            lIdx = -1;
            McElement csRtnElm = null;
            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;

            // 演算制御リストから検索
            int iElmCnt = m_csElementListForCommand.Count;
            csElmNode = m_csElementListForCommand.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                if (csElm.Equal(csID) == true)
                {   // ID一致ならば
                    csRtnElm = csElm;
                    lIdx = (long)iLp;
                    break;
                }
                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
            return csRtnElm;
        }
        /// <summary><para>method outline:</para>
        /// <para>内部要素取り外し</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>RemoveElement( csID ) </para>
        /// </example>
        /// <param name="csID">取り外し要素の識別子</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void RemoveElement(HySIdentifier csID)
        {
            LinkedListNode<McElement> csElmNode=null;
            McElement csElm = null;

            // 演算制御リストから削除
            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                if (csElm.Equal(csID) == true)
                {   // ID一致ならば
                    m_csElementList.Remove(csElmNode);    // 取り外し
                    break;
                }
                csElmNode = csElmNode.Next; // 次のエレメントへ
            }

            // 指示制御リストから削除
            iElmCnt = m_csElementListForCommand.Count;
            csElmNode = m_csElementListForCommand.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                if (csElm.Equal(csID) == true)
                {   // ID一致ならば
                    m_csElementListForCommand.Remove(csElmNode);    // 取り外し
                    break;
                }
                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>内部要素全てクリア</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ClearElement( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void ClearElement()
        {
            m_csElementList.Clear();
            m_csElementListForCommand.Clear();
        }

        /// <summary><para>method outline:</para>
        /// <para>接続を追加する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> long lRtn = AddConnection( csConnection ) </para>
        /// </example>
        /// <param name="csConnection">接続</param>
        /// <returns>0</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal virtual long AddConnection(McConnection csConnection)
        {
            m_csConnectionList.AddLast(csConnection);
            return 0;
        }
        /// <summary><para>method outline:</para>
        /// <para>接続の取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McConnection csCnct = GetConnection( csID ) </para>
        /// </example>
        /// <param name="csID">接続のＩＤ</param>
        /// <returns>取得可能：取得した接続情報、取得不可：null</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal virtual McConnection GetConnection(HySIdentifier csID)
        {
            McConnection csRtnCnct = null;
            LinkedListNode<McConnection> csCnctNode = null;
            McConnection csCnnct = null;

            int iCnctCnt = m_csConnectionList.Count;

            csCnctNode = m_csConnectionList.First; // 最初のノード取得

            for (int iLp = 0; iLp < iCnctCnt; iLp++)
            {
                csCnnct = csCnctNode.Value;
                if (csCnnct.Equal(csID) == true)
                {   // ID一致ならば
                    csRtnCnct = csCnnct;
                    break;
                }
                csCnctNode = csCnctNode.Next; // 次のエレメントへ
            }

            return csRtnCnct;
        }
        /// <summary><para>method outline:</para>
        /// <para>接続の取り外し</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> long lRtn = DeleteConnection( csID ) </para>
        /// </example>
        /// <param name="csID">取り外す接続のＩＤ</param>
        /// <returns>0</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal virtual long DeleteConnection(HySIdentifier csID)
        {
            LinkedListNode<McConnection> csCnctNode = null;
            McConnection csCnnct = null;

            int iCnctCnt = m_csConnectionList.Count;

            csCnctNode = m_csConnectionList.First; // 最初のノード取得

            for (int iLp = 0; iLp < iCnctCnt; iLp++)
            {
                csCnnct = csCnctNode.Value;
                if (csCnnct.Equal(csID) == true)
                {   // ID一致ならば
                    m_csConnectionList.Remove(csCnctNode);    // 取り外し
                    break;
                }
                csCnctNode = csCnctNode.Next; // 次のエレメントへ
            }

            return 0;
        }
        /// <summary><para>method outline:</para>
        /// <para>接続全てクリア</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>ClearConnection( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        internal virtual void ClearConnection()
        {
            m_csConnectionList.Clear();
        }

        /// <summary><para>method outline:</para>
        /// <para>送信端子を取り付ける</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = AddSendPort( csSendPort ) </para>
        /// </example>
        /// <param name="csSendPort">接続端子</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal override bool AddSendPort(McPort csSendPort)
        {
            bool bRtn = false;
            McSendTrnsPort csPort = csSendPort as McSendTrnsPort;
            if (csPort != null)
            {
                bRtn = base.AddSendPort(csSendPort);
            }
            return bRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>受信端子を取り付ける</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = AddReceivePort( csReceivePort ) </para>
        /// </example>
        /// <param name="csReceivePort">受信接続端子</param>
        /// <returns>=true:正常、=false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal override bool AddReceivePort(McPort csReceivePort)
        {
            bool bRtn = false;
            McReceiveTrnsPort csPort = csReceivePort as McReceiveTrnsPort;
            if (csPort != null)
            {
                bRtn = base.AddReceivePort(csReceivePort);
            }

            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>送信端子生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McSendPort cPt = CreateSendPort( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>送信端子インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal override McSendPort CreateSendPort()
        {
            McSendPort csRtn = new McSendTrnsPort();
            return csRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>受信端子生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McReceivePort cPt = CreateReceivePort( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>受信端子インスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        internal override McReceivePort CreateReceivePort()
        {
            McReceivePort csRtn = new McReceiveTrnsPort();
            return csRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>外部への接続中継端子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McSendTrnsPort csPort = GetOuterSendPort( csID ) </para>
        /// </example>
        /// <param name="csID">端子ID</param>
        /// <returns>取得可能：接続端子、取得不可：null</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McSendTrnsPort GetOuterSendPort(HySIdentifier csID)
        {
            McSendTrnsPort csRtn = null;

            int iCnt = m_csSendPortList.Count;
            for (int iLp = 0; iLp < iCnt; iLp++)
            {    // ここで、リスト内を調べて同じIDのPortがあれば
                McSendPort csSndPort = m_csSendPortList[iLp];
                if (csSndPort.Equal(csID) == true)
                {
                    csRtn = csSndPort as McSendTrnsPort;
                    break;
                }
            }
            return csRtn;
        }
        /// <summary><para>method outline:</para>
        /// <para>外部からの接続中継端子取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McReceiveTrnsPort csPort = GetOuterReceivePort( csID ) </para>
        /// </example>
        /// <param name="csID">端子ID</param>
        /// <returns>取得可能：接続端子、取得不可：null</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual McReceiveTrnsPort GetOuterReceivePort(HySIdentifier csID)
        {
            McReceiveTrnsPort csRtn = null;

            int iCnt = m_csReceivePortList.Count;
            for (int iLp = 0; iLp < iCnt; iLp++)
            {    // ここで、リスト内を調べて同じIDのPortがあれば
                McReceivePort csRevPort = m_csReceivePortList[iLp];
                if (csRevPort.Equal(csID) == true)
                {
                    csRtn = csRevPort as McReceiveTrnsPort;
                    break;
                }
            }
            return csRtn;
        }

        //=========================
        // 演算実行前処理関連メソッド
        //=========================

        /// <summary><para>method outline:</para>
        /// <para>計算準備(接続チェック等)</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = Prepare(ref csErrorInfo)</para>
        /// </example>
        /// <param name="csErrorInfo">エラー情報</param>
        /// <returns>=true:接続エラー無し　 =false:接続エラー有り</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool Prepare(ref McStructErrorInfo csErrorInfo) 
        {
            bool bRtn = true;

            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;

            // 
            int iElmCnt = m_csElementListForCommand.Count;
            csElmNode = m_csElementListForCommand.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;

                if (csElm.Prepare(ref csErrorInfo) == false)
                {
                    bRtn = false;
                }
                //if ((this.m_csCalModel is McConvergenceCtl) == true && (csElm is McCvrgElement) == true)
                //{
                //    ((McCvrgElement)csElm).SetConvergenceInfo( (McConvergenceInfo)m_csCalModel.GetCalInfo() );
                //}
                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
            if (bRtn == true)
            {
                // Gr内要素についてエラーがない
                // Grの外に出てゆく、或いは外から入ってくる伝送情報に対する設定が必要
                bRtn = base.Prepare(ref csErrorInfo);
            }
            // 内部と、外部の接続に対する伝送情報に対する設定が必要


            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>演算順序のチェック</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = CheckCalculationOrder( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns> long
        /// 正常時：McDefine.CALCULATION_NORMAL_RETURN
        /// 異常時：McDefine.CALCULATION_ABEND_RETURN_BECAUSE_OF_STRUCT_ERROR
        /// </returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>
        /// 非同期演算の時有効
        /// 演算順序を上流から下流に並び替える。
        /// もし、ループ等があればエラーを返す
        /// </para>
        /// </remarks>
        public virtual long CheckCalculationOrder()
        {
            long lRtn = McDefine.CALCULATION_NORMAL_RETURN;
            McGrElementCtl csGrElmCtlModel = m_csCalModel as McGrElementCtl;
            if (csGrElmCtlModel != null)
            {   // 内部ﾓﾃﾞﾙがGr化要素ならば
                lRtn = csGrElmCtlModel.CheckCalculationOrder(); // 演算順序のチェック
            }
            return lRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデルを初期化する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SimInitialize()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>bool true :正常 , false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool SimInitialize() //McInitialInfo csInitializeInfo)
        {
            return base.SimInitialize();
        }

        /// <summary><para>method outline:</para>
        /// <para>プロパティ等情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SetProperty( csElmID, csMdlInfo, ref csErrorInfo)</para>
        /// </example>
        /// <param name="csElmID">変更対象要素識別子</param>
        /// <param name="csMdlInfo">変更情報</param>
        /// <param name="csErrorInfo">接続エラー情報</param>
        /// <returns>=true:変更対象であった、!=true:変更対象ではない</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>モデル生成時にモデル内部情報を設定する</para>
        /// </remarks>
        internal override bool SetProperty(HySID csElmID, McModelInfo csMdlInfo, ref McStructErrorInfo csErrorInfo)
        {
            bool bRtn = true;
            if (this.m_csID.Equals(csElmID) == true)
            {   // グループ自身のプロパティ設定
                McPropertyInfoRoot csPrpty = csMdlInfo.GetPropertyInfo();
                this.m_csCalModel.SetProperty(csPrpty);
                bRtn = true;
            }
            else
            {   // 内部処理のプロパティ設定
                // 要素のプロパティ設定
                LinkedListNode<McElement> csElmNode = null;
                McCmnElement csElement = null;
                int iElmCnt = m_csElementListForCommand.Count;
                csElmNode = m_csElementList.First;
                for (int iLp = 0; iLp < iElmCnt; iLp++)
                {
                    csElement = (McCmnElement)csElmNode.Value;

                    bRtn = csElement.SetProperty(csElmID, csMdlInfo, ref csErrorInfo);
                    if (bRtn == true)
                    {
                        break;
                    }

                    csElmNode = csElmNode.Next;
                }

                if (bRtn == false)
                {
                    LinkedListNode<McConnection> csCnnctNode = null;
                    McConnection csCnnction = null;
                    int iCnnctNo = m_csConnectionList.Count;
                    csCnnctNode = m_csConnectionList.First;
                    for (int iCp = 0; iCp < iCnnctNo; iCp++)
                    {
                        csCnnction = csCnnctNode.Value;
                        bRtn = csCnnction.SetProperty(csElmID, csMdlInfo, ref csErrorInfo);
                        if (bRtn == true)
                        {
                            break;
                        }
                        csCnnctNode = csCnnctNode.Next;
                    }
                }

            }
            return bRtn;
        }


        //=======================
        // 演算実行処理関連メソッド
        //=======================

        /// <summary><para>method outline:</para>
        /// <para>演算実行／中断中のプロパティ等情報設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = SetOnlineProperty( csElmID, csMdlInfo, ref csErrorInfo)</para>
        /// </example>
        /// <param name="csElmID">変更対象要素識別子</param>
        /// <param name="csMdlInfo">変更情報</param>
        /// <param name="csErrorInfo">接続エラー情報</param>
        /// <returns>=true:変更対象が有った、!=true:変更対象が無かった</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算中断中にプロパティ、初期値等を変更して動作させ場合等に使用する</para>
        /// </remarks>
        internal override bool SetOnlineProperty(HySID csElmID, McModelInfo csMdlInfo, ref McStructErrorInfo csErrorInfo)
        {
            bool bRtn = true;
            if (this.m_csID.Equals(csElmID) == true)
            {   // グループ自身のプロパティ設定
                McPropertyInfoRoot csPrpty = csMdlInfo.GetPropertyInfo();
                this.m_csCalModel.SetOnlineProperty(csPrpty);
                bRtn = true;
            }
            else
            {   // 内部処理のプロパティ設定
                // 要素のプロパティ設定
                McCmnElement csElement = null;
                long lElmItem = -1;
                csElement = this.GetElement(csElmID, ref lElmItem) as McCmnElement;
                if (csElement != null)
                {
                    bRtn = csElement.SetOnlineProperty(csElmID, csMdlInfo, ref csErrorInfo);
                }
                /*
                LinkedListNode<McElement> csElmNode = null;
                int iElmCnt = m_csElementListForCommand.Count;
                csElmNode = m_csElementList.First;

                for (int iLp = 0; iLp < iElmCnt; iLp++)
                {
                    csElement = (McCmnElement)csElmNode.Value;

                    bRtn = csElement.SetOnlineProperty(csElmID, csMdlInfo, ref csErrorInfo);
                    if (bRtn == true)
                    {
                        break;
                    }

                    csElmNode = csElmNode.Next;
                }

                if (bRtn == false)
                {
                    LinkedListNode<McConnection> csCnnctNode = null;
                    McConnection csCnnction = null;
                    int iCnnctNo = m_csConnectionList.Count;
                    csCnnctNode = m_csConnectionList.First;
                    for (int iCp = 0; iCp < iCnnctNo; iCp++)
                    {
                        csCnnction = csCnnctNode.Value;
                        bRtn = csCnnction.SetOnlineProperty(csElmID, csMdlInfo, ref csErrorInfo);
                        if (bRtn == true)
                        {
                            break;
                        }
                        csCnnctNode = csCnnctNode.Next;
                    }
                }
                */

            }
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long Calculate( )
        {
            return base.Calculate();
        }

        /*
        /// <summary><para>method outline:</para>
        /// <para>初回モデル演算</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = Calculate( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>初回の演算時のみコールされる</para>
        /// </remarks>
        public virtual long FirstCalculate()
        {
            long lRtn = -1;

            McGrElementCtl csGrElmCtlModel = m_csCalModel as McGrElementCtl;
            if (csGrElmCtlModel != null)
            {   // 内部ﾓﾃﾞﾙがGr化要素ならば
                lRtn = csGrElmCtlModel.FirstCalculate(ref m_csReceiveInfoList); // 初回コール
                m_lCalculate_Call_Before_DataFution_Call += 1; // Calculate コール数カウントアップ  
            }

            return lRtn;
        }
        */
        /*
        /// <summary><para>method outline:</para>
        /// <para>モデル演算における収束判別設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetUpConvergenceInf(ref csConvergeCondInfo)</para>
        /// </example>
        /// <param name="csConvergeCondInfo">収束条件情報</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>系全体で次の計算を行う場合に呼ばれる</para>
        /// </remarks>
        public override long SetUpConvergenceInf(ref McConvergenceInfo csConvergeCondInfo)
        {
            // Do Nothing
            m_csGrElmCtl.SetUpConvergenceInf(ref csConvergeCondInfo);
            return 0;
        }
        */

        /// <summary><para>method outline:</para>
        /// <para>モデル演算における収束判別</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = IsConverged( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=true:収束完了 =false:未収束</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override bool IsConverged()
        {
            return base.IsConverged();
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算結果を外部のエレメントに対して公開する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>long lRtn = DataFusion()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>=0:正常 -1:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override long DataFusion( ) 
        {
            return base.DataFusion( );
        }

        //================
        // 各種設定メソッド
        //================

        /// <summary><para>method outline:</para>
        /// <para>内部にモデルクラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetCalModel( csCalModel ) </para>
        /// </example>
        /// <param name="csCalModel">演算モデル</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks> 
        public override void SetCalModel(McCalModel csCalModel)
        {
            base.SetCalModel(csCalModel);
            
            McGrElementCtl csGrElmCtl = csCalModel as McGrElementCtl;
            if (csGrElmCtl != null)
            {   // グループ化要素ならば
                csGrElmCtl.SetElementList(this.m_csElementList,this.m_csElementListForCommand);  // エレメントを設定する
                csGrElmCtl.SetSendPortList(this.m_csSendPortList);
                csGrElmCtl.SetConnectionList(this.m_csConnectionList);
                m_csGrElmCtl = csGrElmCtl; // キャストしておく Gr化固有の処理の際、キャストする必要がなくなる
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>モデル演算中の情報格納クラスを設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCalInfo(csCalInfo)</para>
        /// </example>
        /// <param name="csCalInfo">演算結果格納するクラス</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetCalInfo(McCalInfo csCalInfo)
        {
            if (m_csCalModel != null)
            {
                m_csCalModel.SetCalInfo(csCalInfo);
            }
            return;
        }

        /// <summary><para>method outline:</para>
        /// <para>DataFusion()発行のタイミング（演算フロー制御）取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McDefine.DataFusionTiming eTm = GetDataFusionTiming()</para>
        /// </example>
        /// <param name=""> 無し</param>
        /// <returns>同期／非同期</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        //public virtual McDefine.DataFusionTiming GetDataFusionTiming()
        public override McDefine.DataFusionTiming GetDataFusionTiming()
        {
            McDefine.DataFusionTiming eRtn = McDefine.DataFusionTiming.SYNCHRONOUS;
            McGrElementCtl csGrElmCtlModel = m_csCalModel as McGrElementCtl;
            if (csGrElmCtlModel != null)
            {   // 内部ﾓﾃﾞﾙがGr化要素ならば
                eRtn = csGrElmCtlModel.GetDataFusionTiming(); // 初回コール
            }
            return eRtn;
        }

        //====================
        // グループ固有メソッド
        //====================

        /// <summary><para>method outline:</para>
        /// <para>内部演算モデル作成処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ModelConstruction( csStructInfo, csModelFactorySet, ref csCheckInf ) </para>
        /// </example>
        /// <param name="csStructInfo">モデル構造データ</param>
        /// <param name="csModelFactorySet">モデルファクトリ</param>
        /// <param name="csCheckInf">接続エラー情報</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual bool ModelConstruction(McStructGroupElement csStructInfo, McModelFactorySet csModelFactorySet, ref McStructCheckData csCheckInf)
        {
            bool bRtn = true;

            bool bLocalRtn = true;
            // 初期化
            m_csElementList.Clear();
            m_csElementListForCommand.Clear();
            m_csReceivePortList.Clear();
            m_csSendPortList.Clear();
            m_csReceiveInfoList.Clear();
            m_csSendInfoList.Clear();
            m_csConnectionList.Clear();
            //★★★★★★★★★★★★★★★★★
            // Ver1.4で追加(伝送情報の事前作成)
            //★★★★★★★★★★★★★★★★★
            //★★★★★★★★★★★★★★
            // Ver1.4で追加(共有化の選択)
            //★★★★★★★★★★★★★★
            bool bChkFlg = false;// 設定ファイルから取得
            HySString csChkString = HySEnvInf.GetEnvInf("HYMCO_CELL_SERIAL_COMMON_USE");
            if ((object)csChkString != null)
            {
                bChkFlg = Convert.ToBoolean(csChkString.ToString());
            }
            if (bChkFlg == true)
            {
                McTranInfoDataPool.ClearInfo(this.GetOwnerProjectID());
            }
            else
            {
                //McTranInfoDataPool.ClearInfo("");// マルチプロジェクト非対応の為
            }

            // １．要素生成
            HySDataLinkedList csElmList = csStructInfo.GetElementList();  //要素リスト
            HySDataLinkedList csConnectionList = csStructInfo.GetConnectionList();  //接続線リスト
            McStructElement csElm = null;
            McStructGroupElement csGrElm = null;


            HySID csElmID = null;
            McModelInfo csMdlInfo = null;
            McPropertyInfoRoot csMdlProperty = null;   // モデルプロパティ情報
            McPropertyInfoRoot csMdlInitial = null; // モデル初期化情報
            McElement csNewElement = null;
            McCalModel csNewModel = null;
            McCalInfo csNewCalInfo = null;
           

            long lElmNum = csElmList.GetCount();  // 要素数

            // 要素有無チェック
            if (lElmNum == 0)
            {
                // 要素無しの場合エラーとする
               // ver1.5 エラートレース日本語対応
                String sMsg = Properties.HymcoImplResources.STATEMENT_NO_ELEMENT ;
               // String sMsg = "This Project has No Element.";
                csCheckInf.AddCheckData(new HySID(""), new HySObjectKind(""), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);

                return false;
            }

            //csElmList.SetCursorFirst(); // カーソル位置最初 ←処理内部でカーソル位置が変る為本方式はダメ
            for (long lLp = 0; lLp < lElmNum; lLp++)
            {
                //csElm = (McStructElement)csElmList.GetCursorData(); ←処理内部でカーソル位置が変る為本方式はダメ
                csElm = (McStructElement)csElmList.GetData(lLp); // ループ内部でカーソル位置が変る為、指定位置のデータを取得する

                csElmID = (HySID)csElm.GetID(); // ID
                csMdlInfo = csElm.GetModelInfo(); // モデル情報

                if (csMdlInfo != null)
                {   // 
                    csGrElm = csElm as McStructGroupElement;
                    // エレメント生成
                    if (csGrElm != null)
                    {   // グループ要素ならば
                        csNewElement = csModelFactorySet.CreateGroupElement(McModelLibraryDefine.SYSTEM_MODEL_FACTORY, McModelLibraryDefine.ELEMENT_GROUP, csElmID); // グループ要素生成
                    }
                    else
                    {   // 単独要素ならば
                        if ((this.m_csCalModel is McConvergenceCtl) == true)
                        {   // 収束演算演算グループ内の単独要素は、収束計算要素
                            csNewElement = csModelFactorySet.CreateElement(McModelLibraryDefine.SYSTEM_MODEL_FACTORY, McModelLibraryDefine.ELEMENT_CONVERGENCE, csElmID); // 要素生成
                        }
                        else
                        {
                            csNewElement = csModelFactorySet.CreateElement(McModelLibraryDefine.SYSTEM_MODEL_FACTORY, McModelLibraryDefine.ELEMENT_CALC, csElmID); // 要素生成
                        }
                    }
                    ((McCmnElement)csNewElement).SetOwnerProjectID(this.m_sOwnerProjectID.ToString());
                    ((McCmnElement)csNewElement).SetElementName(csElm.GetElementName());
                    //if ( (csNewElement is McCmnElement) == true)
                    //{
                    //    ((McCmnElement)csNewElement).SetCalIndxNo(lLp);
                    //}
                    // モデル生成
                    csNewModel = csModelFactorySet.CreateCalModel(csMdlInfo.GetLibraryID(), csMdlInfo.GetModelKind(), csElmID); // モデル要素生成
                    if (csNewModel == null)
                    {
// Ver1.5 追加（不足要素モデルの事前チェック）>>
                        // String sMsg = "Cannot Create Cal Model. Maybe not find the DLL.  Lib_Name=" + csMdlInfo.GetLibraryID().ToString() + " ModelKind =" + csMdlInfo.GetModelKind().ToString() + " ModelName=" + csMdlInfo.GetModelName().ToString();
                        // ver1.5 エラートレース日本語対応
                        String sMsg = Properties.HymcoImplResources.STATEMENT_MODELDLL_NO 
                            +  "  [" + Properties.HymcoImplResources.STATEMENT_MODEL_NAME + "]=" + csMdlInfo.GetModelName().ToString()
                            +  "  [" +Properties.HymcoImplResources.STATEMENT_LIBRARY_NAME + "]=" +  csMdlInfo.GetLibraryID().ToString()
                            +  "  [" + Properties.HymcoImplResources.STATEMENT_MODEL_KIND + "]=" + csMdlInfo.GetModelKind().ToString() 
                            +  "  [" + Properties.HymcoImplResources.STATEMENT_MDL_AUTHOR + "]=" + csMdlInfo.GetCreatorInf().ToString()
                            ;

                        // String sMsg = "ﾓﾃﾞﾙを定義したDLLが見つかりません。[ﾗｲﾌﾞﾗﾘ名]" + csMdlInfo.GetLibraryID().ToString()
                        //     + ", [ﾓﾃﾞﾙ種別]" + csMdlInfo.GetModelKind().ToString()
                        //     + ", [ﾓﾃﾞﾙ名]" + csMdlInfo.GetModelName().ToString();
// Ver1.5 追加（不足要素モデルの事前チェック）<<
                        csCheckInf.AddCheckData(csElmID, csMdlInfo.GetModelKind(), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                        HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                        //csElmList.MoveCursorNext(); // カーソル位置次 ←処理内部でカーソル位置が変る為本方式はダメ

                        

                        bRtn = false;
                        continue;
                    }
                    csNewElement.SetCalModel(csNewModel);  // モデル積み込み 
                    // 演算データ生成
                    csNewCalInfo = csModelFactorySet.CreateCalInfo(csMdlInfo.GetLibraryID(), csMdlInfo.GetModelKind(), csElmID); // 演算中データクラス生成
                    csNewElement.SetCalInfo(csNewCalInfo); // 演算データ積み込み
                    // モデルプロパティ
                    csMdlProperty = csMdlInfo.GetPropertyInfo(); // モデル情報から、プロパティを取り出す
                    if (csNewModel != null)
                    {
                        try
                        {
                            if (csMdlProperty != null)
                            {   // プロパティ情報有りならば
                                //bLocalRtn = csNewModel.SetProperty(csMdlProperty); // モデルにプロパティを設定
                                //if (bLocalRtn != true)
                                //{
                                //    bRtn = false;
                                //    String sMsg = "Model Property Set Error, or Not Send Pattern Set.";
                                //    csCheckInf.AddCheckErrorData(csElmID, csMdlInfo.GetModelKind(), sMsg);
                                //}
                                //★★★★★★★★★★★★★★★★★★★★★★★★★★★
                                // Ver1.4で追加(プロパティ情報設定時のメッセージスロー)
                                //★★★★★★★★★★★★★★★★★★★★★★★★★★★
                                McStructErrorInfo csChkInf = csCheckInf as McStructErrorInfo;
                                bLocalRtn = csNewModel.SetProperty(csMdlProperty, ref csChkInf);
                                if (bLocalRtn != true)
                                {
                                    bRtn = false;
                                   // ver1.5 エラートレース日本語対応
                                    String sMsg = Properties.HymcoImplResources.STATEMENT_MODEL_SET_OR_SND_PATTEN_ERR ;
                                   // String sMsg = "Model Property Set Error, or Not Send Pattern Set.";
                                    csCheckInf.AddCheckErrorData(csElmID, csMdlInfo.GetModelKind(), sMsg);
                                }
                            }
                            else
                            {   // プロパティ未設定ならば
                                csMdlProperty = csModelFactorySet.CreateModelPropertyInfo(csMdlInfo.GetLibraryID(), csMdlInfo.GetModelKind());
                                if (csMdlProperty != null)
                                {
                                    csMdlInfo.SetPropertyInfo(csMdlProperty);
                                    csNewModel.SetProperty(csMdlProperty); // モデルにプロパティを設定
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            bRtn = false;
                           // ver1.5 エラートレース日本語対応
                            String sMsg = Properties.HymcoImplResources.STATEMENT_CATCH_EXCEPTION + csNewModel.ToString() + ".SetProperty().  ::" + ex.Message;
                           // String sMsg = "Exception Catch in " + csNewModel.ToString() + ".SetProperty().  ::" + ex.Message;
                            csCheckInf.AddCheckErrorData(csElmID, csMdlInfo.GetModelKind(), sMsg);
                            HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                        }
                    }
                    else
                    {
                        //String sMsg = "Cannot Create Cal Model Property. LibID=" + csMdlInfo.GetLibraryID().ToString() + " ModelKind =" + csMdlInfo.GetModelKind().ToString(); 
                        //csCheckInf.AddCheckData(csElmID, csMdlInfo.GetModelKind(), McDefine.MessageLevel.HYM_MODELCHECK_WARNING, new HySString(sMsg));
                        //HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                        //bRtn = false;
                    }
                    // 初期化情報を予め設定しておく
                    csMdlInitial = csMdlInfo.GetInitialInfo(); // モデル情報から、初期化情報を取り出す
                    if (csMdlInitial == null)
                    {
                        csMdlInitial = csModelFactorySet.CreateModelInitialInfo(csMdlInfo.GetLibraryID(), csMdlInfo.GetModelKind());
                    }
                    try
                    {
                        csNewElement.PresetInitializeData(csMdlInitial); // 初期化情報を設定する
                    }
                    catch
                    {
                       // ver1.5 エラートレース日本語対応
                        String sMsg = Properties.HymcoImplResources.STATEMENT_DETECT_MODEL_PRESETINITIALIZEDATA ;
                       // String sMsg = "Detect exception error in Model PresetInitializeData().";
                        csCheckInf.AddCheckErrorData(this.GetID(), csMdlProperty.GetModelKind(), sMsg);
                        HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                        bRtn = false;
                    }

                    // 要素積み込み
                    this.AddElement(csNewElement);

                    if (csGrElm != null)
                    {   // グループ要素ならば
                        bRtn = ((McGrElement)csNewElement).ModelConstruction(csGrElm, csModelFactorySet, ref csCheckInf);
                    }
                    else
                    {   // グループ要素でない
                        if ((csNewModel is McGrElementCtl) == true)
                        {   // モデルが　グループ要素制御ならば
                            bRtn = false;
                           // ver1.5 エラートレース日本語対応
                            String sMsg = Properties.HymcoImplResources.STATEMENT_MCGROUPCTLMODEL_ELEMENT;
                           // String sMsg = "McGroupCtlModel is in McElement.";
                            csCheckInf.AddCheckData(csElmID, new HySObjectKind("*****"), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                            HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                        }
                    }
                }
                else
                {
                   // ver1.5 エラートレース日本語対応
                    String sMsg = Properties.HymcoImplResources.STATEMENT_NOT_HAVE_MODELINFO_DATA + csElmID.ToString();
                   // String sMsg = "Not have ModelInfo data  ID=" + csElmID.ToString();
                    csCheckInf.AddCheckData(csElmID, new HySObjectKind("*****"), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                    HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                    bRtn = false;
                }

                //csElmList.MoveCursorNext(); // カーソル位置次 ←処理内部でカーソル位置が変る為本方式はダメ
            }   // end of for(lElmNum);

            // ここで自モデルのプロパティ設定が必要
            csMdlInfo = csStructInfo.GetModelInfo();
            if (csMdlInfo != null)
            {
                try
                {
                    csMdlProperty = csMdlInfo.GetPropertyInfo();   // モデルプロパティ情報
                    if (csMdlProperty != null)
                    {
                        this.m_csCalModel.SetProperty(csMdlProperty);
                    }
                    csMdlInitial = csMdlInfo.GetInitialInfo();     // モデル初期化情報
                    if (csMdlInitial != null)
                    {
                        this.PresetInitializeData(csMdlInitial);
                    }
                }
                catch
                {
                    bRtn = false;
                   // ver1.5 エラートレース日本語対応
                    String sMsg = Properties.HymcoImplResources.STATEMENT_DETECT_EXCEP_SETPROPERTY;
                   // String sMsg = "Detect exception error in Model SetProperty().";
                    csCheckInf.AddCheckErrorData(this.GetID(), csMdlProperty.GetModelKind(), sMsg);
                    HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                }
            }




            // ２．出力要素は処理が特別な為、演算要素の後に持ってくる（順序の変更）
            LinkedListNode<McElement> csElmNode = null;
            LinkedListNode<McElement> csElmComNode = null;
            LinkedListNode<McElement> csElmNodeNext = null;
            LinkedListNode<McElement> csElmComNodeNext = null;
            McElement csOutElm = null;
            McElement csOutElmCom = null;

            int iElmCnt = m_csElementList.Count;

            if (iElmCnt > 0)
            {
                csElmNode = m_csElementList.First; // 最初のノード取得
                csElmComNode = m_csElementListForCommand.First; // 最初のノード取得
                csElmNodeNext = csElmNode.Next; // 次のノード
                csElmComNodeNext = csElmComNode.Next; // 次のノード
            }

            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csOutElm = csElmNode.Value;
                csOutElmCom = csElmComNode.Value;
                //if (csOutElm.GetCalModel() is McOutModelCtlIF == true ||
                //  csOutElm.GetCalModel() is McScreenCtl == true)// 出力要素ならば
                if (csOutElm.GetCalModel() is McOutModelCtlIF == true )// 出力要素ならば
                {
                    m_csElementList.Remove(csElmNode);// リストから削除
                    m_csElementList.AddLast(csElmNode);// リストの最後に追加
                }

                //if (csOutElmCom.GetCalModel() is McOutModelCtlIF == true ||
                //     csOutElmCom.GetCalModel() is McScreenCtl == true)// 出力要素ならば
                if (csOutElmCom.GetCalModel() is McOutModelCtlIF == true )// 出力要素ならば
                {
                    m_csElementListForCommand.Remove(csElmComNode);// リストから削除
                    m_csElementListForCommand.AddLast(csElmComNode);// リストの最後に追加
                }

                csElmNode = csElmNodeNext; // チェック対象ノード変更
                csElmComNode = csElmComNodeNext; // チェック対象ノード変更
                if (csElmNode != null && csElmComNode != null)
                {
                    csElmNodeNext = csElmNode.Next;// 次のノード
                    csElmComNodeNext = csElmComNode.Next;// 次のノード
                }
            }

            // ３．接続設定
            McStructConnection csCnnct = null;
            HySID csCnnctID = null;
            McTranInfo  csTranInfo = null;
            McModelInfo csTranInfData = null;
            McPropertyInfoRoot csTranInfoProperty = null;
            HySIdentifier csFromElmID = new HySID("");
            HySIdentifier csToElmID = new HySID("");
            HySIdentifier csFromPortID = new HySID("");
            HySIdentifier csToPortID = new HySID("");
            McCmnElement csFromElement = null;
            McCmnElement csToElement = null;
            McConnection csNewConnection = null;
            long lFromElmIdx = -1;
            long lToElmIdx = -1;
            //★★★★★★★★★★★★★★★★★
            // Ver1.4で追加(伝送情報の事前作成)
            //★★★★★★★★★★★★★★★★★
            string sPrjID = "";
            try
            {
                long lCnctNum = csConnectionList.GetCount(); // 接続数
                //csConnectionList.SetCursorFirst(); // カーソル位置最初 ←処理内部でカーソル位置が変る為本方式はダメ
                for (long lLp = 0; lLp < lCnctNum; lLp++)
                {
                    //csCnnct = (McStructConnection)csConnectionList.GetCursorData(); // 接続データ取得 ←処理内部でカーソル位置が変る為本方式はダメ
                    csCnnct = (McStructConnection)csConnectionList.GetData(lLp); // 接続データ取得（キチンと位置を指定して取ること）
                    csCnnctID = (HySID)csCnnct.GetID();

                    csCnnct.GetConnectionElement(ref csFromElmID, ref csToElmID);
                    csFromElement = (McCmnElement)this.GetElement(csFromElmID, ref lFromElmIdx);
                    csToElement = (McCmnElement)this.GetElement(csToElmID, ref lToElmIdx);

                    csCnnct.GetConnectionPort(ref csFromPortID, ref csToPortID);

                    csNewConnection = null;
                    if (csFromElement != null && csToElement != null)
                    {   // 内部の接続ならば
                        csNewConnection = McConnection.CreateConnection(csFromPortID, csFromElement, csToPortID, csToElement); // 接続生成
                        csNewConnection.SetID(csCnnctID);
                    }
                    else if (csFromElement == null && csToElement != null)
                    {   // グループ外部から、内部への接続ならば
                        // 入力中継端子
                        csNewConnection = McConnection.CreateExternalINConnection(csFromPortID, this, csToPortID, csToElement); // 接続生成
                        csNewConnection.SetID(csCnnctID);
                    }
                    else if (csFromElement != null && csToElement == null)
                    {   // 内部からグループ外部への接続ならば
                        // 出力中継端子
                        csNewConnection = McConnection.CreateExternalOUTConnection(csFromPortID, csFromElement, csToPortID, this); // 接続生成
                        csNewConnection.SetID(csCnnctID);
                    }
                    else
                    {   // 内部には接続されずに　そのまま素通りする
                    }

                    if (csNewConnection != null)
                    {   // 接続に成功すれば
                        //csNewConnection.SetUpperElmIdx(lFromElmIdx);
                        //csNewConnection.SetLowerElmIdx(lToElmIdx);
                        csTranInfData = csCnnct.GetTranInfo();
                        if (csTranInfData != null)
                        {   // 伝送データ有り
                            csTranInfoProperty = csTranInfData.GetPropertyInfo();
                            if (csTranInfoProperty == null)
                            {
                                csTranInfoProperty = csModelFactorySet.CreateTranInfoPropertyInfo(csTranInfData.GetLibraryID(), csTranInfData.GetModelKind());
                            }
                            if (csTranInfoProperty != null)
                            {

                                csTranInfo = csModelFactorySet.CreateTransData(csTranInfData.GetLibraryID(), csTranInfData.GetModelKind(), csTranInfoProperty, csCnnctID); // 伝送データ生成
                                if (csTranInfo != null)
                                {
                                    //if ((this.m_csCalModel is McConvergenceCtl) == true &&
                                    //    csFromElement != null && csToElement != null)
                                    //{   // 収束演算演算における内部接続の、伝送データは特別
                                    //    McTranInfo csTranInfoTmp = csTranInfo;
                                    //    csTranInfo = new McMutualTranInfoImpl();
                                    //    ((McMutualTranInfo)csTranInfo).SetTranInfo(csTranInfoTmp, csTranInfoTmp.Clone(csTranInfoTmp));
                                    //}

                                    csNewConnection.SetTranInfo(csTranInfo);
                                    csNewConnection.SetTranInfoKind(csTranInfo);

                                    //★★★★★★★★★★★★★★★★★
                                    // Ver1.4で追加(伝送情報の事前作成)
                                    //★★★★★★★★★★★★★★★★★
                                    sPrjID = this.GetOwnerProjectID();
                                    McTimeSeriesSingleCellTranInfo csSingle = csTranInfo as McTimeSeriesSingleCellTranInfo;
                                    McTimeSeriesD1CellArrayTranInfo csD1 = csTranInfo as McTimeSeriesD1CellArrayTranInfo;
                                    McTimeSeriesD2CellArrayTranInfo csD2 = csTranInfo as McTimeSeriesD2CellArrayTranInfo;
                                    McTimeSeriesD3CellArrayTranInfo csD3 = csTranInfo as McTimeSeriesD3CellArrayTranInfo;
                                    McTimeSeriesGeoD2MeshTranInfo csD2GIS = csTranInfo as McTimeSeriesGeoD2MeshTranInfo;
                                    McTimeSeriesGeoD3MeshTranInfo csD3GIS = csTranInfo as McTimeSeriesGeoD3MeshTranInfo;
                                    McTimeSeriesMutualCellTranInfor csMtlTrn = csTranInfo as McTimeSeriesMutualCellTranInfor;

                                    if( csMtlTrn != null )
                                    {
                                        csMtlTrn.SetPrjID(sPrjID);
                                    }
                                    else if (csSingle != null)
                                    {
                                        csSingle.SetPrjID(sPrjID);
                                    }
                                    else if (csD1 != null)
                                    {
                                        csD1.SetPrjID(sPrjID);
                                    }
                                    else if (csD2 != null)
                                    {
                                        csD2.SetPrjID(sPrjID);
                                    }
                                    else if (csD3 != null)
                                    {
                                        csD3.SetPrjID(sPrjID);
                                    }
                                    else if (csD2GIS != null)
                                    {
                                        csD2GIS.SetPrjID(sPrjID);
                                    }
                                    else if (csD3GIS != null)
                                    {
                                        csD3GIS.SetPrjID(sPrjID);
                                    }

                                    csTranInfo.SetProperty(csTranInfoProperty); // 伝送データにプロパティ情報を設定する

                                    // 伝送データの共通情報を設定する
                                    McTranCommonCellDataIF csCmmnInf = csTranInfo.GetCommonInf();
                                    csCmmnInf.SetConnectionID(csCnnctID);
                                    csCmmnInf.SetConnectionName(csCnnct.GetConnectionName());

                                    csCmmnInf.SetUpperElement(csFromElement);   // 上流要素設定
                                    //if (csFromElement == null)
                                    {   // 上流要素がnullの場合には、　Ｇｒ化要素に接続されている可能性があるため、先ずは、接続端子を設定しておく
                                        csCmmnInf.SetUpperPort(csNewConnection.GetSendPort());
                                    }
                                    csCmmnInf.SetLowerElement(csToElement);
                                    //if (csToElement == null)
                                    {   // 下流要素がnullの場合には、　Ｇｒ化要素に接続されている可能性があるため、先ずは、接続端子を設定しておく
                                        csCmmnInf.SetLowerPort(csNewConnection.GetReceivePort());
                                    }
                                    //csTranInfoProperty.get
                                    // 設定された受信側の情報が設定されない

                                    //★★★★★★★★★★★★★★★★★
                                    // Ver1.4で追加(伝送情報の事前作成)
                                    //★★★★★★★★★★★★★★★★★
                                    // 当該接続線における上流側要素モデルタイムステップの情報を抽出
                                    if (csMtlTrn != null)
                                    {
                                        csMtlTrn.SetUpperElmTimeStep();
                                    }
                                    else if (csSingle != null)
                                    {
                                        csSingle.SetUpperElmTimeStep();
                                    }
                                    else if (csD1 != null)
                                    {
                                        csD1.SetUpperElmTimeStep();
                                    }
                                    else if (csD2 != null)
                                    {
                                        csD2.SetUpperElmTimeStep();
                                    }
                                    else if (csD3 != null)
                                    {
                                        csD3.SetUpperElmTimeStep();
                                    }
                                    else if (csD2GIS != null)
                                    {
                                        csD2GIS.SetUpperElmTimeStep();
                                    }
                                    else if (csD3GIS != null)
                                    {
                                        csD3GIS.SetUpperElmTimeStep();
                                    }

                                    /* この部分不用（TranInfo のコンストラクターでプロパティ情報は取り込み済みの為
                                    McCellArrayTranInfoPropertyInfo csCellProperty = csTranInfoProperty as McCellArrayTranInfoPropertyInfo;
                                    if (csCellProperty != null )
                                    {
                                        if (csTranInfo is McTranInfoIFTimeSeriesType)
                                        {
                                            csCmmnInf.SetInterpolateType(csCellProperty.GetInterpolateType());
                                            csCmmnInf.CreateMcReceiveCellData(csCellProperty);
                                            csCmmnInf.GetReceiveCellData().SetTranInfo(csTranInfo);
                                        }
                                        //if (csTranInfo is McTranInfoIFCellType)
                                        //{
                                        //    csCmmnInf.SetCellDataGetter(csCellProperty.GetCellDataGetter());
                                        //}
                                    }
                                    */
                                }
                                else
                                {
                                   // ver1.5 エラートレース日本語対応
                                    String sMsg = Properties.HymcoImplResources.STATEMENT_NOT_CREATE_TRANINFO + csTranInfData.GetLibraryID().ToString()
                                         + Properties.HymcoImplResources.STATEMENT_TRENINFO_KIND + csTranInfData.GetModelKind().ToString();
                                   // String sMsg = "Cannot Create TranInfo.  LibID=" + csTranInfData.GetLibraryID().ToString()
                                   //      + " TranInfoKind=" + csTranInfData.GetModelKind().ToString();
                                    csCheckInf.AddCheckData(csCnnctID, csTranInfData.GetModelKind(), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                                    HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                                    bRtn = false;
                                }
                            }
                            else
                            {
                               // ver1.5 エラートレース日本語対応
                                String sMsg = Properties.HymcoImplResources.STATEMENT_NOT_HAVE_TRANINFOPROPERTY + csTranInfData.GetLibraryID().ToString() 
                                    + Properties.HymcoImplResources.STATEMENT_TRENINFO_KIND + csTranInfData.GetModelKind().ToString();
                               // String sMsg = "Not have TranInfoProperty.  LibID=" + csTranInfData.GetLibraryID().ToString() + " TranInfoKind=" + csTranInfData.GetModelKind().ToString();
                                csCheckInf.AddCheckData(csCnnctID, csTranInfData.GetModelKind(), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                                HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
                                bRtn = false;
                            }

                            this.AddConnection(csNewConnection); // 生成コネクションの積み込み
                        }
                        else
                        {
                           // ver1.5 エラートレース日本語対応
                            String sMsg = Properties.HymcoImplResources.STATEMENT_NOT_HAVE_TRANINFODATA + csCnnctID.GetString().ToString();
                           // String sMsg = "Not have TranInfo data.  ID=" + csCnnctID.GetString().ToString();
                            csCheckInf.AddCheckData(csCnnctID, csTranInfData.GetModelKind(), McDefine.MessageLevel.HYM_MODELCHECK_ERROR, new HySString(sMsg));
                            HySLog.LogOut(HySLog.ONLINE, "McGrElement", sMsg);
                            bRtn = false;
                        }

                    }


                    //csConnectionList.MoveCursorNext(); // カーソル位置次 ←処理内部でカーソル位置が変る為本方式はダメ
                }
                //★★★★★★★★★★★★★★★★★
                // Ver1.4で追加(伝送情報の事前作成)
                //★★★★★★★★★★★★★★★★★
                // 此処で伝送情報の事前作成を行う
                //★★★★★★★★★★★★★★
                // Ver1.4で追加(共有化の選択)
                //★★★★★★★★★★★★★★
                bChkFlg = false;// 設定ファイルから取得
                csChkString = HySEnvInf.GetEnvInf("HYMCO_CELL_SERIAL_COMMON_USE");
                if ((object)csChkString != null)
                {
                    bChkFlg = Convert.ToBoolean(csChkString.ToString());
                }
                if (bChkFlg == true)
                {
                    McTranInfoDataPool.RegisterDataType(sPrjID);
                }
                else
                {
                    McTranInfoDataPool.RegisterDataType("");
                }
            }
            catch( Exception eee)
            {
                bRtn = false;
               // ver1.5 エラートレース日本語対応
                String sMsg = Properties.HymcoImplResources.STATEMENT_DETECT_EXCEP_CONNECTPROPROPETY;
               // String sMsg = "Detect exception error in Connection Property().";
                csCheckInf.AddCheckErrorData(this.GetID(), csMdlProperty.GetModelKind(), sMsg);
                HySLog.LogOut(HySLog.ONLINE, "McGrElement", "ModelConstruction", sMsg);
            }

            // this.Prepare(); // 準備 <-- 此処で呼ぶと　内部のGr化エレメント内の要素が複数回　Prepare 呼ばれる(外部から呼ばれるべき)
            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>中継端子の導通設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>MakeContinuity( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void MakeContinuity()
        {
            if (this.m_csCalModel is McGrElementCtl)
            {
                ((McGrElementCtl)m_csCalModel).MakeContinuity();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>計算強制終了</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>StopCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void StopCalculation()
        {
            if( m_csCalModel != null )
            {
                ((McGrElementCtl)m_csCalModel).StopCalculation();
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>計算中断</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>PauseCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void PauseCalculation()
        {
            if( m_csCalModel != null )
            {
                ((McGrElementCtl)m_csCalModel).PauseCalculation();
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>計算再開</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>RestartCalculation( )</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public virtual void RestartCalculation()
        {
            if( m_csCalModel != null )
            {
                ((McGrElementCtl)m_csCalModel).RestartCalculation();
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>新グループ化要素への移行</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> McGrElement csGrElm = CreateExchangeGrElement( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>生成されたグループ化要素</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>現在の演算系が部分系として取り込まれる場合に使用する</para>
        /// </remarks>
        internal virtual McGrElement CreateExchangeGrElement()
        {
            McGrElement csElm = new McGrElement();

            csElm.m_csElementList = this.m_csElementList;
            csElm.m_csConnectionList = this.m_csConnectionList;
            csElm.m_csID = this.m_csID;
            csElm.m_csCalModel = this.m_csCalModel;
            csElm.m_csReceivePortList = this.m_csReceivePortList;
            csElm.m_csSendPortList = this.m_csSendPortList;
            csElm.m_csReceiveInfoList = this.m_csReceiveInfoList;
            csElm.m_csSendInfoList = this.m_csSendInfoList;

            this.m_csElementList = null;
            this.m_csConnectionList = null;
            this.m_csID = null;
            this.m_csCalModel = null;
            this.m_csReceivePortList = null;
            this.m_csSendPortList = null;
            this.m_csReceiveInfoList = null;
            this.m_csSendInfoList = null;

            return csElm;
        }

        /// <summary><para>method outline:</para>
        /// <para>伝送データのリセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> ResetTranInfo() </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void ResetTranInfo()
        {
            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;

            int iElmCnt = m_csElementList.Count;

            csElmNode = m_csElementList.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                csElm.ResetTranInfo();
                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
            base.ResetTranInfo();
            // Gr制御モデルに対してフラグをリセットする
        }

        /// <summary><para>method outline:</para>
        /// <para>計算状態復元のためのデータクラスを生成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McCmnElementOutData csElementOutData = CreateOutData()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>データクラス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override McCmnElementOutData CreateOutData()
        {
            return new McGrElementOutData();
        }

        /// <summary><para>method outline:</para>
        /// <para>現在状態の一時記憶（但し計算途中状態は除く）</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Memorize(bMemLvl) </para>
        /// </example>
        /// <param name="bMemLvl">
        /// 記憶レベル：McDefine.ElementMemoryLevel.ELEMENT_MEMORY_ALL／McDefine.ElementMemoryLevel.ELEMENT_MEMORY_SNDPORT_ONLY</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public override void Memorize(McDefine.ElementMemoryLevel bMemLvl)
        {
            base.Memorize(McDefine.ElementMemoryLevel.ELEMENT_MEMORY_ALL);
            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;
            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                csElm.Memorize(bMemLvl);

                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>Memorize()した情報の復元</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> Remember(bMemLvl) </para>
        /// </example>
        /// <param name="bMemLvl">
        /// 記憶レベル：McDefine.ElementMemoryLevel.ELEMENT_MEMORY_ALL／McDefine.ElementMemoryLevel.ELEMENT_MEMORY_SNDPORT_ONLY</param>
        /// <returns>無し</returns>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>Memorize()とRemember()は対で使用する</para>
        /// </remarks>
        public override void Remember(McDefine.ElementMemoryLevel bMemLvl)
        {
            base.Remember(McDefine.ElementMemoryLevel.ELEMENT_MEMORY_ALL);

            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;
            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                csElm.Remember(bMemLvl);

                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>自インスタンスを保持しているプロジェクトのＩＤ値を設定する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SetOwnerProjectID(sOwnerProjectID) </para>
        /// </example>
        /// <param name="sOwnerProjectID">自インスタンスを保持しているプロジェクトのＩＤ値</param>
        /// <returns>無し</returns>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public override void SetOwnerProjectID(string sOwnerProjectID)
        {
            base.SetOwnerProjectID(sOwnerProjectID);
            LinkedListNode<McElement> csElmNode = null;
            McElement csElm = null;
            int iElmCnt = m_csElementList.Count;
            csElmNode = m_csElementList.First; // 最初のノード取得
            for (int iLp = 0; iLp < iElmCnt; iLp++)
            {
                csElm = csElmNode.Value;
                if (csElm != null)
                {
                    csElm.SetOwnerProjectID(sOwnerProjectID);
                }

                csElmNode = csElmNode.Next; // 次のエレメントへ
            }
        }

        // リンクリストの順番を変更するメソッドが必要
    }
}
