internal ProjectTemplateResult CreateAndOpenSolution(ProjectTemplateOptions options, string solutionDirectory, string solutionName)
        {
            FileName  solutionFileName = FileName.Create(Path.Combine(solutionDirectory, solutionName + ".sln"));
            bool      solutionOpened   = false;
            ISolution createdSolution  = SD.ProjectService.CreateEmptySolutionFile(solutionFileName);

            try {
                options.Solution       = createdSolution;
                options.SolutionFolder = createdSolution;
                var result = CreateProjects(options);
                if (result == null)
                {
                    return(null);
                }
                createdSolution.Save();                 // solution must be saved before it can be opened
                if (SD.ProjectService.OpenSolution(createdSolution))
                {
                    solutionOpened = true;
                    SD.GetRequiredService <IProjectServiceRaiseEvents>().RaiseSolutionCreated(new SolutionEventArgs(createdSolution));
                    return(result);
                }
                else
                {
                    return(null);
                }
            } finally {
                if (!solutionOpened)
                {
                    createdSolution.Dispose();
                }
            }
        }
        void OpenProjectInternal(FileName fileName)
        {
            if (!Path.IsPathRooted(fileName))
            {
                throw new ArgumentException("Path must be rooted!");
            }
            FileName  solutionFile   = new FileName(Path.ChangeExtension(fileName, ".sln"));
            ISolution solution       = null;
            bool      solutionOpened = false;

            // Use try-finally block to dispose the solution unless it is opened successfully.
            try {
                if (SD.FileSystem.FileExists(solutionFile))
                {
                    using (var progress = AsynchronousWaitDialog.ShowWaitDialog("Loading Solution...")) {
                        solution = LoadSolutionFile(solutionFile, progress);
                    }
                    // If LoadSolutionFile() throws ProjectLoadException, let that be handled by the ObservedLoad.

                    if (solution.Projects.Any(p => p.FileName == fileName))
                    {
                        // We can use the solution as-is
                        OpenSolution(solution);
                        solutionOpened = true;
                        return;
                    }
                    // The solution does not contain the project, ask the user on how to proceed:
                    var parseArgs = new[] { new StringTagPair("SolutionName", Path.GetFileName(solutionFile)), new StringTagPair("ProjectName", Path.GetFileName(fileName)) };
                    int res       = MessageService.ShowCustomDialog(MessageService.ProductName,
                                                                    StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject}", parseArgs),
                                                                    0, 2,
                                                                    StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.AddProjectToSolution}", parseArgs),
                                                                    StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.CreateNewSolution}", parseArgs),
                                                                    "${res:Global.IgnoreButtonText}");
                    if (res == 0)
                    {
                        // Fall-through: the code below will add the project to the solution
                    }
                    else if (res == 1)
                    {
                        // Create new solution: first make a backup of the old one
                        try {
                            File.Copy(solutionFile, Path.ChangeExtension(solutionFile, ".old.sln"), true);
                        } catch (IOException) {
                        }
                        // Replace solution with an empty one:
                        solution.Dispose();
                        solution = CreateEmptySolutionFile(solutionFile);
                        // Fall-through: the code below will add the project to the solution
                    }
                    else
                    {
                        // ignore, just open the solution as-is
                        OpenSolution(solution);
                        solutionOpened = true;
                        return;
                    }
                }
                else
                {
                    // Solution does not already exist; create a new one
                    solution = CreateEmptySolutionFile(solutionFile);
                }
                solution.AddExistingProject(fileName);
                solution.Save();
                OpenSolution(solution);
                solutionOpened = true;
            } finally {
                // Dispose the solution if it was not opened successfully
                if (solution != null && !solutionOpened)
                {
                    solution.Dispose();
                }
            }
        }