// Populates configSection.DeployFileVars with unique DeployFiles for a particular config
        void ProcessDeployFilesForConfig(DeployFileCollection deployFiles, Project project, ConfigSection configSection, AutotoolsContext ctx, DotNetProjectConfiguration config)
        {
            //@deployFiles can have duplicates
            Dictionary <string, DeployFile> uniqueDeployFiles = new Dictionary <string, DeployFile> ();

            foreach (DeployFile dfile in deployFiles)
            {
                if (dfile.SourcePath == project.GetOutputFileName(configSection.Selector))
                {
                    continue;
                }

                // DeployFileCollection can have duplicates, ignore them
                string key = dfile.RelativeTargetPath;
                if (!dfile.ContainsPathReferences)
                {
                    key += dfile.SourcePath;
                }
                if (uniqueDeployFiles.ContainsKey(key))
                {
                    continue;
                }
                uniqueDeployFiles [key] = dfile;

                string targetDeployVar = GetDeployVar(deployFileVars, dfile.RelativeTargetPath);
                configSection.DeployFileVars [targetDeployVar] = dfile;
                DeployFileData data = new DeployFileData();
                data.File          = dfile;
                data.Configuration = config;
                allDeployVars [targetDeployVar] = data;
            }
        }
        // Handle unique deploy files, emits non-perconfig stuff, like targets for deploy files,
        // un/install commands
        void HandleDeployFile(DeployFileData data, string targetDeployVar, Project project, AutotoolsContext ctx)
        {
            DeployFile dfile = data.File;
            string     dependencyDeployFile = null;         //Dependency for the deployfile target

            if (dfile.ContainsPathReferences)
            {
                // Template file, copy to .in file
                string full_fname = Path.Combine(project.BaseDirectory, Path.GetFileName(dfile.RelativeTargetPath));
                string fname      = full_fname;
                string infname    = fname + ".in";
                if (File.Exists(infname) && project.IsFileInProject(infname))
                {
                    string datadir = Path.Combine(project.BaseDirectory, "data");
                    if (!Directory.Exists(datadir))
                    {
                        Directory.CreateDirectory(datadir);
                    }
                    infname = Path.Combine(datadir, Path.GetFileName(dfile.RelativeTargetPath) + ".in");
                }

                //Absolute path required
                File.Copy(dfile.SourcePath, infname, true);

                //Path relative to TargetCombine
                fname = FileService.NormalizeRelativePath(
                    FileService.AbsoluteToRelativePath(ctx.TargetSolution.BaseDirectory, full_fname));
                infname = fname + ".in";
                ctx.AddAutoconfFile(MakefileData.ToMakefilePath(fname));
                ctx.AddGeneratedFile(full_fname + ".in");

                //Path relative to project
                fname = FileService.NormalizeRelativePath(
                    FileService.AbsoluteToRelativePath(project.BaseDirectory, full_fname));
                infname = fname + ".in";
                extras.AppendFormat("\\\n\t{0} ", MakefileData.ToMakefilePath(infname));

                //dependencyDeployFile here should be filename relative to the project
                dependencyDeployFile = fname;
            }
            else
            {
                dependencyDeployFile = String.Format("$({0}_SOURCE)", targetDeployVar);
            }

            builtFiles.Add(Path.GetFileName(dfile.RelativeTargetPath));

            if (dfile.ContainsPathReferences)
            {
                deployFileCopyTargets.AppendFormat("$(eval $(call emit-deploy-wrapper,{0},{1}{2}))\n",
                                                   targetDeployVar,
                                                   MakefileData.ToMakefilePath(dependencyDeployFile),
                                                   (dfile.FileAttributes & DeployFileAttributes.Executable) != 0 ? ",x" : String.Empty);
            }
            else
            {
                // The emit-deploy-target macro copies the deployable file to the output directory.
                // This is not needed if the file is already there (e.g. for an .mdb file)
                if (Path.GetFullPath(dfile.SourcePath) != Path.GetFullPath(Path.Combine(data.Configuration.OutputDirectory, dfile.RelativeTargetPath)))
                {
                    deployFileCopyTargets.AppendFormat("$(eval $(call emit-deploy-target,{0}))\n", targetDeployVar);
                }
            }

            switch (dfile.TargetDirectoryID)
            {
            case TargetDirectory.Gac:
                // TODO
                break;

            default:
                string var;
                if (dfile.TargetDirectoryID != TargetDirectory.Binaries)
                {
                    string ddir = FileService.NormalizeRelativePath(dfile.RelativeTargetPath.ParentDirectory.ToString().Trim('/', ' '));
                    if (ddir.Length > 0)
                    {
                        ddir = "/" + ddir;
                    }
                    var = ctx.GetDeployDirectoryVar(dfile.TargetDirectoryID + ddir);
                }
                else
                {
                    var = "BINARIES";
                }

                StringBuilder sb;
                if (!deployDirs.TryGetValue(var, out sb))
                {
                    sb = new StringBuilder();
                    deployDirs [var] = sb;
                }
                sb.AppendFormat("\\\n\t$({0}) ", targetDeployVar);
                break;
            }

            if (!generateAutotools)
            {
                string installDir = Path.GetDirectoryName(ctx.DeployContext.GetResolvedPath(dfile.TargetDirectoryID, dfile.RelativeTargetPath));
                //FIXME: temp
                installDir = TranslateDir(installDir);

                if (!installDirs.Contains(installDir))
                {
                    installTarget.AppendFormat("\tmkdir -p '$(DESTDIR){0}'\n", installDir);
                    installDirs.Add(installDir);
                }

                installTarget.AppendFormat("\t$(call cp,$({0}),$(DESTDIR){1})\n", targetDeployVar, installDir);
                uninstallTarget.AppendFormat("\t$(call rm,$({1}),$(DESTDIR){0})\n", installDir, targetDeployVar);
            }
        }
		// Handle unique deploy files, emits non-perconfig stuff, like targets for deploy files,
		// un/install commands
		void HandleDeployFile (DeployFileData data, string targetDeployVar, Project project, AutotoolsContext ctx)
		{
			DeployFile dfile = data.File;
			string dependencyDeployFile = null; //Dependency for the deployfile target
			if (dfile.ContainsPathReferences) {
				// Template file, copy to .in file
				string full_fname = Path.Combine (project.BaseDirectory, Path.GetFileName (dfile.RelativeTargetPath));
				string fname = full_fname;
				string infname = fname + ".in";
				if (File.Exists (infname) && project.IsFileInProject (infname)) {
					string datadir = Path.Combine (project.BaseDirectory, "data");
					if (!Directory.Exists (datadir))
						Directory.CreateDirectory (datadir);
					infname = Path.Combine (datadir, Path.GetFileName (dfile.RelativeTargetPath) + ".in");
				}

				//Absolute path required
				File.Copy (dfile.SourcePath, infname, true);

				//Path relative to TargetCombine
				fname = FileService.NormalizeRelativePath (
						FileService.AbsoluteToRelativePath (ctx.TargetSolution.BaseDirectory, full_fname));
				infname = fname + ".in";
				ctx.AddAutoconfFile (MakefileData.ToMakefilePath (fname));
				ctx.AddGeneratedFile (full_fname + ".in");

				//Path relative to project
				fname = FileService.NormalizeRelativePath (
						FileService.AbsoluteToRelativePath (project.BaseDirectory, full_fname));
				infname = fname + ".in";
				extras.AppendFormat ("\\\n\t{0} ", MakefileData.ToMakefilePath (infname));

				//dependencyDeployFile here should be filename relative to the project
				dependencyDeployFile = fname;
			} else {
				dependencyDeployFile = String.Format ("$({0}_SOURCE)", targetDeployVar);
			}

			builtFiles.Add (Path.GetFileName (dfile.RelativeTargetPath));

			if (dfile.ContainsPathReferences)
				deployFileCopyTargets.AppendFormat ("$(eval $(call emit-deploy-wrapper,{0},{1}{2}))\n",
					targetDeployVar,
					MakefileData.ToMakefilePath (dependencyDeployFile),
					(dfile.FileAttributes & DeployFileAttributes.Executable) != 0 ? ",x" : String.Empty);
			else {
				// The emit-deploy-target macro copies the deployable file to the output directory.
				// This is not needed if the file is already there (e.g. for an .mdb file)
				if (Path.GetFullPath (dfile.SourcePath) != Path.GetFullPath (Path.Combine (data.Configuration.OutputDirectory, dfile.RelativeTargetPath)))
				    deployFileCopyTargets.AppendFormat ("$(eval $(call emit-deploy-target,{0}))\n", targetDeployVar);
			}

			switch (dfile.TargetDirectoryID) {
				case TargetDirectory.Gac:
					// TODO
					break;
				default:
					string var;
					if (dfile.TargetDirectoryID != TargetDirectory.Binaries) {
						string ddir = FileService.NormalizeRelativePath (dfile.RelativeTargetPath.ParentDirectory.ToString().Trim ('/',' '));
						if (ddir.Length > 0)
							ddir = "/" + ddir;
						var = ctx.GetDeployDirectoryVar (dfile.TargetDirectoryID + ddir);
					}
					else
						var = "BINARIES";

					StringBuilder sb;
					if (!deployDirs.TryGetValue (var, out sb)) {
						sb = new StringBuilder ();
						deployDirs [var] = sb;
					}
					sb.AppendFormat ("\\\n\t$({0}) ", targetDeployVar);
					break;
			}

			if (!generateAutotools) {
				string installDir = Path.GetDirectoryName (ctx.DeployContext.GetResolvedPath (dfile.TargetDirectoryID, dfile.RelativeTargetPath));
				//FIXME: temp
				installDir = TranslateDir (installDir);

				if (!installDirs.Contains (installDir)) {
					installTarget.AppendFormat ("\tmkdir -p '$(DESTDIR){0}'\n", installDir);
					installDirs.Add (installDir);
				}

				installTarget.AppendFormat ("\t$(call cp,$({0}),$(DESTDIR){1})\n", targetDeployVar, installDir);
				uninstallTarget.AppendFormat ("\t$(call rm,$({1}),$(DESTDIR){0})\n", installDir, targetDeployVar);
			}
		}
		// Populates configSection.DeployFileVars with unique DeployFiles for a particular config
		void ProcessDeployFilesForConfig (DeployFileCollection deployFiles, Project project, ConfigSection configSection, AutotoolsContext ctx, DotNetProjectConfiguration config)
		{
			//@deployFiles can have duplicates
			Dictionary<string, DeployFile> uniqueDeployFiles = new Dictionary<string, DeployFile> ();
			foreach (DeployFile dfile in deployFiles) {
				if (dfile.SourcePath == project.GetOutputFileName (configSection.Selector))
					continue;

				// DeployFileCollection can have duplicates, ignore them
				string key = dfile.RelativeTargetPath;
				if (!dfile.ContainsPathReferences)
					key += dfile.SourcePath;
				if (uniqueDeployFiles.ContainsKey (key))
					continue;
				uniqueDeployFiles [key] = dfile;

				string targetDeployVar = GetDeployVar (deployFileVars, dfile.RelativeTargetPath);
				configSection.DeployFileVars [targetDeployVar] = dfile;
				DeployFileData data = new DeployFileData ();
				data.File = dfile;
				data.Configuration = config;
				allDeployVars [targetDeployVar] = data;
			}
		}