/**
   * Creates an NL fragment project along with the locale specific properties files.
   *
   * @throws CoreException
   * @throws IOException
   * @throws InvocationTargetException
   * @throws InterruptedException
   */
  private void internationalizePlugins(List plugins, List locales, Map overwrites)
      throws CoreException, IOException, InvocationTargetException, InterruptedException {

    Set created = new HashSet();

    for (Iterator it = plugins.iterator(); it.hasNext(); ) {
      IPluginModelBase plugin = (IPluginModelBase) it.next();

      for (Iterator iter = locales.iterator(); iter.hasNext(); ) {
        Locale locale = (Locale) iter.next();

        IProject project = getNLProject(plugin, locale);
        if (created.contains(project)
            || overwriteWithoutAsking
            || !project.exists()
            || OVERWRITE == overwrites.get(project.getName())) {
          if (!created.contains(project) && project.exists()) {
            project.delete(true, getProgressMonitor());
          }

          if (!created.contains(project)) {
            createNLFragment(plugin, project, locale);
            created.add(project);
            project.getFolder(RESOURCE_FOLDER_PARENT).create(false, true, getProgressMonitor());
          }

          project
              .getFolder(RESOURCE_FOLDER_PARENT)
              .getFolder(locale.toString())
              .create(true, true, getProgressMonitor());
          createLocaleSpecificPropertiesFile(project, plugin, locale);
        }
      }
    }
  }
  private void createParents(IProject fragmentProject, IPath parent) throws CoreException {
    String[] segments = parent.segments();
    String path = new String();

    for (int i = 0; i < segments.length; i++) {
      path += SLASH + segments[i];
      IFolder folder = fragmentProject.getFolder(path);
      if (!folder.exists()) {
        folder.create(true, true, getProgressMonitor());
      }
    }
  }
  /**
   * Creates a locale specific properties file within the fragment project based on the content of
   * the host plug-in's properties file.
   *
   * @param fragmentProject
   * @param locale
   * @throws CoreException
   * @throws IOException
   */
  private void createLocaleSpecificPropertiesFile(
      final IProject fragmentProject, IPluginModelBase plugin, final Locale locale)
      throws CoreException, IOException {
    final IFolder localeResourceFolder =
        fragmentProject.getFolder(RESOURCE_FOLDER_PARENT).getFolder(locale.toString());

    // Case 1: External plug-in
    if (plugin instanceof ExternalPluginModelBase) {
      final String installLocation = plugin.getInstallLocation();
      // Case 1a: External plug-in is a jar file
      if (new File(installLocation).isFile()) {
        ZipFile zf = new ZipFile(installLocation);
        for (Enumeration e = zf.entries(); e.hasMoreElements(); ) {
          worked();

          ZipEntry zfe = (ZipEntry) e.nextElement();
          String name = zfe.getName();

          String[] segments = name.split(SLASH);
          IPath path = Path.fromPortableString(join(SLASH, segments, 0, segments.length - 1));
          String resourceName = segments[segments.length - 1];
          String localizedResourceName = localeSpecificName(resourceName, locale);
          if (propertiesFilter.include(name)) {

            createParents(fragmentProject, path);
            IFile file = fragmentProject.getFile(path.append(localizedResourceName));
            InputStream is = zf.getInputStream(zfe);
            file.create(is, false, getProgressMonitor());
          } else if (resourceFilter.include(name)) {
            IPath target = localeResourceFolder.getFullPath().append(path).append(resourceName);
            createParents(fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
            IFile file = fragmentProject.getFile(target.removeFirstSegments(1));
            file.create(zf.getInputStream(zfe), false, getProgressMonitor());
          }
        }
      }
      // Case 1b: External plug-in has a folder structure
      else {
        Visitor visitor =
            new Visitor() {
              public void visit(File file) throws CoreException, FileNotFoundException {
                worked();

                String relativePath =
                    file.getAbsolutePath()
                        .substring(installLocation.length())
                        .replaceAll(File.separator, SLASH);
                String[] segments = relativePath.split(SLASH);
                IPath path = Path.fromPortableString(join(SLASH, segments, 0, segments.length - 1));
                String resourceName = segments[segments.length - 1];
                String localizedResourceName = localeSpecificName(resourceName, locale);

                if (propertiesFilter.include(
                    relativePath + (file.isDirectory() ? SLASH : EMPTY_STRING))) {
                  createParents(fragmentProject, path);
                  IFile iFile = fragmentProject.getFile(path.append(localizedResourceName));
                  iFile.create(new FileInputStream(file), false, getProgressMonitor());
                } else if (resourceFilter.include(
                    relativePath + (file.isDirectory() ? SLASH : EMPTY_STRING))) {
                  IPath target = localeResourceFolder.getFullPath().append(relativePath);
                  createParents(
                      fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
                  IFile iFile = fragmentProject.getFile(target.removeFirstSegments(1));
                  iFile.create(new FileInputStream(file), false, getProgressMonitor());
                }

                if (file.isDirectory()) {
                  File[] children = file.listFiles();
                  for (int i = 0; i < children.length; i++) {
                    visit(children[i]);
                  }
                }
              }
            };

        visitor.visit(new File(installLocation));
      }
    }
    // Case 2: Workspace plug-in
    else {
      final IProject project = plugin.getUnderlyingResource().getProject();

      project.accept(
          new IResourceVisitor() {
            public boolean visit(IResource resource) throws CoreException {
              worked();

              IPath parent = resource.getFullPath().removeLastSegments(1).removeFirstSegments(1);
              if (propertiesFilter.include(resource)) {
                String segment = localeSpecificName(resource.getFullPath().lastSegment(), locale);
                IPath fragmentResource =
                    fragmentProject.getFullPath().append(parent).append(segment);

                createParents(fragmentProject, parent);
                resource.copy(fragmentResource, true, getProgressMonitor());
              } else if (resourceFilter.include(resource)) {
                IPath target =
                    localeResourceFolder
                        .getFullPath()
                        .append(parent)
                        .append(resource.getFullPath().lastSegment());
                createParents(fragmentProject, target.removeLastSegments(1).removeFirstSegments(1));
                resource.copy(target, true, getProgressMonitor());
              }
              return true;
            }
          });
    }
  }