public bool ValidateChanges(Project project)
        {
            data.IntegrationEnabled   = this.cbEnableMakefileIntegration.Active;
            data.RelativeMakefileName = this.fileEntryMakefilePath.Path;

            data.BuildFilesVar.Sync   = this.cbKeepFilesSync.Active;
            data.BuildFilesVar.Name   = GetActiveVar(comboFilesVar);
            data.BuildFilesVar.Prefix = this.entryFilesPattern.Text.Trim();

            data.DeployFilesVar.Sync   = this.cbKeepDeployFilesSync.Active;
            data.DeployFilesVar.Name   = GetActiveVar(comboDeployFilesVar);
            data.DeployFilesVar.Prefix = this.entryDeployFilesPattern.Text.Trim();

            data.ResourcesVar.Sync   = this.cbKeepResourcesSync.Active;
            data.ResourcesVar.Name   = GetActiveVar(comboResourcesVar);
            data.ResourcesVar.Prefix = this.entryResourcesPattern.Text.Trim();

            data.OthersVar.Sync   = this.cbKeepOthersSync.Active;
            data.OthersVar.Name   = GetActiveVar(comboOthersVar);
            data.OthersVar.Prefix = this.entryOthersPattern.Text.Trim();

            if (!this.cbFileSync.Active)
            {
                // Files sync is unchecked, disable syncing of all files
                data.BuildFilesVar.Sync  = false;
                data.DeployFilesVar.Sync = false;
                data.ResourcesVar.Sync   = false;
                data.OthersVar.Sync      = false;
            }

            // References
            data.SyncReferences       = this.cbKeepRefSync.Active;
            data.PackageRefVar.Sync   = this.cbKeepRefSync.Active;
            data.PackageRefVar.Name   = GetActiveVar(comboPackageRefVar);
            data.PackageRefVar.Prefix = this.entryPackageRefPattern.Text.Trim();

            data.AsmRefVar.Sync   = this.cbKeepRefSync.Active;
            data.AsmRefVar.Name   = GetActiveVar(comboAsmRefVar);
            data.AsmRefVar.Prefix = this.entryAsmRefPattern.Text.Trim();

            data.ProjectRefVar.Sync   = this.cbKeepRefSync.Active;
            data.ProjectRefVar.Name   = GetActiveVar(comboProjectRefVar);
            data.ProjectRefVar.Prefix = this.entryProjectRefPattern.Text.Trim();

            data.IsAutotoolsProject = this.cbAutotoolsProject.Active;
            if (this.cbAutotoolsProject.Active)
            {
                data.RelativeConfigureInPath = this.fileEntryConfigureInPath.Path;
            }

            //data.AssemblyNameVar = GetActiveVar (comboAssemblyName);
            //data.OutputDirVar = GetActiveVar (comboOutputDir);
            data.BuildTargetName   = this.BuildTargetName.Text.Trim();
            data.ExecuteTargetName = this.ExecuteTargetName.Text.Trim();
            data.CleanTargetName   = this.CleanTargetName.Text.Trim();
            data.ParallelProcesses = this.spinProcesses.ValueAsInt;

            data.MessageRegexName = GetActiveVar(comboMessageType);
            if (data.MessageRegexName == "Custom")
            {
                data.CustomErrorRegex   = this.entryErrorRegex.Text;
                data.CustomWarningRegex = this.entryWarningRegex.Text;
            }

            // Data validation

            MakefileData oldData = project.ExtendedProperties ["MonoDevelop.Autotools.MakefileInfo"] as MakefileData;
            MakefileData tmpData = data;

            if (tmpData.IntegrationEnabled)
            {
                //Validate
                try {
                    tmpData.Makefile.GetVariables();
                } catch (FileNotFoundException e) {
                    ShowMakefileNotFoundError(e);
                    return(false);
                } catch (Exception e) {
                    MessageService.ShowException(parentDialog, e, GettextCatalog.GetString("Specified makefile is invalid: {0}", tmpData.AbsoluteMakefileName));
                    return(false);
                }

                if (tmpData.IsAutotoolsProject &&
                    !File.Exists(System.IO.Path.Combine(tmpData.AbsoluteConfigureInPath, "configure.in")) &&
                    !File.Exists(System.IO.Path.Combine(tmpData.AbsoluteConfigureInPath, "configure.ac")))
                {
                    MessageService.ShowError(parentDialog, GettextCatalog.GetString("Path specified for configure.in is invalid: {0}", tmpData.RelativeConfigureInPath));
                    return(false);
                }

                if (tmpData.SyncReferences &&
                    (String.IsNullOrEmpty(tmpData.PackageRefVar.Name) ||
                     String.IsNullOrEmpty(tmpData.AsmRefVar.Name) ||
                     String.IsNullOrEmpty(tmpData.ProjectRefVar.Name)))
                {
                    MessageService.ShowError(parentDialog, GettextCatalog.GetString("'Sync References' is enabled, but one of Reference variables is not set. Please correct this."));
                    return(false);
                }

                if (!CheckNonEmptyFileVar(tmpData.BuildFilesVar, "Build"))
                {
                    return(false);
                }

                if (!CheckNonEmptyFileVar(tmpData.DeployFilesVar, "Deploy"))
                {
                    return(false);
                }

                if (!CheckNonEmptyFileVar(tmpData.ResourcesVar, "Resources"))
                {
                    return(false);
                }

                if (!CheckNonEmptyFileVar(tmpData.OthersVar, "Others"))
                {
                    return(false);
                }

                //FIXME: All file vars must be distinct
                try {
                    tmpData.GetErrorRegex(true);
                } catch (Exception e) {
                    MessageService.ShowError(parentDialog, GettextCatalog.GetString("Invalid regex for Error messages: {0}", e.Message));
                    return(false);
                }

                try {
                    tmpData.GetWarningRegex(true);
                } catch (Exception e) {
                    MessageService.ShowError(parentDialog, GettextCatalog.GetString(
                                                 "Invalid regex for Warning messages: {0}", e.Message));
                    return(false);
                }

                //FIXME: Do this only if there are changes b/w tmpData and Data
                project.ExtendedProperties ["MonoDevelop.Autotools.MakefileInfo"] = tmpData;

                IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor(
                    GettextCatalog.GetString("Updating project"), "gtk-run", true);

                tmpData.UpdateProject(monitor, oldData == null || (!oldData.IntegrationEnabled && tmpData.IntegrationEnabled));
            }
            else
            {
                if (oldData != null)
                {
                    oldData.IntegrationEnabled = false;
                }
            }

            return(true);
        }
        //FIXME: Check whether autogen.sh is required or not
        protected override BuildResult Build(IProgressMonitor monitor, SolutionEntityItem entry, ConfigurationSelector configuration)
        {
            Project project = entry as Project;

            if (project == null)
            {
                return(base.Build(monitor, entry, configuration));
            }

            MakefileData data = project.ExtendedProperties ["MonoDevelop.Autotools.MakefileInfo"] as MakefileData;

            if (data == null || !data.SupportsIntegration || String.IsNullOrEmpty(data.BuildTargetName))
            {
                return(base.Build(monitor, entry, configuration));
            }

            //FIXME: Gen autofoo ? autoreconf?

            string output   = String.Empty;
            int    exitCode = 0;

            monitor.BeginTask(GettextCatalog.GetString("Building {0}", project.Name), 1);
            try
            {
                string baseDir = project.BaseDirectory;
                string args    = string.Format("-j {0} {1}", data.ParallelProcesses, data.BuildTargetName);

                StringWriter  swOutput      = new StringWriter();
                LogTextWriter chainedOutput = new LogTextWriter();
                chainedOutput.ChainWriter(monitor.Log);
                chainedOutput.ChainWriter(swOutput);

                ProcessWrapper process = Runtime.ProcessService.StartProcess("make",
                                                                             args,
                                                                             baseDir,
                                                                             chainedOutput,
                                                                             chainedOutput,
                                                                             null);
                process.WaitForOutput();

                exitCode = process.ExitCode;
                output   = swOutput.ToString();
                chainedOutput.Close();
                swOutput.Close();
                monitor.Step(1);
            }
            catch (Exception e)
            {
                monitor.ReportError(GettextCatalog.GetString("Project could not be built: "), e);
                return(null);
            }
            finally
            {
                monitor.EndTask();
            }

            TempFileCollection tf = new TempFileCollection();
            Regex regexError      = data.GetErrorRegex(false);
            Regex regexWarning    = data.GetWarningRegex(false);

            BuildResult cr = ParseOutput(tf, output, project.BaseDirectory, regexError, regexWarning);

            if (exitCode != 0 && cr.FailedBuildCount == 0)
            {
                cr.AddError(GettextCatalog.GetString("Build failed. See Build Output panel."));
            }

            return(cr);
        }
        //FIXME: Check whether autogen.sh is required or not
        protected async override Task <BuildResult> OnBuild(ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
        {
            if (data == null || !data.SupportsIntegration || String.IsNullOrEmpty(data.BuildTargetName))
            {
                return(await base.OnBuild(monitor, configuration, operationContext));
            }

            //FIXME: Gen autofoo ? autoreconf?

            string output   = String.Empty;
            int    exitCode = 0;

            monitor.BeginTask(GettextCatalog.GetString("Building {0}", Project.Name), 1);
            try
            {
                string baseDir = Project.BaseDirectory;
                string args    = string.Format("-j {0} {1}", data.ParallelProcesses, data.BuildTargetName);

                using (var swOutput = new StringWriter()) {
                    using (var chainedOutput = new LogTextWriter()) {
                        chainedOutput.ChainWriter(monitor.Log);
                        chainedOutput.ChainWriter(swOutput);

                        using (ProcessWrapper process = Runtime.ProcessService.StartProcess("make",
                                                                                            args,
                                                                                            baseDir,
                                                                                            chainedOutput,
                                                                                            chainedOutput,
                                                                                            null)) {
                            await process.Task;

                            chainedOutput.UnchainWriter(monitor.Log);
                            chainedOutput.UnchainWriter(swOutput);

                            exitCode = process.ExitCode;
                            output   = swOutput.ToString();
                            monitor.Step(1);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                monitor.ReportError(GettextCatalog.GetString("Project could not be built: "), e);
                return(null);
            }
            finally
            {
                monitor.EndTask();
            }

            TempFileCollection tf = new TempFileCollection();
            Regex regexError      = data.GetErrorRegex(false);
            Regex regexWarning    = data.GetWarningRegex(false);

            BuildResult cr = ParseOutput(tf, output, Project.BaseDirectory, regexError, regexWarning);

            if (exitCode != 0 && cr.FailedBuildCount == 0)
            {
                cr.AddError(GettextCatalog.GetString("Build failed. See Build Output panel."));
            }

            return(cr);
        }