public void SaveHistory(HistoryData historyData)
		{
			Func<string, string> ToPathSafeString = (string x) =>
			{
				if (String.IsNullOrEmpty(x)) { return ""; }

				foreach(var invalidChar in Path.GetInvalidFileNameChars())
				{
					if (x.Contains(invalidChar))
					{
						x = x.Replace(invalidChar, ' ');
					}
				}

				return x;
			};


			var filename = String.Join("-",
				historyData.Actions.Select(x => ToPathSafeString(x.AppPolicy.AppName) + "(" + String.Join("_", x.Options.Select(y => ToPathSafeString(y.OptionDeclaration.Name))) + ") "
			))
			+ Path.GetRandomFileName();


			var filePath = Path.Combine(HistorySaveFolderPath, Path.ChangeExtension(filename, HISTORY_FILE_EXTENTION));
			FileSerializeHelper.Save(filePath, historyData);
		}
		public HistoryDataViewModel(HistoryPageViewModel pageVM, PageManager pageManager, IFolderReactionMonitorModel monitor, IInstantActionManager instantActionManager, HistoryData historyData)
		{
			PageVM = pageVM;
			PageManager = pageManager;
			Monitor = monitor;
			InstantActionManage = instantActionManager;
			HistoryData = historyData;

			Actions = HistoryData.Actions
				.Select(x => new HistoryActionViewModel(this, x))
				.ToList();

			Files = HistoryData.FileHistories
				.Select(x => new HistoryDataByFileViewModel(this, x))
				.ToList();

			TargetFileAmount = Files.Count;

			SuccessCount = Files.Where(x => x.IsSuccessed).Count();

			var fileName = Path.GetFileName(HistoryData.ActionSourceFilePath);
			if (fileName.EndsWith(FolderModel.REACTION_EXTENTION))
			{
				IsSourceReaction = true;
			}
			else if (fileName.EndsWith(".rfinstant.json"))
			{
				IsSourceInstantAction = true;
			}
			
		}
		public void StartProcess()
		{
			var historyData = new HistoryData();
			historyData.Actions = InstantAction.Actions.ToArray();
			historyData.ActionSourceFilePath = PageVM.InstantActionManager.GetSavePath(InstantAction);

			var byFiles = new List<HistoryDataByFile>();


			Task.Run(() =>
			{
				foreach (var file in InstantAction.TargetFiles.Where(x => x.IsReady))
				{
					lock (_InstantActionProcessLock)
					{
						var startTime = DateTime.Now;


						InstantAction.Execute(file);


						byFiles.Add(new HistoryDataByFile()
						{
							InputFilePath = file.FilePath,
							OutputFilePath = file.OutputPath,
							StartTime = startTime,
							EndTime = DateTime.Now,
							IsSuccessed = file.ProcessState == FileProcessState.Complete
						});
					}
				}
			})
			.ContinueWith(x => 
			{
				historyData.FileHistories = byFiles.ToArray();
				PageVM.HistoryManager.SaveHistory(historyData);
			});
		}
		private void TriggerReaction()
		{
			HistoryDataByFile[] results = null;


			try
			{
				results = Reaction.Execute();
			}
			catch(Exception e)
			{
				IsTerminated = true;
				TerminateCauseException = e;
				Dispose();
			}


			if (results != null)
			{
				var historyData = new HistoryData()
				{
					Actions = Reaction.Actions.Select(x => x as AppLaunchReactiveAction).ToArray(),
					ActionSourceFilePath = Monitor.RootFolder.MakeReactionSaveFilePath(Reaction),
					FileHistories = results
				};

				HistoryManager.SaveHistory(historyData);
			}
		}