public Makefile Deploy(AutotoolsContext ctx, SolutionItem entry, IProgressMonitor monitor)
        {
            generateAutotools = ctx.MakefileType == MakefileType.AutotoolsMakefile;

            monitor.BeginTask(GettextCatalog.GetString(
                                  "Creating {0} for Solution {1}",
                                  generateAutotools ? "Makefile.am" : "Makefile", entry.Name), 1);

            Makefile      solutionMakefile = new Makefile();
            StringBuilder solutionTop      = new StringBuilder();

            try
            {
                SolutionFolder solutionFolder  = (SolutionFolder)entry;
                string         targetDirectory = solutionFolder.BaseDirectory;

                StringBuilder subdirs = new StringBuilder();
                subdirs.Append("#Warning: This is an automatically generated file, do not edit!\n");

                if (!generateAutotools)
                {
                    solutionTop.AppendFormat("top_srcdir={0}\n", FileService.AbsoluteToRelativePath(
                                                 entry.BaseDirectory, ctx.TargetSolution.BaseDirectory));
                    solutionTop.Append("include $(top_srcdir)/config.make\n");
                    solutionTop.Append("include $(top_srcdir)/Makefile.include\n");
                    solutionTop.Append("include $(top_srcdir)/rules.make\n\n");
                    solutionTop.Append("#include $(top_srcdir)/custom-hooks.make\n\n");
                }

                ArrayList children = new ArrayList();
                foreach (SolutionConfiguration config in solutionFolder.ParentSolution.Configurations)
                {
                    if (!ctx.IsSupportedConfiguration(config.Id))
                    {
                        continue;
                    }

                    if (generateAutotools)
                    {
                        subdirs.AppendFormat("if {0}\n", "ENABLE_" + ctx.EscapeAndUpperConfigName(config.Id));
                    }
                    else
                    {
                        subdirs.AppendFormat("ifeq ($(CONFIG),{0})\n", ctx.EscapeAndUpperConfigName(config.Id));
                    }

                    subdirs.Append(" SUBDIRS = ");

                    foreach (SolutionItem ce in CalculateSubDirOrder(ctx, solutionFolder, config))
                    {
                        string baseDirectory;
                        if (!(ce is SolutionEntityItem) && !(ce is SolutionFolder))
                        {
                            continue;
                        }

                        // Ignore projects which can't be deployed
                        IMakefileHandler handler = AutotoolsContext.GetMakefileHandler(ce, ctx.MakefileType);
                        if (handler == null)
                        {
                            continue;
                        }

                        baseDirectory = ce.BaseDirectory;

                        if (solutionFolder.BaseDirectory == baseDirectory)
                        {
                            subdirs.Append(" . ");
                        }
                        else
                        {
                            if (!baseDirectory.StartsWith(solutionFolder.BaseDirectory))
                            {
                                throw new Exception(GettextCatalog.GetString(
                                                        "Child projects must be in sub-directories of their parent"));
                            }

                            // add the subdirectory to the list
                            string path = FileService.AbsoluteToRelativePath(targetDirectory, baseDirectory);
                            if (path.StartsWith("." + Path.DirectorySeparatorChar))
                            {
                                path = path.Substring(2);
                            }

                            AutotoolsContext.CheckSpaces(path);
                            subdirs.Append(" ");
                            subdirs.Append(AutotoolsContext.EscapeStringForAutomake(path));
                        }

                        if (!children.Contains(ce))
                        {
                            children.Add(ce);
                        }
                    }
                    subdirs.Append("\nendif\n");
                }
                solutionTop.Append(subdirs.ToString());

                string includedProject = null;

                // deploy recursively
                foreach (SolutionItem ce in children)
                {
                    IMakefileHandler handler = AutotoolsContext.GetMakefileHandler(ce, ctx.MakefileType);
                    Makefile         makefile;
                    string           outpath;
                    if (handler != null && handler.CanDeploy(ce, ctx.MakefileType))
                    {
                        ctx.RegisterBuiltProject(ce);
                        makefile = handler.Deploy(ctx, ce, monitor);

                        if (targetDirectory == ce.BaseDirectory)
                        {
                            if (includedProject != null)
                            {
                                throw new Exception(GettextCatalog.GetString(
                                                        "More than 1 project in the same directory as the top-level solution is not supported."));
                            }

                            // project is in the solution directory
                            string projectMakefileName = ce.Name + ".make";
                            includedProject = String.Format("include {0}", projectMakefileName);
                            outpath         = Path.Combine(targetDirectory, projectMakefileName);
                            ctx.AddGeneratedFile(outpath);

                            if (!generateAutotools)
                            {
                                solutionMakefile.SetVariable("EXTRA_DIST", projectMakefileName);
                            }
                        }
                        else
                        {
                            makefile.AppendToVariable("EXTRA_DIST", generateAutotools ? String.Empty : "Makefile");
                            outpath = Path.Combine(ce.BaseDirectory, "Makefile");
                            if (generateAutotools)
                            {
                                ctx.AddAutoconfFile(outpath);
                                outpath = outpath + ".am";
                            }
                            else
                            {
                                makefile.Append("install: install-local\nuninstall: uninstall-local\nclean: clean-local\n");
                                if (ce is SolutionFolder)
                                {
                                    //non TargetCombine
                                    makefile.Append("dist-local: dist-local-recursive\n");
                                }
                                else
                                {
                                    makefile.Append("include $(top_srcdir)/rules.make\n");
                                }
                            }
                            ctx.AddGeneratedFile(outpath);
                        }

                        StreamWriter writer = new StreamWriter(outpath);
                        makefile.Write(writer);
                        writer.Close();
                    }
                    else
                    {
                        monitor.Log.WriteLine("Project '{0}' skipped.", ce.Name);
                    }
                }

                if (includedProject != null)
                {
                    solutionTop.Append(GettextCatalog.GetString("\n# Include project specific makefile\n"));
                    solutionTop.Append(includedProject);
                }

                if (generateAutotools)
                {
                    solutionMakefile.Append(solutionTop.ToString());
                }
                else
                {
                    TemplateEngine templateEngine = new TemplateEngine();
                    templateEngine.Variables ["MAKEFILE_SOLUTION_TOP"] = solutionTop.ToString();

                    Stream       stream = ctx.GetTemplateStream("Makefile.solution.template");
                    StreamReader reader = new StreamReader(stream);
                    StringWriter sw     = new StringWriter();

                    templateEngine.Process(reader, sw);
                    reader.Close();

                    solutionMakefile.Append(sw.ToString());

                    if (solutionFolder.IsRoot)
                    {
                        // Emit dist and distcheck targets only for TargetCombine
                        reader = new StreamReader(Path.Combine(ctx.TemplateDir, "make-dist.targets"));
                        solutionMakefile.Append(reader.ReadToEnd());
                        reader.Close();
                    }
                }

                monitor.Step(1);
            }
            finally
            {
                monitor.EndTask();
            }
            return(solutionMakefile);
        }
		public Makefile Deploy (AutotoolsContext ctx, SolutionFolderItem entry, ProgressMonitor monitor)
		{
			generateAutotools = ctx.MakefileType == MakefileType.AutotoolsMakefile;
			
			monitor.BeginTask ( GettextCatalog.GetString (
						"Creating {0} for Solution {1}",
						generateAutotools ? "Makefile.am" : "Makefile", entry.Name), 1 );

			Makefile solutionMakefile = new Makefile ();
			StringBuilder solutionTop = new StringBuilder ();

			try
			{
				SolutionFolder solutionFolder = (SolutionFolder) entry;
				string targetDirectory = solutionFolder.BaseDirectory;

				StringBuilder subdirs = new StringBuilder();
				subdirs.Append ("#Warning: This is an automatically generated file, do not edit!\n");

				if (!generateAutotools) {
					solutionTop.AppendFormat ("top_srcdir={0}\n", FileService.AbsoluteToRelativePath (
							entry.BaseDirectory, ctx.TargetSolution.BaseDirectory));
					solutionTop.Append ("include $(top_srcdir)/config.make\n");
					solutionTop.Append ("include $(top_srcdir)/Makefile.include\n");
					solutionTop.Append ("include $(top_srcdir)/rules.make\n\n");
					solutionTop.Append ("#include $(top_srcdir)/custom-hooks.make\n\n");
				}

				ArrayList children = new ArrayList ();
				foreach ( SolutionConfiguration config in solutionFolder.ParentSolution.Configurations )
				{
					if ( !ctx.IsSupportedConfiguration ( config.Id ) ) continue;
					
					if (generateAutotools)
						subdirs.AppendFormat ( "if {0}\n", "ENABLE_" + ctx.EscapeAndUpperConfigName (config.Id));
					else
						subdirs.AppendFormat ( "ifeq ($(CONFIG),{0})\n", ctx.EscapeAndUpperConfigName (config.Id));

					subdirs.Append (" SUBDIRS = ");
					
					foreach (SolutionFolderItem ce in CalculateSubDirOrder (ctx, solutionFolder, config))
					{
						string baseDirectory;
						if (!(ce is SolutionItem) && !(ce is SolutionFolder))
							continue;
						
						// Ignore projects which can't be deployed
						IMakefileHandler handler = AutotoolsContext.GetMakefileHandler (ce, ctx.MakefileType);
						if (handler == null)
							continue;
							
						baseDirectory = ce.BaseDirectory;
						
						if (solutionFolder.BaseDirectory == baseDirectory) {
							subdirs.Append (" . ");
						} else {
							if (!baseDirectory.StartsWith (solutionFolder.BaseDirectory) )
								throw new Exception ( GettextCatalog.GetString (
									"Child projects must be in sub-directories of their parent") );
							
							// add the subdirectory to the list
							string path = FileService.AbsoluteToRelativePath (targetDirectory, baseDirectory);
							if (path.StartsWith ("." + Path.DirectorySeparatorChar) )
								path = path.Substring (2);
							
							AutotoolsContext.CheckSpaces (path);
							subdirs.Append (" ");
							subdirs.Append ( AutotoolsContext.EscapeStringForAutomake (path) );
						}

						if (!children.Contains (ce))
							children.Add ( ce );
					}
					subdirs.Append ( "\nendif\n" );
				}
				solutionTop.Append ( subdirs.ToString () );

				string includedProject = null;

				// deploy recursively
				foreach (SolutionFolderItem ce in children)
				{
					IMakefileHandler handler = AutotoolsContext.GetMakefileHandler ( ce, ctx.MakefileType );
					Makefile makefile;
					string outpath;
					if ( handler != null && handler.CanDeploy ( ce, ctx.MakefileType ) )
					{
						ctx.RegisterBuiltProject (ce);
						makefile = handler.Deploy ( ctx, ce, monitor );

						if (targetDirectory == ce.BaseDirectory)
						{
							if (includedProject != null)
								throw new Exception ( GettextCatalog.GetString (
									"More than 1 project in the same directory as the top-level solution is not supported."));

							// project is in the solution directory
							string projectMakefileName = ce.Name + ".make";
							includedProject = String.Format ("include {0}", projectMakefileName);
							outpath = Path.Combine (targetDirectory, projectMakefileName);
							ctx.AddGeneratedFile (outpath);

							if (!generateAutotools)
								solutionMakefile.SetVariable ("EXTRA_DIST", projectMakefileName);
						} else {
							makefile.AppendToVariable ("EXTRA_DIST", generateAutotools ? String.Empty : "Makefile");
							outpath = Path.Combine (ce.BaseDirectory, "Makefile");
							if (generateAutotools) {
								ctx.AddAutoconfFile (outpath);
								outpath = outpath + ".am";
							} else {
								makefile.Append ("install: install-local\nuninstall: uninstall-local\nclean: clean-local\n");
								if (ce is SolutionFolder)
									//non TargetCombine
									makefile.Append ("dist-local: dist-local-recursive\n");
								else
									makefile.Append ("include $(top_srcdir)/rules.make\n");
							}
							ctx.AddGeneratedFile (outpath);
						}

						StreamWriter writer = new StreamWriter (outpath);
						makefile.Write ( writer );
						writer.Close ();
					}
					else {
						monitor.Log .WriteLine("Project '{0}' skipped.", ce.Name); 
					}
				}

				if (includedProject != null) {
					solutionTop.Append (GettextCatalog.GetString ("\n# Include project specific makefile\n"));
					solutionTop.Append (includedProject);
				}

				if (generateAutotools) {
					solutionMakefile.Append (solutionTop.ToString ());
				} else {
					TemplateEngine templateEngine = new TemplateEngine ();
					templateEngine.Variables ["MAKEFILE_SOLUTION_TOP"] = solutionTop.ToString ();

					Stream stream = ctx.GetTemplateStream ("Makefile.solution.template");
					StreamReader reader = new StreamReader (stream);
					StringWriter sw = new StringWriter ();

					templateEngine.Process (reader, sw);
					reader.Close ();

					solutionMakefile.Append (sw.ToString ());

					if (solutionFolder.IsRoot) {
						// Emit dist and distcheck targets only for TargetCombine
						reader = new StreamReader (Path.Combine (ctx.TemplateDir, "make-dist.targets"));
						solutionMakefile.Append (reader.ReadToEnd ());
						reader.Close ();
					}
				}

				monitor.Step (1);
			}
			finally
			{
				monitor.EndTask ();
			}
			return solutionMakefile;
		}