public AgentWorkerStartInfo( IAgent agent, IAgentUpdateInfo agentUpdateInfo, AgentThreadInfo thread ) {
				this.Agent = agent;
				this.AgentUpdateInfo = agentUpdateInfo;
				this.Thread = thread;
			}
		public virtual void ProcessTick() {
			this.TickNumber++;
			foreach (DeckBase deck in this.Players.Values) {
				deck.TickNumber = this.TickNumber;
			}

			var newlyLaunchedAgents = this.Agents.Keys.Except(this.Processes.Keys).ToList();
			foreach (var __newlyLaunchedAgent in newlyLaunchedAgents) {
				var newlyLaunchedAgent = __newlyLaunchedAgent;
				var agentInfo = this.Agents[newlyLaunchedAgent];

				var thread = new System.Threading.Thread(this.AgentWorker);
				thread.IsBackground = true;
				thread.Priority = System.Threading.ThreadPriority.Lowest;
				thread.Name = string.Format("{0}({1}({2}))"
					, agentInfo.Owner.DisplayHandle
					, newlyLaunchedAgent.GetType().FullName
					, agentInfo.Level);

				var threadEx = new AgentThreadInfo(thread);
				this.Processes.Add(newlyLaunchedAgent, threadEx);
			}

			var rnd = new Random();
			foreach (var kpProc in this.Processes.OrderBy(p => rnd.Next())) {
				var agent = kpProc.Key;
				var thread = kpProc.Value;
				IAgentUpdateInfo agentInfo;
				this.Agents.TryGetValue(agent, out agentInfo);
				if (null == agentInfo) { continue; /* agent crashed or was recalled */ }

				var mainReset = thread.MainReset;
				var workerReset = thread.AgentReset;

				if (false == thread.Thread.IsAlive) {
					workerReset.Reset();
					var startInfo = new AgentWorkerStartInfo(agent, agentInfo, thread);
					thread.Thread.Start(startInfo);
				}

				mainReset.Reset();
				workerReset.Set();
				mainReset.WaitOne();
			}
		}