public InstantActionPageViewModel(PageManager pageManager, IEventAggregator ea, IAppPolicyManager appPolicyManager, IInstantActionManager instantActionManager, IFolderReactionMonitorModel monitor, IHistoryManager historyManager)
			: base(pageManager)
		{
			_EventAggregator = ea;
			AppPolicyManger = appPolicyManager;
			InstantActionManager = instantActionManager;
			Monitor = monitor;
			HistoryManager = historyManager;

			InstantActionVM = new ReactiveProperty<InstantActionStepViewModel>();
				
		}
		public AppPolicyManagePageViewModel(PageManager pageManager, IAppPolicyManager appPolicyManager, IFolderReactionMonitorModel monitor)
			: base(pageManager)
		{
			Monitor = monitor;
			AppPolicyManager = appPolicyManager;
			AppPolicies = AppPolicyManager.Policies
				.ToReadOnlyReactiveCollection(x => new AppPolicyListItemViewModel(this, x));
			SelectedAppPolicy = new ReactiveProperty<AppPolicyListItemViewModel>();

			SelectedAppPolicy.Subscribe(x => 
			{
				if (x != null)
				{
					ShowAppPolicyEditPage(x.AppPolicy);
				}
			});
		}
		public ReactionEditPageViewModel(PageManager pageManager, IFolderReactionMonitorModel monitor, IAppPolicyManager appPolicyManager, IHistoryManager historyManager)
			: base(pageManager)
		{
			Monitor = monitor;
			_AppPolicyManager = appPolicyManager;
			HistoryManager = historyManager;

			_CompositeDisposable = new CompositeDisposable();

			ReactionVM = new ReactiveProperty<ReactionViewModel>()
				.AddTo(_CompositeDisposable);

			SaveCommand = new ReactiveCommand();

			SaveCommand.Subscribe(_ => Save())
				.AddTo(_CompositeDisposable);

		}
		public ActionsEditViewModel(FolderReactionModel reactionModel, PageManager pageManager, IAppPolicyManager appPolicyManager)
			: base(pageManager, reactionModel)
		{
			_AppPolicyManager = appPolicyManager;

			Reaction.ObserveProperty(x => x.IsActionsValid)
				.Subscribe(x => IsValid.Value = x)
				.AddTo(_CompositeDisposable);


			// TODO: CollectionChangedをマージしてReactiveCollectionにする方法を使ってまとめる
			// Note: AppLaunchActionViewModelをAppOptionValueInstance1つずつに対して作成している
			Actions = new ObservableCollection<AppLaunchActionViewModel>(
				Reaction.Actions.Select(
					x =>
					{
						var appLaunchAction = x as AppLaunchReactiveAction;
						return new AppLaunchActionViewModel(this, Reaction, appLaunchAction);
					}
					)
				);

			Actions.CollectionChangedAsObservable()
				.Subscribe(itemPair => 
				{
					var onceRemoveItems = Reaction.Actions.ToArray();
					foreach (var onceRemoveItem in onceRemoveItems)
					{
						Reaction.RemoveAction(onceRemoveItem);
					}
					
					foreach(var reAdditem in Actions)
					{
						Reaction.AddAction(reAdditem.Action);
					}
				});

			IsActionsEmpty = Actions.ObserveProperty(x => x.Count)
				.Select(x => x == 0)
				.ToReactiveProperty();

			IsActionsEmpty.Subscribe();
		}
		public FolderReactionManagePageViewModel(PageManager pageManager, IFolderReactionMonitorModel monitor, IEventAggregator ea, IAppPolicyManager appPolicyManager, IHistoryManager historyManager, IReactiveFolderSettings settings)
			: base(pageManager)
		{
			Monitor = monitor;
			_EventAggregator = ea;
			AppPolicyManager = appPolicyManager;
			HistoryManager = historyManager;
			Settings = settings;



			CurrentFolder = new ReactiveProperty<ReactionManageFolderViewModel>();
			FolderStack = new ObservableCollection<ReactionManageFolderViewModel>();

			FolderStack.CollectionChangedAsObservable()
				.Subscribe(x => 
				{
					CurrentFolder.Value = FolderStack.Last();
				});

			FolderStack.Add(new ReactionManageFolderViewModel(this, Monitor.RootFolder));
		}
		public AppOptionSelectDialogViewModel(IAppPolicyManager appPolicyManager)
		{
			_CompositeDisposable = new CompositeDisposable();

			AppPolicyManager = appPolicyManager;

			Options = AppPolicyManager.Policies.SelectMany(x => 
			{
				return x.OptionDeclarations
					.Concat(x.OutputOptionDeclarations)
					.Select(y => new AppOptionListItemViewModel(x, y));
			})
			.ToList();

			SelectedOption = new ReactiveProperty<AppOptionListItemViewModel>()
				.AddTo(_CompositeDisposable);

			IsSelectedOption = SelectedOption.Select(x => x != null)
				.ToReactiveProperty(false);
		}
		// Reactionmodelを受け取ってVMを生成する

		public ReactionViewModel(FolderReactionModel reaction, PageManager pageManager, IAppPolicyManager appPolicyManager)
		{
			_CompositeDisposable = new CompositeDisposable();
			Reaction = reaction;
			PageManager = pageManager;
			_AppPolicyManager = appPolicyManager;


			IsReactionValid = Reaction.ObserveProperty(x => x.IsValid)
				.ToReactiveProperty()
				.AddTo(_CompositeDisposable);

			ReactionWorkName = Reaction.ToReactivePropertyAsSynchronized(x => x.Name)
				.AddTo(_CompositeDisposable);

			WorkFolderEditVM = new WorkFolderEditViewModel(PageManager, Reaction);
			FilterEditVM = new FilterEditViewModel(PageManager, Reaction);
			ActionsEditVM = new ActionsEditViewModel(Reaction, PageManager, _AppPolicyManager);
			DestinationEditVM = new DestinationEditViewModel(PageManager, Reaction);


			EditVMList = new List<ReactionEditViewModelBase>()
			{
				WorkFolderEditVM,
				FilterEditVM,
				ActionsEditVM,
				DestinationEditVM
			};

			IsEnable = Reaction.ToReactivePropertyAsSynchronized(x => x.IsEnable)
				.AddTo(_CompositeDisposable);

			// see@ http://stackoverflow.com/questions/1833830/timespan-parse-time-format-hhmmss
			// https://msdn.microsoft.com/en-us/library/ee372286.aspx
			MonitorIntervalSeconds = Reaction.ToReactivePropertyAsSynchronized(
				x => x.CheckInterval
				, convert: (timespan) => ((int)timespan.TotalSeconds).ToString()
				, convertBack: (seconds) => TimeSpan.FromSeconds(int.Parse(seconds))
				, ignoreValidationErrorValue: true
			)
			.AddTo(_CompositeDisposable);

			MonitorIntervalSeconds.SetValidateNotifyError(text =>
			{
				int temp;
				if (false == int.TryParse(text, out temp))
				{
					return "Number Only";
				}

				return null;
			});

			


		}
		public PageViewModelBase(IRegionManager regionManager, IAppPolicyManager appPolicyFactory)
		{
			_RegionManager = regionManager;
			_AppPolicyManager = appPolicyFactory;
		}
		public static InstantActionModel FromSerializedData(InstantActionSaveModel saveModel, IAppPolicyManager appPolicyManager)
		{
			var instantAction = new InstantActionModel(appPolicyManager);

			instantAction.Guid = saveModel.Guid;

			foreach (var targetFile in saveModel.TargetFiles.Select(x => new InstantActionTargetFile(x)))
			{
				instantAction._TargetFiles.Add(targetFile);
			}

			foreach (var action in saveModel.Actions)
			{
				instantAction._Actions.Add(action);
			}

			instantAction.OutputFolderPath = saveModel.OutputFolderPath;

			return instantAction;
		}
		public InstantActionModel(IAppPolicyManager appPolicyManager)
		{
			AppPolicyManager = appPolicyManager;

			Guid = Guid.NewGuid();
			_TargetFiles = new ObservableCollection<InstantActionTargetFile>();
			TargetFiles = new ReadOnlyObservableCollection<InstantActionTargetFile>(_TargetFiles);
			_Actions = new ObservableCollection<AppLaunchReactiveAction>();
			Actions = new ReadOnlyObservableCollection<AppLaunchReactiveAction>(_Actions);


			OutputFolderPath = "";

		}
		public ApplicationExecuteSandbox CreateExecuteSandbox(IAppPolicyManager manager, AppOptionInstance[] options)
		{
			if (manager.Security.IsAuthorized(this.ApplicationPath))
			{
				return new ApplicationExecuteSandbox(this, options);
			}
			else
			{
				return null;
			}
		}
		public static void SetAppPolicyManager(IAppPolicyManager manager)
		{
			_AppPolicyManager = manager;
		}
		public InstantActionManager(IAppPolicyManager appPolicyManager)
		{
			AppPolicyManager = appPolicyManager;
		}