/*
 * 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.project;

import com.android.SdkConstants;
import com.android.ide.common.sdk.LoadStatus;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
import com.google.common.collect.Maps;
import com.google.common.io.Closeables;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.osgi.framework.Bundle;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Classpath container initializer responsible for binding {@link AndroidClasspathContainer} to
 * {@link IProject}s. This removes the hard-coded path to the android.jar.
 */
public class AndroidClasspathContainerInitializer extends BaseClasspathContainerInitializer {

    public static final String NULL_API_URL = "<null>"; //$NON-NLS-1$

    public static final String SOURCES_ZIP = "/sources.zip"; //$NON-NLS-1$

    public static final String COM_ANDROID_IDE_ECLIPSE_ADT_SOURCE =
        "com.android.ide.eclipse.source"; //$NON-NLS-1$

    private static final String ANDROID_API_REFERENCE =
        "http://developer.android.com/reference/"; //$NON-NLS-1$

    private final static String PROPERTY_ANDROID_API = "androidApi"; //$NON-NLS-1$

    private final static String PROPERTY_ANDROID_SOURCE = "androidSource"; //$NON-NLS-1$

    /** path separator to store multiple paths in a single property. This is guaranteed to not
     * be in a path.
     */
    private final static String PATH_SEPARATOR = "\u001C"; //$NON-NLS-1$

    private final static String PROPERTY_CONTAINER_CACHE = "androidContainerCache"; //$NON-NLS-1$
    private final static String PROPERTY_TARGET_NAME = "androidTargetCache"; //$NON-NLS-1$
    private final static String CACHE_VERSION = "01"; //$NON-NLS-1$
    private final static String CACHE_VERSION_SEP = CACHE_VERSION + PATH_SEPARATOR;

    private final static int CACHE_INDEX_JAR = 0;
    private final static int CACHE_INDEX_SRC = 1;
    private final static int CACHE_INDEX_DOCS_URI = 2;
    private final static int CACHE_INDEX_OPT_DOCS_URI = 3;
    private final static int CACHE_INDEX_ADD_ON_START = CACHE_INDEX_OPT_DOCS_URI;

    public AndroidClasspathContainerInitializer() {
        // pass
    }

    /**
     * Binds a classpath container  to a {@link IClasspathContainer} for a given project,
     * or silently fails if unable to do so.
     * @param containerPath the container path that is the container id.
     * @param project the project to bind
     */
    @Override
    public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
        if (AdtConstants.CONTAINER_FRAMEWORK.equals(containerPath.toString())) {
            IClasspathContainer container = allocateAndroidContainer(project);
            if (container != null) {
                JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_FRAMEWORK),
                        new IJavaProject[] { project },
                        new IClasspathContainer[] { container },
                        new NullProgressMonitor());
            }
        }
    }

    /**
     * Updates the {@link IJavaProject} objects with new android framework container. This forces
     * JDT to recompile them.
     * @param androidProjects the projects to update.
     * @return <code>true</code> if success, <code>false</code> otherwise.
     */
    static boolean updateProjects(IJavaProject[] androidProjects) {
        try {
            // Allocate a new AndroidClasspathContainer, and associate it to the android framework
            // container id for each projects.
            // By providing a new association between a container id and a IClasspathContainer,
            // this forces the JDT to query the IClasspathContainer for new IClasspathEntry (with
            // IClasspathContainer#getClasspathEntries()), and therefore force recompilation of
            // the projects.
            int projectCount = androidProjects.length;

            IClasspathContainer[] containers = new IClasspathContainer[projectCount];
            for (int i = 0 ; i < projectCount; i++) {
                containers[i] = allocateAndroidContainer(androidProjects[i]);
            }

            // give each project their new container in one call.
            JavaCore.setClasspathContainer(
                    new Path(AdtConstants.CONTAINER_FRAMEWORK),
                    androidProjects, containers, new NullProgressMonitor());

            return true;
        } catch (JavaModelException e) {
            return false;
        }
    }

    /**
     * Allocates and returns an {@link AndroidClasspathContainer} object with the proper
     * path to the framework jar file.
     * @param javaProject The java project that will receive the container.
     */
    private static IClasspathContainer allocateAndroidContainer(IJavaProject javaProject) {
        final IProject iProject = javaProject.getProject();

        String markerMessage = null;
        boolean outputToConsole = true;
        IAndroidTarget target = null;

        try {
            AdtPlugin plugin = AdtPlugin.getDefault();
            if (plugin == null) { // This is totally weird, but I've seen it happen!
                return null;
            }

            synchronized (Sdk.getLock()) {
                boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED;

                // check if the project has a valid target.
                ProjectState state = Sdk.getProjectState(iProject);
                if (state == null) {
                    // looks like the project state (project.properties) couldn't be read!
                    markerMessage = String.format(
                            "Project has no %1$s file! Edit the project properties to set one.",
                            SdkConstants.FN_PROJECT_PROPERTIES);
                } else {
                    // this might be null if the sdk is not yet loaded.
                    target = state.getTarget();

                    // if we are loaded and the target is non null, we create a valid
                    // ClassPathContainer
                    if (sdkIsLoaded && target != null) {
                        // check the renderscript support mode. If support mode is enabled,
                        // target API must be 18+
                        if (!state.getRenderScriptSupportMode() ||
                                target.getVersion().getApiLevel() >= 18) {
                            // first make sure the target has loaded its data
                            Sdk.getCurrent().checkAndLoadTargetData(target, null /*project*/);

                            String targetName = target.getClasspathName();

                            return new AndroidClasspathContainer(
                                    createClasspathEntries(iProject, target, targetName),
                                    new Path(AdtConstants.CONTAINER_FRAMEWORK),
                                    targetName,
                                    IClasspathContainer.K_DEFAULT_SYSTEM);
                        } else {
                            markerMessage = "Renderscript support mode requires compilation target API to be 18+.";
                        }
                    } else {
                        // In case of error, we'll try different thing to provide the best error message
                        // possible.
                        // Get the project's target's hash string (if it exists)
                        String hashString = state.getTargetHashString();

                        if (hashString == null || hashString.length() == 0) {
                            // if there is no hash string we only show this if the SDK is loaded.
                            // For a project opened at start-up with no target, this would be displayed
                            // twice, once when the project is opened, and once after the SDK has
                            // finished loading.
                            // By testing the sdk is loaded, we only show this once in the console.
                            if (sdkIsLoaded) {
                                markerMessage = String.format(
                                        "Project has no target set. Edit the project properties to set one.");
                            }
                        } else if (sdkIsLoaded) {
                            markerMessage = String.format(
                                    "Unable to resolve target '%s'", hashString);
                        } else {
                            // this is the case where there is a hashString but the SDK is not yet
                            // loaded and therefore we can't get the target yet.
                            // We check if there is a cache of the needed information.
                            AndroidClasspathContainer container = getContainerFromCache(iProject,
                                    target);

                            if (container == null) {
                                // either the cache was wrong (ie folder does not exists anymore), or
                                // there was no cache. In this case we need to make sure the project
                                // is resolved again after the SDK is loaded.
                                plugin.setProjectToResolve(javaProject);

                                markerMessage = String.format(
                                        "Unable to resolve target '%s' until the SDK is loaded.",
                                        hashString);

                                // let's not log this one to the console as it will happen at
                                // every boot, and it's expected. (we do keep the error marker though).
                                outputToConsole = false;

                            } else {
                                // we created a container from the cache, so we register the project
                                // to be checked for cache validity once the SDK is loaded
                                plugin.setProjectToCheck(javaProject);

                                // and return the container
                                return container;
                            }
                        }
                    }
                }

                // return a dummy container to replace the one we may have had before.
                // It'll be replaced by the real when if/when the target is resolved if/when the
                // SDK finishes loading.
                return new IClasspathContainer() {
                    @Override
                    public IClasspathEntry[] getClasspathEntries() {
                        return new IClasspathEntry[0];
                    }

                    @Override
                    public String getDescription() {
                        return "Unable to get system library for the project";
                    }

                    @Override
                    public int getKind() {
                        return IClasspathContainer.K_DEFAULT_SYSTEM;
                    }

                    @Override
                    public IPath getPath() {
                        return null;
                    }
                };
            }
        } finally {
           processError(iProject, markerMessage, AdtConstants.MARKER_TARGET, outputToConsole);
        }
    }

    /**
     * Creates and returns an array of {@link IClasspathEntry} objects for the android
     * framework and optional libraries.
     * <p/>This references the OS path to the android.jar and the
     * java doc directory. This is dynamically created when a project is opened,
     * and never saved in the project itself, so there's no risk of storing an
     * obsolete path.
     * The method also stores the paths used to create the entries in the project persistent
     * properties. A new {@link AndroidClasspathContainer} can be created from the stored path
     * using the {@link #getContainerFromCache(IProject)} method.
     * @param project
     * @param target The target that contains the libraries.
     * @param targetName
     */
    private static IClasspathEntry[] createClasspathEntries(IProject project,
            IAndroidTarget target, String targetName) {

        // get the path from the target
        String[] paths = getTargetPaths(target);

        // create the classpath entry from the paths
        IClasspathEntry[] entries = createClasspathEntriesFromPaths(paths, target);

        // paths now contains all the path required to recreate the IClasspathEntry with no
        // target info. We encode them in a single string, with each path separated by
        // OS path separator.
        StringBuilder sb = new StringBuilder(CACHE_VERSION);
        for (String p : paths) {
            sb.append(PATH_SEPARATOR);
            sb.append(p);
        }

        // store this in a project persistent property
        ProjectHelper.saveStringProperty(project, PROPERTY_CONTAINER_CACHE, sb.toString());
        ProjectHelper.saveStringProperty(project, PROPERTY_TARGET_NAME, targetName);

        return entries;
    }

    /**
     * Generates an {@link AndroidClasspathContainer} from the project cache, if possible.
     */
    private static AndroidClasspathContainer getContainerFromCache(IProject project,
            IAndroidTarget target) {
        // get the cached info from the project persistent properties.
        String cache = ProjectHelper.loadStringProperty(project, PROPERTY_CONTAINER_CACHE);
        String targetNameCache = ProjectHelper.loadStringProperty(project, PROPERTY_TARGET_NAME);
        if (cache == null || targetNameCache == null) {
            return null;
        }

        // the first 2 chars must match CACHE_VERSION. The 3rd char is the normal separator.
        if (cache.startsWith(CACHE_VERSION_SEP) == false) {
            return null;
        }

        cache = cache.substring(CACHE_VERSION_SEP.length());

        // the cache contains multiple paths, separated by a character guaranteed to not be in
        // the path (\u001C).
        // The first 3 are for android.jar (jar, source, doc), the rest are for the optional
        // libraries and should contain at least one doc and a jar (if there are any libraries).
        // Therefore, the path count should be 3 or 5+
        String[] paths = cache.split(Pattern.quote(PATH_SEPARATOR));
        if (paths.length < 3 || paths.length == 4) {
            return null;
        }

        // now we check the paths actually exist.
        // There's an exception: If the source folder for android.jar does not exist, this is
        // not a problem, so we skip it.
        // Also paths[CACHE_INDEX_DOCS_URI] is a URI to the javadoc, so we test it a
        // bit differently.
        try {
            if (new File(paths[CACHE_INDEX_JAR]).exists() == false ||
                    new File(new URI(paths[CACHE_INDEX_DOCS_URI])).exists() == false) {
                return null;
            }

            // check the path for the add-ons, if they exist.
            if (paths.length > CACHE_INDEX_ADD_ON_START) {

                // check the docs path separately from the rest of the paths as it's a URI.
                if (new File(new URI(paths[CACHE_INDEX_OPT_DOCS_URI])).exists() == false) {
                    return null;
                }

                // now just check the remaining paths.
                for (int i = CACHE_INDEX_ADD_ON_START + 1; i < paths.length; i++) {
                    String path = paths[i];
                    if (path.length() > 0) {
                        File f = new File(path);
                        if (f.exists() == false) {
                            return null;
                        }
                    }
                }
            }
        } catch (URISyntaxException e) {
            return null;
        }

        IClasspathEntry[] entries = createClasspathEntriesFromPaths(paths, target);

        return new AndroidClasspathContainer(entries,
                new Path(AdtConstants.CONTAINER_FRAMEWORK),
                targetNameCache, IClasspathContainer.K_DEFAULT_SYSTEM);
    }

    /**
     * Generates an array of {@link IClasspathEntry} from a set of paths.
     * @see #getTargetPaths(IAndroidTarget)
     */
    private static IClasspathEntry[] createClasspathEntriesFromPaths(String[] paths,
            IAndroidTarget target) {
        ArrayList<IClasspathEntry> list = new ArrayList<IClasspathEntry>();

        // First, we create the IClasspathEntry for the framework.
        // now add the android framework to the class path.
        // create the path object.
        IPath androidLib = new Path(paths[CACHE_INDEX_JAR]);

        IPath androidSrc = null;
        String androidSrcOsPath = null;
        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        if (target != null) {
            androidSrcOsPath =
                ProjectHelper.loadStringProperty(root, getAndroidSourceProperty(target));
        }
        if (androidSrcOsPath != null && androidSrcOsPath.trim().length() > 0) {
            androidSrc = new Path(androidSrcOsPath);
        }
        if (androidSrc == null) {
            androidSrc = new Path(paths[CACHE_INDEX_SRC]);
            File androidSrcFile = new File(paths[CACHE_INDEX_SRC]);
            if (!androidSrcFile.isDirectory()) {
                androidSrc = null;
            }
        }

        if (androidSrc == null && target != null) {
            Bundle bundle = getSourceBundle();

            if (bundle != null) {
                AndroidVersion version = target.getVersion();
                String apiString = version.getApiString();
                String sourcePath = apiString + SOURCES_ZIP;
                URL sourceURL = bundle.getEntry(sourcePath);
                if (sourceURL != null) {
                    URL url = null;
                    try {
                        url = FileLocator.resolve(sourceURL);
                    } catch (IOException ignore) {
                    }
                    if (url != null) {
                        androidSrcOsPath = url.getFile();
                        if (new File(androidSrcOsPath).isFile()) {
                            androidSrc = new Path(androidSrcOsPath);
                        }
                    }
                }
            }
        }

        // create the java doc link.
        String androidApiURL = ProjectHelper.loadStringProperty(root, PROPERTY_ANDROID_API);
        String apiURL = null;
        if (androidApiURL != null && testURL(androidApiURL)) {
            apiURL = androidApiURL;
        } else {
            if (testURL(paths[CACHE_INDEX_DOCS_URI])) {
                apiURL = paths[CACHE_INDEX_DOCS_URI];
            } else if (testURL(ANDROID_API_REFERENCE)) {
                apiURL = ANDROID_API_REFERENCE;
            }
        }

        IClasspathAttribute[] attributes = null;
        if (apiURL != null && !NULL_API_URL.equals(apiURL)) {
            IClasspathAttribute cpAttribute = JavaCore.newClasspathAttribute(
                    IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, apiURL);
            attributes = new IClasspathAttribute[] {
                cpAttribute
            };
        }
        // create the access rule to restrict access to classes in
        // com.android.internal
        IAccessRule accessRule = JavaCore.newAccessRule(new Path("com/android/internal/**"), //$NON-NLS-1$
                IAccessRule.K_NON_ACCESSIBLE);

        IClasspathEntry frameworkClasspathEntry = JavaCore.newLibraryEntry(androidLib,
                androidSrc, // source attachment path
                null, // default source attachment root path.
                new IAccessRule[] { accessRule },
                attributes,
                false // not exported.
                );

        list.add(frameworkClasspathEntry);

        // now deal with optional libraries
        if (paths.length >= 5) {
            String docPath = paths[CACHE_INDEX_OPT_DOCS_URI];
            int i = 4;
            while (i < paths.length) {
                Path jarPath = new Path(paths[i++]);

                attributes = null;
                if (docPath.length() > 0) {
                    attributes = new IClasspathAttribute[] {
                        JavaCore.newClasspathAttribute(
                                IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, docPath)
                    };
                }

                IClasspathEntry entry = JavaCore.newLibraryEntry(
                        jarPath,
                        null, // source attachment path
                        null, // default source attachment root path.
                        null,
                        attributes,
                        false // not exported.
                        );
                list.add(entry);
            }
        }

        if (apiURL != null) {
            ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API, apiURL);
        }
        if (androidSrc != null && target != null) {
            ProjectHelper.saveStringProperty(root, getAndroidSourceProperty(target),
                    androidSrc.toOSString());
        }
        return list.toArray(new IClasspathEntry[list.size()]);
    }

    private static Bundle getSourceBundle() {
        String bundleId = System.getProperty(COM_ANDROID_IDE_ECLIPSE_ADT_SOURCE,
                COM_ANDROID_IDE_ECLIPSE_ADT_SOURCE);
        Bundle bundle = Platform.getBundle(bundleId);
        return bundle;
    }

    private static String getAndroidSourceProperty(IAndroidTarget target) {
        if (target == null) {
            return null;
        }
        String androidSourceProperty = PROPERTY_ANDROID_SOURCE + "_"
                + target.getVersion().getApiString();
        return androidSourceProperty;
    }

    /**
     * Cache results for testURL: Some are expensive to compute, and this is
     * called repeatedly (perhaps for each open project)
     */
    private static final Map<String, Boolean> sRecentUrlValidCache =
            Maps.newHashMapWithExpectedSize(4);

    @SuppressWarnings("resource") // Eclipse does not handle Closeables#closeQuietly
    private static boolean testURL(String androidApiURL) {
        Boolean cached = sRecentUrlValidCache.get(androidApiURL);
        if (cached != null) {
            return cached.booleanValue();
        }
        boolean valid = false;
        InputStream is = null;
        try {
            URL testURL = new URL(androidApiURL);
            URLConnection connection = testURL.openConnection();
            // Only try for 5 seconds (though some implementations ignore this flag)
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            is = connection.getInputStream();
            valid = true;
        } catch (Exception ignore) {
        } finally {
            Closeables.closeQuietly(is);
        }

        sRecentUrlValidCache.put(androidApiURL, valid);

        return valid;
    }

    /**
     * Checks the projects' caches. If the cache was valid, the project is removed from the list.
     * @param projects the list of projects to check.
     */
    public static void checkProjectsCache(ArrayList<IJavaProject> projects) {
        Sdk currentSdk = Sdk.getCurrent();
        int i = 0;
        projectLoop: while (i < projects.size()) {
            IJavaProject javaProject = projects.get(i);
            IProject iProject = javaProject.getProject();

            // check if the project is opened
            if (iProject.isOpen() == false) {
                // remove from the list
                // we do not increment i in this case.
                projects.remove(i);

                continue;
            }

            // project that have been resolved before the sdk was loaded
            // will have a ProjectState where the IAndroidTarget is null
            // so we load the target now that the SDK is loaded.
            IAndroidTarget target = currentSdk.loadTargetAndBuildTools(
                    Sdk.getProjectState(iProject));
            if (target == null) {
                // this is really not supposed to happen. This would mean there are cached paths,
                // but project.properties was deleted. Keep the project in the list to force
                // a resolve which will display the error.
                i++;
                continue;
            }

            String[] targetPaths = getTargetPaths(target);

            // now get the cached paths
            String cache = ProjectHelper.loadStringProperty(iProject, PROPERTY_CONTAINER_CACHE);
            if (cache == null) {
                // this should not happen. We'll force resolve again anyway.
                i++;
                continue;
            }

            String[] cachedPaths = cache.split(Pattern.quote(PATH_SEPARATOR));
            if (cachedPaths.length < 3 || cachedPaths.length == 4) {
                // paths length is wrong. simply resolve the project again
                i++;
                continue;
            }

            // Now we compare the paths. The first 4 can be compared directly.
            // because of case sensitiveness we need to use File objects

            if (targetPaths.length != cachedPaths.length) {
                // different paths, force resolve again.
                i++;
                continue;
            }

            // compare the main paths (android.jar, main sources, main javadoc)
            if (new File(targetPaths[CACHE_INDEX_JAR]).equals(
                            new File(cachedPaths[CACHE_INDEX_JAR])) == false ||
                    new File(targetPaths[CACHE_INDEX_SRC]).equals(
                            new File(cachedPaths[CACHE_INDEX_SRC])) == false ||
                    new File(targetPaths[CACHE_INDEX_DOCS_URI]).equals(
                            new File(cachedPaths[CACHE_INDEX_DOCS_URI])) == false) {
                // different paths, force resolve again.
                i++;
                continue;
            }

            if (cachedPaths.length > CACHE_INDEX_OPT_DOCS_URI) {
                // compare optional libraries javadoc
                if (new File(targetPaths[CACHE_INDEX_OPT_DOCS_URI]).equals(
                        new File(cachedPaths[CACHE_INDEX_OPT_DOCS_URI])) == false) {
                    // different paths, force resolve again.
                    i++;
                    continue;
                }

                // testing the optional jar files is a little bit trickier.
                // The order is not guaranteed to be identical.
                // From a previous test, we do know however that there is the same number.
                // The number of libraries should be low enough that we can simply go through the
                // lists manually.
                targetLoop: for (int tpi = 4 ; tpi < targetPaths.length; tpi++) {
                    String targetPath = targetPaths[tpi];

                    // look for a match in the other array
                    for (int cpi = 4 ; cpi < cachedPaths.length; cpi++) {
                        if (new File(targetPath).equals(new File(cachedPaths[cpi]))) {
                            // found a match. Try the next targetPath
                            continue targetLoop;
                        }
                    }

                    // if we stop here, we haven't found a match, which means there's a
                    // discrepancy in the libraries. We force a resolve.
                    i++;
                    continue projectLoop;
                }
            }

            // at the point the check passes, and we can remove the project from the list.
            // we do not increment i in this case.
            projects.remove(i);
        }
    }

    /**
     * Returns the paths necessary to create the {@link IClasspathEntry} for this targets.
     * <p/>The paths are always in the same order.
     * <ul>
     * <li>Path to android.jar</li>
     * <li>Path to the source code for android.jar</li>
     * <li>Path to the javadoc for the android platform</li>
     * </ul>
     * Additionally, if there are optional libraries, the array will contain:
     * <ul>
     * <li>Path to the libraries javadoc</li>
     * <li>Path to the first .jar file</li>
     * <li>(more .jar as needed)</li>
     * </ul>
     */
    private static String[] getTargetPaths(IAndroidTarget target) {
        ArrayList<String> paths = new ArrayList<String>();

        // first, we get the path for android.jar
        // The order is: android.jar, source folder, docs folder
        paths.add(target.getPath(IAndroidTarget.ANDROID_JAR));
        paths.add(target.getPath(IAndroidTarget.SOURCES));
        paths.add(AdtPlugin.getUrlDoc());

        // now deal with optional libraries.
        IOptionalLibrary[] libraries = target.getOptionalLibraries();
        if (libraries != null) {
            // all the optional libraries use the same javadoc, so we start with this
            String targetDocPath = target.getPath(IAndroidTarget.DOCS);
            if (targetDocPath != null) {
                paths.add(ProjectHelper.getJavaDocPath(targetDocPath));
            } else {
                // we add an empty string, to always have the same count.
                paths.add("");
            }

            // because different libraries could use the same jar file, we make sure we add
            // each jar file only once.
            HashSet<String> visitedJars = new HashSet<String>();
            for (IOptionalLibrary library : libraries) {
                String jarPath = library.getJarPath();
                if (visitedJars.contains(jarPath) == false) {
                    visitedJars.add(jarPath);
                    paths.add(jarPath);
                }
            }
        }

        return paths.toArray(new String[paths.size()]);
    }

    @Override
    public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
        return true;
    }

    @Override
    public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project,
            IClasspathContainer containerSuggestion) throws CoreException {
        AdtPlugin plugin = AdtPlugin.getDefault();

        synchronized (Sdk.getLock()) {
            boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED;

            // check if the project has a valid target.
            IAndroidTarget target = null;
            if (sdkIsLoaded) {
                target = Sdk.getCurrent().getTarget(project.getProject());
            }
            if (sdkIsLoaded && target != null) {
                String[] paths = getTargetPaths(target);
                IPath android_lib = new Path(paths[CACHE_INDEX_JAR]);
                IClasspathEntry[] entries = containerSuggestion.getClasspathEntries();
                for (int i = 0; i < entries.length; i++) {
                    IClasspathEntry entry = entries[i];
                    if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                        IPath entryPath = entry.getPath();

                        if (entryPath != null) {
                            if (entryPath.equals(android_lib)) {
                                IPath entrySrcPath = entry.getSourceAttachmentPath();
                                IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
                                if (entrySrcPath != null) {
                                    ProjectHelper.saveStringProperty(root,
                                            getAndroidSourceProperty(target),
                                            entrySrcPath.toString());
                                } else {
                                    ProjectHelper.saveStringProperty(root,
                                            getAndroidSourceProperty(target), null);
                                }
                                IClasspathAttribute[] extraAttributtes = entry.getExtraAttributes();
                                if (extraAttributtes.length == 0) {
                                    ProjectHelper.saveStringProperty(root, PROPERTY_ANDROID_API,
                                            NULL_API_URL);
                                }
                                for (int j = 0; j < extraAttributtes.length; j++) {
                                    IClasspathAttribute extraAttribute = extraAttributtes[j];
                                    String value = extraAttribute.getValue();
                                    if ((value == null || value.trim().length() == 0)
                                            && IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME
                                                    .equals(extraAttribute.getName())) {
                                        value = NULL_API_URL;
                                    }
                                    if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME
                                            .equals(extraAttribute.getName())) {
                                        ProjectHelper.saveStringProperty(root,
                                                PROPERTY_ANDROID_API, value);

                                    }
                                }
                            }
                        }
                    }
                }
                rebindClasspathEntries(project.getJavaModel(), containerPath);
            }
        }
    }

    private static void rebindClasspathEntries(IJavaModel model, IPath containerPath)
            throws JavaModelException {
        ArrayList<IJavaProject> affectedProjects = new ArrayList<IJavaProject>();

        IJavaProject[] projects = model.getJavaProjects();
        for (int i = 0; i < projects.length; i++) {
            IJavaProject project = projects[i];
            IClasspathEntry[] entries = project.getRawClasspath();
            for (int k = 0; k < entries.length; k++) {
                IClasspathEntry curr = entries[k];
                if (curr.getEntryKind() == IClasspathEntry.CPE_CONTAINER
                        && containerPath.equals(curr.getPath())) {
                    affectedProjects.add(project);
                }
            }
        }
        if (!affectedProjects.isEmpty()) {
            IJavaProject[] affected = affectedProjects
                    .toArray(new IJavaProject[affectedProjects.size()]);
            updateProjects(affected);
        }
    }
}
