/*
 * Copyright (c) 2012, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.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/legal/epl-v10.html
 * 
 * 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.google.dart.tools.core;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.dart.engine.AnalysisEngine;
import com.google.dart.engine.error.ErrorCode;
import com.google.dart.engine.index.Index;
import com.google.dart.engine.index.IndexFactory;
import com.google.dart.engine.index.IndexStore;
import com.google.dart.engine.sdk.DirectoryBasedDartSdk;
import com.google.dart.engine.utilities.instrumentation.Instrumentation;
import com.google.dart.engine.utilities.instrumentation.InstrumentationBuilder;
import com.google.dart.engine.utilities.logging.Logger;
import com.google.dart.server.generated.AnalysisServer;
import com.google.dart.server.generated.types.RequestError;
import com.google.dart.server.generated.types.ServerService;
import com.google.dart.server.internal.remote.DebugPrintStream;
import com.google.dart.server.internal.remote.FileReadMode;
import com.google.dart.server.internal.remote.RemoteAnalysisServerImpl;
import com.google.dart.server.internal.remote.StdioServerSocket;
import com.google.dart.server.utilities.logging.Logging;
import com.google.dart.tools.core.analysis.model.AnalysisServerData;
import com.google.dart.tools.core.analysis.model.ProjectManager;
import com.google.dart.tools.core.analysis.model.PubFolder;
import com.google.dart.tools.core.internal.MessageConsoleImpl;
import com.google.dart.tools.core.internal.OptionManager;
import com.google.dart.tools.core.internal.analysis.model.AnalysisServerDataImpl;
import com.google.dart.tools.core.internal.analysis.model.DartProjectManager;
import com.google.dart.tools.core.internal.analysis.model.ProjectManagerImpl;
import com.google.dart.tools.core.internal.analysis.model.WorkspaceAnalysisServerListener;
import com.google.dart.tools.core.internal.builder.AnalysisMarkerManager;
import com.google.dart.tools.core.internal.model.DartIgnoreManager;
import com.google.dart.tools.core.internal.model.DartProjectNature;
import com.google.dart.tools.core.internal.util.Extensions;
import com.google.dart.tools.core.internal.util.ResourceUtil;
import com.google.dart.tools.core.internal.util.Util;
import com.google.dart.tools.core.jobs.CleanLibrariesJob;
import com.google.dart.tools.core.model.DartIgnoreListener;
import com.google.dart.tools.core.model.DartSdkListener;
import com.google.dart.tools.core.model.DartSdkManager;
import com.google.dart.tools.core.pub.PubCacheManager_NEW;
import com.google.dart.tools.core.utilities.general.StringUtilities;
import com.google.dart.tools.core.utilities.io.FileUtilities;
import com.google.dart.tools.core.utilities.performance.PerformanceManager;
import com.google.dart.tools.core.utilities.yaml.PubYamlUtils;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.resources.IContainer;
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.IResourceVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
import org.osgi.service.prefs.BackingStoreException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;

/**
 * The class <code>DartCore</code> is used to access the elements modeling projects that have a Dart
 * nature.
 * 
 * @coverage dart.tools.core
 */
public class DartCore extends Plugin implements DartSdkListener {

  /**
   * The unique instance of this class.
   */
  private static DartCore PLUG_IN;

  /**
   * The log used by {@link #logError(String)} and other local methods for logging errors, warnings,
   * and information or <code>null</code> to use the default system log.
   */
  private static ILog PLUGIN_LOG;

  /**
   * Flag indicating whether instrumentation logging of errors is enabled
   */
  private static boolean instrumentationLogErrorEnabled = true;

  /**
   * The id of the plug-in that defines the Dart model.
   */
  public static final String PLUGIN_ID = DartCore.class.getPackage().getName();

  /**
   * Name of file containing user-defined properties.
   */
  public static final String EDITOR_PROPERTIES = "editor.properties";

  /**
   * The id of the project nature used for Dart projects.
   */
  public static final String DART_PROJECT_NATURE = PLUGIN_ID + ".dartNature";

  /**
   * The id of the builder used for Dart projects.
   */
  public static final String DART_BUILDER_ID = PLUGIN_ID + ".dartBuilder";

  /**
   * The id of the content type used to represent Dart compilation units.
   */
  public static final String DART_SOURCE_CONTENT_TYPE = PLUGIN_ID + ".dartSourceFile";

  /**
   * Eclipse problem marker type used to display Dart compilation errors.
   */
  public static final String DART_PROBLEM_MARKER_TYPE = PLUGIN_ID + ".problem";

  /**
   * Eclipse problem marker type used to display Dart hints.
   */
  public static final String DART_HINT_MARKER_TYPE = PLUGIN_ID + ".hint";

  /**
   * Eclipse problem marker type used to display todo markers.
   */
  public static final String DART_TASK_MARKER_TYPE = PLUGIN_ID + ".task";

  /**
   * Eclipse problem marker type used to Angular warning markers
   */
  public static final String ANGULAR_WARNING_MARKER_TYPE = PLUGIN_ID + ".angular_warning";

  /**
   * Correction marker attribute.
   */
  public static final String MARKER_ATTR_CORRECTION = "correction";

  /**
   * Extension for single unit compiled into JavaScript.
   */
  public static final String EXTENSION_JS = "js";

  /**
   * Preference for the automatically running pub.
   */
  public static final String PUB_AUTO_RUN_PREFERENCE = "pubAutoRun";

  /**
   * Preference for enabling hints.
   */
  public static final String ENABLE_HINTS_PREFERENCE = "enableHints";

  /**
   * Preference for enabling lints.
   */
  public static final String ENABLE_LINTS_PREFERENCE = "enableLints";

  /**
   * Preference for enabling dart2js related hints.
   */
  public static final String ENABLE_HINTS_DART2JS_PREFERENCE = "enableHints_dart2js";

  public static final String PROJECT_PREF_PACKAGE_ROOT = "projectPackageRoot";

  /**
   * Project package root for VM launches
   */
  public static final String PROJECT_PREF_VM_PACKAGE_ROOT = "projectVmPackageRoot";

  public static final String PREFS_DART2JS_FLAGS = "dart2jsFlags";

  /**
   * Preference for specifying location of the Dart SDK.
   */
  public static final String PREFS_SDK_LOCATION = "sdkLocation";

  /**
   * Preference for specifying location of Dartium
   */
  public static final String PREFS_DARTIUM_LOCATION = "dartiumLocation";

  /**
   * Preference to control if "not a member" warnings should be reported for inferred types.
   */
  public static final String TYPE_CHECKS_FOR_INFERRED_TYPES = "typeChecksForInferredTypes";

  public static final String PROJECT_PREF_DISABLE_DART_BASED_BUILDER = "disableDartBasedBuilder";

  /**
   * Preference for enabling usage collection
   */
  public static final String PREFS_ENABLE_ANALYTICS = "enableAnalytics";

  public static final String PREFS_SHOW_ANALYTICS_DIALOG = "showAnalyticsDialog";

  // white listed dirs that can be used for pub build
  public static final List<String> pubDirectories = Arrays.asList(
      "assest",
      "benchmark",
      "bin",
      "example",
      "test",
      "web");

  /**
   * Cached extensions for CSS files.
   */
  private static final String[] CSS_FILE_EXTENSIONS = {"css"};

  /**
   * Cached extensions for HTML files.
   */
  private static final String[] HTML_FILE_EXTENSIONS = {"html", "htm"};

  /**
   * Cached extensions for JS files.
   */
  private static final String[] JS_FILE_EXTENSIONS = {"js"};

  /**
   * Cached extensions for TXT files.
   */
  private static final String[] TXT_FILE_EXTENSIONS = {"txt"};

  /**
   * Cached extensions for files that are generated by the dartc compiler.
   */
  private static final String[] DART_GENERATED_FILE_EXTENSIONS = {"api", "deps", "js", "map"};

  /**
   * Cached extensions for image files.
   */
  public static final String[] IMAGE_FILE_EXTENSIONS = {
      "bmp", "gif", "jpeg", "jpg", "png", "raw", "thm", "tif", "tiff"};

  /**
   * Name of directory for packages installed by pub
   */
  public static final String PACKAGES_DIRECTORY_NAME = "packages";

  /**
   * Name of directory for build artifacts generated by pub
   */
  public static final String BUILD_DIRECTORY_NAME = "build";

  /**
   * Name of "lib" directory in package
   */
  public static final String LIB_DIRECTORY_NAME = "lib";

  /**
   * Path string for packages directory, uses "/" as path separator, equals "/packages/".
   */
  public static final String PACKAGES_DIRECTORY_PATH = "/" + PACKAGES_DIRECTORY_NAME + "/";

  /**
   * Path string for packages directory in a url.
   */
  public static final String PACKAGES_DIRECTORY_URL = "/" + PACKAGES_DIRECTORY_NAME + "/";

  public static final String PACKAGE_SCHEME_SPEC = "package:";

  /**
   * Path string for lib directory in a url.
   */
  public static final String LIB_URL_PATH = "/lib/";

  /**
   * Name of pubspec file
   */
  public static final String PUBSPEC_FILE_NAME = "pubspec.yaml";

  /**
   * Name of special pubspec lock file
   */
  public static final String PUBSPEC_LOCK_FILE_NAME = "pubspec.lock";

  /**
   * The name of the build.dart special file.
   */
  public static final String BUILD_DART_FILE_NAME = "build.dart";

  /**
   * Used by the {@link DartDebugUserAgentManager} to indicate whether the allow remote connection
   * dialog is open.
   */
  public static boolean allowConnectionDialogOpen = false;

  /**
   * The shared message console instance.
   */
  private static final MessageConsole CONSOLE = new MessageConsoleImpl();

  /**
   * The QualifiedName for a resource remapping (a.foo ==> a.bar).
   */
  private static final QualifiedName RESOURCE_REMAP_NAME = new QualifiedName(
      PLUGIN_ID,
      "resourceRemap");

  /**
   * The QualifiedName for the package version.
   */
  public static final QualifiedName PUB_PACKAGE_VERSION = new QualifiedName(
      DartCore.PLUGIN_ID,
      "pub.package.version");

  /**
   * The QualifiedName for library names.
   */
  public static final QualifiedName LIBRARY_NAME = new QualifiedName(
      DartCore.PLUGIN_ID,
      "libraryName");

  /**
   * The unique project manager used for analysis of anything in the workspace
   */
  private static ProjectManager projectManager;

  /**
   * Used to synchronize access to {@link #projectManager}.
   */
  private static final Object projectManagerLock = new Object();

  /**
   * The unique {@link AnalysisServer} used for analysis of anything in the workspace.
   */
  private static AnalysisServer analysisServer;

  /**
   * The unique {@link AnalysisServerDataImpl} instance.
   */
  private static AnalysisServerDataImpl analysisServerDataImpl = new AnalysisServerDataImpl();

  /**
   * The unique {@link WorkspaceAnalysisServerListener} instance.
   */
  private static WorkspaceAnalysisServerListener analysisServerListener;

  /**
   * Used to synchronize access to {@link #analysisServer}.
   */
  private static final Object analysisServerLock = new Object();

  /**
   * Add the given listener for dart ignore changes to the Dart Model. Has no effect if an identical
   * listener is already registered.
   * 
   * @param listener the listener to add
   */
  public static void addIgnoreListener(DartIgnoreListener listener) {
    getIgnoreManager().addListener(listener);
  }

  /**
   * Add the given resource to the set of ignored resources.
   * 
   * @param resource the resource to ignore
   * @throws IOException if there was an error accessing the ignore file
   * @throws CoreException if there was an error deleting markers
   */
  public static void addToIgnores(IResource resource) throws IOException, CoreException {
    getIgnoreManager().addToIgnores(resource);
  }

  /**
   * Remove any resource mapping for the given container.
   * 
   * @param resource
   */
  public static void clearResourceRemapping(IContainer container) {
    try {
      container.accept(new IResourceVisitor() {
        @Override
        public boolean visit(IResource resource) throws CoreException {
          if (resource instanceof IFile) {
            clearResourceRemapping((IFile) resource);

            return true;
          } else if (resource instanceof IContainer) {
            IContainer childContainer = (IContainer) resource;

            if (childContainer.getName().startsWith(".")) {
              return false;
            } else {
              return true;
            }
          } else {
            return false;
          }
        }
      });
    } catch (CoreException e) {
      DartCore.logError(e);
    }
  }

  /**
   * Remove any resource mapping for the given file.
   * 
   * @param resource
   */
  public static void clearResourceRemapping(IFile resource) {
    if (getResourceRemapping(resource) != null) {
      setResourceRemapping(resource, null);
    }
  }

  /**
   * Return true if directory contains a "packages" directory that is installed by pub
   */
  public static boolean containsPackagesDirectory(File file) {
    return new File(file, PACKAGES_DIRECTORY_NAME).isDirectory();
  }

  /**
   * Return <code>true</code> if the directory contains a "pubspec.yaml" file
   */
  public static boolean containsPubspecFile(File directory) {
    return new File(directory, PUBSPEC_FILE_NAME).isFile();
  }

  /**
   * Return an array of analysis server arguments
   * 
   * @return a non-null array of arguments
   */
  public static String[] getAdditionalAnalysisServerArguments() {
    String value = getUserDefinedProperty(ANALYSIS_SERVER_ARG_PROP_KEY);
    if (value == null) {
      return StringUtilities.EMPTY_ARRAY;
    }
    return value.split(",");
  }

  /**
   * Answer the unique {@link AnalysisServer} used for analysis of anything in the workspace.
   * 
   * @return the {@link AnalysisServer} (not {@code null})
   */
  public static AnalysisServer getAnalysisServer() {
    synchronized (analysisServerLock) {
      if (analysisServer == null) {
        DartSdkManager sdkManager = DartSdkManager.getManager();
        if (!sdkManager.hasSdk()) {
          DartCore.logError("Add the dart sdk (com.google.dart.sdk) as a JVM argument");
          System.exit(1);
        }

        boolean isRunningFromSource = false;
        String runtimePath = sdkManager.getSdk().getVmExecutable().getAbsolutePath();
        String analysisServerPath = DartCoreDebug.ANALYSIS_SERVER_PATH;
        if (StringUtils.isEmpty(analysisServerPath)) {
          String svnRoot = System.getProperty("com.google.dart.svnRoot");
          if (svnRoot == null) {
            File analysisServerSnapshot = new File(
                DartSdkManager.getManager().getSdk().getDirectory(),
                "bin/snapshots/analysis_server.dart.snapshot");
            analysisServerPath = analysisServerSnapshot.getAbsolutePath();
            if (!analysisServerSnapshot.exists()) {
              DartCore.logError("Analysis Server snapshot was not found in "
                  + analysisServerSnapshot.getAbsolutePath() + ", SDK is corrupt.");
              System.exit(1);
            }
          } else {
            analysisServerPath = svnRoot + "/pkg/analysis_server/bin/server.dart";
            isRunningFromSource = true;
          }
        } else {
          isRunningFromSource = true;
        }

        String packageRoot = System.getProperty("com.google.dart.packageRoot");
        if (packageRoot == null && isRunningFromSource) {
          DartCore.logError("To run analysis server from source, a package root must be "
              + "supplied using -Dcom.google.dart.packageRoot.");
          System.exit(1);
        }

        try {
          String[] additionalArguments = DartCore.getAdditionalAnalysisServerArguments();
          // prepare debug stream
          DebugPrintStream debugStream;
          {
            String logPath = DartCoreDebug.ANALYSIS_SERVER_LOG_FILE;
            if (StringUtils.isBlank(logPath)) {
              debugStream = null;
            } else if ("console".equals(logPath)) {
              debugStream = new DebugPrintStream() {
                @Override
                public void println(String s) {
                  if (s.length() > 1000) {
                    s = s.substring(0, 1000) + "...";
                  }
                  System.out.println(s);
                }
              };
            } else {
              @SuppressWarnings("resource")
              final PrintStream fileStream = new PrintStream(logPath);
              debugStream = new DebugPrintStream() {
                @Override
                public void println(String s) {
                  fileStream.println(s);
                }
              };
            }
          }
          // additional options
          if (DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_API) {
            additionalArguments = ArrayUtils.add(
                additionalArguments,
                "--enable-incremental-resolution-api");
          }
          if (DartCoreDebug.ANALYSIS_SERVER_NEW_TASK_MODEL) {
            additionalArguments = ArrayUtils.add(additionalArguments, "--enable-new-task-model");
          }
          {
            String log = DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_LOG;
            if (!StringUtils.isEmpty(log)) {
              additionalArguments = ArrayUtils.add(
                  additionalArguments,
                  "--incremental-resolution-log=" + log);
            }
          }
          if (DartCoreDebug.ANALYSIS_SERVER_INCREMENTAL_RESOLUTION_VALIDATION) {
            additionalArguments = ArrayUtils.add(
                additionalArguments,
                "--incremental-resolution-validation");
          }
          {
            String log = DartCoreDebug.ANALYSIS_SERVER_INSTRUMENTATION_LOG_FILE;
            if (!StringUtils.isEmpty(log)) {
              log = log.trim();
              if (log.length() > 0) {
                additionalArguments = ArrayUtils.add(
                    additionalArguments,
                    "--instrumentation-log-file=" + log);
              }
            }
          }
          if (DartCoreDebug.ANALYSIS_SERVER_PRINT_TO_CONSOLE) {
            additionalArguments = ArrayUtils.add(additionalArguments, "--internal-print-to-console");
          }
          // HTTP port
          int httpPort = 0;
          if (DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT != null
              && !DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT.isEmpty()) {
            try {
              httpPort = Integer.parseInt(DartCoreDebug.ANALYSIS_SERVER_HTTP_PORT);
            } catch (NumberFormatException e) {
              DartCore.logError("Analysis server HTTP port must be an integer.");
              System.exit(1);
            }
          }
          // create server, if "com.google.dart.svnRoot" flag was not set then use snapshot
          StdioServerSocket socket = new StdioServerSocket(
              runtimePath,
              analysisServerPath,
              packageRoot,
              debugStream,
              additionalArguments,
              DartCoreDebug.ANALYSIS_SERVER_DEBUG,
              DartCoreDebug.ANALYSIS_SERVER_PROFILE,
              httpPort,
              false,
              FileReadMode.AS_IS);
          if (isPluginsBuild()) {
            // plugin mode
            socket.setClientId("org.dartlang.dartplugin");
          } else {
            // editor mode
            socket.setClientId("org.dartlang.darteditor");
          }
          socket.setClientVersion(getVersion());
          // start server
          analysisServer = new RemoteAnalysisServerImpl(socket);
          analysisServerDataImpl.setServer(analysisServer);
          analysisServerListener = new WorkspaceAnalysisServerListener(
              analysisServerDataImpl,
              new DartProjectManager(
                  ResourcesPlugin.getWorkspace().getRoot(),
                  analysisServer,
                  DartIgnoreManager.getInstance()));
          analysisServer.addAnalysisServerListener(analysisServerListener);
          analysisServer.start();
          analysisServer.server_setSubscriptions(ImmutableList.of(ServerService.STATUS));
          analysisServerDataImpl.updateOptions();
        } catch (Throwable e) {
          DartCore.logError("Enable to start stdio server", e);
          System.exit(1);
        }
      }
    }
    return analysisServer;
  }

  /**
   * Answer the unique {@link AnalysisServerData} used to provide analysis information in the
   * workspace.
   * 
   * @return the {@link AnalysisServerData} (not {@code null})
   */
  public static AnalysisServerData getAnalysisServerData() {
    getAnalysisServer();
    return analysisServerDataImpl;
  }

  /**
   * Answer the application directory (a directory contains a "packages" directory and a
   * "pubspec.yaml" file) directly or indirectly containing the specified file or the file itself if
   * it is an application directory.
   * 
   * @param libFileOrDir the library file or directory
   * @return the context in which the specified library should be analyzed (not <code>null</code>)
   */
  public static File getApplicationDirectory(File file) {
    while (file != null) {
      if (isApplicationDirectory(file)) {
        return file;
      }
      file = file.getParentFile();
    }
    return null;
  }

  /**
   * Answer the application directory (a directory that contains a "packages" directory and a
   * "pubspec.yaml" file) directly or indirectly containing the specified resource or the resource
   * itself if it is an application directory.
   * 
   * @param resource the file or directory
   * @return the directory with the pubspec for the given file
   */
  public static IContainer getApplicationDirectory(IResource resource) {
    IContainer container;
    if (resource instanceof IFile) {
      container = resource.getParent();
    } else {
      container = (IContainer) resource;
    }
    while (container != null) {
      if (isApplicationDirectory(container)) {
        return container;
      }
      container = container.getParent();
    }
    return null;
  }

  /**
   * Returns the day (yyyy-MM-dd) the product was built.
   */
  public static String getBuildDate() {
    return "@BUILDDATE@";
  }

  /**
   * Returns the SVN revision number as a String.
   */
  public static String getBuildId() {
    return "@REVISION@";
  }

  /**
   * Return a unique token that can be used to determine whether cached data that changes only when
   * the version of the editor changes is still valid.
   * 
   * @return a token used to determine the validity of cached data
   */
  public static String getBuildIdOrDate() {
    String buildIdOrDate = getBuildId();
    if (buildIdOrDate.startsWith("@")) {
      buildIdOrDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    }
    return buildIdOrDate;
  }

  /**
   * Returns the shared message console. Unlike the log ({@link DartCore#getLog()}), the console is
   * intended for communication with the end-user.
   * 
   * @return the message console
   */
  public static MessageConsole getConsole() {
    return CONSOLE;
  }

  /**
   * Return the list of known Dart-like file extensions. Dart-like extensions are defined in the
   * {@link Platform.getContentManager() content type manager} for the
   * {@link #DART_SOURCE_CONTENT_TYPE}. Note that a Dart-like extension does not include the leading
   * dot, and that the "dart" extension is always defined as a Dart-like extension.
   * 
   * @return the list of known Dart-like file extensions
   */
  public static String[] getDartLikeExtensions() {
    IContentType dartContentType = Platform.getContentTypeManager().getContentType(
        DART_SOURCE_CONTENT_TYPE);
    HashSet<String> extensionSet = new HashSet<String>();
    for (IContentType contentType : Platform.getContentTypeManager().getAllContentTypes()) {
      if (contentType.isKindOf(dartContentType)) {
        for (String extension : contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)) {
          extensionSet.add(extension);
        }
      }
    }
    extensionSet.remove(Extensions.DART);
    ArrayList<String> extensionList = new ArrayList<String>(extensionSet);
    extensionList.add(0, Extensions.DART);
    return extensionList.toArray(new String[extensionList.size()]);
  }

  /**
   * Returns all existing and open workspace Dart projects.
   */
  public static IProject[] getDartProjects() {
    List<IProject> dartProjects = Lists.newArrayList();
    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
    for (IProject project : projects) {
      if (!project.isAccessible()) {
        continue;
      }
      if (!DartProjectNature.hasDartNature(project)) {
        continue;
      }
      if (PubCacheManager_NEW.isPubCacheProject(project)) {
        continue;
      }
      dartProjects.add(project);
    }
    return dartProjects.toArray(new IProject[dartProjects.size()]);
  }

  /**
   * Return a table of all known configurable options with their default values. These options allow
   * to configure the behavior of the underlying components. The client may safely use the result as
   * a template that they can modify and then pass to {@link #setOptions()}</code>.
   * <p>
   * Helper constants have been defined on DartPreferenceConstants for each of the option IDs
   * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their
   * acceptable values (categorized in Option value). Some options accept open value sets beyond the
   * documented constant values.
   * <p>
   * Note: each release may add new options.
   * 
   * @return a table of all known configurable options with their default values
   */
  public static Hashtable<String, String> getDefaultOptions() {
    return null;
  }

  public static File getEclipseInstallationDirectory() {
    return new File(Platform.getInstallLocation().getURL().getFile());
  }

  /**
   * Return the workspace root default charset encoding.
   * 
   * @return the name of the default charset encoding for the workspace root
   */
  public static String getEncoding() {
    try {
      return ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
    } catch (IllegalStateException exception) {
      // happen when there's no workspace (see bug
      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=216817)
      // or when it is shutting down (see bug
      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=60687)
      return System.getProperty("file.encoding"); //$NON-NLS-1$
    } catch (CoreException exception) {
      // fails silently and return plugin global encoding if core exception
      // occurs
    }
    return ResourcesPlugin.getEncoding();
  }

  /**
   * Extract {@link ErrorCode} form the given {@link IMarker}.
   * 
   * @return the {@link ErrorCode}, may be {@code null}.
   */
  public static ErrorCode getErrorCode(IMarker marker) {
    return AnalysisMarkerManager.getErrorCode(marker);
  }

  /**
   * Return the DartIgnoreManager
   */
  public static DartIgnoreManager getIgnoreManager() {
    if (DartCoreDebug.ENABLE_ANALYSIS_SERVER) {
      return DartIgnoreManager.getInstance();
    } else {
      return getProjectManager().getIgnoreManager();
    }
  }

  /**
   * Utility method for returning one option value only. Equivalent to
   * <code>DartCore.getOptions().get(optionName)</code> Note that it may answer <code>null</code> if
   * this option does not exist.
   * <p>
   * Helper constants have been defined on DartPreferenceConstants for each of the option IDs
   * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their
   * acceptable values (categorized in Option value). Some options accept open value sets beyond the
   * documented constant values.
   * <p>
   * Note: each release may add new options.
   * 
   * @param optionName the name of the option whose value is to be returned
   * @return the value of a given option
   */
  public static String getOption(String optionName) {
    return OptionManager.getInstance().getOption(optionName);
  }

  /**
   * Return the table of the current options. Initially, all options have their default values, and
   * this method returns a table that includes all known options.
   * <p>
   * Helper constants have been defined on DartPreferenceConstants for each of the option IDs
   * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their
   * acceptable values (categorized in Option value). Some options accept open value sets beyond the
   * documented constant values.
   * <p>
   * Note: each release may add new options.
   * <p>
   * Returns a default set of options even if the platform is not running.
   * </p>
   * 
   * @return table of current settings of all options (key type: <code>String</code>; value type:
   *         <code>String</code>)
   */
  public static HashMap<String, String> getOptions() {
    return OptionManager.getInstance().getOptions();
  }

  /**
   * Return the unique instance of this class.
   * 
   * @return the unique instance of this class
   */
  public static DartCore getPlugin() {
    return PLUG_IN;
  }

  /**
   * Answer the unique project manager used for analysis of anything in the workspace.
   * 
   * @return the manager (not {@code null})
   */
  public static ProjectManager getProjectManager() {
    synchronized (projectManagerLock) {
      if (projectManager == null) {
        // start index
        final Index index;
        {
          File stateDir = getPlugin().getStateLocation().toFile();
          File indexDir = new File(stateDir, "index");
          indexDir.mkdirs();
          IndexStore indexStore = IndexFactory.newFileIndexStore(indexDir);
          index = IndexFactory.newIndex(indexStore);
          Thread thread = new Thread() {
            @Override
            public void run() {
              index.run();
            }
          };
          thread.setName("Index Thread");
          thread.setDaemon(true);
          thread.start();
        }
        // create ProjectManagerImpl
        projectManager = new ProjectManagerImpl(
            ResourcesPlugin.getWorkspace().getRoot(),
            DartSdkManager.getManager().getSdk(),
            DartSdkManager.getManager().getSdkContextId(),
            index,
            DartIgnoreManager.getInstance());
      }
    }
    return projectManager;
  }

  /**
   * @return the mapping for the given resource, if any
   */
  public static String getResourceRemapping(IFile originalResource) {
    try {
      return originalResource.getPersistentProperty(RESOURCE_REMAP_NAME);
    } catch (CoreException e) {
      return null;
    }
  }

  /**
   * Returns the name of the directory in packages that is linked to the "lib" folder in the project
   * 
   * @param project
   * @return the name of the directory, <code>null</code> if there is no self linked packages folder
   */
  public static String getSelfLinkedPackageName(IResource resource) {
    String packageName = null;

    try {
      IContainer appFolder = getApplicationDirectory(resource);

      if (appFolder != null) {
        IResource pubspec = appFolder.findMember(DartCore.PUBSPEC_FILE_NAME);

        if (pubspec != null) {
          String contents = FileUtilities.getContents(pubspec.getLocation().toFile(), "UTF-8");

          if (contents != null) {
            String name = PubYamlUtils.getPubspecName(contents);

            if (name != null) {
              return name;
            }
          }
        }
      }
    } catch (Exception e) {

    }

    return packageName;
  }

  /**
   * Returns the path string for the default dart directory - user.home/dart
   * 
   * @return the name of the user.home/dart directory
   */
  public static String getUserDefaultDartFolder() {
    String defaultLocation = System.getProperty("user.home"); //$NON-NLS-1$
    return defaultLocation + File.separator + "dart" + File.separator; //$NON-NLS-1$
  }

  /**
   * Returns the current value of the string-valued user-defined property with the given name.
   * Returns <code>null</code> if there is no user-defined property with the given name.
   * <p>
   * User-defined properties are defined in the <code>editor.properties</code> file located in the
   * eclipse installation directory.
   * 
   * @see DartCore#getEclipseInstallationDirectory()
   * @param name the name of the property
   * @return the string-valued property
   */
  public static String getUserDefinedProperty(String key) {

    Properties properties = new Properties();

    File installDirectory = getEclipseInstallationDirectory();
    File file = new File(installDirectory, EDITOR_PROPERTIES);

    if (file.exists()) {
      try {
        properties.load(new FileReader(file));
      } catch (FileNotFoundException e) {
        logError(e);
      } catch (IOException e) {
        logError(e);
      }
    }

    return properties.getProperty(key);
  }

  /**
   * @return the version text for this plugin (i.e. 1.1.0)
   */
  public static String getVersion() {
    Version version = getPlugin().getBundle().getVersion();

    return version.getMajor() + "." + version.getMinor() + "." + version.getMicro();
  }

  public static boolean is32Bit() {
    return Platform.getOSArch().indexOf("64") == -1;
  }

  /**
   * Return <code>true</code> if the given resource should be analyzed. All resources are to be
   * analyzed unless they have been excluded.
   * 
   * @param resource the resource being tested
   * @return <code>true</code> if the given resource should be analyzed
   */
  public static boolean isAnalyzed(IResource resource) {
    return getIgnoreManager().isAnalyzed(resource);
  }

  /**
   * Return true if directory contains a "packages" directory and a "pubspec.yaml" file
   */
  public static boolean isApplicationDirectory(File directory) {
    return containsPubspecFile(directory);
  }

  /**
   * Return true if directory contains a "packages" directory and a "pubspec.yaml" file
   */
  public static boolean isApplicationDirectory(IContainer container) {
    if (container.getLocation() == null) {
      return false;
    }

    File directory = container.getLocation().toFile();

    return isApplicationDirectory(directory);
  }

  /**
   * Answer {@code true} if the specified resource is a build.dart file and exists either in a
   * project or in a folder containing a pubspec file.
   * 
   * @param file the file
   * @return {@code true} if the file is a build.dart file that will be run by the builder
   */
  public static boolean isBuildDart(IFile file) {
    if (file == null || !file.getName().equals(BUILD_DART_FILE_NAME) || !file.exists()) {
      return false;
    }

    IContainer container = file.getParent();

    // Always run build.dart in a project's root.
    if (container.getType() == IResource.PROJECT) {
      return true;
    }

    return container.getFile(new Path(PUBSPEC_FILE_NAME)).exists();
  }

  /**
   * Return true if directory is one that is generated by pub build
   * 
   * @param folder the folder to be checked
   * @return <code>true</code> if folder name matches and is sibling of pubspec.yaml
   */
  public static boolean isBuildDirectory(IFolder folder) {
    IPath location = folder.getLocation();
    if (location != null && folder.getName().equals(BUILD_DIRECTORY_NAME)) {
      if (folder.getParent().findMember(PUBSPEC_FILE_NAME) != null) {
        return true;
      }
    }
    return false;
  }

  /**
   * Return <code>true</code> if the given file is contained in the packages directory created by
   * pub
   * 
   * @param file the file that is to be checked
   * @return <code>true</code> if the given file is in packages
   */
  public static boolean isContainedInPackages(File file) {
    if (file.getAbsolutePath().contains(PACKAGES_DIRECTORY_NAME)) {
      return true;
    }
    return false;
  }

  /**
   * Return <code>true</code> if the given file is contained in the packages directory created by
   * pub
   * 
   * @param file the file that is to be checked
   * @return <code>true</code> if the given file is in packages
   */
  public static boolean isContainedInPackages(IFile file) {
    return file.getFullPath().toString().contains(DartCore.PACKAGES_DIRECTORY_PATH);
  }

  /**
   * Return <code>true</code> if the given file name's extension is an CSS-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is an CSS-like extension
   */
  public static boolean isCssLikeFileName(String fileName) {
    return isLikeFileName(fileName, CSS_FILE_EXTENSIONS);
  }

  /**
   * Return <code>true</code> if the given file name's extension is a generated Dart like extension.
   * 
   * @return <code>true</code> if the given file name's extension is a generated Dart like extension
   */
  public static boolean isDartGeneratedFile(String fileName) {
    return isLikeFileName(fileName, DART_GENERATED_FILE_EXTENSIONS);
  }

  /**
   * Return <code>true</code> if the name of the given {@link IFile} has a Dart-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the name of the given {@link IFile} has a Dart-like extension
   */
  public static boolean isDartLikeFile(IFile file) {
    String fileName = file.getName();
    return isDartLikeFileName(fileName);
  }

  /**
   * Return <code>true</code> if the given file name's extension is a Dart-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is a Dart-like extension
   */
  public static boolean isDartLikeFileName(String fileName) {
    return StringUtilities.endsWithIgnoreCase(fileName, ".dart");
  }

  /**
   * Return <code>true</code> if file is in the dart sdk lib directory
   * 
   * @param file
   * @return <code>true</code> if file is in dart-sdk/lib
   */
  public static boolean isDartSdkLibraryFile(File file) {
    File sdkLibrary = DartSdkManager.getManager().getSdk().getLibraryDirectory();
    File parentFile = file.getParentFile();
    while (parentFile != null) {
      if (parentFile.equals(sdkLibrary)) {
        return true;
      }
      parentFile = parentFile.getParentFile();
    }
    return false;
  }

  /**
   * Return <code>true</code> if the given file name's extension is an HTML-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is an HTML-like extension
   */
  public static boolean isHtmlLikeFileName(String fileName) {
    return isLikeFileName(fileName, HTML_FILE_EXTENSIONS);
  }

  /**
   * Return <code>true</code> if the given file name's extension is an image-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is an image-like extension
   */
  public static boolean isImageLikeFileName(String fileName) {
    return isLikeFileName(fileName, IMAGE_FILE_EXTENSIONS);
  }

  /**
   * Return true if directory is build directory created by pub
   * 
   * @param folder the folder to be checked
   * @return <code>true</code> if folder/parent name matches and is sibling of pubspec.yaml
   */
  public static boolean isInBuildDirectory(IContainer folder) {
    while (folder.getParent() != null) {
      if (folder.getName().equals(BUILD_DIRECTORY_NAME)
          && folder.getParent().getFile(new Path(PUBSPEC_FILE_NAME)).exists()) {
        return true;
      }
      folder = folder.getParent();
    }
    return false;
  }

  /**
   * Return true if is in build directory created by pub
   */
  public static boolean isInBuildDirectory(IResource resource) {
    if (resource == null) {
      return false;
    }
    if (!(resource instanceof IContainer)) {
      resource = resource.getParent();
    }
    return !(resource instanceof IProject || resource instanceof IWorkspaceRoot)
        && (isBuildDirectory((IFolder) resource) || isInBuildDirectory((IContainer) resource));

  }

  /**
   * @return {@code true} if the given resource is located in the top-level "packages" folder of its
   *         enclosing package.
   */
  public static boolean isInDuplicatePackageFolder(IResource resource) {
    if (resource == null) {
      return false;
    }
    // prepare "pub" folder
    PubFolder pubFolder = DartCore.getProjectManager().getPubFolder(resource);
    if (pubFolder == null) {
      return false;
    }
    IPath pubPath = pubFolder.getResource().getFullPath();
    // check if resource is in "packages"
    IPath resourcePath = resource.getFullPath();
    String[] segments = resourcePath.segments();
    for (int i = 1; i < segments.length - 1; i++) {
      String segment = segments[i];
      if (segment.equals(PACKAGES_DIRECTORY_NAME)) {
        return !resourcePath.uptoSegment(i).equals(pubPath);
      }
    }
    // not in "packages"
    return false;
  }

  /**
   * @return {@code true} if the given resource is located in the "packages" sub-folder that
   *         corresponds to the enclosing package.
   */
  public static boolean isInSelfLinkedPackageFolder(IResource resource) {
    if (resource == null) {
      return false;
    }
    try {
      // prepare "pub" folder
      PubFolder pubFolder = DartCore.getProjectManager().getPubFolder(resource);
      if (pubFolder == null) {
        return false;
      }
      // the name of the enclosing package
      String packageName = pubFolder.getPubspec().getName();
      // check if resource is in "packages" and references the enclosing package
      String[] segments = resource.getFullPath().segments();
      for (int i = 0; i < segments.length - 1; i++) {
        String segment = segments[i];
        if (segment.equals(PACKAGES_DIRECTORY_NAME) && segments[i + 1].equals(packageName)) {
          return true;
        }
      }
    } catch (Throwable e) {
      // pubFolder.getPubspec() may fail
      return false;
    }
    // not a self-reference
    return false;
  }

  /**
   * Return <code>true</code> if the given file name's extension is an HTML-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is an HTML-like extension
   */
  public static boolean isJSLikeFileName(String fileName) {
    return isLikeFileName(fileName, JS_FILE_EXTENSIONS);
  }

  public static boolean isLinux() {
    return !isMac() && !isWindows();
  }

  public static boolean isMac() {
    // Look for the "Mac" OS name.
    return System.getProperty("os.name").toLowerCase().startsWith("mac");
  }

  /**
   * Return true if directory is one that is installed by pub
   * 
   * @param file the file to be checked
   * @return <code>true</code> if file name matches and is sibling of pubspec.yaml
   */
  public static boolean isPackagesDirectory(File file) {
    if (file.getName().equals(PACKAGES_DIRECTORY_NAME)) {
      return true;
    }
    return false;
  }

  /**
   * Return true if directory is one that is installed by pub
   * 
   * @param folder the folder to be checked
   * @return <code>true</code> if folder name matches and is sibling of pubspec.yaml
   */
  public static boolean isPackagesDirectory(IFolder folder) {
    IPath location = folder.getLocation();
    return location != null && isPackagesDirectory(location.toFile());
  }

  /**
   * Answer <code>true</code> if the string is a package spec
   */
  public static boolean isPackageSpec(String spec) {
    return spec != null && spec.startsWith(PACKAGE_SCHEME_SPEC);
  }

  /**
   * @return <code>true</code> if given {@link IResource} was installed by pub.
   */
  public static boolean isPackagesResource(IResource resource) {
    if (resource instanceof IFolder) {
      if (isPackagesDirectory((IFolder) resource)) {
        return true;
      }
    }
    if (resource != null && resource.getParent() instanceof IFolder) {
      IFolder parentFolder = (IFolder) resource.getParent();
      return isPackagesResource(parentFolder);
    }
    return false;
  }

  /**
   * Check if this URI denotes a patch file.
   */
  public static boolean isPatchfile(File file) {
    return file != null && file.getName().endsWith("_patch.dart");
  }

  /**
   * @return whether we're running in the context of the eclipse plugins build
   */
  public static boolean isPluginsBuild() {
    return Platform.getBundle("com.google.dart.eclipse.core") != null;
  }

  /**
   * Checks if the given linkedResource points to a file in the container. This is used to check for
   * the self link in the packages directory
   * 
   * @param resource
   * @param linkedResource
   * @return <code>true</code> if the linked resource points to a file/folder in the project
   */
  public static boolean isSelfLinkedResource(IContainer resource, IResource linkedResource) {

    try {
      //     if (linkedResource.getParent().getParent() == resource) {
      String resourcePath = resource.getLocation().toFile().getCanonicalPath();
      String linkPath = linkedResource.getLocation().toFile().getCanonicalPath();
      if (linkPath.startsWith(resourcePath)) {
        return true;
      }
      //     }
    } catch (IOException e) {
      return false;
    }
    return false;
  }

  /**
   * Return <code>true</code> if the given file name's extension is an HTML-like extension.
   * 
   * @param fileName the file name being tested
   * @return <code>true</code> if the given file name's extension is an HTML-like extension
   */
  public static boolean isTxtLikeFileName(String fileName) {
    return isLikeFileName(fileName, TXT_FILE_EXTENSIONS);
  }

  public static boolean isWindows() {
    // Look for the "Windows" OS name.
    return System.getProperty("os.name").toLowerCase().startsWith("win");
  }

  public static boolean isWindowsXp() {
    // Look for the "Windows XP" OS name.
    return System.getProperty("os.name").toLowerCase().equals("windows xp");
  }

  /**
   * Log the given message as an error.
   * 
   * @param message an explanation of why the error occurred or what it means
   */
  public static void logError(String message) {
    logErrorImpl(message, null);
    instrumentationLogErrorImpl(message, null);
  }

  /**
   * Log the given exception as one representing an error.
   * 
   * @param message an explanation of why the error occurred or what it means
   * @param exception the exception being logged
   */
  public static void logError(String message, Throwable exception) {
    logErrorImpl(message, exception);
    instrumentationLogErrorImpl(message, exception);
  }

  /**
   * Log the given exception as one representing an error.
   * 
   * @param exception the exception being logged
   */
  public static void logError(Throwable exception) {
    logErrorImpl(exception.getMessage(), exception);
    instrumentationLogErrorImpl(null, exception);
  }

  /**
   * Log the given informational message.
   * 
   * @param message an explanation of why the error occurred or what it means
   * @param exception the exception being logged
   */
  public static void logInformation(String message) {
    logInformation(message, null);
  }

  /**
   * Log the given exception as one representing an informational message.
   * 
   * @param message an explanation of why the error occurred or what it means
   * @param exception the exception being logged
   */
  public static void logInformation(String message, Throwable exception) {

    if (DartCoreDebug.VERBOSE) {
      ILog pluginLog = getPluginLog();
      if (pluginLog != null) {
        pluginLog.log(new Status(Status.INFO, PLUGIN_ID, "INFO: " + message, exception));
      }
    }

    instrumentationLogInfoImpl(message, exception);
  }

  /**
   * Log the given {@link RequestError}.
   */
  public static void logRequestError(RequestError requestError) {
    StringBuilder buf = new StringBuilder();
    buf.append("RequestError: ");
    buf.append(requestError.getCode());
    buf.append("\n");
    buf.append(requestError.getMessage());
    buf.append("\n");
    buf.append(requestError.getStackTrace());
    buf.append("\n");
    String str = buf.toString();
    DartCore.logError(str);
  }

  /**
   * This method exists as a convenient marker for methods that have not yet been fully implemented.
   * It should be deleted before this product ships.
   */
  public static void notYetImplemented() {
  }

  /**
   * Removes the file extension from the given file name, if it has a Dart-like file extension.
   * Otherwise the file name itself is returned. Note this removes the dot ('.') before the
   * extension as well.
   * 
   * @param fileName the name of a file
   * @return the fileName without the Dart-like extension
   */
  public static String removeDartLikeExtension(String fileName) {
    return Util.getNameWithoutDartLikeExtension(fileName);
  }

  /**
   * Remove the given resource (as a path) from the set of ignored resources.
   * 
   * @param resource the resource path to (un)ignore
   * @throws IOException if there was an error accessing the ignore file
   */
  public static void removeFromIgnores(IPath resource) throws IOException {
    getIgnoreManager().removeFromIgnores(resource);
  }

  /**
   * Remove the given resource from the set of ignored resources.
   * 
   * @param resource the resource to (un)ignore
   * @throws IOException if there was an error accessing the ignore file
   */
  public static void removeFromIgnores(IResource resource) throws IOException {
    getIgnoreManager().removeFromIgnores(resource);
  }

  /**
   * Remove the given listener for dart ignore changes from the Dart Model. Has no effect if an
   * identical listener is not registered.
   * 
   * @param listener the non-<code>null</code> listener to remove
   */
  public static void removeIgnoreListener(DartIgnoreListener listener) {
    getIgnoreManager().removeListener(listener);
  }

  public static void setOptions(HashMap<String, String> newOptions) {

  }

  /**
   * Sets the current table of options. All and only the options explicitly included in the given
   * table are remembered; all previous option settings are forgotten, including ones not explicitly
   * mentioned.
   * <p>
   * Helper constants have been defined on DartPreferenceConstants for each of the option IDs
   * (categorized in Code assist option ID, Compiler option ID and Core option ID) and some of their
   * acceptable values (categorized in Option value). Some options accept open value sets beyond the
   * documented constant values.
   * <p>
   * Note: each release may add new options.
   * 
   * @param newOptions the new options, or <code>null</code> to reset all options to their default
   *          values
   */
  public static void setOptions(Hashtable<String, String> newOptions) {

  }

  /**
   * TESTING ONLY: Set the log used by {@link #logError(String)} and other local methods for logging
   * errors, warnings, and information.
   * 
   * @param log the log or <code>null</code> to use the default system log
   * @return the log prior to calling this method or <code>null</code> for the default system log
   */
  public static ILog setPluginLog(ILog log) {
    ILog oldLog = PLUGIN_LOG;
    PLUGIN_LOG = log;
    return oldLog;
  }

  /**
   * Set a symbolic resource mapping from one resource to another. For some uses of the original
   * resource, like serving web content, the mapped resource should be substituted.
   * 
   * @param originalResource
   * @param newResource
   */
  public static void setResourceRemapping(IFile originalResource, IFile newResource) {
    try {
      String resourcePath = (newResource == null ? null
          : newResource.getFullPath().toPortableString());
      originalResource.setPersistentProperty(RESOURCE_REMAP_NAME, resourcePath);
    } catch (CoreException e) {
      DartCore.logError(e);
    }
  }

  /**
   * Sets the value of the string-valued user-defined property for the given key.
   * <p>
   * User-defined properties are defined in the <code>editor.properties</code> file located in the
   * eclipse installation directory.
   * 
   * @see DartCore#getEclipseInstallationDirectory()
   * @param key the name of the property
   * @param value the string-valued property
   */
  public static void setUserDefinedProperty(String key, String value) {

    Properties properties = new Properties();

    File installDirectory = getEclipseInstallationDirectory();
    File file = new File(installDirectory, EDITOR_PROPERTIES);

    try {
      if (!file.exists()) {
        file.createNewFile();
      }
      properties.load(new FileReader(file));
      properties.setProperty(key, value);
      properties.store(new FileWriter(file), null);
    } catch (FileNotFoundException e) {
      logError(e);
    } catch (IOException e) {
      logError(e);
    }

  }

  /**
   * Answer the log used by {@link #logError(String)} and other local methods for logging errors,
   * warnings, and information.
   * 
   * @return the {@link ILog} or {@code null} if not accessible (for example during platform
   *         shutdown)
   */
  private static ILog getPluginLog() {
    try {
      return PLUGIN_LOG != null ? PLUGIN_LOG : getPlugin().getLog();
    } catch (Throwable e) {
      return null;
    }
  }

  /**
   * Record an error
   */
  private static void instrumentationLogErrorImpl(String message, Throwable exception) {
    instrumentationLogImpl(message, exception, "LogError");
  }

  /**
   * Internal instrumentation message delivery implementation
   * 
   * @param message optional message to be delivered
   * @param exception optional exception to be delivered
   * @param messageType message type, common values LogError/LogMessage
   */
  private static void instrumentationLogImpl(String message, Throwable exception, String messageType) {
    if (instrumentationLogErrorEnabled) {
      InstrumentationBuilder instrumentation = Instrumentation.builder("DartCore." + messageType);
      try {
        instrumentation.data("Log_Message", message != null ? message : "null");
        instrumentation.data("Log_Exception", exception != null ? exception.toString() : "null");
        if (exception != null) {
          instrumentation.record(exception);
        }
      } catch (Exception e) {
        instrumentationLogErrorEnabled = false;
        logErrorImpl("Instrumentation failed to log error", exception);
      } finally {
        instrumentation.log();
      }

    }

  }

  /**
   * Record an 'informational exception'
   */
  private static void instrumentationLogInfoImpl(String message, Throwable exception) {

    instrumentationLogImpl(message, exception, "LogInfo");

  }

  /**
   * Return <code>true</code> if the given file name's extension matches one of the passed
   * extensions.
   * 
   * @param fileName the file name being tested
   * @param extensions an array of file extensions to test against
   * @return <code>true</code> if the given file name's extension matches one of the passed
   *         extensions
   */
  private static boolean isLikeFileName(String fileName, String[] extensions) {
    if (fileName == null || fileName.length() == 0) {
      return false;
    }
    for (String extension : extensions) {
      if (StringUtilities.endsWithIgnoreCase(fileName, '.' + extension)) {
        return true;
      }
    }
    return false;
  }

  private static void logErrorImpl(String message, Throwable exception) {
    ILog pluginLog = getPluginLog();
    if (pluginLog != null) {
      pluginLog.log(new Status(Status.ERROR, PLUGIN_ID, message, exception));
    }
  }

  private IEclipsePreferences prefs;

  /**
   * Property key for user-specified analysis server arguments.
   */
  public static final String ANALYSIS_SERVER_ARG_PROP_KEY = "com.dart.tools.server.args";

  /**
   * Initialize a newly created instance of this class.
   */
  public DartCore() {
    PLUG_IN = this;
  }

  /**
   * Use dart2js if the SDK is present.
   */
  public boolean getCompileWithDart2JS() {
    return DartSdkManager.getManager().hasSdk();
  }

  public String getDart2jsFlags() {
    return getPrefs().get(PREFS_DART2JS_FLAGS, "");
  }

  public String[] getDart2jsFlagsAsArray() {
    return StringUtilities.parseArgumentString(getDart2jsFlags());
  }

  public String getDartiumLocationPref() {
    return getPrefs().get(PREFS_DARTIUM_LOCATION, "");
  }

  public boolean getDisableDartBasedBuilder(IProject project) {
    return getProjectPreferences(project).getBoolean(PROJECT_PREF_DISABLE_DART_BASED_BUILDER, false);
  }

  public boolean getEnableAnalytics() {
    if (DartCoreDebug.ASK_FOR_USER_ANALYTICS) {
      return getPrefs().getBoolean(PREFS_ENABLE_ANALYTICS, false);
    }
    return false;
  }

  /**
   * Given an File, return the appropriate java.io.File representing a package root. This can be
   * null if a package root should not be used.
   * 
   * @param file the File
   * @return the File for the package root, or null if none
   */
  public File getPackageRoot(File file) {
    IResource resource = ResourceUtil.getResource(file);
    if (resource != null) {
      return getPackageRoot(resource.getProject());
    }
    return null;
  }

  /**
   * Given an IProject, return the appropriate java.io.File representing a package root. This can be
   * null if a package root should not be used.
   * 
   * @param project the IProject
   * @return the File for the package root, or null if none
   */
  public File getPackageRoot(IProject project) {
    if (project != null) {
      String setting = getProjectPreferences(project).get(PROJECT_PREF_PACKAGE_ROOT, "");

      if (setting != null && setting.length() > 0) {
        String[] paths = setting.split(File.pathSeparator);
        return new File(paths[0]);
      }
    }

    File[] roots = CmdLineOptions.getOptions().getPackageRoots();

    if (roots.length > 0) {
      return roots[0];
    }

    return null;
  }

  /**
   * Get the core plugin preferences. Use savePrefs() to save the preferences.
   */
  public IEclipsePreferences getPrefs() {
    if (prefs == null) {
      prefs = InstanceScope.INSTANCE.getNode(PLUGIN_ID);
    }

    return prefs;
  }

  public IEclipsePreferences getProjectPreferences(IProject project) {
    ProjectScope projectScope = new ProjectScope(project);

    return projectScope.getNode(PLUGIN_ID);
  }

  public String getSdkLocationPref() {
    return getPrefs().get(PREFS_SDK_LOCATION, "");
  }

  public boolean getShowAnalyticsDailog() {
    return getPrefs().getBoolean(PREFS_SHOW_ANALYTICS_DIALOG, true);
  }

  /**
   * Given an IProject, return string representing a package root to be used for all VM launches.
   * This can be null if a package root should not be used.
   * 
   * @param project the IProject
   * @return the String for the package root, or null if none
   */
  public String getVmPackageRoot(IProject project) {
    if (project != null) {
      String setting = getProjectPreferences(project).get(PROJECT_PREF_VM_PACKAGE_ROOT, "");
      if (!setting.isEmpty()) {
        return setting;
      }
    }
    return null;
  }

  public boolean isAutoRunPubEnabled() {
    return DartCore.getPlugin().getPrefs().getBoolean(PUB_AUTO_RUN_PREFERENCE, true);
  }

  public boolean isHintsDart2JSEnabled() {
    return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_HINTS_DART2JS_PREFERENCE, true);
  }

  public boolean isHintsEnabled() {
    return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_HINTS_PREFERENCE, true);
  }

  public boolean isLintsEnabled() {
    return DartCore.getPlugin().getPrefs().getBoolean(ENABLE_LINTS_PREFERENCE, false);
  }

  /**
   * Save the core plugin preferences
   * 
   * @throws CoreException
   */
  public void savePrefs() throws CoreException {
    try {
      getPrefs().flush();
    } catch (BackingStoreException e) {
      throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, e.toString(), e));
    }
  }

  @Override
  public void sdkUpdated(DirectoryBasedDartSdk sdk) {
    Job job = new CleanLibrariesJob();

    job.schedule();
  }

  public void setDart2JsPreferences(String args) {
    IEclipsePreferences prefs = getPrefs();
    prefs.put(PREFS_DART2JS_FLAGS, args);

    try {
      getPrefs().flush();
    } catch (BackingStoreException exception) {
      logError(exception);
    }
  }

  public void setDisableDartBasedBuilder(IProject project, boolean value) throws CoreException {
    try {
      IEclipsePreferences prefs = getProjectPreferences(project);
      prefs.putBoolean(PROJECT_PREF_DISABLE_DART_BASED_BUILDER, value);
      prefs.flush();
    } catch (BackingStoreException ex) {
      throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex));
    }
  }

  public void setEnableAnalytics(boolean value) {
    if (DartCoreDebug.ASK_FOR_USER_ANALYTICS) {
      IEclipsePreferences prefs = getPrefs();
      prefs.putBoolean(PREFS_ENABLE_ANALYTICS, value);

      try {
        getPrefs().flush();
      } catch (BackingStoreException exception) {
        logError(exception);
      }
    }
  }

  public void setPackageRoot(IProject project, String packageRootPath) throws CoreException {
    try {
      IEclipsePreferences prefs = getProjectPreferences(project);
      prefs.put(PROJECT_PREF_PACKAGE_ROOT, packageRootPath);
      prefs.flush();
    } catch (BackingStoreException ex) {
      throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex));
    }
  }

  public void setShowAnalyticsDialogFalse() {
    IEclipsePreferences prefs = getPrefs();
    prefs.putBoolean(PREFS_SHOW_ANALYTICS_DIALOG, false);

    try {
      getPrefs().flush();
    } catch (BackingStoreException exception) {
      logError(exception);
    }
  }

  public void setVmPackageRoot(IProject project, String packageRootPath) throws CoreException {
    try {
      IEclipsePreferences prefs = getProjectPreferences(project);
      prefs.put(PROJECT_PREF_VM_PACKAGE_ROOT, packageRootPath);
      prefs.flush();
    } catch (BackingStoreException ex) {
      throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, ex.toString(), ex));
    }
  }

  @Override
  public void start(BundleContext context) throws Exception {
    super.start(context);

    CmdLineOptions.setOptions(CmdLineOptions.parseCmdLine(Platform.getApplicationArgs()));
    CmdLineOptions.getOptions().printWarnings();

    if (DartCoreDebug.PERF_THREAD_CONTENTION_MONIOR) {
      try {
        java.lang.management.ThreadMXBean th = ManagementFactory.getThreadMXBean();
        th.setThreadContentionMonitoringEnabled(true);
      } catch (UnsupportedOperationException e) {
      }
    }

    AnalysisEngine analysisEngine = AnalysisEngine.getInstance();
    analysisEngine.setLogger(new Logger() {
      @Override
      public void logError(String message) {
        DartCore.logError(message);
      }

      @Override
      public void logError(String message, Throwable exception) {
        DartCore.logError(message, exception);
      }

      @Override
      public void logInformation(String message) {
        DartCore.logInformation(message);
      }

      @Override
      public void logInformation(String message, Throwable exception) {
        DartCore.logInformation(message, exception);
      }
    });
    Logging.setLogger(new com.google.dart.server.utilities.logging.Logger() {
      @Override
      public void logError(String message) {
        DartCore.logError(message);
      }

      @Override
      public void logError(String message, Throwable exception) {
        DartCore.logError(message, exception);
      }

      @Override
      public void logInformation(String message) {
        DartCore.logInformation(message);
      }

      @Override
      public void logInformation(String message, Throwable exception) {
        DartCore.logInformation(message, exception);
      }
    });

    DartSdkManager.getManager().addSdkListener(this);
    if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) {
      getProjectManager().hookListeners();
    } else {
      getAnalysisServer();
    }
  }

  @Override
  public void stop(BundleContext context) throws Exception {
    DartSdkManager.getManager().removeSdkListener(this);

    try {
      if (!DartCoreDebug.ENABLE_ANALYSIS_SERVER) {
        getProjectManager().stop();
      }

      synchronized (analysisServerLock) {
        if (analysisServer != null) {
          analysisServer.server_shutdown();
        }
      }

      if (DartCoreDebug.METRICS) {
        StringWriter writer = new StringWriter();
        PerformanceManager.getInstance().printMetrics(new PrintWriter(writer));
        String metricsInfo = writer.toString();
        if (metricsInfo.length() > 0) {
          getLog().log(new Status(Status.INFO, PLUGIN_ID, metricsInfo, null));
        }
      }
    } finally {
      super.stop(context);
    }
  }
}
