using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Serialization;
using QC.QsprShared.Dialogs;
using QC.QsprShared.GlobalData;
using QC.QsprShared.Trace;
using QC.QsprShared.Utilities;
using QC.QsprTestObjects.Loops;
using QC.QsprTestObjects.Parameters;
using QC.QsprTestObjects.Registry;
using QC.QsprTestObjects.Tests.Base;
using QC.QsprTestObjects.Tests.TestCase;
using QC.QTMDotNetKernelInterface.Environment;
using QC.QTMInterface;
using QC.QTMInterface.Business_Objects;

namespace QC.QsprTestObjects;

public class Scheduler
{
	public enum SoundLevel
	{
		CRITICAL,
		INFO,
		TESTFAIL,
		None
	}

	public enum TestingType
	{
		GoNoGo,
		Debug,
		SetupTest
	}

	public const int SND_ASYNC = 1;

	public const int SND_FILENAME = 131072;

	public static string[] soundFiles = new string[3] { "Notify.wav", "Notify.wav", "Notify.wav" };

	[XmlIgnore]
	public Mutex mutTest = new Mutex(initiallyOwned: false);

	[XmlIgnore]
	public Hashtable ListOfTestsRunning = new Hashtable();

	internal MessageDelegate msgDelegate;

	private Queue testQueue = new Queue();

	private Queue secondaryQueue = new Queue();

	private StopOnErrorTypes stopOnError;

	public PostConditionActions postConditionAction;

	private string linkedLoopName = "";

	private string linkedLoopValue = "";

	private ArrayList linkedTreeTesterConfigs = new ArrayList();

	private Stack gvInfoStack = new Stack();

	private Guid SchedulerID;

	private TestMessageBroadCaster testMsgBroadCaster;

	private TestKernelManager kernelMgr;

	public QSPREnvironment Env;

	public GlobalStatus GlobalStatus = new GlobalStatus();

	public QTMData QTMData = new QTMData();

	public Action RerunStarted;

	public string LinkedLoopName => linkedLoopName;

	public string LinkedLoopValue => linkedLoopValue;

	private Dictionary<int, List<BaseTest>> _failedTestStack { get; set; }

	private Dictionary<int, List<BaseTest>> _mustRunOnRerunTestStack { get; set; }

	private Dictionary<int, List<BaseTest>> _preRequisiteTestStack { get; set; }

	public TestMessageBroadCaster TestMsgBroadCaster => testMsgBroadCaster;

	public TestKernelManager KernelMgr => kernelMgr;

	private int CurrentRerunIteration
	{
		get
		{
			string gvValue = string.Empty;
			Env.GlobalVariable.GetGlobalVariable("RERUN_CURRENT_ITERATION", out gvValue);
			if (!int.TryParse(gvValue, out var result))
			{
				return 0;
			}
			return result;
		}
		set
		{
			Env.GlobalVariable.SetGlobalVariable("RERUN_CURRENT_ITERATION", value.ToString());
			try
			{
				QTMUtility.WriteToEventLog("CurrentRerunIteration", "Value Was rest to : " + value);
			}
			catch
			{
			}
		}
	}

	private int TotalReruns
	{
		get
		{
			string gvValue = string.Empty;
			Env.GlobalVariable.GetGlobalVariable("RERUN_TOTAL_COUNT", out gvValue);
			if (!int.TryParse(gvValue, out var result))
			{
				return 0;
			}
			return result;
		}
		set
		{
			Env.GlobalVariable.SetGlobalVariable("RERUN_TOTAL_COUNT", value.ToString());
		}
	}

	private bool ShouldRerun
	{
		get
		{
			if (CurrentRerunIteration <= TotalReruns)
			{
				return GetFailedTests().Count > 0;
			}
			return false;
		}
	}

	public bool IsInRerunMode => CurrentRerunIteration > 0;

	public QTMRegistry Registry
	{
		get
		{
			return (QTMRegistry)QTMData.theRegistry;
		}
		set
		{
			QTMData.theRegistry = value;
		}
	}

	public RootTest RootFolder
	{
		get
		{
			return (RootTest)GlobalStatus.RootTest;
		}
		set
		{
			GlobalStatus.RootTest = value;
			if (value != null)
			{
				InitializeParent(value);
			}
		}
	}

	public Queue TestQueue
	{
		get
		{
			return testQueue;
		}
		set
		{
			testQueue = value;
		}
	}

	public Queue SecondaryQueue
	{
		get
		{
			return secondaryQueue;
		}
		set
		{
			secondaryQueue = value;
		}
	}

	[DllImport("winmm.dll", SetLastError = true)]
	public static extern bool PlaySound(string pszSound, IntPtr hMod, int sf);

	public Scheduler()
	{
		SchedulerID = Guid.NewGuid();
		GlobalStatus.SchedulerID = SchedulerID.ToString();
		QTMData.SchedulerID = SchedulerID.ToString();
		GlobalStatus.TreeSavingStatusChangedEvent += GlobalStatus_TreeSavingStatusChangedEvent;
		testMsgBroadCaster = new TestMessageBroadCaster();
		testMsgBroadCaster.Scheduler = this;
		kernelMgr = new TestKernelManager();
		kernelMgr.scheduler = this;
		Env = new QSPREnvironment(SchedulerID.ToString());
		Action rerunStarted = delegate
		{
			ResetRuntimeStates(RootFolder);
		};
		RerunStarted = rerunStarted;
	}

	private void GlobalStatus_TreeSavingStatusChangedEvent(bool saving)
	{
		RootFolder.TreeSaving = saving;
	}

	private void InitializeParent(FolderTest folderTest)
	{
		folderTest.Root = GlobalStatus.RootTest as RootTest;
		foreach (BaseTest test in folderTest.TestList)
		{
			test.Parent = folderTest;
			if (test is FolderTest)
			{
				InitializeParent((FolderTest)test);
			}
		}
	}

	public bool RunUnitTests(bool rerun = false)
	{
		bool result = true;
		if (rerun)
		{
			TotalReruns = 1;
			CurrentRerunIteration = 1;
		}
		else
		{
			TotalReruns = 0;
			CurrentRerunIteration = 0;
		}
		try
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "RunUnitTests", TraceMessageType.Trace);
			if (!rerun)
			{
				_failedTestStack = new Dictionary<int, List<BaseTest>>();
				_mustRunOnRerunTestStack = new Dictionary<int, List<BaseTest>>();
				_preRequisiteTestStack = new Dictionary<int, List<BaseTest>>();
			}
			RootFolder = (RootTest)testQueue.Dequeue();
			if (RootFolder != null)
			{
				while (!IsInRerunMode || (ShouldRerun && !GlobalStatus.Stop))
				{
					try
					{
						GlobalStatus.EndOfUnitTestingHandled = false;
						if (IsInRerunMode)
						{
							RerunStarted();
						}
						SetCommonGlobalVariables(RootFolder);
						((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("QSPR_STOP_ON_ERROR", string.Empty);
						StartOfUnitTesting(RootFolder);
						RootFolder.StartTest();
						postConditionAction = RootFolder.RuntimeAttributes.PostConditionAction;
						result = EndOfUnitTesting(sentFromCleanup: false);
					}
					catch (Exception ex)
					{
						TraceMessage.Write("QC.QTMApplication.Scheduler", "RunUnitTests " + ex.Message, TraceMessageType.Exception);
					}
					CurrentRerunIteration++;
				}
				CurrentRerunIteration--;
			}
		}
		catch (Exception ex2)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "RunUnitTests " + ex2.Message, TraceMessageType.Exception);
		}
		return result;
	}

	internal void ResetRerun()
	{
		CurrentRerunIteration = 0;
	}

	public void AddFailedTest(BaseTest test)
	{
		if (_failedTestStack == null)
		{
			_failedTestStack = new Dictionary<int, List<BaseTest>>();
		}
		if (!_failedTestStack.ContainsKey(CurrentRerunIteration))
		{
			_failedTestStack.Add(CurrentRerunIteration, new List<BaseTest>());
		}
		List<BaseTest> list = _failedTestStack[CurrentRerunIteration];
		if (test.TestCase != null && !list.Contains(test.TestCase))
		{
			list.Add(test.TestCase);
			foreach (BaseTest test2 in test.TestCase.TestList)
			{
				AddFailedTest(test2);
			}
		}
		if (!list.Contains(test))
		{
			list.Add(test);
		}
	}

	public void AddMustRunOnRerunTest(BaseTest test)
	{
		if (_mustRunOnRerunTestStack == null)
		{
			_mustRunOnRerunTestStack = new Dictionary<int, List<BaseTest>>();
		}
		if (!_mustRunOnRerunTestStack.ContainsKey(CurrentRerunIteration))
		{
			_mustRunOnRerunTestStack.Add(CurrentRerunIteration, new List<BaseTest>());
		}
		List<BaseTest> list = _mustRunOnRerunTestStack[CurrentRerunIteration];
		if (test.TestCase != null && !list.Contains(test.TestCase))
		{
			list.Add(test.TestCase);
			foreach (BaseTest test2 in test.TestCase.TestList)
			{
				AddMustRunOnRerunTest(test2);
			}
		}
		if (!list.Contains(test))
		{
			list.Add(test);
		}
	}

	public void AddPreRequisiteTest(BaseTest test)
	{
		if (_preRequisiteTestStack == null)
		{
			_preRequisiteTestStack = new Dictionary<int, List<BaseTest>>();
		}
		if (!_preRequisiteTestStack.ContainsKey(CurrentRerunIteration))
		{
			_preRequisiteTestStack.Add(CurrentRerunIteration, new List<BaseTest>());
		}
		List<BaseTest> list = _preRequisiteTestStack[CurrentRerunIteration];
		if (test.TestCase != null && !list.Contains(test.TestCase))
		{
			list.Add(test.TestCase);
			foreach (BaseTest test2 in test.TestCase.TestList)
			{
				AddPreRequisiteTest(test2);
			}
		}
		else if (test is FolderTest && !list.Contains(test))
		{
			list.Add(test);
			foreach (BaseTest test3 in ((FolderTest)test).TestList)
			{
				AddPreRequisiteTest(test3);
			}
		}
		if (!list.Contains(test))
		{
			list.Add(test);
		}
	}

	public bool ContainsFailedTests(FolderTest folder)
	{
		bool result = false;
		if (GetFailedTests().Contains(folder))
		{
			return true;
		}
		foreach (BaseTest test in folder.TestList)
		{
			if (test is FolderTest && ContainsFailedTests(test as FolderTest))
			{
				result = true;
				break;
			}
			if (GetFailedTests().Contains(test))
			{
				result = true;
				break;
			}
		}
		return result;
	}

	public List<BaseTest> GetFailedTests()
	{
		if (_failedTestStack.ContainsKey(CurrentRerunIteration - 1))
		{
			return _failedTestStack[CurrentRerunIteration - 1];
		}
		return new List<BaseTest>();
	}

	public List<BaseTest> GetPreRequisiteTest()
	{
		if (_preRequisiteTestStack.ContainsKey(CurrentRerunIteration - 1))
		{
			return _preRequisiteTestStack[CurrentRerunIteration - 1];
		}
		return new List<BaseTest>();
	}

	public List<BaseTest> GetMustRunTests()
	{
		if (_mustRunOnRerunTestStack.ContainsKey(CurrentRerunIteration - 1))
		{
			return _mustRunOnRerunTestStack[CurrentRerunIteration - 1];
		}
		return new List<BaseTest>();
	}

	public void ResetGlobals(RootTest RootFolder)
	{
		GlobalStatus.GlobalTestResult = TestResult.Passed;
		Env.GlobalVariable.ResetErrorCode();
		Env.GlobalVariable.ResetTechnologies();
		ResetRuntimeStates(RootFolder);
		ResetLoopRuntimeStates(RootFolder);
		postConditionAction = PostConditionActions.None;
		gvInfoStack.Clear();
	}

	public void ResetGlobalsForLinks(FolderTest LinkedFolder)
	{
		GlobalStatus.GlobalTestResult = TestResult.Passed;
		Env.GlobalVariable.ResetErrorCode();
		Env.GlobalVariable.ResetTechnologies();
		ResetRuntimeStates(LinkedFolder);
		ResetLoopRuntimeStates(LinkedFolder);
		postConditionAction = PostConditionActions.None;
	}

	private void PrepareForLinkStart(BaseTest test)
	{
		try
		{
			FolderTest folderTest = null;
			if (test is FolderTest && ((FolderTest)test).FolderProperties.LinkRoot)
			{
				folderTest = (FolderTest)test;
			}
			else if (test is FolderTest && ((FolderTest)test).TestList.Count > 0 && ((FolderTest)test).TestList[0].Properties.LinkNode)
			{
				folderTest = ((FolderTest)test).TestList[0].GetLinkRootFolder();
			}
			if (folderTest != null)
			{
				KernelMgr.SetTreeName(folderTest.FolderProperties.LinkLocation);
				((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("RootName", folderTest.Properties.TestName);
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("Scheduler", "PrepareForLinkStart failed, " + ex.Message, TraceMessageType.Exception);
		}
	}

	private void SetCommonGlobalVariables(BaseTest test)
	{
		try
		{
			if (test is RootTest)
			{
				((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("RootName", test.Properties.TestName);
			}
			else if (test is FolderTest && ((FolderTest)test).TestList.Count > 0)
			{
				BaseTest baseTest = ((FolderTest)test).TestList[0];
				RootTest rootTest = baseTest.GetRootTest();
				((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("RootName", rootTest.Properties.TestName);
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("Scheduler", "SetCommonGlobalVariables failed, " + ex.Message, TraceMessageType.Exception);
		}
	}

	private void ResetAtLinkEnd(BaseTest test)
	{
		try
		{
			SetCommonGlobalVariables(test);
			KernelMgr.SetTreeName(GlobalStatus.TreeName);
		}
		catch (Exception ex)
		{
			TraceMessage.Write("Scheduler", "PrepareForLinkStart failed, " + ex.Message, TraceMessageType.Exception);
		}
	}

	public void StartOfLinkedTesting(FolderTest LinkedFolder)
	{
		TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfLinkedTesting", TraceMessageType.Trace);
		try
		{
			PrepareForLinkStart(LinkedFolder);
			string gvValue = "";
			Env.GlobalVariable.GetGlobalVariable("SN", out gvValue);
			linkedTreeTesterConfigs = QTMData.UpdateGlobalVbleForLinkedTree(LinkedFolder.FolderProperties.ConfigLocation, out var overwriteConfigs);
			gvInfoStack.Push(overwriteConfigs);
			PhoneStart phoneStart = default(PhoneStart);
			phoneStart.count = LinkedFolder.QueueTestCount(0, new ArrayList());
			phoneStart.configInfo = linkedTreeTesterConfigs;
			AddExtraLinkedTreeConfigs(LinkedFolder);
			TestMessage message = default(TestMessage);
			message.Message = $"{LinkedFolder.Properties.TestName}_;_{LinkedFolder.FolderProperties.SaveAsNewSession}";
			message.NodeRID = LinkedFolder.FolderProperties.LinkTreeID;
			message.Object = phoneStart;
			message.Result = TestResult.Passed;
			message.TestIndex = LinkedFolder.Index;
			message.SerialNumber = gvValue;
			message.IsLinkedRoot = LinkedFolder.FolderProperties.LinkRoot;
			msgDelegate(TestMsgType.OnLinkedTreeStart, message);
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfLinkedTesting " + ex.Message, TraceMessageType.Exception);
		}
	}

	public bool EndOfLinkedTesting(FolderTest LinkedFolder, TestResult Result)
	{
		bool result = true;
		TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfLinkedTesting", TraceMessageType.Trace);
		try
		{
			UnitEndData unitEndData = default(UnitEndData);
			string gvValue = "";
			Env.GlobalVariable.GetGlobalVariable("SN", out gvValue);
			unitEndData.SerialNumber = gvValue;
			unitEndData.TesterConfiguration = GetLinkedEndTesterConfigs(LinkedFolder);
			TestMessage message = default(TestMessage);
			message.Message = $"{LinkedFolder.Properties.TestName}_;_{LinkedFolder.FolderProperties.SaveAsNewSession}";
			message.NodeRID = LinkedFolder.FolderProperties.LinkTreeID;
			message.Object = unitEndData;
			message.Result = Result;
			message.TestIndex = LinkedFolder.Index;
			message.SerialNumber = gvValue;
			message.ErrorCode = Env.GlobalVariable.GetErrorCode();
			message.IsLinkedRoot = LinkedFolder.FolderProperties.LinkRoot;
			msgDelegate(TestMsgType.OnLinkedTreeEnd, message);
			linkedTreeTesterConfigs.Clear();
			if (gvInfoStack.Count > 0)
			{
				Dictionary<string, string> dictionary = gvInfoStack.Pop() as Dictionary<string, string>;
				foreach (KeyValuePair<string, string> item in dictionary)
				{
					((QTMRegistry)QTMData.theRegistry).SetGlobalVariable(item.Key, item.Value);
				}
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfLinkedTesting " + ex.Message, TraceMessageType.Exception);
		}
		finally
		{
			linkedLoopName = "";
			linkedLoopValue = "";
			ResetAtLinkEnd(LinkedFolder);
		}
		return result;
	}

	private void AddExtraLinkedTreeConfigs(FolderTest LinkedFolder)
	{
		if (!string.IsNullOrEmpty(linkedLoopName) || !string.IsNullOrEmpty(linkedLoopValue))
		{
			TesterConfigurationInfo testerConfigurationInfo = new TesterConfigurationInfo();
			testerConfigurationInfo.Name = linkedLoopName;
			testerConfigurationInfo.Value = linkedLoopValue;
			testerConfigurationInfo.IncludeInTestResults = true;
			linkedTreeTesterConfigs.Add(testerConfigurationInfo);
		}
		TesterConfigurationInfo testerConfigurationInfo2 = new TesterConfigurationInfo();
		testerConfigurationInfo2.Name = "TreeFileName";
		testerConfigurationInfo2.Value = LinkedFolder.FolderProperties.LinkLocation;
		testerConfigurationInfo2.IncludeInTestResults = true;
		linkedTreeTesterConfigs.Add(testerConfigurationInfo2);
		object[] array = QTMData.TesterConfigurationList.ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			TesterConfigurationInfo testerConfigurationInfo3 = (TesterConfigurationInfo)array[i];
			if (testerConfigurationInfo3.Name == "TreeType" || testerConfigurationInfo3.Name == "Server" || testerConfigurationInfo3.Name == "Database")
			{
				linkedTreeTesterConfigs.Add(testerConfigurationInfo3);
			}
		}
		if (LinkedFolder.FolderProperties.LinkTreeStringID == "-1")
		{
			testerConfigurationInfo2 = new TesterConfigurationInfo();
			testerConfigurationInfo2.IncludeInTestResults = false;
			testerConfigurationInfo2.Name = "SiteTreeID";
			testerConfigurationInfo2.Value = LinkedFolder.FolderProperties.LinkSiteTreeID;
			linkedTreeTesterConfigs.Add(testerConfigurationInfo2);
			testerConfigurationInfo2 = new TesterConfigurationInfo();
			testerConfigurationInfo2.IncludeInTestResults = false;
			testerConfigurationInfo2.Name = "SiteKey";
			testerConfigurationInfo2.Value = LinkedFolder.FolderProperties.LinkSiteKey;
			linkedTreeTesterConfigs.Add(testerConfigurationInfo2);
			testerConfigurationInfo2 = new TesterConfigurationInfo();
			testerConfigurationInfo2.IncludeInTestResults = false;
			testerConfigurationInfo2.Name = "RegisteredMachine";
			testerConfigurationInfo2.Value = LinkedFolder.FolderProperties.LinkRegisteredMachine;
			linkedTreeTesterConfigs.Add(testerConfigurationInfo2);
		}
	}

	private Hashtable GetLinkedEndTesterConfigs(FolderTest LinkedFolder)
	{
		Hashtable hashtable = new Hashtable();
		try
		{
			ArrayList arrayList = new ArrayList(linkedTreeTesterConfigs);
			arrayList.AddRange(QTMData.TesterConfigurationList);
			TesterConfigurationInfo testerConfigurationInfo = new TesterConfigurationInfo();
			testerConfigurationInfo.Name = "TreeFileName";
			testerConfigurationInfo.Value = LinkedFolder.FolderProperties.LinkLocation;
			testerConfigurationInfo.IncludeInTestResults = true;
			hashtable[testerConfigurationInfo.Name] = testerConfigurationInfo;
			if (LinkedFolder.FolderProperties.LinkTreeStringID != "-1")
			{
				TesterConfigurationInfo testerConfigurationInfo2 = new TesterConfigurationInfo();
				testerConfigurationInfo2.IncludeInTestResults = false;
				testerConfigurationInfo2.Name = "SiteTreeID";
				testerConfigurationInfo2.Value = LinkedFolder.FolderProperties.LinkSiteTreeID;
				hashtable[testerConfigurationInfo2.Name] = testerConfigurationInfo2;
				TesterConfigurationInfo testerConfigurationInfo3 = new TesterConfigurationInfo();
				testerConfigurationInfo3.IncludeInTestResults = false;
				testerConfigurationInfo3.Name = "SiteKey";
				testerConfigurationInfo3.Value = LinkedFolder.FolderProperties.LinkSiteKey;
				hashtable[testerConfigurationInfo3.Name] = testerConfigurationInfo3;
				TesterConfigurationInfo testerConfigurationInfo4 = new TesterConfigurationInfo();
				testerConfigurationInfo4.IncludeInTestResults = false;
				testerConfigurationInfo4.Name = "RegisteredMachine";
				testerConfigurationInfo4.Value = LinkedFolder.FolderProperties.LinkRegisteredMachine;
				hashtable[testerConfigurationInfo4.Name] = testerConfigurationInfo4;
			}
			foreach (TesterConfigurationInfo item in arrayList)
			{
				if (item.IncludeInTestResults && !hashtable.ContainsKey(item.Name) && item.Name != "TreeFileName" && item.Name != "SiteTreeID" && item.Name != "SiteKey" && item.Name != "RegisteredMachine")
				{
					string gvValue = "";
					if (Env.GlobalVariable.GetGlobalVariable(item.Name, out gvValue))
					{
						item.Value = gvValue;
					}
					hashtable[item.Name] = item;
				}
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "GetLinkedEndTesterConfigs " + ex.Message + ex.InnerException, TraceMessageType.Exception);
		}
		return hashtable;
	}

	private void StartOfUnitTesting(RootTest RootFolder)
	{
		TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfUnitTesting", TraceMessageType.Trace);
		try
		{
			ResetGlobals(RootFolder);
			GlobalStatus.TestRunning = true;
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("SN", QTMData.WConfig.LastUsedSerialNumber);
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("CURRENT_UNIT_INDEX", "0");
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("GONOGO_RUNNING", "True");
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("COMBINED_SUITE_LOG", QTMData.WConfig.EnableSUITEOutParam ? "1" : "0");
			QTMData.UpdateGlobalVble(GetFromTesterConfig: false, null);
			ArrayList testNames = new ArrayList();
			ArrayList nodeNames = new ArrayList();
			RootFolder.GetSelectedTests(ref testNames, ref nodeNames);
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("SelectedTestNames", testNames);
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("SelectedRealTestNames", nodeNames);
			PhoneStart phoneStart = default(PhoneStart);
			phoneStart.count = RootFolder.QueueTestCount(0, new ArrayList());
			phoneStart.configInfo = QTMData.TesterConfigurationList;
			TestMessage message = default(TestMessage);
			message.Message = QTMData.WConfig.LastUsedSerialNumber;
			message.NodeRID = RootFolder.Properties.NodeRID;
			message.Object = phoneStart;
			message.Result = TestResult.Passed;
			message.TestIndex = RootFolder.Index;
			if (RootFolder.Properties is TestPlanProperties)
			{
				message.TestCaseID = ((TestPlanProperties)RootFolder.Properties).TestPlanVersionID;
				message.DisplayID = ((TestPlanProperties)RootFolder.Properties).ID;
				message.TestCaseName = ((TestPlanProperties)RootFolder.Properties).TestPlanName;
				message.IsApprovedTestPlan = GetIsApprovedTestPlan();
				message.TestPlanVersion = GetTestPlanVersion();
			}
			else
			{
				message.TestCaseName = ((RootTestProperties)RootFolder.Properties).TestName;
			}
			msgDelegate(TestMsgType.OnUnitStart, message);
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfUnitTesting " + ex.Message, TraceMessageType.Exception);
		}
	}

	public bool EndOfUnitTesting(bool sentFromCleanup)
	{
		if (GlobalStatus.EndOfUnitTestingHandled)
		{
			return true;
		}
		GlobalStatus.EndOfUnitTestingHandled = true;
		bool result = true;
		TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfUnitTesting", TraceMessageType.Trace);
		try
		{
			GlobalStatus.TestRunning = false;
			GlobalStatus.TestCaseRunning = false;
			RootFolder.TestUserInterfaceProperties.ResetRunTimeAttributes(clearStatusIcon: false);
			((QTMRegistry)QTMData.theRegistry).SetGlobalVariable("GONOGO_RUNNING", "False");
			if (GlobalStatus.Stop)
			{
				if (msgDelegate != null)
				{
					msgDelegate(TestMsgType.OnTestMsgSend, new TestMessage
					{
						Result = TestResult.Aborted
					});
				}
				GlobalStatus.GlobalTestResult = TestResult.Aborted;
			}
			TestResult globalTestResult = GlobalStatus.GlobalTestResult;
			if (globalTestResult != TestResult.Passed)
			{
				result = false;
			}
			if (globalTestResult == TestResult.IgnoreSession)
			{
				Env.GlobalVariable.SetGlobalVariable("TreeType", "IgnoreSession");
			}
			else if (GlobalStatus.DVTMode)
			{
				Env.GlobalVariable.SetGlobalVariable("TreeType", QC.QsprTestObjects.Tests.Base.TreeTypes.DVT.ToString());
			}
			TestMessage message = GenerateTestMessage(globalTestResult);
			msgDelegate(TestMsgType.OnUnitEnd, message);
			QTMData.WConfig.LastUsedSerialNumber = GetSN();
			GlobalStatus.DVTMode = false;
			if (!sentFromCleanup)
			{
				OnTreeDone();
			}
			QTMUtility.WriteToEventLog("OnUnitEnd", "States has been reset. Test result is " + GlobalStatus.GlobalTestResult);
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfUnitTesting " + ex, TraceMessageType.Exception);
		}
		return result;
	}

	public void OnTreeDone()
	{
		TraceMessage.Write("QC.QTMApplication.Scheduler", "OnTreeDone", TraceMessageType.Trace);
		TestResult globalTestResult = GlobalStatus.GlobalTestResult;
		TestMessage message = GenerateTestMessage(globalTestResult);
		msgDelegate(TestMsgType.OnTreeDone, message);
		TraceMessage.Write("QC.QTMApplication.Scheduler", "OnTreeDone message sent", TraceMessageType.Trace);
	}

	private string GetSN()
	{
		string gvValue = "";
		Env.GlobalVariable.GetGlobalVariable("SN", out gvValue);
		return gvValue;
	}

	public Hashtable GetTesterConfig()
	{
		Hashtable hashtable = new Hashtable();
		object[] array = QTMData.TesterConfigurationList.ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			TesterConfigurationInfo testerConfigurationInfo = (TesterConfigurationInfo)array[i];
			if (testerConfigurationInfo.IncludeInTestResults)
			{
				string gvValue = "";
				if (Env.GlobalVariable.GetGlobalVariable(testerConfigurationInfo.Name, out gvValue))
				{
					testerConfigurationInfo.Value = gvValue;
				}
				hashtable[testerConfigurationInfo.Name] = testerConfigurationInfo;
			}
		}
		string gvValue2 = "";
		Env.GlobalVariable.GetGlobalVariable("SUBERRORCODE", out gvValue2);
		if (IsSubErrorSet(gvValue2))
		{
			TesterConfigurationInfo testerConfigurationInfo2 = new TesterConfigurationInfo("SUBERRORCODE", gvValue2);
			testerConfigurationInfo2.AddToSessionData = true;
			testerConfigurationInfo2.IncludeInTestResults = true;
			testerConfigurationInfo2.Description = "Sub Error Code";
			if (hashtable.Contains("SUBERRORCODE"))
			{
				hashtable["SUBERRORCODE"] = testerConfigurationInfo2;
			}
			else
			{
				hashtable.Add("SUBERRORCODE", testerConfigurationInfo2);
			}
		}
		return hashtable;
	}

	private TestMessage GenerateTestMessage(TestResult Result)
	{
		UnitEndData unitEndData = default(UnitEndData);
		string text = (unitEndData.SerialNumber = GetSN());
		unitEndData.TesterConfiguration = GetTesterConfig();
		TestMessage result = default(TestMessage);
		result.Message = text;
		result.NodeRID = RootFolder.Properties.NodeRID;
		result.Object = unitEndData;
		result.Result = Result;
		result.TestIndex = RootFolder.Index;
		result.SerialNumber = text;
		result.ErrorCode = Env.GlobalVariable.GetErrorCode();
		result.IsApprovedTestPlan = GetIsApprovedTestPlan();
		result.TestPlanVersion = GetTestPlanVersion();
		return result;
	}

	public bool GetIsApprovedTestPlan()
	{
		if (RootFolder == null)
		{
			return false;
		}
		RootTestProperties rootProperties = RootFolder.RootProperties;
		if (rootProperties is TestPlanProperties && ((TestPlanProperties)rootProperties).Status == "Approved" && !ContainsDraftTestCases(RootFolder))
		{
			return true;
		}
		return false;
	}

	public static bool ContainsDraftTestCases(BaseTest node)
	{
		if (node is TestCaseTest && (node as TestCaseTest).TestCaseProperties.Status == ApprovalStates.Draft)
		{
			return true;
		}
		if (node is FolderTest)
		{
			foreach (BaseTest test in (node as FolderTest).TestList)
			{
				if (ContainsDraftTestCases(test))
				{
					return true;
				}
			}
		}
		return false;
	}

	public uint GetTestPlanVersion()
	{
		if (RootFolder == null)
		{
			return 0u;
		}
		RootTestProperties rootProperties = RootFolder.RootProperties;
		if (rootProperties is TestPlanProperties)
		{
			return ((TestPlanProperties)rootProperties).Version;
		}
		return 0u;
	}

	private static bool IsSubErrorSet(string errorCode)
	{
		int result = 0;
		if (string.IsNullOrWhiteSpace(errorCode))
		{
			return false;
		}
		if (int.TryParse(errorCode, out result) && result == 0)
		{
			return false;
		}
		return true;
	}

	private bool RunDebugTests()
	{
		bool flag = true;
		TraceMessage.Write("QC.QTMApplication.Scheduler", "RunDebugTests", TraceMessageType.Trace);
		try
		{
			FolderTest folderTest;
			if (GlobalStatus.SecondaryQueueRunning)
			{
				folderTest = (FolderTest)SecondaryQueue.Dequeue();
			}
			else
			{
				if (GlobalStatus.TestRunning)
				{
					return flag;
				}
				folderTest = (FolderTest)TestQueue.Dequeue();
			}
			SetCommonGlobalVariables(folderTest);
			PrepareForLinkStart(folderTest);
			StartOfDebugTesting(folderTest);
			folderTest.RuntimeAttributes.RightClickTest = true;
			if (stopOnError == StopOnErrorTypes.CompleteStop || stopOnError == StopOnErrorTypes.CompleteStopNoRetry || stopOnError == StopOnErrorTypes.IgnoreSession)
			{
				folderTest.RuntimeAttributes.StopOnError = stopOnError;
			}
			flag = folderTest.RunTestsOnce();
			EndOfDebugTesting();
			ResetAtLinkEnd(folderTest);
			stopOnError = folderTest.RuntimeAttributes.StopOnError;
			if (TestQueue.Count > 0 && !GlobalStatus.SecondaryQueueRunning)
			{
				flag &= RunDebugTests();
			}
			else if (SecondaryQueue.Count > 0 && GlobalStatus.SecondaryQueueRunning)
			{
				flag &= RunDebugTests();
			}
			else
			{
				_ = GlobalStatus.BranchOnError;
				stopOnError = StopOnErrorTypes.None;
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "RunDebugTests " + ex.Message, TraceMessageType.Exception);
		}
		return flag;
	}

	private void StartOfDebugTesting(FolderTest tests)
	{
		TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfDebugTesting", TraceMessageType.Trace);
		try
		{
			GlobalStatus.TestRunning = true;
			object @object = tests.QueueTestCount(0, new ArrayList());
			TestMessage message = default(TestMessage);
			message.Message = "";
			message.NodeRID = -1L;
			message.Object = @object;
			message.Result = TestResult.Passed;
			message.TestIndex = "";
			if (msgDelegate != null)
			{
				msgDelegate(TestMsgType.OnStartOfDebugTesting, message);
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "StartOfDebugTesting " + ex.Message, TraceMessageType.Exception);
		}
	}

	private void EndOfDebugTesting()
	{
		TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfDebugTesting", TraceMessageType.Trace);
		try
		{
			GlobalStatus.TestRunning = false;
			GlobalStatus.TestCaseRunning = false;
			TestMessage message = default(TestMessage);
			message.Message = "";
			message.NodeRID = -1L;
			message.Object = null;
			message.Result = TestResult.Passed;
			message.TestIndex = "";
			if (msgDelegate != null)
			{
				msgDelegate(TestMsgType.OnEndOfDebugTesting, message);
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "EndOfDebugTesting " + ex.Message, TraceMessageType.Exception);
		}
	}

	public bool ScheduleTests(FolderTest tests, TestingType tType, bool rerun = false)
	{
		bool result = false;
		InitializeTesting(tests);
		switch (tType)
		{
		case TestingType.Debug:
			if (!GlobalStatus.SecondaryQueueRunning)
			{
				GlobalStatus.IsDebugMode = true;
			}
			foreach (BaseTest test in tests.TestList)
			{
				if (test is FolderTest && test.Properties.ToolTest)
				{
					test.RuntimeAttributes.Tool = true;
				}
			}
			QueueTests(tests);
			result = RunDebugTests();
			break;
		case TestingType.GoNoGo:
			GlobalStatus.IsDebugMode = false;
			QueueTests(tests);
			result = RunUnitTests(rerun);
			if (GlobalStatus.IsInteractiveMode)
			{
				if (GlobalStatus.GlobalTestResult == TestResult.Passed)
				{
					GlobalStatus.InteractiveStatus = GlobalStatus.ExecutionStatus.Passed;
				}
				else
				{
					GlobalStatus.InteractiveStatus = GlobalStatus.ExecutionStatus.Failed;
				}
			}
			break;
		}
		return result;
	}

	public void QueueTests(FolderTest tests)
	{
		if (GlobalStatus.SecondaryQueueRunning)
		{
			SecondaryQueue.Enqueue(tests);
			tests.QueueTestCount(0, new ArrayList());
		}
		else
		{
			TestQueue.Enqueue(tests);
			tests.QueueTestCount(0, new ArrayList());
		}
	}

	public static void ResetRuntimeStates(FolderTest tests)
	{
		try
		{
			tests.TestUserInterfaceProperties.ResetRunTimeAttributes();
			foreach (BaseTest test in tests.TestList)
			{
				if (test is FolderTest)
				{
					ResetRuntimeStates((FolderTest)test);
				}
				test.TestUserInterfaceProperties.ResetRunTimeAttributes();
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "ResetRuntimeStates : " + ex.Message, TraceMessageType.Exception);
		}
	}

	public static void ResetLoopRuntimeStates(FolderTest tests)
	{
		try
		{
			tests.RuntimeAttributes.ResetLoopStateInfo();
			foreach (BaseTest test in tests.TestList)
			{
				if (test is FolderTest)
				{
					ResetLoopRuntimeStates((FolderTest)test);
				}
				test.RuntimeAttributes.ResetLoopStateInfo();
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "ResetLoopRuntimeStates : " + ex.Message, TraceMessageType.Exception);
		}
	}

	private void InitializeTesting(FolderTest fTest)
	{
		try
		{
			ResetRuntimeStates(fTest);
			ResetLoopRuntimeStates(fTest);
			if (TestQueue.Count == 0 && !GlobalStatus.TestRunning)
			{
				GlobalStatus.Reset();
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "InitializeTesting : " + ex.Message, TraceMessageType.Exception);
		}
	}

	public void SetMessageDelegate(MessageDelegate SomeFunction)
	{
		msgDelegate = SomeFunction;
	}

	private void RunBranchOnErrorTest()
	{
		RootTest rootTest = (RootTest)GlobalStatus.RootTest;
		BaseTest baseTest = rootTest.FindTest(GlobalStatus.BranchOnTestIndex);
		GlobalStatus.BranchOnError = false;
		if (baseTest != null)
		{
			FolderTest folderTest = new FolderTest("DummyTest");
			folderTest.Add(baseTest);
			ScheduleTests(folderTest, TestingType.Debug);
		}
	}

	public void SyncTests(FolderTest tests)
	{
		try
		{
			SetDebugMessage("Synchronizing the tests.......", SoundLevel.None);
			ArrayList arrayList = new ArrayList();
			if (!tests.SyncParameters(arrayList, QTMData.WConfig.SyncDescriptions) && arrayList.Count > 0)
			{
				AppMessageDialog.Show("Synchronize Failed for " + arrayList[0].ToString(), "QSPR - Message Center", MessageBoxButtons.OK, MessageBoxIcon.Hand, DialogResult.OK, MessageDialogType.Error);
			}
			SetDebugMessage("Synchronizing Done.", SoundLevel.None);
		}
		catch (Exception ex)
		{
			SetDebugMessage("Sync Test  " + ex.Message, SoundLevel.INFO);
		}
	}

	public bool LoopTest(FolderTest ParentFolder)
	{
		bool result = true;
		if (ParentFolder.FolderProperties.Scenarios == null)
		{
			return true;
		}
		bool flag = false;
		try
		{
			if (ParentFolder.FolderProperties.RefreshLoopValuesAtLoopStart)
			{
				ParentFolder.UpdateLoopValues();
			}
		}
		catch (Exception)
		{
			return false;
		}
		try
		{
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			ArrayList arrayList = null;
			LoopCondition loopCondition;
			if ((loopCondition = (LoopCondition)ParentFolder.FolderProperties.Scenarios.LoopConditions[0]) != null)
			{
				if (loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYCOUNT)
				{
					flag2 = true;
				}
				if (loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYTIME)
				{
					flag3 = true;
				}
				if (loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYSEQUENCE)
				{
					flag4 = true;
				}
			}
			arrayList = ParentFolder.FolderProperties.Scenarios.ConditionCheck;
			ArrayList descriptions = ParentFolder.FolderProperties.Scenarios.Descriptions;
			int num = -1;
			DateTime now = DateTime.Now;
			DateTime dateTime = DateTime.Now;
			string elapsedTime = "";
			if (flag3)
			{
				double value = double.Parse(loopCondition.OriginalValue, CultureInfo.InvariantCulture);
				dateTime = (loopCondition.LoopDetails.StartsWith("Hours") ? now.AddHours(value) : ((!loopCondition.LoopDetails.StartsWith("Minutes")) ? now.AddSeconds(value) : now.AddMinutes(value)));
			}
			if (loopCondition.IgnoreIntermediateResults)
			{
				TestMessage message = default(TestMessage);
				message.Message = "";
				message.NodeRID = -1L;
				message.Object = null;
				message.Result = TestResult.Passed;
				message.TestIndex = "";
				if (msgDelegate != null)
				{
					msgDelegate(TestMsgType.OnTestMsgHold, message);
				}
			}
			bool flag5 = false;
			while (true)
			{
				if (GlobalStatus.Abort || GlobalStatus.Stop)
				{
					return false;
				}
				if (ParentFolder.Properties.CheckStateTest == CheckState.Unchecked && num > -1)
				{
					break;
				}
				num++;
				bool flag6 = false;
				if (flag2)
				{
					if (!(bool)arrayList[0])
					{
						break;
					}
					if (loopCondition.OriginalValue == "Loop Forever")
					{
						if (num == 2147483646)
						{
							num = 0;
						}
						flag6 = true;
						if (!loopCondition.IgnoreIntermediateResults)
						{
						}
					}
					else
					{
						if (num == int.Parse(loopCondition.OriginalValue) - 1)
						{
							flag5 = true;
						}
						if (num == int.Parse(loopCondition.OriginalValue))
						{
							break;
						}
						flag6 = true;
					}
				}
				else if (flag3)
				{
					if (!(bool)arrayList[0])
					{
						break;
					}
					if (num == 2147483646)
					{
						num = 0;
					}
					DateTime now2 = DateTime.Now;
					if (flag5)
					{
						break;
					}
					TimeSpan timeSpan = now2 - now;
					int num2 = timeSpan.Days * 24 + timeSpan.Hours;
					elapsedTime = IntToStringForTime(num2) + IntToStringForTime(timeSpan.Minutes) + IntToStringForTime(timeSpan.Seconds);
					flag6 = true;
				}
				else
				{
					if (arrayList.Count == num)
					{
						break;
					}
					flag6 = (bool)arrayList[num];
				}
				if (!flag6)
				{
					continue;
				}
				int index = num;
				if (((LoopCondition)ParentFolder.FolderProperties.Scenarios.LoopConditions[0]).LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYCOUNT || ((LoopCondition)ParentFolder.FolderProperties.Scenarios.LoopConditions[0]).LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYTIME)
				{
					index = 0;
				}
				if (!CanScenarioRun(ParentFolder.FolderProperties.Scenarios.DontRunCondition[index].ToString()))
				{
					ArrayList arrayList2 = new ArrayList();
					MsgData msgData = default(MsgData);
					msgData.msgType = TestMsgType.OnDequeueTest;
					msgData.TestFullPath = ParentFolder.TestPath;
					msgData.TestIndex = ParentFolder.Index;
					arrayList2.Add(msgData);
					TestMessage message2 = default(TestMessage);
					message2.Message = ParentFolder.TestPath;
					message2.NodeRID = ParentFolder.Properties.NodeRID;
					message2.Object = arrayList2;
					message2.Result = TestResult.Passed;
					message2.TestIndex = ParentFolder.Index;
					msgDelegate(TestMsgType.OnDequeueTest, message2);
					continue;
				}
				flag = false;
				flag = HandleEachLoopCondition(ParentFolder, flag, flag2, flag3, descriptions, num, elapsedTime);
				if (loopCondition.IgnoreIntermediateResults)
				{
					TestMessage message3 = default(TestMessage);
					message3.Message = "";
					message3.NodeRID = -1L;
					message3.Object = null;
					message3.Result = TestResult.Passed;
					message3.TestIndex = "";
					if (msgDelegate != null)
					{
						msgDelegate(TestMsgType.OnTestMsgClear, message3);
					}
				}
				if (flag3 && dateTime.CompareTo(DateTime.Now) <= 0)
				{
					flag5 = true;
				}
				if (flag5 && !ParentFolder.IsInRetry() && loopCondition.IgnoreIntermediateResults)
				{
					TestMessage message4 = default(TestMessage);
					message4.Message = "";
					message4.NodeRID = -1L;
					message4.Object = null;
					message4.Result = TestResult.Passed;
					message4.TestIndex = "";
					if (msgDelegate != null)
					{
						msgDelegate(TestMsgType.OnTestMsgSend, message4);
					}
				}
				FolderTest folderTest = ParentFolder;
				if (flag4)
				{
					ParentFolder = ConstructNewLoopSequenceFolder(ParentFolder, num);
					ParentFolder.TestUserInterfaceProperties.ActualSequenceLoopFolder = folderTest;
				}
				result = ParentFolder.RunTestsOnce();
				if (flag4)
				{
					ParentFolder = folderTest;
					ParentFolder.RuntimeAttributes = folderTest.RuntimeAttributes;
					ParentFolder.FolderProperties.Failed = folderTest.FolderProperties.Failed;
					ParentFolder.FolderProperties.Exception = folderTest.FolderProperties.Exception;
					ParentFolder.FolderProperties.TestResult = folderTest.FolderProperties.TestResult;
				}
				if (ParentFolder.FolderProperties.LinkRoot && ParentFolder != null)
				{
					TestResult testResult = TestResult.Failed;
					EndOfLinkedTesting(Result: ParentFolder.FolderProperties.Exception ? TestResult.Exception : ((!ParentFolder.FolderProperties.Failed) ? TestResult.Passed : TestResult.Failed), LinkedFolder: ParentFolder);
				}
				TestMessage message5 = default(TestMessage);
				message5.Message = "";
				message5.NodeRID = -1L;
				message5.Object = null;
				message5.Result = TestResult.Passed;
				if (ParentFolder.Properties.CheckStateTest == CheckState.Unchecked && ParentFolder.GetRootTest().RootProperties.LogSkippedResults)
				{
					message5.Result = TestResult.Skipped;
				}
				message5.TestIndex = "";
				if (msgDelegate != null)
				{
					msgDelegate(TestMsgType.OnLoopEnd, message5);
				}
				TraceMessage.EndXMLLogging();
				bool flag7 = false;
				if (ParentFolder.FolderProperties.Scenarios.Condition != null)
				{
					bool failed = ParentFolder.RuntimeAttributes.Failed;
					if (!flag5 && loopCondition.IgnoreIntermediateResults && !GlobalStatus.TestMsgHold)
					{
						TestMessage message6 = default(TestMessage);
						message6.Message = "";
						message6.NodeRID = -1L;
						message6.Object = null;
						message6.Result = TestResult.Passed;
						message6.TestIndex = "";
						if (msgDelegate != null)
						{
							msgDelegate(TestMsgType.OnTestMsgHold, message6);
						}
					}
					if (GlobalStatus.TestMsgHold && !failed && QTMData.PeekForFailedMessageInQueue())
					{
						ParentFolder.RuntimeAttributes.Failed = true;
					}
					if (ParentFolder.FolderProperties.Scenarios.Condition.Enabled && ParentFolder.FolderProperties.Scenarios.Condition.IsConditionMet(new ParameterCollection(), TestResult.Passed))
					{
						flag7 = true;
					}
					ParentFolder.RuntimeAttributes.Failed = failed;
				}
				if ((flag7 || !GlobalStatus.TestMsgHold) && ((!ParentFolder.IsMustRunFolder()) ? (flag7 | CheckForPostConditions(ref ParentFolder)) : flag7))
				{
					break;
				}
			}
			if (ParentFolder.FolderProperties.FolderForTestLoop)
			{
				BaseTest baseTest = ParentFolder.TestList[0];
				ParentFolder.HandleRunTimeAttributes(baseTest);
				baseTest.Properties.Scenarios = ParentFolder.Properties.Scenarios;
				baseTest.Parent = ParentFolder.Parent;
				baseTest.Parent.RuntimeAttributes.Failed = baseTest.RuntimeAttributes.Failed;
				baseTest.Parent.HandleRunTimeAttributes(baseTest);
			}
			if (loopCondition.IgnoreIntermediateResults)
			{
				if (!ParentFolder.IsInRetry())
				{
					TestMessage message7 = default(TestMessage);
					message7.Message = "";
					message7.NodeRID = -1L;
					message7.Object = null;
					message7.Result = TestResult.Passed;
					message7.TestIndex = "";
					if (msgDelegate != null)
					{
						msgDelegate(TestMsgType.OnTestMsgSend, message7);
					}
				}
				else
				{
					TestMessage message8 = default(TestMessage);
					message8.Message = "";
					message8.NodeRID = -1L;
					message8.Object = null;
					message8.Result = TestResult.Passed;
					message8.TestIndex = "";
					if (msgDelegate != null)
					{
						msgDelegate(TestMsgType.OnTestMsgRetryDone, message8);
					}
				}
			}
		}
		catch (Exception ex2)
		{
			SetDebugMessage("Error in Looping  " + ex2.Message, SoundLevel.INFO);
			AppMessageDialog.Show("Loop Test : " + ex2.Message, DialogResult.OK, MessageDialogType.Exception);
		}
		return result;
	}

	private static FolderTest ConstructNewLoopSequenceFolder(FolderTest LoopedFolder, int loopRowIndex)
	{
		_ = LoopedFolder.TestList;
		FolderTest folderTest = (FolderTest)LoopedFolder.Clone();
		folderTest.FolderProperties.FolderForTestLoop = true;
		folderTest.RuntimeAttributes = LoopedFolder.RuntimeAttributes;
		Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
		Dictionary<string, List<string>> dictionary2 = new Dictionary<string, List<string>>();
		foreach (LoopCondition loopCondition in LoopedFolder.FolderProperties.Scenarios.LoopConditions)
		{
			string[] collection = loopCondition.TestIndex.Split(new string[1] { "," }, StringSplitOptions.None);
			List<string> value = new List<string>(collection);
			dictionary.Add(loopCondition.LoopName, value);
			string[] array = loopCondition.LoopValuesAsString.Split(new char[1] { ',' }, StringSplitOptions.None);
			string text = array[loopRowIndex];
			string[] collection2 = text.Split(new char[1] { '_' }, StringSplitOptions.RemoveEmptyEntries);
			List<string> value2 = new List<string>(collection2);
			dictionary2.Add(loopCondition.LoopName, value2);
		}
		SequenceChildNodes(folderTest, dictionary, dictionary2);
		return folderTest;
	}

	private static void SequenceChildNodes(FolderTest sequenceFolder, Dictionary<string, List<string>> testIndicesByLoopName, Dictionary<string, List<string>> sequenceByLoopName)
	{
		List<string> list = sequenceByLoopName.Keys.ToList();
		List<FolderTest> list2 = new List<FolderTest>();
		foreach (string item in list)
		{
			string testIndex = testIndicesByLoopName[item][0];
			BaseTest baseTest = sequenceFolder.FindTest(testIndex);
			if (baseTest == null)
			{
				continue;
			}
			FolderTest parent = baseTest.Parent;
			List<BaseTest> list3 = parent.TestList.ToList();
			if (!list2.Contains(parent))
			{
				parent.TestList.Clear();
				list2.Add(parent);
			}
			for (int i = 0; i < list3.Count; i++)
			{
				string key = "";
				bool flag = false;
				foreach (KeyValuePair<string, List<string>> item2 in testIndicesByLoopName)
				{
					if (item2.Value.Contains(list3[i].Index))
					{
						flag = true;
						key = item2.Key;
						break;
					}
				}
				if (flag)
				{
					List<string> list4 = sequenceByLoopName[key];
					if (list4.Count > 0)
					{
						for (int j = 0; j < list4.Count; j++)
						{
							parent.Add(list3[i + int.Parse(list4[j])]);
						}
						flag = false;
						i = i + list4.Count - 1;
					}
					else
					{
						int count = testIndicesByLoopName[key].Count;
						for (int k = 0; k < count; k++)
						{
							parent.Add(list3[i + k]);
						}
						i = i + count - 1;
					}
				}
				else
				{
					parent.Add(list3[i]);
				}
			}
		}
		list2.Clear();
		list.Clear();
		list2 = null;
		list = null;
	}

	private bool HandleEachLoopCondition(FolderTest ParentFolder, bool bLoopingOnScenario, bool loopByCount, bool loopByTime, ArrayList loopDesc, int scenarioIndex, string elapsedTime)
	{
		foreach (LoopCondition loopCondition in ParentFolder.FolderProperties.Scenarios.LoopConditions)
		{
			if (loopCondition == null)
			{
				continue;
			}
			structLoopValues structLoopValues = default(structLoopValues);
			structLoopValues.sLoopName = loopCondition.LoopName;
			structLoopValues.bPartOfScenario = bLoopingOnScenario;
			int index = scenarioIndex;
			if (loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYCOUNT || loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYTIME)
			{
				index = 0;
			}
			try
			{
				structLoopValues.sDesc = ((string)loopDesc[index]).Trim();
			}
			catch (Exception ex)
			{
				TraceMessage.Write("QC.QTMApplication.Scheduler", "LoopTest " + ex.Message, TraceMessageType.Exception);
				structLoopValues.sDesc = "";
			}
			bLoopingOnScenario = true;
			structLoopValues.iRowIndex = scenarioIndex;
			structLoopValues.ScenarioID = (int)loopCondition.ScenarioID;
			if (loopCondition.LoopType != QC.QsprTestObjects.Loops.LoopTypes.BYCOUNT && loopCondition.LoopType != QC.QsprTestObjects.Loops.LoopTypes.BYTIME)
			{
				try
				{
					string text = "";
					if (loopCondition.LoopValues.Count > scenarioIndex)
					{
						text = (string)loopCondition.LoopValues[scenarioIndex];
					}
					if (loopCondition.TestName == "ALLTests")
					{
						if (text.Trim().Length != 0 || loopCondition.IsNullable || loopCondition.DataType == DataType.String)
						{
							UpdateParamsFolder(ParentFolder, loopCondition, text);
							BaseTest baseTest = ParentFolder.FindTestWithParameter(loopCondition.ParamName);
							if (baseTest != null)
							{
								structLoopValues.sLoopValue = GetConditionName(baseTest, loopCondition, text);
							}
							else
							{
								structLoopValues.sLoopValue = text;
							}
						}
					}
					else if (string.Compare(loopCondition.TestName, "Global Variables") == 0)
					{
						structLoopValues.sLoopValue = HandleGVLoop(scenarioIndex, loopCondition);
					}
					else
					{
						ParentFolder.SetTestDescriptionName(((string)loopDesc[index]).Trim());
						BaseTest test = ParentFolder.FindTest(loopCondition.TestIndex);
						if (text.Trim().Length != 0 || loopCondition.IsNullable || loopCondition.DataType == DataType.String)
						{
							UpdateParams(test, loopCondition, text);
							structLoopValues.sLoopValue = GetConditionName(test, loopCondition, text);
						}
						else
						{
							text = GetLastParamValue(test, loopCondition);
							structLoopValues.sLoopValue = GetConditionName(test, loopCondition, text);
						}
					}
				}
				catch (Exception ex2)
				{
					SetDebugMessage("Error in setting param in Loop at row " + scenarioIndex + "  " + ex2.Message, SoundLevel.INFO);
				}
			}
			else
			{
				ParentFolder.SetTestDescriptionName(((string)loopDesc[index]).Trim());
				if (loopByCount)
				{
					structLoopValues.sLoopValue = (scenarioIndex + 1).ToString();
				}
				else if (loopByTime)
				{
					structLoopValues.sLoopValue = elapsedTime;
				}
				if (ParentFolder.FolderProperties.LinkRoot)
				{
					structLoopValues.isLinkedTree = true;
				}
				else
				{
					structLoopValues.isLinkedTree = false;
				}
			}
			if (msgDelegate != null && !GlobalStatus.Stop)
			{
				TestMessage message = default(TestMessage);
				message.Message = ParentFolder.TestPath;
				message.NodeRID = ParentFolder.Properties.NodeRID;
				message.Object = structLoopValues;
				message.Result = TestResult.Passed;
				message.TestIndex = ParentFolder.Index;
				if (msgDelegate != null)
				{
					msgDelegate(TestMsgType.OnLoopStart, message);
				}
				if (ParentFolder.FolderProperties.LinkRoot && ParentFolder != null)
				{
					linkedLoopName = structLoopValues.sLoopName;
					linkedLoopValue = structLoopValues.sLoopValue;
					StartOfLinkedTesting(ParentFolder);
				}
			}
			if (loopCondition.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYCOUNT)
			{
				break;
			}
		}
		return bLoopingOnScenario;
	}

	private string HandleGVLoop(int scenarioIndex, LoopCondition loop)
	{
		try
		{
			string text = "";
			string gvValue = "";
			if (loop.LoopValues.Count > scenarioIndex)
			{
				text = (string)loop.LoopValues[scenarioIndex];
			}
			if (!string.IsNullOrEmpty(text))
			{
				Env.GlobalVariable.SetGlobalVariable(loop.ParamName, text);
				return text;
			}
			if (Env.GlobalVariable.GetGlobalVariable(loop.ParamName, out gvValue))
			{
				return gvValue;
			}
		}
		catch (Exception ex)
		{
			SetDebugMessage("Error in setting param in Loop at row " + scenarioIndex + "  " + ex.Message, SoundLevel.INFO);
		}
		return "";
	}

	private bool CheckForPostConditions(ref FolderTest ParentFolder)
	{
		bool result = false;
		switch (ParentFolder.RuntimeAttributes.StopOnError)
		{
		case StopOnErrorTypes.SkipToNextLoopIteration:
			switch (ParentFolder.Properties.StopOnError)
			{
			case StopOnErrorTypes.SkipTheFolder:
				ParentFolder.RuntimeAttributes.StopOnError = StopOnErrorTypes.SkipTheFolder;
				break;
			case StopOnErrorTypes.None:
				ParentFolder.RuntimeAttributes.StopOnError = StopOnErrorTypes.None;
				break;
			}
			break;
		case StopOnErrorTypes.SkipToFirstTestAfterTheLoop:
			switch (ParentFolder.Properties.StopOnError)
			{
			case StopOnErrorTypes.SkipToFirstTestAfterTheLoop:
				ParentFolder.RuntimeAttributes.StopOnError = StopOnErrorTypes.SkipToFirstTestAfterTheLoop;
				break;
			case StopOnErrorTypes.SkipTheFolder:
				ParentFolder.RuntimeAttributes.StopOnError = StopOnErrorTypes.SkipTheFolder;
				break;
			case StopOnErrorTypes.None:
				ParentFolder.RuntimeAttributes.StopOnError = StopOnErrorTypes.None;
				break;
			}
			result = true;
			break;
		case StopOnErrorTypes.SkipToNextCategory:
		case StopOnErrorTypes.SkipToNextUnit:
		case StopOnErrorTypes.CompleteStop:
		case StopOnErrorTypes.CompleteStopNoRetry:
		case StopOnErrorTypes.IgnoreSession:
			result = true;
			break;
		}
		switch (ParentFolder.Properties.StopOnError)
		{
		case StopOnErrorTypes.SkipTheFolder:
		case StopOnErrorTypes.SkipToNextLoopIteration:
		case StopOnErrorTypes.SkipToFirstTestAfterTheLoop:
		case StopOnErrorTypes.SkipToNextUnit:
			result = true;
			break;
		}
		if (GlobalStatus.BranchOnError || GlobalStatus.Stop || ParentFolder.RuntimeAttributes.StopLoop)
		{
			result = true;
		}
		switch (ParentFolder.RuntimeAttributes.PostConditionAction)
		{
		case PostConditionActions.SkipToNextLoopIteration:
			ParentFolder.RuntimeAttributes.PostConditionAction = PostConditionActions.None;
			break;
		case PostConditionActions.SkipToFirstTestAfterTheLoop:
			result = true;
			ParentFolder.RuntimeAttributes.PostConditionAction = PostConditionActions.None;
			break;
		case PostConditionActions.SkipToNextCategory:
		case PostConditionActions.CompleteStop:
		case PostConditionActions.CompleteStopNoRetry:
		case PostConditionActions.IgnoreSession:
		case PostConditionActions.RestartTestTree:
			result = true;
			break;
		}
		return result;
	}

	private static string IntToStringForTime(int num)
	{
		try
		{
			if (num < 10)
			{
				return "0" + num;
			}
			return num.ToString();
		}
		catch
		{
		}
		return "00";
	}

	private bool CanScenarioRun(string dontRunCondition)
	{
		bool flag = false;
		int num = 0;
		bool flag2 = false;
		bool flag3 = false;
		bool flag4 = false;
		while (dontRunCondition.Contains("&") || dontRunCondition.Contains("|"))
		{
			flag4 = false;
			int num2 = dontRunCondition.IndexOf("&");
			if (num2 == -1)
			{
				flag4 = true;
				num2 = dontRunCondition.IndexOf("|");
			}
			flag2 = CanScenarioRunThisCondition(dontRunCondition.Substring(0, num2).Trim());
			flag = ((num != 0) ? ((!flag3) ? (flag || flag2) : (flag && flag2)) : flag2);
			flag3 = flag4;
			dontRunCondition = dontRunCondition.Remove(0, num2 + 1).Trim();
		}
		flag2 = CanScenarioRunThisCondition(dontRunCondition);
		if (flag3)
		{
			return flag && flag2;
		}
		return flag || flag2;
	}

	private bool CanScenarioRunThisCondition(string dontRunCondition)
	{
		if (dontRunCondition.Trim() == "")
		{
			return true;
		}
		string[] array = "<=,=<,>=,=<,!=,=,<,>".Split(',');
		int num = -1;
		string text = "";
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			num = dontRunCondition.IndexOf(text2);
			if (num != -1)
			{
				text = text2.Trim();
				break;
			}
		}
		if (num == -1)
		{
			return true;
		}
		string text3 = dontRunCondition.Substring(0, num).Trim();
		string s = dontRunCondition.Substring(num + text.Length).Trim();
		string loopDetails = GlobalStatus.LoopDetails;
		int num2 = loopDetails.IndexOf(text3);
		string gvValue = "";
		double num3 = -1.0;
		double num4 = -1.0;
		if (num2 == -1 && Env.GlobalVariable.GetGlobalVariable(text3, out gvValue))
		{
			try
			{
				num3 = double.Parse(gvValue);
				num4 = double.Parse(s);
			}
			catch
			{
				gvValue = "";
			}
		}
		if (num2 > -1)
		{
			string[] array3 = loopDetails.Split(new string[3] { "_._", "_ _", "__" }, StringSplitOptions.RemoveEmptyEntries);
			for (int j = 0; j < array3.Length; j++)
			{
				if (text3 == array3[j].Trim())
				{
					try
					{
						gvValue = array3[j + 1];
						num3 = double.Parse(gvValue);
						num4 = double.Parse(s);
					}
					catch
					{
						gvValue = "";
					}
				}
			}
		}
		if (gvValue != "")
		{
			switch (text)
			{
			case "<=":
			case "=<":
				if (num3 >= num4)
				{
					return false;
				}
				break;
			case ">=":
			case "=>":
				if (num4 <= num3)
				{
					return false;
				}
				break;
			case "!=":
				if (num3 != num4)
				{
					return false;
				}
				break;
			case "=":
				if (num3 == num4)
				{
					return false;
				}
				break;
			case ">":
				if (num4 < num3)
				{
					return false;
				}
				break;
			case "<":
				if (num4 > num3)
				{
					return false;
				}
				break;
			}
		}
		return true;
	}

	public static void UpdateParamsFolder(FolderTest ParentFolder, LoopCondition loop, string currentLoopValue)
	{
		foreach (BaseTest test in ParentFolder.TestList)
		{
			try
			{
				if (test is FolderTest)
				{
					UpdateParamsFolder((FolderTest)test, loop, currentLoopValue);
				}
				else
				{
					UpdateParams(test, loop, currentLoopValue);
				}
			}
			catch
			{
			}
		}
	}

	public static void UpdateParams(BaseTest test, LoopCondition loop, string currentLoopValue)
	{
		try
		{
			switch (loop.LoopOnType)
			{
			case LoopOnTypes.INPUTPARAM:
				test.Properties.Parameters.SetParamValue(loop.ParamName, currentLoopValue, loop.ArrayIndex, loop.Array2DIndex);
				break;
			case LoopOnTypes.LL:
				test.Properties.Parameters.SetParamLowerLimit(loop.ParamName, currentLoopValue, loop.ArrayIndex);
				break;
			case LoopOnTypes.UL:
				test.Properties.Parameters.SetParamUpperLimit(loop.ParamName, currentLoopValue, loop.ArrayIndex);
				break;
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "UpdateParams : " + ex.Message, TraceMessageType.Exception);
		}
	}

	public static string GetLastParamValue(BaseTest test, LoopCondition loop)
	{
		string result = "";
		try
		{
			switch (loop.LoopOnType)
			{
			case LoopOnTypes.INPUTPARAM:
				result = test.Properties.Parameters.GetParamValue(loop.ParamName);
				break;
			case LoopOnTypes.LL:
				result = test.Properties.Parameters.GetParamLL(loop.ParamName);
				break;
			case LoopOnTypes.UL:
				result = test.Properties.Parameters.GetParamUL(loop.ParamName);
				break;
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "GetLastParamValue : " + ex.Message, TraceMessageType.Exception);
		}
		return result;
	}

	public static string GetConditionName(BaseTest test, LoopCondition loop, string currentValue)
	{
		try
		{
			currentValue = currentValue.Trim();
			if (loop.LoopType == QC.QsprTestObjects.Loops.LoopTypes.BYSEQUENCE)
			{
				currentValue = loop.GetDisplayString(test.Root, currentValue);
			}
			else
			{
				ParameterCls parameter = test.Properties.Parameters.GetParameter(loop.ParamName);
				if (parameter != null)
				{
					currentValue = parameter.GetDisplayValue(currentValue);
				}
			}
		}
		catch (Exception ex)
		{
			TraceMessage.Write("QC.QTMApplication.Scheduler", "GetConditionName : " + ex.Message, TraceMessageType.Exception);
		}
		return currentValue;
	}

	public void SetDebugMessage(string msg, SoundLevel sound)
	{
		if (msgDelegate == null)
		{
			return;
		}
		if (msg.Trim() == "")
		{
			TestMessage message = default(TestMessage);
			message.Message = msg;
			message.NodeRID = -1L;
			message.Object = null;
			message.Result = TestResult.Passed;
			message.TestIndex = "";
			if (msgDelegate != null)
			{
				msgDelegate(TestMsgType.OnDebugMsg, message);
			}
			return;
		}
		TestMessage message2 = default(TestMessage);
		message2.Message = msg;
		message2.NodeRID = -1L;
		message2.Object = null;
		message2.Result = TestResult.Passed;
		message2.TestIndex = "";
		if (msgDelegate != null)
		{
			msgDelegate(TestMsgType.OnDebugMsg, message2);
		}
		if (sound != SoundLevel.None && QTMData.WConfig.EnableSound)
		{
			int num = int.Parse(Enum.Format(typeof(SoundLevel), sound, "d"));
			PlaySound(soundFiles[num], IntPtr.Zero, 131073);
		}
	}

	public void SendGoNoGoDidNotStartMsg()
	{
		GlobalStatus.SetupTestStatus = TestResult.Failed;
		TestMessage message = default(TestMessage);
		string gvValue = "";
		Env.GlobalVariable.GetGlobalVariable("SetupTest Message", out gvValue);
		message.Message = gvValue;
		message.Object = QTMData.WConfig.LastUsedSerialNumber;
		message.Result = TestResult.Failed;
		message.ErrorCode = Env.GlobalVariable.GetErrorCode();
		msgDelegate(TestMsgType.OnGoNoGoDidNotStart, message);
	}

	public void SendMessage(TestMsgType testMsgType)
	{
		SendMessage(testMsgType, default(TestMessage));
	}

	internal void SendMessage(TestMsgType testMsgType, TestMessage tMessage)
	{
		if (msgDelegate != null)
		{
			msgDelegate(testMsgType, tMessage);
		}
	}

	public void SendNodeSelectMessage(TestMessage tMessage)
	{
		if (msgDelegate != null)
		{
			msgDelegate(TestMsgType.OnTestNodeSelected, tMessage);
		}
	}

	public void SendTreePauseResumeMsg(object obj)
	{
		if (msgDelegate != null)
		{
			bool flag = (bool)obj;
			TestMessage message = default(TestMessage);
			if (flag)
			{
				msgDelegate(TestMsgType.OnTreePause, message);
			}
			else
			{
				msgDelegate(TestMsgType.OnTreeResume, message);
			}
		}
	}

	public void SendLogDoneMessage(TestResultPlugin trPlugin)
	{
		TestMessage message = default(TestMessage);
		message.Message = trPlugin.Caption;
		if (msgDelegate != null)
		{
			msgDelegate(TestMsgType.OnLoggingDone, message);
		}
	}
}
