/// <summary>
        /// Creates the traversal project instance.  This has all of the properties against which we can perform evaluations for the remainder of the process.
        /// </summary>
        private ProjectInstance CreateTraversalInstance(string wrapperProjectToolsVersion, bool explicitToolsVersionSpecified, List<ProjectInSolution> projectsInOrder)
        {
            // Create the traversal project's root element.  We will later instantiate this, and use it for evaluation of conditions on
            // the metaprojects.
            ProjectRootElement traversalProject = ProjectRootElement.Create();
            traversalProject.ToolsVersion = wrapperProjectToolsVersion;
            traversalProject.DefaultTargets = "Build";
            traversalProject.InitialTargets = "ValidateSolutionConfiguration;ValidateToolsVersions;ValidateProjects";
            traversalProject.FullPath = _solutionFile.FullPath + ".metaproj";

            // We don't use dependency levels any more - however this will find circular dependencies and throw for us.
            Dictionary<int, List<ProjectInSolution>> projectsByDependencyLevel = new Dictionary<int, List<ProjectInSolution>>();

            // Add default solution configuration/platform names in case the user doesn't specify them on the command line
            AddConfigurationPlatformDefaults(traversalProject);

            // Add default Venus configuration names (for more details, see comments for this method)
            AddVenusConfigurationDefaults(traversalProject);

            // Add solution related macros
            AddGlobalProperties(traversalProject);

            // Add a property group for each solution configuration, each with one XML property containing the
            // project configurations in this solution configuration.
            foreach (SolutionConfigurationInSolution solutionConfiguration in _solutionFile.SolutionConfigurations)
            {
                AddPropertyGroupForSolutionConfiguration(traversalProject, solutionConfiguration);
            }

            // Add our global extensibility points to the project representing the solution:
            // Imported at the top:  $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore\* 
            // Imported at the bottom:  $(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter\*             
            ProjectImportElement importBefore = traversalProject.CreateImportElement(@"$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore\*");
            importBefore.Condition = @"'$(ImportByWildcardBeforeSolution)' != 'false' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportBefore')"; // Avoids wildcard perf problem

            ProjectImportElement importAfter = traversalProject.CreateImportElement(@"$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter\*");
            importAfter.Condition = @"'$(ImportByWildcardBeforeSolution)' != 'false' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\SolutionFile\ImportAfter')"; // Avoids wildcard perf problem

            // Add our local extensibility points to the project representing the solution
            // Imported at the top: before.mysolution.sln.targets
            // Imported at the bottom: after.mysolution.sln.targets
            string escapedSolutionFile = EscapingUtilities.Escape(Path.GetFileName(_solutionFile.FullPath));
            string escapedSolutionDirectory = EscapingUtilities.Escape(_solutionFile.SolutionFileDirectory);
            string localFile = Path.Combine(escapedSolutionDirectory, "before." + escapedSolutionFile + ".targets");
            ProjectImportElement importBeforeLocal = traversalProject.CreateImportElement(localFile);
            importBeforeLocal.Condition = @"exists('" + localFile + "')";

            localFile = Path.Combine(escapedSolutionDirectory, "after." + escapedSolutionFile + ".targets");
            ProjectImportElement importAfterLocal = traversalProject.CreateImportElement(localFile);
            importAfterLocal.Condition = @"exists('" + localFile + "')";

            // Put locals second so they can override globals if they want
            traversalProject.PrependChild(importBeforeLocal);
            traversalProject.PrependChild(importBefore);
            traversalProject.AppendChild(importAfter);
            traversalProject.AppendChild(importAfterLocal);

            // These are just dummies necessary to make the evaluation into a project instance succeed when 
            // any custom imported targets have declarations like BeforeTargets="Build"
            // They'll be replaced momentarily with the real ones.
            traversalProject.AddTarget("Build");
            traversalProject.AddTarget("Rebuild");
            traversalProject.AddTarget("Clean");
            traversalProject.AddTarget("Publish");

            // For debugging purposes: some information is lost when evaluating into a project instance,
            // so make it possible to see what we have at this point.
            if (Environment.GetEnvironmentVariable("MSBUILDEMITSOLUTION") != null)
            {
                string path = traversalProject.FullPath;
                traversalProject.Save(_solutionFile.FullPath + ".metaproj.tmp");
                traversalProject.FullPath = path;
            }

            // Create the instance.  From this point forward we can evaluate conditions against the traversal project directly.
            ProjectInstance traversalInstance = new ProjectInstance
                (
                traversalProject,
                _globalProperties,
                explicitToolsVersionSpecified ? wrapperProjectToolsVersion : null,
                _solutionFile.VisualStudioVersion,
                new ProjectCollection()
                );

            // Make way for the real ones                
            traversalInstance.RemoveTarget("Build");
            traversalInstance.RemoveTarget("Rebuild");
            traversalInstance.RemoveTarget("Clean");
            traversalInstance.RemoveTarget("Publish");

            AddStandardTraversalTargets(traversalInstance, projectsInOrder);

            return traversalInstance;
        }