public void RunTagAsync_TagsAsString_TagsConvertedToArray()
		{
			// Arrange
			var options = new TagOptions() {
				FilesOrDirectories = new[] { "SomeVerb", @"C:\Temp" },
				Tags = "Tag1;;Tag2;Tag3;",
				Recursive = true,
				Clear = true
			};

			var filesOrDirectories = new List<string>() { "SomeVerb", @"C:\Temp" };
			_optionUtils.EnsureFilesOrDirectoriesValues(options).Returns(filesOrDirectories);

			List<string> tags = null;
			_tagsOperation.WriteUserTagsAsync(
				filesOrDirectories, 
				Arg.Do<IEnumerable<string>>(t => tags = t.ToList()), 
				options.Clear, 
				options.Recursive);

			// Act
			_target.RunTagAsync(options);

			// Assert
			var expected = options.Tags.Split(new[]{ ';' }, StringSplitOptions.RemoveEmptyEntries);
			CollectionAssert.AreEquivalent(expected, tags);
		}
		public void RunTagAsync_TagsOptionNull_GiveEmptyTags()
		{
			// Arrange
			var options = new TagOptions() {
				FilesOrDirectories = new[] { "SomeVerb", @"C:\Temp" },
				Tags = null,
				Recursive = true,
				Clear = true
			};

			var filesOrDirectories = new List<string>() { "SomeVerb", @"C:\Temp" };
			_optionUtils.EnsureFilesOrDirectoriesValues(options).Returns(filesOrDirectories);

			// Act
			_target.RunTagAsync(options);

			// Assert
			_tagsOperation.Received(1).WriteUserTagsAsync(filesOrDirectories, Arg.Is<IEnumerable<string>>(t => !t.Any()), options.Clear, options.Recursive);
		}
		public void RunTagAsync_OptionsOk_CheckEnsureFilesOrDirectoriesValuesCalled()
		{
			// Arrange
			var options = new TagOptions() {
				FilesOrDirectories = new[] { "SomeVerb", @"C:\Temp" },
				Tags = "Tag1;Tag2;Tag3",
				Recursive = true,
				Clear = true
			};

			var expected = new List<string>() { "SomeVerb", @"C:\Temp" };
			_optionUtils.EnsureFilesOrDirectoriesValues(options).Returns(expected);

			// Act
			_target.RunTagAsync(options);

			// Assert
			_optionUtils.Received(1).EnsureFilesOrDirectoriesValues(options);
			CollectionAssert.AreEquivalent(expected, options.FilesOrDirectories);
		}
		public void RunTagAsync_OptionsOk_CheckRunTagAsyncCalled()
		{
			// Arrange
			var options = new TagOptions() {
				FilesOrDirectories = new[] { "SomeVerb", @"C:\Temp" },
				Tags = "Tag1;Tag2;Tag3",
				Recursive = true,
				Clear = true
			};

			var filesOrDirectories = new List<string>() { "SomeVerb", @"C:\Temp" };
			_optionUtils.EnsureFilesOrDirectoriesValues(options).Returns(filesOrDirectories);

			var expectedTask = Task.FromResult(0);
			_tagsOperation.WriteUserTagsAsync(filesOrDirectories, Arg.Any<IEnumerable<string>>(), options.Clear, options.Recursive).Returns(expectedTask);

			// Act
			var task = _target.RunTagAsync(options);

			// Assert
			_tagsOperation.Received(1).WriteUserTagsAsync(filesOrDirectories, Arg.Any<IEnumerable<string>>(), options.Clear, options.Recursive);
			Assert.AreSame(expectedTask, task);
		}
		/// <summary>
        /// Runs the tag operation.
        /// </summary>
        /// <returns>A task that represents the tag operation.</returns>
        /// <param name="tagOptions">Parsed tag options.</param>
		public Task RunTagAsync(TagOptions tagOptions)
		{
            if (tagOptions == null)
                throw new ArgumentNullException("tagOptions");

            LogHelper.InitializeLogging(tagOptions);

            Log.T("Processing 'tag' operation.");
            tagOptions.FilesOrDirectories = _optionsUtils.EnsureFilesOrDirectoriesValues(tagOptions);

            var tags = Enumerable.Empty<string>();
            if (tagOptions.Tags != null)
                tags = tagOptions.Tags.Split(new[]{ ';' }, StringSplitOptions.RemoveEmptyEntries);

            return _tagsOperation.WriteUserTagsAsync(tagOptions.FilesOrDirectories, tags, tagOptions.Clear, tagOptions.Recursive);
		}