public void GenerateSolution(string masterConfiguration,
                                     string[] externalDefineConstants,
                                     PropertyElement[] propertyOverrides,
                                     string[] configurationFilter = null)
        {
            Reader.ReadFullSolution(propertyOverrides, masterConfiguration, configurationFilter);
            projectIdLookup = Reader.Modules
                              .SelectMany(kvp => kvp.Value.ProjectIdLookup)
                              .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            ValidateProjectIds();

            externalDefineConstants = externalDefineConstants ?? new string[0];

            Log.Heading("Generating solution '{0}' for master configuration '{1}'",
                        Reader.Solution.Name,
                        masterConfiguration);

            if (externalDefineConstants.Length > 0)
            {
                Log.Info("with external define constans:");
                Log.IndentedCollection(externalDefineConstants, Log.Info);
            }

            using (new CompositeDisposable(
                       new Log.ScopedIndent(),
                       new Log.ScopedTimer(Log.Level.Info, "Generate Solution")))
            {
                if (string.IsNullOrEmpty(masterConfiguration))
                {
                    masterConfiguration = Reader.Solution.ConfigurationGroups.Keys.First();
                    Log.Info("No master configuration was provided. Using default '{0}'.", masterConfiguration);
                }

                HashSet <string> includedProjects    = Reader.Solution.IncludedProjects;
                HashSet <string> generatableProjects = includedProjects
                                                       .Where(p => Reader.Solution.CanGenerateProject(p))
                                                       .ToHashSet();

                bool generateAll = includedProjects.SetEquals(generatableProjects);

                GenerateSolutionFiles("", Reader.Modules.Values, masterConfiguration, includedProjects,
                                      externalDefineConstants);

                if (Reader.Solution.GeneratedProjectsPatterns.Count > 0 && !generateAll)
                {
                    var builder = new SolutionBuilder(Reader.Solution, masterConfiguration);
                    builder.BuildAllConfigurations();

                    // Generate new solution with references to those DLLs.
                    IEnumerable <Module> updatedModules = ReplacePrebuiltReferences(generatableProjects);
                    GenerateSolutionFiles("-small", updatedModules, masterConfiguration, generatableProjects,
                                          externalDefineConstants);
                }
            }
        }