private void MakeUnloading()
        {
            FAExtendECPart.ECResult ecResult = new FAExtendECPart.ECResult();

            var seq = Unloading;

            seq.OnStart +=
                delegate
                {
                    RetryInfoUnloadingTray.ClearCount();
                };

            seq.OnStop += delegate { ConveyorMotor.Stop.Execute(this); };
            seq.OnSuspended += delegate { ConveyorMotor.Stop.Execute(this); };
            seq.OnSuspending += delegate { ConveyorMotor.Stop.Execute(this); };

            seq.Steps.Add("Start", new StepInfo());
            seq.Steps.Add("Unloading", new StepInfo());

            seq.AddItem(
                delegate(object obj)
                {
                    if (ProductInfo.VT8792ProductInfo.LotScanCompleted.IsLastTray == true)
                    {
                        if (ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess)
                            LastPartIDOfProduct = ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID;
                        else
                            LastPartIDOfProduct = string.Empty;
                    }
                });

            seq.Steps["Start"].StepIndex = seq.AddItem(Stopper.Down.Sequence);

            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess == false &&
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted == true)
                    {
                        if (ProductInfo.VT8792ProductInfo.LotScanCompleted.IsLastTray == true)
                        {
                            ProductInfo.VT8792ProductInfo.LotScanCompleted.IsLastTray = false;
                            actor.NextStep();
                        }
                        else
                        {
                            actor.NextStep("Unloading");
                        }

                    }
                    else
                    {
                        actor.NextStep("Unloading");
                    }
                });

            seq.AddItem(
                delegate(object obj)
                {
                    WriteTraceLog(string.Format("Scan Fail And Unloading To Fail C/V. LotID={0}", ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID));
                    FAECInfo.PK_XCLOSE_REQ command = new FAECInfo.PK_XCLOSE_REQ();
                    command.LOT_ID = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID;
                    command.EQP_ID = Equipment.Config.SystemID;
                    command.OPER_ID = Equipment.CurrentUser.Name;
                    ecResult.Clear();
                    InterfaceUnit.ECPart.AddCommand(command, ecResult);
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ecResult.ReceiveOk)
                    {
                        if (ecResult.ParsingSuccess)
                        {
                            if (ecResult.ECInfo.PK_XCLOSE.RESULT == FAECInfo.FAECResult.PASS)
                            {
                                WriteTraceLog(" PK_XCLOSE OK");
                                ecResult.ECInfo.PK_XCLOSE.CopyTo(ProductInfo.ECInfo.PK_XCLOSE);
                                actor.NextStep();
                            }
                            else
                            {
                                string windowName = string.Empty;
                                var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[SSD MODULE] PK_XCLOSE INFO EC RESULT FAIL.");
                                Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "PK_XCLOSE_ECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                                actor.NextStep();
                            }
                        }
                        else
                        {
                            var msg = GetErrorMessageOfTrayPXCLOSECheck(ecResult.ECInfo.PK_XCLOSE);
                            string windowName = string.Empty;
                            var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[SSD MODULE] EC PK_XCLOSE INFO RECEIVE DATA PARSING FAIL.");
                            Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "PK_XCLOSE_ECCommFail",
                                    out windowName,
                                    alarm,
                                    msg,
                                    true);
                            actor.NextStep();
                        }
                    }
                    else if (ecResult.LastAlarmNo != 0)
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[SSD MODULE] EC PK_XCLOSE INFO RECEIVE FAIL.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "PK_XCLOSE_ECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                        actor.NextStep();
                    }
                });
            seq.Steps["Unloading"].StepIndex = seq.AddItem(ConfirmUnloadedTray);
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (TimeConveyorDelayRunTimeAfterUnloading.Time < time)
                    {
                        ConveyorMotor.Stop.Execute(actor);
                        actor.NextStep();
                    }
                    else
                        ConveyorMotor.Run.Execute(actor);
                });
            seq.AddItem(Stopper.Up.Execute);
        }
        private void MakeProcess()
        {
            FAExtendECPart.ECResult ecResult = new FAExtendECPart.ECResult();

            var seq = Process;

            #region RegisterEventHandler
            seq.OnStart +=
                delegate
                {
                    RetryInfoGateChangeRetry.ClearCount();
                };
            #endregion

            #region AddSteps
            seq.Steps.Add("IncreaseGateNo", new StepInfo());
            seq.Steps.Add("RetryRequestLotClose", new StepInfo());
            seq.Steps.Add("RequestMasterInfo", new StepInfo());
            seq.Steps.Add("RequestLotClose", new StepInfo());
            seq.Steps.Add("SelectUnloadingDirection", new StepInfo());
            #endregion

            seq.AddItem(Aligner.Extend.Sequence);
            #region CheckTrayEdge
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (UseTrayIndexCheck && RFReaderUnit.EdgeSensor.IsOn)
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(AlarmTrayIndexDirectionFailDetected, "[RF READER MODULE] Tray Index Direction Fail.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                            "TrayIndexDirectionFail",
                            out windowName,
                            alarm,
                            string.Empty,
                            true);

                        NextModule = FailureWayModule;
                        WriteTraceLog("Unloading to Fail C/V. Edge Sensor Detected.");
                        actor.NextStep("SelectUnloadingDirection");
                    }
                    else
                    {
                        actor.NextStep();
                    }
                });
            #endregion
            #region ConfirmManualLotIDInput
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.DRY_RUN)
                    {
                        ProductInfo.VT8792ProductInfo.TrayCount = LotTrayCount;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID = "TEST_LOT";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_MARKING = "TEST";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID = "TEST";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X = 2;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y = 3;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.S_BOX_MOQ = LotSmallBoxMOQ;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.L_BOX_MOQ = LotSmallBoxMOQ;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY = LotSmallBoxMOQ;
                        WriteTraceLog("Track In " + ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID);
                        actor.NextStep();
                    }
                    else if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.COLD_RUN)
                    {
                        ProductInfo.VT8792ProductInfo.TrayCount = LotTrayCount;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID = "TEST_LOT";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_MARKING = "TEST";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID = "TEST";
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X = 2;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y = 3;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.S_BOX_MOQ = LotSmallBoxMOQ;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.L_BOX_MOQ = LotSmallBoxMOQ;
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY = LotSmallBoxMOQ;
                        actor.NextStep();
                    }
                    else
                    {
                        if (UseManualLotIDInput)
                        {
                            if (LotIDList.Count > 0)
                            {
                                try
                                {
                                    ReadingLotID = LotIDList.First();
                                    string lotID = ReadingLotID;

                                    WriteTraceLog(string.Format("Read Lot ID. {0}", ReadingLotID));

                                    System.Windows.Threading.DispatcherTimer timer =
                                        new System.Windows.Threading.DispatcherTimer(System.Windows.Threading.DispatcherPriority.Normal, App.Current.Dispatcher);

                                    timer.Interval = new TimeSpan(0, 0, 0, 0, 50);
                                    timer.Tick +=
                                        delegate
                                        {
                                            try
                                            {
                                                LotIDList.Remove(lotID);
                                                timer.Stop();
                                            }
                                            catch
                                            {
                                            }
                                        };
                                    timer.Start();

                                    actor.NextStep();
                                }
                                catch
                                {
                                    actor.NextStep();
                                }
                            }
                        }
                        else
                            actor.NextStep();
                    }
                });
            #endregion
            #region IncreaseGateNo
            seq.Steps["IncreaseGateNo"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    if (CurrentGate == GATE_NO_ZERO)
                    {
                        CurrentGate = GATE_NO_MIN;
                    }
                    else
                    {
                        CurrentGate++;
                        if (CurrentGate > GATE_NO_MAX)
                            CurrentGate = GATE_NO_MIN;
                    }
                });
            #endregion
            seq.AddItem(new FASequenceAtomicInfo(ScanAndTrayCounting, true));
            #region ConfirmReadSuccessRFID
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.HOT_RUN)
                    {
                        if (RFIDScanSuccess)
                            actor.NextStep();
                        else
                        {
                            string windowName = string.Empty;
                            var alarm = Utility.AlarmUtility.GetAlarm(AlarmRFIDScanFail, "[RF READER MODULE] RFID Scan Fail.");
                            Manager.MessageWindowManager.Instance.Show(Equipment,
                                "RFIDScanFail",
                                out windowName,
                                alarm,
                                string.Empty,
                                true);
                            NextModule = FailureWayModule;
                            actor.NextStep("SelectUnloadingDirection");
                        }
                    }
                    else
                    {
                        actor.NextStep("SelectUnloadingDirection");
                    }
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    string msg = string.Empty;
                    if (ConstainLot(ReadingLotID, out msg) == true)
                        actor.NextStep();
                    else
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(AlarmDuplicateLotID, "[RF READER MODULE] Duplicate LotID.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                            "RFReaderDuplicateLotID",
                            out windowName,
                            alarm,
                            string.Format("LOT_ID={0}", ReadingLotID),
                            true);
                        NextModule = FailureWayModule;
                        actor.NextStep("SelectUnloadingDirection");
                    }
                });
            #endregion
            #region RequestMasterInfo
            seq.Steps["RequestMasterInfo"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    FAECInfo.PACKING_MASTER_INFO_REQ command = new FAECInfo.PACKING_MASTER_INFO_REQ();
                    command.LOT_ID = ReadingLotID;
                    ecResult.Clear();
                    InterfaceUnit.ECPart.AddCommand(command, ecResult);
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ecResult.ReceiveOk)
                    {
                        if (ecResult.ParsingSuccess)
                        {
                            if (ecResult.ECInfo.PACKING_MASTER_INFO.RESULT == FAECInfo.FAECResult.PASS)
                            {
                                ProductInfo.SerialBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.SERIAL);
                                ProductInfo.PPIDBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.PPID);
                                ProductInfo.WWNBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.WWN);
                                ProductInfo.CSerialBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.C_SERIAL);
                                ProductInfo.PSIDBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.PSID);

                                WriteTraceLog("PACKING MASTER INFO RECEIVE OK");
                                ecResult.ECInfo.PACKING_MASTER_INFO.CopyTo(ProductInfo.ECInfo.PACKING_MASTER_INFO);
                                actor.NextStep();
                            }
                            else
                            {
                                string windowName = string.Empty;
                                var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] PACKING MASTER INFO EC RESULT FAIL.");
                                Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                                NextModule = FailureWayModule;
                                actor.NextStep("SelectUnloadingDirection");
                            }
                        }
                        else
                        {
                            string windowName = string.Empty;
                            var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] EC PACKING MASTER INFO RECEIVE DATA PARSING FAIL.");
                            Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                            NextModule = FailureWayModule;
                            actor.NextStep("SelectUnloadingDirection");
                        }
                    }
                    else if (ecResult.LastAlarmNo != 0)
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] EC PACKING MASTER INFO RECEIVE FAIL.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                        NextModule = FailureWayModule;
                        actor.NextStep("SelectUnloadingDirection");
                    }
                });
            #endregion
            #region ConfirmStepCorrection
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    var step = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_STEP;
                    bool result = false;
                    string windowName = string.Empty;
                    string msg = string.Empty;

                    if (string.IsNullOrEmpty(step) == true)
                        msg = string.Format("LOT_ID={0}, Step is Empty", ReadingLotID);
                    else if (step == ValidStep1 ||
                        step == ValidStep2 ||
                        step == ValidStep3)
                        result = true;
                    else
                        msg = string.Format("LOT_ID={0}, Invalid Step. {1}", ReadingLotID, step);

                    if (result == true)
                    {
                        actor.NextStep();
                    }
                    else
                    {
                        var alarm = Utility.AlarmUtility.GetAlarm(AlarmInvalidStep, msg);
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "InvalidStep",
                                    out windowName,
                                    alarm,
                                    msg,
                                    true);
                        NextModule = FailureWayModule;
                        actor.NextStep("SelectUnloadingDirection");
                    }
                });
            #endregion
            seq.AddItem(LoadJob);
            #region SendRecipeFileToGEM
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    var VT8792Equipment = Equipment as VT8792.SubEquipment;
                    if (VT8792Equipment.GlobalConfigModule.UseGEMCommunication == false)
                    {
                        actor.NextStep();
                        return;
                    }

                    bool raisedException = false;
                    try
                    {
                        string recipeName = ProductInfo.ECInfo.PACKING_MASTER_INFO.PRODUCT_NAME;
                        string recipeFileName = System.IO.Path.Combine(System.IO.Path.GetTempPath(), recipeName);
                        string recipe = string.Empty;
                        LotJobInfo.ToINIFormat(out recipe);
                        System.IO.File.WriteAllText(recipeFileName, recipe);
                        GEM.GEMFuncWrapper.SendRecipeFile(recipeName, recipeFileName);
                        raisedException = false;
                    }
                    catch
                    {
                        raisedException = true;
                    }
                    finally
                    {
                        if (raisedException == false)
                            actor.NextStep();
                    }
                });
            #endregion
            #region ConfirmTrayCountCorrection
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.HOT_RUN)
                    {
                        if (UseTrayCodeOfAJob)
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_MARKING = JobInfo.TrayCode;

                        var ecTrayCount = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY /
                            (ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X * ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y);
                        var ssdCountInTray = ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X * ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y;
                        var lotQty = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY;
                        ecTrayCount = lotQty / ssdCountInTray;

                        if (lotQty % ssdCountInTray > 0)
                            ecTrayCount += 1;

                        ProductInfo.VT8792ProductInfo.TrayCount = ecTrayCount;
                        ProductInfo.VT8792ProductInfo.RemainSSDCount = lotQty % ssdCountInTray;

                        if (ProductInfo.ECInfo.PACKING_MASTER_INFO.S_BOX_MOQ < ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY)
                        {
                            NextModule = FailureWayModule;

                            string msg = string.Format("EC Data Invalid. LOT_QTY is better than S_BOX_MOQ. LOT_QTY={0}, S_BOX_MOQ={1}",
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.S_BOX_MOQ);

                            Manager.MessageWindowManager.Instance.Show(Equipment, "TrayCountNotCorrect", msg);
                            actor.NextStep("SelectUnloadingDirection");
                        }
                        else if (ecTrayCount > TRAY_NO_MAX)
                        {
                            NextModule = FailureWayModule;

                            string msg = string.Format("EC Tray Count is better than {0}. LOT_QTY={1}, ARRAY_X={2}, ARRAY_Y={3}",
                                TRAY_NO_MAX,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y);

                            Manager.MessageWindowManager.Instance.Show(Equipment, "TrayCountNotCorrect", msg);
                            actor.NextStep("SelectUnloadingDirection");
                        }
                        else if (ecTrayCount != TrayCount - 1 && UseTrayCountCheck)
                        {
                            NextModule = FailureWayModule;

                            string msg = string.Format("Tray Count Not Correct.\n[DETECTED TRAY COUNT]={0}\n[EC INFO] TRAY_COUNT={1}, LOT_QTY={2}, ARRAY_X={3}, ARRAY_Y={4}",
                            TrayCount - 1,
                            ecTrayCount,
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY,
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X,
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y);

                            Manager.MessageWindowManager.Instance.Show(Equipment, "TrayCountNotCorrect", msg);
                            actor.NextStep("SelectUnloadingDirection");
                        }
                        else
                            actor.NextStep("RequestLotClose");
                    }
                });
            #endregion
            #region RetryRequestLotClose
            seq.Steps["RetryRequestLotClose"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    if (CurrentGate == GATE_NO_ZERO)
                    {
                        CurrentGate = GATE_NO_MIN;
                    }
                    else
                    {
                        CurrentGate++;
                        if (CurrentGate > GATE_NO_MAX)
                            CurrentGate = GATE_NO_MIN;
                    }
                });
            #endregion
            #region RequestLotClose
            seq.Steps["RequestLotClose"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    FAECInfo.LOT_CLOSE_REQ command = new FAECInfo.LOT_CLOSE_REQ();
                    command.LOT_ID = ReadingLotID;
                    command.GATE = string.Format("GATE{0}", CurrentGate.ToString());
                    command.OPER_ID = Equipment.CurrentUser.Name;
                    ecResult.Clear();
                    InterfaceUnit.ECPart.AddCommand(command, ecResult);
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ecResult.ReceiveOk)
                    {
                        if (ecResult.ParsingSuccess)
                        {
                            if (ecResult.ECInfo.LOT_CLOSE.RESULT == FAECInfo.FAECResult.PASS)
                            {
                                Manager.MessageWindowManager.Instance.CloseWindow("GateAlreadyWorkingWarning");
                                WriteTraceLog("LOT CLOSE OK");
                                NextModule = SuccessWayModule;
                                ecResult.ECInfo.LOT_CLOSE.CopyTo(ProductInfo.ECInfo.LOT_CLOSE);
                                actor.NextStep();
                            }
                            else if (string.IsNullOrEmpty(ecResult.ECInfo.LOT_CLOSE.MSG) == false && ecResult.ECInfo.LOT_CLOSE.MSG.IndexOf(GateAlreadyWorkingMsg) >= 0)
                            {
                                if (RetryInfoGateChangeRetry.IncreaseCount() == false)
                                {
                                    Manager.MessageWindowManager.Instance.Show(Equipment, "GateAlreadyWorkingWarning", string.Concat(ecResult.ECInfo.LOT_CLOSE.MSG, ", ", ReadingLotID));
                                    NextModule = FailureWayModule;
                                    actor.NextStep("SelectUnloadingDirection");
                                }
                                else
                                    actor.NextStep("RetryRequestLotClose");
                            }
                            else
                            {
                                string windowName = string.Empty;
                                var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] LOT CLOSE INFO EC RESULT FAIL.");
                                Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                                NextModule = FailureWayModule;
                                actor.NextStep("SelectUnloadingDirection");
                            }
                        }
                        else if (string.IsNullOrEmpty(ecResult.ECInfo.LOT_CLOSE.MSG) == false && ecResult.ECInfo.LOT_CLOSE.MSG.IndexOf(GateAlreadyWorkingMsg) >= 0)
                        {
                            if (RetryInfoGateChangeRetry.IncreaseCount() == false)
                            {
                                Manager.MessageWindowManager.Instance.Show(Equipment, "GateAlreadyWorkingWarning", string.Concat(ecResult.ECInfo.LOT_CLOSE.MSG, ", ", ReadingLotID));
                                NextModule = FailureWayModule;
                                actor.NextStep("SelectUnloadingDirection");
                            }
                            else
                                actor.NextStep("RetryRequestLotClose");
                        }
                        else
                        {
                            var msg = GetErrorMessageOfTrayLOTCLOSECheck(ecResult.ECInfo.LOT_CLOSE);
                            string windowName = string.Empty;
                            var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] EC LOT CLOSE INFO RECEIVE DATA PARSING FAIL.");
                            Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    msg,
                                    true);
                            NextModule = FailureWayModule;
                            actor.NextStep("SelectUnloadingDirection");
                        }
                    }
                    else if (ecResult.LastAlarmNo != 0)
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] EC LOT CLOSE INFO RECEIVE FAIL.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "RFReaderECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                        NextModule = FailureWayModule;
                        actor.NextStep("SelectUnloadingDirection");
                    }
                });
            #endregion
            #region SelectUnloadingDirection
            seq.Steps["SelectUnloadingDirection"].StepIndex = seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (NextModule == FailureWayModule)
                    {
                        string msg = string.Empty;
                        actor.NextTerminate();
                    }
                    else
                        actor.NextStep();
                });
            #endregion
            #region PreUnloadingAction
            seq.AddItem(
                delegate(object obj)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.HOT_RUN)
                    {
                        ProductInfo.Gate = string.Format("GATE{0}", CurrentGate);

                        var ssdCountInTray = ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X * ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y;
                        var lotQty = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY;
                        int trayCount = lotQty / ssdCountInTray;

                        if (lotQty % ssdCountInTray > 0)
                            trayCount += 1;

                        ProductInfo.VT8792ProductInfo.TrayCount = trayCount;
                        ProductInfo.VT8792ProductInfo.RemainSSDCount = lotQty % ssdCountInTray;
                    }
                });
            seq.AddItem((object obj) => NextModule = SuccessWayModule);
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.DRY_RUN ||
                        Equipment.RunMode == FAFramework.Equipment.RunModeTypes.COLD_RUN)
                    {
                        if (UseTrayCoutingResultOnDryRun)
                        {
                            ProductInfo.VT8792ProductInfo.TrayCount = TrayCount - 1;
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID = "TEST_LOT";
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_MARKING = "TEST";
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID = "TEST";
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X = 2;
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y = 3;
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.S_BOX_MOQ = LotSmallBoxMOQ;
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.L_BOX_MOQ = LotSmallBoxMOQ;
                            ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY = ProductInfo.VT8792ProductInfo.TrayCount * 2 * 3;
                            actor.NextStep();
                        }
                        else
                            actor.NextStep();
                    }
                    else
                        actor.NextStep();
                });
            seq.AddItem(
                delegate(object obj)
                {
                    string msg;
                    AddLot(ReadingLotID, out msg);
                    Equipment.LotManager.AddLot(ReadingLotID);
                });
            #endregion
        }
        private void MakeBarcodeScanProcess()
        {
            FAExtendECPart.ECResult ecResult = new FAExtendECPart.ECResult();

            var seq = BarcodeScanProcess;

            #region Regist Event
            seq.OnStart +=
                delegate
                {
                    JobStepIndex = 0;
                    RetryInfoScanRetry.ClearCount();
                    VisionJobNamePreFix = string.Empty;
                };
            #endregion

            #region Add Steps
            seq.Steps.Add("LoadJob", new StepInfo());
            seq.Steps.Add("GetStructOfBarcodes", new StepInfo());
            seq.Steps.Add("ChangeVisionJob", new StepInfo());
            seq.Steps.Add("Align", new StepInfo());
            seq.Steps.Add("ConfirmJobStepEnd", new StepInfo());
            seq.Steps.Add("ScanStep", new StepInfo());
            seq.Steps.Add("Scan", new StepInfo());
            seq.Steps.Add("IncreaseJobStep", new StepInfo());
            seq.Steps.Add("ConfirmScanResult", new StepInfo());
            seq.Steps.Add("ScanDataClear", new StepInfo());
            seq.Steps.Add("TurnOffLight", new StepInfo());
            seq.Steps.Add("ScanFailRetry", new StepInfo());
            seq.Steps.Add("StaticScanRetry", new StepInfo());
            #endregion

            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess == false)
                        actor.NextStep("TurnOffLight");
                    else
                        actor.NextStep();
                });
            seq.Steps["LoadJob"].StepIndex = seq.AddItem(LoadJob);

            #region Action Before Scan
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ProductInfo.VT8792ProductInfo.TrayIndex == 1)
                    {
                        PassCount = 0;
                        FailCount = 0;
                        PEBagStartTime = DateTime.Now;

                        if (VT8792Equipment.GlobalConfigModule.UseGEMCommunication)
                        {
                            GEM.GEMFuncWrapper.SetPEBagStart(Equipment.Name,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID,
                                DateTime.Now);
                        }

                        JobStepIndex = 0;
                        Equipment.ProductOutput.TrackInLot(DateTime.Now, ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID);

                        if (AlwaysGetStructOfBarcodes)
                        {
                            LastPartIDOfProduct = string.Empty;
                            actor.NextStep("GetStructOfBarcodes");
                        }
                        else if (LastPartIDOfProduct == ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID)
                        {
                            WriteTraceLog(string.Format("GetStructOfBarcodes Skip. LastPartID={0}, CurrentPartID{1}", LastPartIDOfProduct, ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID));
                            actor.NextStep("ChangeVisionJob");
                        }
                        else
                        {
                            WriteTraceLog(string.Format("GetStructOfBarcodes Start. LastPartID={0}, CurrentPartID{1}", LastPartIDOfProduct, ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID));
                            actor.NextStep("GetStructOfBarcodes");
                        }
                    }
                    else
                    {
                        if (CommonJobInfo.UsePositionCheck)
                            actor.NextStep("ChangeVisionJob");
                        else
                            actor.NextStep("Align");
                    }
                });
            seq.Steps["GetStructOfBarcodes"].StepIndex = seq.AddItem(GetStructOfBarcodes);
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (BarcodeStructScanFail)
                        actor.NextStep("TurnOffLight");
                    else
                        actor.NextStep();
                });
            seq.Steps["ChangeVisionJob"].StepIndex = seq.AddItem(ChangeVisionJob);
            seq.Steps["Align"].StepIndex = seq.AddItem(Aligner.Up.Sequence, Stopper.Up.Sequence);
            seq.AddItem(TimeAlignTime);
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ProductInfo.VT8792ProductInfo.TrayIndex > ProductInfo.VT8792ProductInfo.TrayCount)
                    {
                        Equipment.ProductOutput.TrackOutLot(DateTime.Now, ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID);
                        actor.NextTerminate();
                    }
                    else
                        actor.NextStep();
                });
            seq.AddItem(
                delegate(object obj)
                {
                    ProductInfo.SerialBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.SERIAL);
                    ProductInfo.PPIDBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.PPID);
                    ProductInfo.WWNBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.WWN);
                    ProductInfo.CSerialBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.C_SERIAL);
                    ProductInfo.PSIDBarcodeInfo.SetBarcodeInfo(ProductInfo.ECInfo.LOT_CLOSE.PSID);
                });

            seq.AddItem(VisionLight.DoTurnOn);
            seq.Steps["ScanDataClear"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    JobStepIndex = 0;
                    SSDScanFullResult.Clear();
                    SSDScanResultList.Clear();
                    ecResult.Clear();
                });
            #endregion

            seq.Steps["ConfirmJobStepEnd"].StepIndex = seq.AddItem(ConfirmJobStepEnd);
            seq.AddItem(SelectJobStepAction);

            #region ScanStep
            seq.Steps["ScanStep"].StepIndex = seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    SSDCountInTray = ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_X *
                        ProductInfo.ECInfo.PACKING_MASTER_INFO.TRAY_ARRAY_Y;

                    if (ProductInfo.VT8792ProductInfo.TrayIndex == ProductInfo.VT8792ProductInfo.TrayCount &&
                        ProductInfo.VT8792ProductInfo.RemainSSDCount != 0)
                    {
                        SSDCountInTray = ProductInfo.VT8792ProductInfo.RemainSSDCount;
                        actor.NextStep();
                    }
                    else
                        actor.NextStep();
                });
            seq.AddItem(SetRobotPositionFromJob);
            seq.AddItem(MoveRobot);
            #endregion

            seq.Steps["Scan"].StepIndex = seq.AddItem(Scan);
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (Equipment.RunMode == FAFramework.Equipment.RunModeTypes.DRY_RUN ||
                        Equipment.RunMode == FAFramework.Equipment.RunModeTypes.COLD_RUN)
                    {
                        actor.NextStep("IncreaseJobStep");
                    }
                    else
                        actor.NextStep();
                });

            #region ConfirmScanResult
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    var job = BarcodeScanJobInfo.Steps[JobStepIndex] as FASSDScanJobPositionMoveStep;
                    List<int> validCrossNumber, emptyPocketList;
                    GetValidCrossNumber(job.IndexList, SSDCountInTray, out validCrossNumber);
                    GetInvalidCrossNumber(job.IndexList, SSDCountInTray, out emptyPocketList);

                    var ssdScanResults = SSDScanResultList.Select(x => x).Where(x => validCrossNumber.Contains(x.Index));

                    ScanFailMessage = string.Empty;

                    if (validCrossNumber.Count == ssdScanResults.Count())
                    {
                        bool isScanFail = false;
                        List<SSDBarcodesInfo> barcodeInfoList = GetBarcodeInfoList(ssdScanResults, emptyPocketList, out isScanFail);

                        string emptyPocketCheckErrorMessage = string.Empty;
                        bool emptyPocketCheckResult = CheckEmptyPocketOfTray(SSDScanResultList, emptyPocketList, out emptyPocketCheckErrorMessage);

                        if (isScanFail || emptyPocketCheckResult == false)
                        {
                            if (RetryInfoScanRetry.IncreaseCount() == false)
                            {
                                ScanFailMessage += emptyPocketCheckErrorMessage;
                                actor.NextStep("ScanFailRetry");
                            }
                            else
                                actor.NextStep("StaticScanRetry");
                        }
                        else
                        {
                            foreach (var item in barcodeInfoList)
                            {
                                this.SSDScanFullResult.Add(item.Clone());
                            }

                            actor.NextStep();
                        }
                    }
                    else
                    {
                        ScanFailMessage = string.Format("Index Count Of Job is not match with scan result. Index count of job={0}, scan result index count={1}, JobStep={2}", validCrossNumber.Count, ssdScanResults.Count(), JobStepIndex);
                        WriteTraceLog(ScanFailMessage);

                        if (RetryInfoScanRetry.IncreaseCount() == false)
                        {
                            actor.NextStep("ScanFailRetry");
                        }
                        else
                            actor.NextStep("StaticScanRetry");
                    }
                });
            #endregion

            seq.AddItem("IncreaseJobStep");

            seq.Steps["IncreaseJobStep"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    if (BarcodeScanJobInfo.Steps.Count > JobStepIndex)
                    {
                        JobStepIndex++;
                    }
                });
            seq.AddItem("ConfirmJobStepEnd");

            seq.Steps["ConfirmScanResult"].StepIndex = seq.AddItem(ConfirmScanResult);

            #region PEBag
            seq.AddItem(
                delegate(object obj)
                {
                    FAECInfo.BRAND_PEBAG_TRAY_CHECK_REQ command = new FAECInfo.BRAND_PEBAG_TRAY_CHECK_REQ();
                    command.LOT_ID = ProductInfo.ECInfo.LOT_CLOSE.LOT_ID;
                    command.SSD_CNT = SSDCountInTray;

                    foreach (var item in this.SSDScanFullResult)
                    {
                        Utility.FAECInfo.PEBAG_TRAY_CHECK_ITEM info = new Utility.FAECInfo.PEBAG_TRAY_CHECK_ITEM();
                        info.PROD_SRLNO = item.PROD_SRLNO;
                        info.CUST_SRLNO = item.CUST_SRLNO;
                        info.WWN_SRLNO = item.WWN_SRLNO;
                        info.PIECE_PROD_ID = item.PIECE_PROD_ID;
                        info.PHYS_SECRTY_ID = item.PHYS_SECRTY_ID;
                        command.SERIAL_LIST.Add(info);
                    }

                    ecResult.Clear();
                    InterfaceUnit.ECPart.AddCommand(command, ecResult);
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (ecResult.ReceiveOk)
                    {
                        if (ecResult.ParsingSuccess)
                        {
                            if (ecResult.ECInfo.BRAND_PEBAG_TRAY_CHECK.RESULT == FAECInfo.FAECResult.PASS)
                            {
                                WriteTraceLog("PACKING MASTER INFO RECEIVE OK");
                                ecResult.ECInfo.BRAND_PEBAG_TRAY_CHECK.CopyTo(ProductInfo.ECInfo.BRAND_PEBAG_TRAY_CHECK);
                                actor.NextStep();
                            }
                            else
                            {
                                ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted = true;
                                ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess = false;
                                ProductInfo.VT8792ProductInfo.LotScanCompleted.LotFailMessage = "EC PEBAG CHECK RESULT FAIL";

                                var msg = GetErrorMessageOfTrayPEBAGCheck(ProductInfo.VT8792ProductInfo.TrayIndex, ecResult.ECInfo.BRAND_PEBAG_TRAY_CHECK);
                                string windowName = string.Empty;
                                var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] PEBAG CHECK EC RESULT FAIL.");
                                Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "TrayScanModuleECCommFail",
                                    out windowName,
                                    alarm,
                                    "[TRAY SCAN MODULE] TRAY SCAN FAIL\n" + msg,
                                    true);

                                actor.NextStep();
                            }
                        }
                        else
                        {
                            string windowName = string.Empty;
                            var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[RF READER MODULE] EC PEBAG CHECK RECEIVE DATA PARSING FAIL.");
                            Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "TrayScanModuleECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                            ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted = true;
                            ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess = false;
                            ProductInfo.VT8792ProductInfo.LotScanCompleted.LotFailMessage = "EC PEBAG CHECK RECEIVE DATA PARSING FAIL";
                            actor.NextStep();
                        }
                    }
                    else if (ecResult.LastAlarmNo != 0)
                    {
                        string windowName = string.Empty;
                        var alarm = Utility.AlarmUtility.GetAlarm(ecResult.LastAlarmNo, "[TRAY SCAN MODULE] EC PEBAG CHECK RECEIVE FAIL.");
                        Manager.MessageWindowManager.Instance.Show(Equipment,
                                    "TrayScanModuleECCommFail",
                                    out windowName,
                                    alarm,
                                    string.Empty,
                                    true);
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted = true;
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess = false;
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.LotFailMessage = "EC PEBAG CHECK RECEIVE FAIL";
                        actor.NextStep();
                    }
                });
            #endregion

            #region Action Before Terminate
            seq.AddItem(
               delegate(object obj)
               {
                   PassCount += SSDCountInTray;

                   Equipment.ProductOutput.AddProduct(DateTime.Now,
                       ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID,
                       SSDCountInTray);
               });
            seq.Steps["TurnOffLight"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    VisionLight.DoTurnOff(obj);
                    Aligner.Down.Execute(obj);
                    Stopper.Down.Execute(obj);

                    if (ProductInfo.VT8792ProductInfo.TrayIndex == ProductInfo.VT8792ProductInfo.TrayCount)
                    {
                        if (VT8792Equipment.GlobalConfigModule.UseGEMCommunication)
                        {
                            FailCount = ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY - PassCount;
                            GEM.GEMFuncWrapper.SetPEBagEnd(Equipment.Name,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_ID,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.LOT_QTY,
                                ProductInfo.ECInfo.PACKING_MASTER_INFO.PART_ID,
                                PassCount,
                                FailCount,
                                DateTime.Now - PEBagStartTime,
                                DateTime.Now);
                        }

                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted = true;
                    }
                });
            #endregion

            seq.AddTerminate();

            #region ScanFailRetry
            FAFramework.GUI.QuestionMessageBoxWindow questionWindow = null;
            seq.Steps["ScanFailRetry"].StepIndex = seq.AddItem(
                delegate(object obj)
                {
                    App.Current.Dispatcher.Invoke(
                        new Action(
                            delegate
                            {
                                questionWindow = new FAFramework.GUI.QuestionMessageBoxWindow();
                                questionWindow.Message = Utility.UtilityClass.GetStringResource(this, "VT8792.AreYouSureYouWantToScanRetry", "Are you sure you want to scan retry?") + "\n" + ScanFailMessage;
                                questionWindow.EquipmentInstance = Equipment;
                                questionWindow.Show();
                                Equipment.StateSignalModuleReferance.EquipmentStateConfigs.WarningStateConfig.CopyTo(
                                    Equipment.StateSignalModuleReferance.CustomState);
                                Equipment.StateSignalModuleReferance.CustomMode = true;

                            }), null);
                });
            seq.AddItem(
                delegate(FASequence actor, TimeSpan time)
                {
                    if (questionWindow.Result == FAFramework.GUI.QuestionMessageBoxWindow.QuestionResult.Yes)
                    {
                        Equipment.StateSignalModuleReferance.CustomMode = false;
                        actor.NextStep();
                    }
                    else if (questionWindow.Result == FAFramework.GUI.QuestionMessageBoxWindow.QuestionResult.No)
                    {
                        Equipment.StateSignalModuleReferance.CustomMode = false;
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanCompleted = true;
                        ProductInfo.VT8792ProductInfo.LotScanCompleted.ScanSuccess = false;
                        actor.NextStep("TurnOffLight");
                    }
                });
            seq.AddItem(ChangeVisionJob);

            seq.Steps["StaticScanRetry"].StepIndex =
            seq.AddItem("Scan");
            #endregion
        }