/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.build.builders;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.build.AaptParser;
import com.android.ide.eclipse.adt.internal.build.AidlProcessor;
import com.android.ide.eclipse.adt.internal.build.Messages;
import com.android.ide.eclipse.adt.internal.build.RenderScriptLauncher;
import com.android.ide.eclipse.adt.internal.build.RsSourceChangeHandler;
import com.android.ide.eclipse.adt.internal.build.SourceProcessor;
import com.android.ide.eclipse.adt.internal.build.builders.BaseBuilder.AbortBuildException;
import com.android.ide.eclipse.adt.internal.lint.EclipseLintClient;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener;
import com.android.ide.eclipse.adt.internal.resources.manager.IdeScanningContext;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.ide.eclipse.adt.io.IFolderWrapper;
import com.android.io.StreamException;
import com.android.manifmerger.ManifestMerger;
import com.android.manifmerger.MergerLog;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.build.RenderScriptChecker;
import com.android.sdklib.build.RenderScriptProcessor;
import com.android.sdklib.internal.build.BuildConfigGenerator;
import com.android.sdklib.internal.build.SymbolLoader;
import com.android.sdklib.internal.build.SymbolWriter;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.io.FileOp;
import com.android.sdklib.repository.FullRevision;
import com.android.utils.ILogger;
import com.android.utils.Pair;
import com.android.xml.AndroidManifest;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

/**
 * Pre Java Compiler.
 * This incremental builder performs 2 tasks:
 * <ul>
 * <li>compiles the resources located in the res/ folder, along with the
 * AndroidManifest.xml file into the R.java class.</li>
 * <li>compiles any .aidl files into a corresponding java file.</li>
 * </ul>
 *
 */
public class PreCompilerBuilder extends BaseBuilder {

    /** This ID is used in plugin.xml and in each project's .project file.
     * It cannot be changed even if the class is renamed/moved */
    public static final String ID = "com.android.ide.eclipse.adt.PreCompilerBuilder"; //$NON-NLS-1$

    /** Flag to pass to PreCompiler builder that the build is a release build.
     */
    public final static String RELEASE_REQUESTED = "android.releaseBuild"; //$NON-NLS-1$

    private static final String PROPERTY_PACKAGE = "manifestPackage"; //$NON-NLS-1$
    private static final String PROPERTY_MERGE_MANIFEST = "mergeManifest"; //$NON-NLS-1$
    private static final String PROPERTY_COMPILE_RESOURCES = "compileResources"; //$NON-NLS-1$
    private static final String PROPERTY_COMPILE_BUILDCONFIG = "createBuildConfig"; //$NON-NLS-1$
    private static final String PROPERTY_BUILDCONFIG_MODE = "buildConfigMode"; //$NON-NLS-1$

    private static final boolean MANIFEST_MERGER_ENABLED_DEFAULT = false;
    private static final String MANIFEST_MERGER_PROPERTY = "manifestmerger.enabled"; //$NON-NLS-1$

    /** Merge Manifest Flag. Computed from resource delta, reset after action is taken.
     * Stored persistently in the project. */
    private boolean mMustMergeManifest = false;
    /** Resource compilation Flag. Computed from resource delta, reset after action is taken.
     * Stored persistently in the project. */
    private boolean mMustCompileResources = false;
    /** BuildConfig Flag. Computed from resource delta, reset after action is taken.
     * Stored persistently in the project. */
    private boolean mMustCreateBuildConfig = false;
    /** BuildConfig last more Flag. Computed from resource delta, reset after action is taken.
     * Stored persistently in the project. */
    private boolean mLastBuildConfigMode;

    /** cache of the java package defined in the manifest */
    private String mManifestPackage;

    /** Output folder for generated Java File. Created on the Builder init
     * @see #startupOnInitialize()
     */
    private IFolder mGenFolder;

    /**
     * Progress monitor used at the end of every build to refresh the content of the 'gen' folder
     * and set the generated files as derived.
     */
    private DerivedProgressMonitor mDerivedProgressMonitor;

    private AidlProcessor mAidlProcessor;
    private RsSourceChangeHandler mRenderScriptSourceChangeHandler;

    /**
     * Progress monitor waiting the end of the process to set a persistent value
     * in a file. This is typically used in conjunction with <code>IResource.refresh()</code>,
     * since this call is asynchronous, and we need to wait for it to finish for the file
     * to be known by eclipse, before we can call <code>resource.setPersistentProperty</code> on
     * a new file.
     */
    private static class DerivedProgressMonitor implements IProgressMonitor {
        private boolean mCancelled = false;
        private boolean mDone = false;
        private final IFolder mGenFolder;

        public DerivedProgressMonitor(IFolder genFolder) {
            mGenFolder = genFolder;
        }

        void reset() {
            mDone = false;
        }

        @Override
        public void beginTask(String name, int totalWork) {
        }

        @Override
        public void done() {
            if (mDone == false) {
                mDone = true;
                processChildrenOf(mGenFolder);
            }
        }

        private void processChildrenOf(IFolder folder) {
            IResource[] list;
            try {
                list = folder.members();
            } catch (CoreException e) {
                return;
            }

            for (IResource member : list) {
                if (member.exists()) {
                    if (member.getType() == IResource.FOLDER) {
                        processChildrenOf((IFolder) member);
                    }

                    try {
                        member.setDerived(true, new NullProgressMonitor());
                    } catch (CoreException e) {
                        // This really shouldn't happen since we check that the resource
                        // exist.
                        // Worst case scenario, the resource isn't marked as derived.
                    }
                }
            }
        }

        @Override
        public void internalWorked(double work) {
        }

        @Override
        public boolean isCanceled() {
            return mCancelled;
        }

        @Override
        public void setCanceled(boolean value) {
            mCancelled = value;
        }

        @Override
        public void setTaskName(String name) {
        }

        @Override
        public void subTask(String name) {
        }

        @Override
        public void worked(int work) {
        }
    }

    public PreCompilerBuilder() {
        super();
    }

    // build() returns a list of project from which this project depends for future compilation.
    @Override
    protected IProject[] build(
            int kind,
            @SuppressWarnings("rawtypes") Map args,
            IProgressMonitor monitor)
            throws CoreException {
        // get a project object
        IProject project = getProject();

        if (DEBUG_LOG) {
            AdtPlugin.log(IStatus.INFO, "%s BUILD(PRE)", project.getName());
        }

        // For the PreCompiler, only the library projects are considered Referenced projects,
        // as only those projects have an impact on what is generated by this builder.
        IProject[] result = null;

        IFolder resOutFolder = null;

        try {
            assert mDerivedProgressMonitor != null;

            mDerivedProgressMonitor.reset();

            // get the project info
            ProjectState projectState = Sdk.getProjectState(project);

            // this can happen if the project has no project.properties.
            if (projectState == null) {
                return null;
            }

            boolean isLibrary = projectState.isLibrary();

            IAndroidTarget projectTarget = projectState.getTarget();

            // get the libraries
            List<IProject> libProjects = projectState.getFullLibraryProjects();
            result = libProjects.toArray(new IProject[libProjects.size()]);

            IJavaProject javaProject = JavaCore.create(project);

            // Top level check to make sure the build can move forward.
            abortOnBadSetup(javaProject, projectState);

            // now we need to get the classpath list
            List<IPath> sourceFolderPathList = BaseProjectHelper.getSourceClasspaths(javaProject);

            IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project);

            resOutFolder = getResOutFolder(androidOutputFolder);

            setupSourceProcessors(javaProject, projectState, sourceFolderPathList,
                    androidOutputFolder);

            PreCompilerDeltaVisitor dv = null;
            String javaPackage = null;
            String minSdkVersion = null;

            if (kind == FULL_BUILD) {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Start_Full_Pre_Compiler);

                if (DEBUG_LOG) {
                    AdtPlugin.log(IStatus.INFO, "%s full build!", project.getName());
                }

                // do some clean up.
                doClean(project, monitor);

                mMustMergeManifest = true;
                mMustCompileResources = true;
                mMustCreateBuildConfig = true;

                mAidlProcessor.prepareFullBuild(project);
                mRenderScriptSourceChangeHandler.prepareFullBuild();
            } else {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Start_Inc_Pre_Compiler);

                // Go through the resources and see if something changed.
                // Even if the mCompileResources flag is true from a previously aborted
                // build, we need to go through the Resource delta to get a possible
                // list of aidl files to compile/remove.
                IResourceDelta delta = getDelta(project);
                if (delta == null) {
                    mMustCompileResources = true;

                    mAidlProcessor.prepareFullBuild(project);
                    mRenderScriptSourceChangeHandler.prepareFullBuild();
                } else {
                    dv = new PreCompilerDeltaVisitor(this, sourceFolderPathList,
                            mAidlProcessor.getChangeHandler(),
                            mRenderScriptSourceChangeHandler);
                    delta.accept(dv);

                    // Check to see if Manifest.xml, Manifest.java, or R.java have changed:
                    mMustCompileResources |= dv.getCompileResources();
                    mMustMergeManifest |= dv.hasManifestChanged();

                    // Notify the ResourceManager:
                    ResourceManager resManager = ResourceManager.getInstance();

                    if (ResourceManager.isAutoBuilding()) {
                        ProjectResources projectResources = resManager.getProjectResources(project);

                        IdeScanningContext context = new IdeScanningContext(projectResources,
                                project, true);

                        boolean wasCleared = projectResources.ensureInitialized();

                        if (!wasCleared) {
                            resManager.processDelta(delta, context);
                        }

                        // Check whether this project or its dependencies (libraries) have
                        // resources that need compilation
                        if (wasCleared || context.needsFullAapt()) {
                            mMustCompileResources = true;

                            // Must also call markAaptRequested on the project to not just
                            // store "aapt required" on this project, but also on any projects
                            // depending on this project if it's a library project
                            ResourceManager.markAaptRequested(project);
                        }

                        // Update error markers in the source editor
                        if (!mMustCompileResources) {
                            context.updateMarkers(false /* async */);
                        }
                    } // else: already processed the deltas in ResourceManager's IRawDeltaListener

                    mAidlProcessor.doneVisiting(project);

                    // get the java package from the visitor
                    javaPackage = dv.getManifestPackage();
                    minSdkVersion = dv.getMinSdkVersion();
                }
            }

            // Has anyone marked this project as needing aapt? Typically done when
            // one of the library projects this project depends on has changed
            mMustCompileResources |= ResourceManager.isAaptRequested(project);

            // if the main manifest didn't change, then we check for the library
            // ones (will trigger manifest merging too)
            if (libProjects.size() > 0) {
                for (IProject libProject : libProjects) {
                    IResourceDelta delta = getDelta(libProject);
                    if (delta != null) {
                        PatternBasedDeltaVisitor visitor = new PatternBasedDeltaVisitor(
                                project, libProject,
                                "PRE:LibManifest"); //$NON-NLS-1$
                        visitor.addSet(ChangedFileSetHelper.MANIFEST);

                        ChangedFileSet textSymbolCFS = null;
                        if (isLibrary == false) {
                            textSymbolCFS = ChangedFileSetHelper.getTextSymbols(
                                    libProject);
                            visitor.addSet(textSymbolCFS);
                        }

                        delta.accept(visitor);

                        mMustMergeManifest |= visitor.checkSet(ChangedFileSetHelper.MANIFEST);

                        if (textSymbolCFS != null) {
                            mMustCompileResources |= visitor.checkSet(textSymbolCFS);
                        }

                        // no need to test others if we have all flags at true.
                        if (mMustMergeManifest &&
                                (mMustCompileResources || textSymbolCFS == null)) {
                            break;
                        }
                    }
                }
            }

            // store the build status in the persistent storage
            saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest);
            saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
            saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);

            // if there was some XML errors, we just return w/o doing
            // anything since we've put some markers in the files anyway.
            if (dv != null && dv.mXmlError) {
                AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);

                return result;
            }

            if (projectState.getRenderScriptSupportMode()) {
                FullRevision minBuildToolsRev = new FullRevision(19,0,3);
                if (mBuildToolInfo.getRevision().compareTo(minBuildToolsRev) == -1) {
                    String msg = "RenderScript support mode requires Build-Tools 19.0.3 or later.";
                    AdtPlugin.printErrorToConsole(project, msg);
                    markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);

                    return result;
                }
            }

            // get the manifest file
            IFile manifestFile = ProjectHelper.getManifest(project);

            if (manifestFile == null) {
                String msg = String.format(Messages.s_File_Missing,
                        SdkConstants.FN_ANDROID_MANIFEST_XML);
                AdtPlugin.printErrorToConsole(project, msg);
                markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);

                return result;

                // TODO: document whether code below that uses manifest (which is now guaranteed
                // to be null) will actually be executed or not.
            }

            // lets check the XML of the manifest first, if that hasn't been done by the
            // resource delta visitor yet.
            if (dv == null || dv.getCheckedManifestXml() == false) {
                BasicXmlErrorListener errorListener = new BasicXmlErrorListener();
                try {
                    ManifestData parser = AndroidManifestHelper.parseUnchecked(
                            new IFileWrapper(manifestFile),
                            true /*gather data*/,
                            errorListener);

                    if (errorListener.mHasXmlError == true) {
                        // There was an error in the manifest, its file has been marked
                        // by the XmlErrorHandler. The stopBuild() call below will abort
                        // this with an exception.
                        String msg = String.format(Messages.s_Contains_Xml_Error,
                                SdkConstants.FN_ANDROID_MANIFEST_XML);
                        AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
                        markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);

                        return result;
                    }

                    // Get the java package from the parser.
                    // This can be null if the parsing failed because the resource is out of sync,
                    // in which case the error will already have been logged anyway.
                    if (parser != null) {
                        javaPackage = parser.getPackage();
                        minSdkVersion = parser.getMinSdkVersionString();
                    }
                } catch (StreamException e) {
                    handleStreamException(e);

                    return result;
                } catch (ParserConfigurationException e) {
                    String msg = String.format(
                            "Bad parser configuration for %s: %s",
                            manifestFile.getFullPath(),
                            e.getMessage());

                    handleException(e, msg);
                    return result;

                } catch (SAXException e) {
                    String msg = String.format(
                            "Parser exception for %s: %s",
                            manifestFile.getFullPath(),
                            e.getMessage());

                    handleException(e, msg);
                    return result;
                } catch (IOException e) {
                    String msg = String.format(
                            "I/O error for %s: %s",
                            manifestFile.getFullPath(),
                            e.getMessage());

                    handleException(e, msg);
                    return result;
                }
            }

            int minSdkValue = -1;

            if (minSdkVersion != null) {
                try {
                    minSdkValue = Integer.parseInt(minSdkVersion);
                } catch (NumberFormatException e) {
                    // it's ok, it means minSdkVersion contains a (hopefully) valid codename.
                }

                AndroidVersion targetVersion = projectTarget.getVersion();

                // remove earlier marker from the manifest
                removeMarkersFromResource(manifestFile, AdtConstants.MARKER_ADT);

                if (minSdkValue != -1) {
                    String codename = targetVersion.getCodename();
                    if (codename != null) {
                        // integer minSdk when the target is a preview => fatal error
                        String msg = String.format(
                                "Platform %1$s is a preview and requires application manifest to set %2$s to '%1$s'",
                                codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
                        AdtPlugin.printErrorToConsole(project, msg);
                        BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                                msg, IMarker.SEVERITY_ERROR);
                        return result;
                    } else if (minSdkValue > targetVersion.getApiLevel()) {
                        // integer minSdk is too high for the target => warning
                        String msg = String.format(
                                "Attribute %1$s (%2$d) is higher than the project target API level (%3$d)",
                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
                                minSdkValue, targetVersion.getApiLevel());
                        AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project, msg);
                        BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                                msg, IMarker.SEVERITY_WARNING);
                    }
                } else {
                    // looks like the min sdk is a codename, check it matches the codename
                    // of the platform
                    String codename = targetVersion.getCodename();
                    if (codename == null) {
                        // platform is not a preview => fatal error
                        String msg = String.format(
                                "Manifest attribute '%1$s' is set to '%2$s'. Integer is expected.",
                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion);
                        AdtPlugin.printErrorToConsole(project, msg);
                        BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                                msg, IMarker.SEVERITY_ERROR);
                        return result;
                    } else if (codename.equals(minSdkVersion) == false) {
                        // platform and manifest codenames don't match => fatal error.
                        String msg = String.format(
                                "Value of manifest attribute '%1$s' does not match platform codename '%2$s'",
                                AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, codename);
                        AdtPlugin.printErrorToConsole(project, msg);
                        BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                                msg, IMarker.SEVERITY_ERROR);
                        return result;
                    }

                    // if we get there, the minSdkVersion is a codename matching the target
                    // platform codename. In this case we set minSdkValue to the previous API
                    // level, as it's used by source processors.
                    minSdkValue = targetVersion.getApiLevel();
                }
            } else if (projectTarget.getVersion().isPreview()) {
                // else the minSdkVersion is not set but we are using a preview target.
                // Display an error
                String codename = projectTarget.getVersion().getCodename();
                String msg = String.format(
                        "Platform %1$s is a preview and requires application manifests to set %2$s to '%1$s'",
                        codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
                AdtPlugin.printErrorToConsole(project, msg);
                BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT, msg,
                        IMarker.SEVERITY_ERROR);
                return result;
            }

            if (javaPackage == null || javaPackage.length() == 0) {
                // looks like the AndroidManifest file isn't valid.
                String msg = String.format(Messages.s_Doesnt_Declare_Package_Error,
                        SdkConstants.FN_ANDROID_MANIFEST_XML);
                AdtPlugin.printErrorToConsole(project, msg);
                BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                        msg, IMarker.SEVERITY_ERROR);

                return result;
            } else if (javaPackage.indexOf('.') == -1) {
                // The application package name does not contain 2+ segments!
                String msg = String.format(
                        "Application package '%1$s' must have a minimum of 2 segments.",
                        SdkConstants.FN_ANDROID_MANIFEST_XML);
                AdtPlugin.printErrorToConsole(project, msg);
                BaseProjectHelper.markResource(manifestFile, AdtConstants.MARKER_ADT,
                        msg, IMarker.SEVERITY_ERROR);

                return result;
            }

            // at this point we have the java package. We need to make sure it's not a different
            // package than the previous one that were built.
            if (javaPackage.equals(mManifestPackage) == false) {
                // The manifest package has changed, the user may want to update
                // the launch configuration
                if (mManifestPackage != null) {
                    AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                            Messages.Checking_Package_Change);

                    FixLaunchConfig flc = new FixLaunchConfig(project, mManifestPackage,
                            javaPackage);
                    flc.start();
                }

                // record the new manifest package, and save it.
                mManifestPackage = javaPackage;
                saveProjectStringProperty(PROPERTY_PACKAGE, mManifestPackage);

                // force a clean
                doClean(project, monitor);
                mMustMergeManifest = true;
                mMustCompileResources = true;
                mMustCreateBuildConfig = true;
                mAidlProcessor.prepareFullBuild(project);
                mRenderScriptSourceChangeHandler.prepareFullBuild();

                saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest);
                saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
                saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);
            }

            try {
                handleBuildConfig(args);
            } catch (IOException e) {
                handleException(e, "Failed to create BuildConfig class");
                return result;
            }

            // merge the manifest
            if (mMustMergeManifest) {
                boolean enabled = MANIFEST_MERGER_ENABLED_DEFAULT;
                String propValue = projectState.getProperty(MANIFEST_MERGER_PROPERTY);
                if (propValue != null) {
                    enabled = Boolean.valueOf(propValue);
                }

                if (mergeManifest(androidOutputFolder, libProjects, enabled) == false) {
                    return result;
                }
            }

            List<File> libProjectsOut = new ArrayList<File>(libProjects.size());
            for (IProject libProject : libProjects) {
                libProjectsOut.add(
                        BaseProjectHelper.getAndroidOutputFolder(libProject)
                            .getLocation().toFile());
            }

            // run the source processors
            int processorStatus = SourceProcessor.COMPILE_STATUS_NONE;


            try {
                processorStatus |= mAidlProcessor.compileFiles(this,
                        project, projectTarget, sourceFolderPathList,
                        libProjectsOut, monitor);
            } catch (Throwable t) {
                handleException(t, "Failed to run aidl. Check workspace log for detail.");
                return result;
            }

            try {
                processorStatus |= compileRs(minSdkValue, projectState, androidOutputFolder,
                        resOutFolder, monitor);
            } catch (Throwable t) {
                handleException(t, "Failed to run renderscript. Check workspace log for detail.");
                return result;
            }

            // if a processor created some resources file, force recompilation of the resources.
            if ((processorStatus & SourceProcessor.COMPILE_STATUS_RES) != 0) {
                mMustCompileResources = true;
                // save the current state before attempting the compilation
                saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mMustCompileResources);
            }

            // handle the resources, after the processors are run since some (renderscript)
            // generate resources.
            boolean compiledTheResources = mMustCompileResources;
            if (mMustCompileResources) {
                if (DEBUG_LOG) {
                    AdtPlugin.log(IStatus.INFO, "%s compiling resources!", project.getName());
                }

                IFile proguardFile = null;
                if (projectState.getProperty(ProjectProperties.PROPERTY_PROGUARD_CONFIG) != null) {
                    proguardFile = androidOutputFolder.getFile(AdtConstants.FN_AAPT_PROGUARD);
                }

                handleResources(project, javaPackage, projectTarget, manifestFile, resOutFolder,
                        libProjects, isLibrary, proguardFile);
            }

            if (processorStatus == SourceProcessor.COMPILE_STATUS_NONE &&
                    compiledTheResources == false) {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.Nothing_To_Compile);
            }
        } catch (AbortBuildException e) {
            return result;
        } finally {
            // refresh the 'gen' source folder. Once this is done with the custom progress
            // monitor to mark all new files as derived
            mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
            if (resOutFolder != null) {
                resOutFolder.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
            }
        }

        return result;
    }

    private IFolder getResOutFolder(IFolder androidOutputFolder) {
        return androidOutputFolder.getFolder(AdtConstants.WS_BIN_RELATIVE_BC);
    }

    @Override
    protected void clean(IProgressMonitor monitor) throws CoreException {
        super.clean(monitor);

        if (DEBUG_LOG) {
            AdtPlugin.log(IStatus.INFO, "%s CLEAN(PRE)", getProject().getName());
        }

        doClean(getProject(), monitor);
        if (mGenFolder != null) {
            mGenFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
        }
    }

    private void doClean(IProject project, IProgressMonitor monitor) throws CoreException {
        AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                Messages.Removing_Generated_Classes);

        // remove all the derived resources from the 'gen' source folder.
        if (mGenFolder != null && mGenFolder.exists()) {
            // gen folder should not be derived, but previous version could set it to derived
            // so we make sure this isn't the case (or it'll get deleted by the clean)
            mGenFolder.setDerived(false, monitor);

            removeDerivedResources(mGenFolder, monitor);
        }

        // Clear the project of the generic markers
        removeMarkersFromContainer(project, AdtConstants.MARKER_AAPT_COMPILE);
        removeMarkersFromContainer(project, AdtConstants.MARKER_XML);
        removeMarkersFromContainer(project, AdtConstants.MARKER_AIDL);
        removeMarkersFromContainer(project, AdtConstants.MARKER_RENDERSCRIPT);
        removeMarkersFromContainer(project, AdtConstants.MARKER_MANIFMERGER);
        removeMarkersFromContainer(project, AdtConstants.MARKER_ANDROID);

        // Also clean up lint
        EclipseLintClient.clearMarkers(project);

        // clean the project repo
        ProjectResources res = ResourceManager.getInstance().getProjectResources(project);
        res.clear();
    }

    @Override
    protected void startupOnInitialize() {
        try {
            super.startupOnInitialize();

            IProject project = getProject();

            // load the previous IFolder and java package.
            mManifestPackage = loadProjectStringProperty(PROPERTY_PACKAGE);

            // get the source folder in which all the Java files are created
            mGenFolder = project.getFolder(SdkConstants.FD_GEN_SOURCES);
            mDerivedProgressMonitor = new DerivedProgressMonitor(mGenFolder);

            // Load the current compile flags. We ask for true if not found to force a recompile.
            mMustMergeManifest = loadProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, true);
            mMustCompileResources = loadProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, true);
            mMustCreateBuildConfig = loadProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, true);
            Boolean v = ProjectHelper.loadBooleanProperty(project, PROPERTY_BUILDCONFIG_MODE);
            if (v == null) {
                // no previous build config mode? force regenerate
                mMustCreateBuildConfig = true;
            } else {
                mLastBuildConfigMode = v;
            }

        } catch (Throwable throwable) {
            AdtPlugin.log(throwable, "Failed to finish PrecompilerBuilder#startupOnInitialize()");
        }
    }

    private void setupSourceProcessors(@NonNull IJavaProject javaProject,
            @NonNull ProjectState projectState,
            @NonNull List<IPath> sourceFolderPathList,
            @NonNull IFolder androidOutputFolder) {
        if (mAidlProcessor == null) {
            mAidlProcessor = new AidlProcessor(javaProject, mBuildToolInfo, mGenFolder);
        } else {
            mAidlProcessor.setBuildToolInfo(mBuildToolInfo);
        }

        List<File> sourceFolders = Lists.newArrayListWithCapacity(sourceFolderPathList.size());
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

        for (IPath path : sourceFolderPathList) {
            IResource resource = root.findMember(path);
            if (resource != null && resource.exists() && resource.getType() == IResource.FOLDER) {
                IPath fullPath = resource.getLocation();
                if (fullPath != null) {
                    sourceFolders.add(fullPath.toFile());
                }
            }
        }

        RenderScriptChecker checker = new RenderScriptChecker(sourceFolders,
                androidOutputFolder.getLocation().toFile());
        mRenderScriptSourceChangeHandler = new RsSourceChangeHandler(checker);
    }

    private int compileRs(int minSdkValue,
            @NonNull ProjectState projectState,
            @NonNull IFolder androidOutputFolder,
            @NonNull IFolder resOutFolder,
            @NonNull IProgressMonitor monitor)
            throws IOException, InterruptedException {
        if (!mRenderScriptSourceChangeHandler.mustCompile()) {
            return SourceProcessor.COMPILE_STATUS_NONE;
        }

        RenderScriptChecker checker = mRenderScriptSourceChangeHandler.getChecker();

        List<File> inputs = checker.findInputFiles();
        List<File> importFolders = checker.getSourceFolders();
        File buildFolder = androidOutputFolder.getLocation().toFile();


        // get the renderscript target
        int rsTarget = minSdkValue == -1 ? 11 : minSdkValue;
        String rsTargetStr = projectState.getProperty(ProjectProperties.PROPERTY_RS_TARGET);
        if (rsTargetStr != null) {
            try {
                rsTarget = Integer.parseInt(rsTargetStr);
            } catch (NumberFormatException e) {
                handleException(e, String.format(
                        "Property %s is not an integer.",
                        ProjectProperties.PROPERTY_RS_TARGET));
                return SourceProcessor.COMPILE_STATUS_NONE;
            }
        }

        RenderScriptProcessor processor = new RenderScriptProcessor(
                inputs,
                importFolders,
                buildFolder,
                mGenFolder.getLocation().toFile(),
                resOutFolder.getLocation().toFile(),
                new File(buildFolder, SdkConstants.FD_RS_OBJ),
                new File(buildFolder, SdkConstants.FD_RS_LIBS),
                mBuildToolInfo,
                rsTarget,
                false /*debugBuild, always false for now*/,
                3,
                projectState.getRenderScriptSupportMode());

        // clean old dependency files fiest
        checker.cleanDependencies();

        // then clean old output files
        processor.cleanOldOutput(checker.getOldOutputs());

        RenderScriptLauncher launcher = new RenderScriptLauncher(
                getProject(),
                mGenFolder,
                resOutFolder,
                monitor,
                AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE /*verbose*/);

        // and run the build
        processor.build(launcher);

        return SourceProcessor.COMPILE_STATUS_CODE | SourceProcessor.COMPILE_STATUS_RES;
    }

    @SuppressWarnings("deprecation")
    private void handleBuildConfig(@SuppressWarnings("rawtypes") Map args)
            throws IOException, CoreException {
        boolean debugMode = !args.containsKey(RELEASE_REQUESTED);

        BuildConfigGenerator generator = new BuildConfigGenerator(
                mGenFolder.getLocation().toOSString(), mManifestPackage, debugMode);

        if (mMustCreateBuildConfig == false) {
            // check the file is present.
            IFolder folder = getGenManifestPackageFolder();
            if (folder.exists(new Path(BuildConfigGenerator.BUILD_CONFIG_NAME)) == false) {
                mMustCreateBuildConfig = true;
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
                        String.format("Class %1$s is missing!",
                                BuildConfigGenerator.BUILD_CONFIG_NAME));
            } else if (debugMode != mLastBuildConfigMode) {
                // else if the build mode changed, force creation
                mMustCreateBuildConfig = true;
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
                        String.format("Different build mode, must update %1$s!",
                                BuildConfigGenerator.BUILD_CONFIG_NAME));
            }
        }

        if (mMustCreateBuildConfig) {
            if (DEBUG_LOG) {
                AdtPlugin.log(IStatus.INFO, "%s generating BuilderConfig!", getProject().getName());
            }

            AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, getProject(),
                    String.format("Generating %1$s...", BuildConfigGenerator.BUILD_CONFIG_NAME));
            generator.generate();

            mMustCreateBuildConfig = false;
            saveProjectBooleanProperty(PROPERTY_COMPILE_BUILDCONFIG, mMustCreateBuildConfig);
            saveProjectBooleanProperty(PROPERTY_BUILDCONFIG_MODE, mLastBuildConfigMode = debugMode);
        }
    }

    private boolean mergeManifest(IFolder androidOutFolder, List<IProject> libProjects,
            boolean enabled) throws CoreException {
        if (DEBUG_LOG) {
            AdtPlugin.log(IStatus.INFO, "%s merging manifests!", getProject().getName());
        }

        IFile outFile = androidOutFolder.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);
        IFile manifest = getProject().getFile(SdkConstants.FN_ANDROID_MANIFEST_XML);

        // remove existing markers from the manifest.
        // FIXME: only remove from manifest once the markers are put there.
        removeMarkersFromResource(getProject(), AdtConstants.MARKER_MANIFMERGER);

        // If the merging is not enabled or if there's no library then we simply copy the
        // manifest over.
        if (enabled == false || libProjects.size() == 0) {
            try {
                new FileOp().copyFile(manifest.getLocation().toFile(),
                        outFile.getLocation().toFile());

                outFile.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);

                saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest = false);
            } catch (IOException e) {
                handleException(e, "Failed to copy Manifest");
                return false;
            }
        } else {
            final ArrayList<String> errors = new ArrayList<String>();

            // TODO change MergerLog.wrapSdkLog by a custom IMergerLog that will create
            // and maintain error markers.
            ManifestMerger merger = new ManifestMerger(
                MergerLog.wrapSdkLog(new ILogger() {
                    @Override
                    public void warning(@NonNull String warningFormat, Object... args) {
                        AdtPlugin.printToConsole(getProject(), String.format(warningFormat, args));
                    }

                    @Override
                    public void info(@NonNull String msgFormat, Object... args) {
                        AdtPlugin.printToConsole(getProject(), String.format(msgFormat, args));
                    }

                    @Override
                    public void verbose(@NonNull String msgFormat, Object... args) {
                        info(msgFormat, args);
                    }

                    @Override
                    public void error(@Nullable Throwable t, @Nullable String errorFormat,
                            Object... args) {
                        errors.add(String.format(errorFormat, args));
                    }
                }),
                new AdtManifestMergeCallback());

            File[] libManifests = new File[libProjects.size()];
            int libIndex = 0;
            for (IProject lib : libProjects) {
                libManifests[libIndex++] = lib.getFile(SdkConstants.FN_ANDROID_MANIFEST_XML)
                        .getLocation().toFile();
            }

            if (merger.process(
                    outFile.getLocation().toFile(),
                    manifest.getLocation().toFile(),
                    libManifests,
                    null /*injectAttributes*/, null /*packageOverride*/) == false) {
                if (errors.size() > 1) {
                    StringBuilder sb = new StringBuilder();
                    for (String s : errors) {
                        sb.append(s).append('\n');
                    }

                    markProject(AdtConstants.MARKER_MANIFMERGER, sb.toString(),
                            IMarker.SEVERITY_ERROR);

                } else if (errors.size() == 1) {
                    markProject(AdtConstants.MARKER_MANIFMERGER, errors.get(0),
                            IMarker.SEVERITY_ERROR);
                } else {
                    markProject(AdtConstants.MARKER_MANIFMERGER, "Unknown error merging manifest",
                            IMarker.SEVERITY_ERROR);
                }
                return false;
            }

            outFile.refreshLocal(IResource.DEPTH_INFINITE, mDerivedProgressMonitor);
            saveProjectBooleanProperty(PROPERTY_MERGE_MANIFEST, mMustMergeManifest = false);
        }

        return true;
    }

    /**
     * Handles resource changes and regenerate whatever files need regenerating.
     * @param project the main project
     * @param javaPackage the app package for the main project
     * @param projectTarget the target of the main project
     * @param manifest the {@link IFile} representing the project manifest
     * @param libProjects the library dependencies
     * @param isLibrary if the project is a library project
     * @throws CoreException
     * @throws AbortBuildException
     */
    private void handleResources(IProject project, String javaPackage, IAndroidTarget projectTarget,
            IFile manifest, IFolder resOutFolder, List<IProject> libProjects, boolean isLibrary,
            IFile proguardFile) throws CoreException, AbortBuildException {
        // get the resource folder
        IFolder resFolder = project.getFolder(AdtConstants.WS_RESOURCES);

        // get the file system path
        IPath outputLocation = mGenFolder.getLocation();
        IPath resLocation = resFolder.getLocation();
        IPath manifestLocation = manifest == null ? null : manifest.getLocation();

        // those locations have to exist for us to do something!
        if (outputLocation != null && resLocation != null
                && manifestLocation != null) {
            String osOutputPath = outputLocation.toOSString();
            String osResPath = resLocation.toOSString();
            String osManifestPath = manifestLocation.toOSString();

            // remove the aapt markers
            removeMarkersFromResource(manifest, AdtConstants.MARKER_AAPT_COMPILE);
            removeMarkersFromContainer(resFolder, AdtConstants.MARKER_AAPT_COMPILE);

            AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                    Messages.Preparing_Generated_Files);

            // we need to figure out where to store the R class.
            // get the parent folder for R.java and update mManifestPackageSourceFolder
            IFolder mainPackageFolder = getGenManifestPackageFolder();

            // handle libraries
            ArrayList<IFolder> libResFolders = Lists.newArrayList();
            ArrayList<Pair<File, String>> libRFiles = Lists.newArrayList();
            if (libProjects != null) {
                for (IProject lib : libProjects) {
                    IFolder libResFolder = lib.getFolder(SdkConstants.FD_RES);
                    if (libResFolder.exists()) {
                        libResFolders.add(libResFolder);
                    }

                    try {
                        // get the package of the library, and if it's different form the
                        // main project, generate the R class for it too.
                        String libJavaPackage = AndroidManifest.getPackage(new IFolderWrapper(lib));
                        if (libJavaPackage.equals(javaPackage) == false) {

                            IFolder libOutput = BaseProjectHelper.getAndroidOutputFolder(lib);
                            File libOutputFolder = libOutput.getLocation().toFile();

                            libRFiles.add(Pair.of(
                                    new File(libOutputFolder, "R.txt"),
                                    libJavaPackage));

                        }
                    } catch (Exception e) {
                    }
                }
            }

            String proguardFilePath = proguardFile != null ?
                    proguardFile.getLocation().toOSString(): null;

            File resOutFile = resOutFolder.getLocation().toFile();
            String resOutPath = resOutFile.isDirectory() ? resOutFile.getAbsolutePath() : null;

            execAapt(project, projectTarget, osOutputPath, resOutPath, osResPath, osManifestPath,
                    mainPackageFolder, libResFolders, libRFiles, isLibrary, proguardFilePath);
        }
    }

    /**
     * Executes AAPT to generate R.java/Manifest.java
     * @param project the main project
     * @param projectTarget the main project target
     * @param osOutputPath the OS output path for the generated file. This is the source folder, not
     * the package folder.
     * @param osResPath the OS path to the res folder for the main project
     * @param osManifestPath the OS path to the manifest of the main project
     * @param packageFolder the IFolder that will contain the generated file. Unlike
     * <var>osOutputPath</var> this is the direct parent of the generated files.
     * If <var>customJavaPackage</var> is not null, this must match the new destination triggered
     * by its value.
     * @param libResFolders the list of res folders for the library.
     * @param libRFiles a list of R files for the libraries.
     * @param isLibrary if the project is a library project
     * @param proguardFile an optional path to store proguard information
     * @throws AbortBuildException
     */
    @SuppressWarnings("deprecation")
    private void execAapt(IProject project, IAndroidTarget projectTarget, String osOutputPath,
            String osBcOutPath, String osResPath, String osManifestPath, IFolder packageFolder,
            ArrayList<IFolder> libResFolders, List<Pair<File, String>> libRFiles,
            boolean isLibrary, String proguardFile)
            throws AbortBuildException {

        // We actually need to delete the manifest.java as it may become empty and
        // in this case aapt doesn't generate an empty one, but instead doesn't
        // touch it.
        IFile manifestJavaFile = packageFolder.getFile(SdkConstants.FN_MANIFEST_CLASS);
        manifestJavaFile.getLocation().toFile().delete();

        // launch aapt: create the command line
        ArrayList<String> array = new ArrayList<String>();

        String aaptPath = mBuildToolInfo.getPath(BuildToolInfo.PathId.AAPT);

        array.add(aaptPath);
        array.add("package"); //$NON-NLS-1$
        array.add("-m"); //$NON-NLS-1$
        if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
            array.add("-v"); //$NON-NLS-1$
        }

        if (isLibrary) {
            array.add("--non-constant-id"); //$NON-NLS-1$
        }

        if (libResFolders.size() > 0) {
            array.add("--auto-add-overlay"); //$NON-NLS-1$
        }

        // If a library or has libraries, generate a text version of the R symbols.
        File outputFolder = BaseProjectHelper.getAndroidOutputFolder(project).getLocation()
                .toFile();

        if (isLibrary || !libRFiles.isEmpty()) {
            array.add("--output-text-symbols"); //$NON-NLS-1$
            array.add(outputFolder.getAbsolutePath());
        }

        array.add("-J"); //$NON-NLS-1$
        array.add(osOutputPath);
        array.add("-M"); //$NON-NLS-1$
        array.add(osManifestPath);
        if (osBcOutPath != null) {
            array.add("-S"); //$NON-NLS-1$
            array.add(osBcOutPath);
        }
        array.add("-S"); //$NON-NLS-1$
        array.add(osResPath);
        for (IFolder libResFolder : libResFolders) {
            array.add("-S"); //$NON-NLS-1$
            array.add(libResFolder.getLocation().toOSString());
        }

        array.add("-I"); //$NON-NLS-1$
        array.add(projectTarget.getPath(IAndroidTarget.ANDROID_JAR));

        // use the proguard file
        if (proguardFile != null && proguardFile.length() > 0) {
            array.add("-G");
            array.add(proguardFile);
        }

        if (AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE) {
            StringBuilder sb = new StringBuilder();
            for (String c : array) {
                sb.append(c);
                sb.append(' ');
            }
            String cmd_line = sb.toString();
            AdtPlugin.printToConsole(project, cmd_line);
        }

        // launch
        try {
            // launch the command line process
            Process process = Runtime.getRuntime().exec(
                    array.toArray(new String[array.size()]));

            // list to store each line of stderr
            ArrayList<String> stdErr = new ArrayList<String>();

            // get the output and return code from the process
            int returnCode = grabProcessOutput(process, stdErr);

            // attempt to parse the error output
            boolean parsingError = AaptParser.parseOutput(stdErr, project);

            // if we couldn't parse the output we display it in the console.
            if (parsingError) {
                if (returnCode != 0) {
                    AdtPlugin.printErrorToConsole(project, stdErr.toArray());
                } else {
                    AdtPlugin.printBuildToConsole(BuildVerbosity.NORMAL,
                            project, stdErr.toArray());
                }
            }

            if (returnCode != 0) {
                // if the exec failed, and we couldn't parse the error output
                // (and therefore not all files that should have been marked,
                // were marked), we put a generic marker on the project and abort.
                if (parsingError) {
                    markProject(AdtConstants.MARKER_ADT,
                            Messages.Unparsed_AAPT_Errors, IMarker.SEVERITY_ERROR);
                } else if (stdErr.size() == 0) {
                    // no parsing error because sdterr was empty. We still need to put
                    // a marker otherwise there's no user visible feedback.
                    markProject(AdtConstants.MARKER_ADT,
                            String.format(Messages.AAPT_Exec_Error_d, returnCode),
                            IMarker.SEVERITY_ERROR);
                }

                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, project,
                        Messages.AAPT_Error);

                // abort if exec failed.
                throw new AbortBuildException();
            }

            // now if the project has libraries, R needs to be created for each libraries
            // unless this is a library.
            if (isLibrary == false && !libRFiles.isEmpty()) {
                File rFile = new File(outputFolder, SdkConstants.FN_RESOURCE_TEXT);
                // if the project has no resources, the file could not exist.
                if (rFile.isFile()) {
                    // Load the full symbols from the full R.txt file.
                    SymbolLoader fullSymbolValues = new SymbolLoader(rFile);
                    fullSymbolValues.load();

                    Multimap<String, SymbolLoader> libMap = ArrayListMultimap.create();

                    // First pass processing the libraries, collecting them by packageName,
                    // and ignoring the ones that have the same package name as the application
                    // (since that R class was already created).

                    for (Pair<File, String> lib : libRFiles) {
                        String libPackage = lib.getSecond();
                        File rText = lib.getFirst();

                        if (rText.isFile()) {
                            // load the lib symbols
                            SymbolLoader libSymbols = new SymbolLoader(rText);
                            libSymbols.load();

                            // store these symbols by associating them with the package name.
                            libMap.put(libPackage, libSymbols);
                        }
                    }

                    // now loop on all the package names, merge all the symbols to write,
                    // and write them
                    for (String packageName : libMap.keySet()) {
                        Collection<SymbolLoader> symbols = libMap.get(packageName);

                        SymbolWriter writer = new SymbolWriter(osOutputPath, packageName,
                                fullSymbolValues);
                        for (SymbolLoader symbolLoader : symbols) {
                            writer.addSymbolsToWrite(symbolLoader);
                        }
                        writer.write();
                    }
                }
            }

        } catch (IOException e1) {
            // something happen while executing the process,
            // mark the project and exit
            String msg;
            String path = array.get(0);
            if (!new File(path).exists()) {
                msg = String.format(Messages.AAPT_Exec_Error_s, path);
            } else {
                String description = e1.getLocalizedMessage();
                if (e1.getCause() != null && e1.getCause() != e1) {
                    description = description + ": " + e1.getCause().getLocalizedMessage();
                }
                msg = String.format(Messages.AAPT_Exec_Error_Other_s, description);
            }

            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);

            // Add workaround for the Linux problem described here:
            //    http://developer.android.com/sdk/installing.html#troubleshooting
            // There are various posts on StackOverflow elsewhere where people are asking
            // about aapt failing to run, so even though this is documented in the
            // Troubleshooting section add an error message to help with this
            // scenario.
            if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX
                    && System.getProperty("os.arch").endsWith("64") //$NON-NLS-1$ //$NON-NLS-2$
                    && new File(aaptPath).exists()
                    && new File("/usr/bin/apt-get").exists()) {     //$NON-NLS-1$
                markProject(AdtConstants.MARKER_ADT,
                        "Hint: On 64-bit systems, make sure the 32-bit libraries are installed: \"sudo apt-get install ia32-libs\" or on some systems, \"sudo apt-get install lib32z1\"",
                        IMarker.SEVERITY_ERROR);
                // Note - this uses SEVERITY_ERROR even though it's really SEVERITY_INFO because
                // we want this error message to show up adjacent to the aapt error message
                // (and Eclipse sorts by priority)
            }

            // This interrupts the build.
            throw new AbortBuildException();
        } catch (InterruptedException e) {
            // we got interrupted waiting for the process to end...
            // mark the project and exit
            String msg = String.format(Messages.AAPT_Exec_Error_s, array.get(0));
            markProject(AdtConstants.MARKER_ADT, msg, IMarker.SEVERITY_ERROR);

            // This interrupts the build.
            throw new AbortBuildException();
        } finally {
            // we've at least attempted to run aapt, save the fact that we don't have to
            // run it again, unless there's a new resource change.
            saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES,
                    mMustCompileResources = false);
            ResourceManager.clearAaptRequest(project);
        }
    }

    /**
     * Creates a relative {@link IPath} from a java package.
     * @param javaPackageName the java package.
     */
    private IPath getJavaPackagePath(String javaPackageName) {
        // convert the java package into path
        String[] segments = javaPackageName.split(AdtConstants.RE_DOT);

        StringBuilder path = new StringBuilder();
        for (String s : segments) {
           path.append(AdtConstants.WS_SEP_CHAR);
           path.append(s);
        }

        return new Path(path.toString());
    }

    /**
     * Returns an {@link IFolder} (located inside the 'gen' source folder), that matches the
     * package defined in the manifest. This {@link IFolder} may not actually exist
     * (aapt will create it anyway).
     * @return the {@link IFolder} that will contain the R class or null if
     * the folder was not found.
     * @throws CoreException
     */
    private IFolder getGenManifestPackageFolder() throws CoreException {
        // get the path for the package
        IPath packagePath = getJavaPackagePath(mManifestPackage);

        // get a folder for this path under the 'gen' source folder, and return it.
        // This IFolder may not reference an actual existing folder.
        return mGenFolder.getFolder(packagePath);
    }
}
