public void ModulePropertiesAreCreated()
        {
            ModulePropertyGenerator modulePropertyGenerator = new ModulePropertyGenerator(_packagesPath, _packagesConfigPath);

            string outputPath = Path.Combine(_intermediateOutputPath, "build.props");
            string extensionsPath = Path.Combine(_intermediateOutputPath, "Extensions");

            string[] importsBefore = { "before.props", "before2.props" };
            string[] importsAfter = { "after.props", "after2.props" };

            bool success = modulePropertyGenerator.Generate(outputPath, extensionsPath, importsBefore, importsAfter);

            success.ShouldBeTrue();

            File.Exists(outputPath).ShouldBeTrue();

            ProjectRootElement project = ProjectRootElement.Open(outputPath);

            project.ShouldNotBeNull();

            // Verify all properties
            //
            foreach (Tuple<string, string> item in new[]
            {
                new Tuple<string, string>("MSBuildAllProjects", "$(MSBuildAllProjects);$(MSBuildThisFileFullPath)"),
            }.Concat(_packages.Select(i =>
                new Tuple<string, string>(
                    $"{ModulePropertyGenerator.PropertyNamePrefix}{i.Id.Replace(".", "_")}",
                    $"{ModulePropertyGenerator.PropertyValuePrefix}{i.Id}.{i.VersionString}"))))
            {
                ProjectPropertyElement propertyElement = project.Properties.FirstOrDefault(i => i.Name.Equals(item.Item1));

                propertyElement.ShouldNotBeNull();

                propertyElement.Value.ShouldBe(item.Item2);
            }


            // Verify "before" imports
            //
            for (int i = 0; i < importsBefore.Length; i++)
            {
                ProjectImportElement import = project.Imports.Skip(i).FirstOrDefault();

                import.ShouldNotBeNull();

                import.Project.ShouldBe(importsBefore[i]);

                import.Condition.ShouldBe($" Exists('{importsBefore[i]}') ");
            }

            // Verify "after" imports
            //
            for (int i = 0; i < importsAfter.Length; i++)
            {
                ProjectImportElement import = project.Imports.Skip((project.Imports.Count - importsAfter.Length) + i).FirstOrDefault();

                import.ShouldNotBeNull();

                import.Project.ShouldBe(importsAfter[i]);

                import.Condition.ShouldBe($" Exists('{importsAfter[i]}') ");
            }

            // Verify module extensions were created
            //
            foreach (string item in _moduleExtensions.SelectMany(i => i.Item2))
            {
                string extensionPath = Path.Combine(extensionsPath, item);

                File.Exists(extensionPath).ShouldBeTrue();

                ProjectRootElement extensionProject = ProjectRootElement.Open(extensionPath);

                extensionProject.ShouldNotBeNull();

                extensionProject.Imports.Count.ShouldBe(_packages.Count);

                for (int i = 0; i < _packages.Count; i++)
                {
                    string importProject = $"$({ModulePropertyGenerator.PropertyNamePrefix}{_packages[i].Id.Replace(".", "_")})\\{ModulePropertyGenerator.ImportRelativePath}";
                    ProjectImportElement import = extensionProject.Imports.Skip(i).FirstOrDefault();

                    import.ShouldNotBeNull();

                    import.Project.ShouldBe(importProject);

                    import.Condition.ShouldBe($"Exists('{importProject}')");
                }
            }
        }
        public bool Execute()
        {
            // Get a semaphore name based on the output file
            //
            string semaphoreName = ImportsFile.ToUpper().GetHashCode().ToString("X");

            bool releaseSemaphore;

            using (Semaphore semaphore = new Semaphore(0, 1, semaphoreName, out releaseSemaphore))
            {
                try
                {
                    if (!releaseSemaphore)
                    {
                        releaseSemaphore = semaphore.WaitOne(TimeSpan.FromMinutes(30));

                        return releaseSemaphore;
                    }

                    _log.LogMessage(MessageImportance.High, "Restore CBT modules:");

                    if (!File.Exists(RestoreCommand))
                    {
                        if (!DownloadNuGet().Result)
                        {
                            return false;
                        }
                    }

                    if (!RestorePackages())
                    {
                        return false;
                    }

                    _log.LogMessage(MessageImportance.Low, "Create CBT module imports");

                    ModulePropertyGenerator modulePropertyGenerator = new ModulePropertyGenerator(PackagesPath, PackageConfig);

                    if (!modulePropertyGenerator.Generate(ImportsFile, ExtensionsPath, BeforeImports, AfterImports))
                    {
                        return false;
                    }
                }
                catch (Exception e)
                {
                    _log.LogError(e.Message);
                    _log.LogMessage(e.ToString());

                    return false;
                }
                finally
                {
                    if (releaseSemaphore)
                    {
                        semaphore.Release();
                    }
                }
            }

            return true;
        }