public ExtractClassViewModel( IContext context, string suggestedName, IObservable <HashSet <string> > allClassNames, IClassExtractor classExtractor, IFileSystem fileSystem, IProject project) { _className = Property.Create(suggestedName); _createInNewFile = Property.Create(false); var newFileNameSubject = new BehaviorSubject <string>(""); var hasEditedFileName = false; _newFileName = newFileNameSubject.AsProperty( isReadOnly: _createInNewFile.Select(check => check == false), write: (name, save) => { hasEditedFileName = true; newFileNameSubject.OnNext(name); }); _className.Subscribe( name => { if (!hasEditedFileName) { var filename = name.Replace(".", System.IO.Path.DirectorySeparatorChar.ToString()) + ".ux"; newFileNameSubject.OnNext(filename); } }); var action = _className.CombineLatest( allClassNames, _createInNewFile, _newFileName, project.RootDirectory, (name, allClasses, toNewFile, fileName, projectPath) => { // Don't care about whitespace at beginning or end name = name.Trim(); if (name.IsNullOrEmpty()) { return(new ValidatedAction("")); } if (name.Any(char.IsWhiteSpace)) { return(new ValidatedAction("Class name can't contain whitespaces")); } if (!ClassNameValidationRegexp.IsMatch(name)) { return(new ValidatedAction("Class name is not valid")); } if (allClasses.Contains(name)) { return(new ValidatedAction("Class name already in use")); } if (toNewFile) { var relativePath = RelativeFilePath.TryParse(fileName); if (!relativePath.HasValue) { return(new ValidatedAction("Not a valid filename")); } if (!fileName.EndsWith(".ux")) { return(new ValidatedAction("Filename must end in .ux")); } if (fileSystem.Exists(projectPath.Combine(relativePath.Value))) { return(new ValidatedAction("The file already exists")); } if (fileName.IsNullOrEmpty()) { return(new ValidatedAction("Filename can not be empty")); } } return(new ValidatedAction( () => { // A Task is returned by this method, however, we don't do anything with it // and just let it finish in the background classExtractor.ExtractClass( element: context.CurrentSelection, name: name, fileName: toNewFile ? Optional.Some(RelativeFilePath.Parse(fileName)) : Optional.None()); })); }) .Replay(1).RefCount(); _userInfo = action.Select(x => x.Message); _createCommand = Command.Create(action.Select(x => x.Action)); }