/// <summary>
        /// Get application routing information.
        /// </summary>
        /// <returns>RbAppRouterCache</returns>
        private RbAppRouterCache GetAppRoutingInfo(RbHeader rbh)
        {
            AppRouter        ar        = null;
            bool             ar_action = true;
            string           cachekey  = rbh.AppId + "_" + rbh.AppProcessingId;
            RbAppRouterCache rbapprc   = null;

            if (rbAppRouterCacheDic.ContainsKey(cachekey))
            {
                rbapprc = (RbAppRouterCache)rbAppRouterCacheDic[cachekey];
                if (rbapprc.CacheExpiredDatetime >= DateTime.Now)
                {
                    ar_action = false;
                }
            }
            if (ar_action)
            {
                ar      = new AppRouter(rbh.AppId, rbh.AppProcessingId, sqlConnectionString, rbCacheExpiredTimeSec);
                rbapprc = ar.GetAppRouting();
                if (rbapprc != null)
                {
                    lock (thisLock)
                    {
                        rbAppRouterCacheDic[cachekey] = rbapprc;
                    }
                }
                else
                {
                    throw new ApplicationException("Error ** GetAppRouting() returns Null Object");
                }
            }

            return(rbapprc);
        }
        private void callAppButton_Click(object sender, EventArgs e)
        {
            if (textBoxDllFilePath.Text == string.Empty)
            {
                MessageBox.Show("** Error ** DLL File Local Path must be set !!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (textBoxDeviceId.Text == string.Empty)
            {
                MessageBox.Show("** Error ** Device ID must be set !!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (checkBoxSkipAppRouter.Checked && textBoxClassName.Text == string.Empty)
            {
                MessageBox.Show("** Error ** Class Name must be set !!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            // Save the TextBox content
            saveTextBoxContent();

            JObject jo_message = JsonConvert.DeserializeObject <JObject>(textBoxInput.Text);

            // Check RbHeader in detail
            RbHeaderBuilder hdBuilder = new RbHeaderBuilder(jo_message, textBoxDeviceId.Text);
            RbHeader        rbh       = hdBuilder.ValidateJsonSchema();
            // RbBody
            JObject jo_temp      = (JObject)jo_message[RbFormatType.RbBody];
            string  rbBodyString = JsonConvert.SerializeObject(jo_temp);

            // App Master Cache (RBFX.AppMaster)
            AppMaster        am      = new AppMaster(rbh.AppId, activeEncPassPhrase, activeSqlConnectionString, constTimeOutSec);
            RbAppMasterCache rbappmc = am.GetAppMaster();

            // App Router Cache (RBFX.AppRouting)
            RbAppRouterCache rbapprc;

            if (checkBoxSkipAppRouter.Checked)
            {
                rbapprc                 = new RbAppRouterCache();
                rbapprc.AppId           = rbh.AppId;
                rbapprc.AppProcessingId = rbh.AppProcessingId;
                rbapprc.ClassName       = textBoxClassName.Text;
                rbapprc.FileName        = textBoxDllFilePath.Text;
            }
            else
            {
                AppRouter ar = new AppRouter(rbh.AppId, rbh.AppProcessingId, activeSqlConnectionString, constTimeOutSec);
                rbapprc = ar.GetAppRouting();
            }

            // Load DLL
            //Assembly assembly = null;
            AppDomain     appDomain    = null;
            IAppRouterDll routedAppDll = null;

            try
            {
                //assembly = System.Reflection.Assembly.LoadFrom(textBoxDllFilePath.Text);
                //routedAppDll = assembly.CreateInstance(rbapprc.ClassName) as IAppRouterDll;
                string pid                      = Thread.CurrentThread.ManagedThreadId.ToString();
                string appDomainName            = "AppDomain_P" + pid;
                string cachedDirectory          = Path.GetDirectoryName(textBoxDllFilePath.Text);
                string cachedFileName           = Path.GetFileName(textBoxDllFilePath.Text);
                string cachedFileNameWithoutExt = Path.GetFileNameWithoutExtension(textBoxDllFilePath.Text);
                appDomain    = createAppDomain(appDomainName, cachedDirectory);
                routedAppDll = appDomain.CreateInstanceAndUnwrap(cachedFileNameWithoutExt, rbapprc.ClassName) as IAppRouterDll;
            }
            catch (Exception ex)
            {
                MessageBox.Show("** Application (DLL) Load Error ** Check File Path or Class Name \n" + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Process Message
            try
            {
                rbh.ProcessingStack = activeFileName;
                JArrayString ja_messagesString = routedAppDll.ProcessMessage(rbappmc, rbapprc, rbh, rbBodyString);
                JArray       ja_messages       = ja_messagesString.ConvertToJArray();
                textBoxOutput.Text = JsonConvert.SerializeObject(ja_messages);
                AppDomain.Unload(appDomain);
            }
            catch (Exception ex)
            {
                MessageBox.Show("** Error occured in Application (DLL) **\n" + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                AppDomain.Unload(appDomain);
                return;
            }
        }