Index: DefaultInstallPackageService.java
===================================================================
--- DefaultInstallPackageService.java	(revision 43125)
+++ DefaultInstallPackageService.java	(revision 43126)
@@ -3,29 +3,27 @@
  *
  * Copyright (C) 2007-2013 gvSIG Association.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3 of the License, or (at your option) any later
+ * version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
- * For any additional information, do not hesitate to contact us
- * at info AT gvsig.com, or visit our website www.gvsig.com.
+ * For any additional information, do not hesitate to contact us at info AT
+ * gvsig.com, or visit our website www.gvsig.com.
  */
 /*
  * AUTHORS (In addition to CIT):
  * 2010 {Prodevelop}   {Task}
  */
-
 package org.gvsig.installer.lib.impl.execution;
 
 import java.io.BufferedInputStream;
@@ -43,7 +41,9 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,518 +68,565 @@
 /**
  * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodr&aacute;</a>
  */
-
 public class DefaultInstallPackageService extends Thread implements
-		InstallPackageService {
+        InstallPackageService {
 
-	private static final Logger LOG = LoggerFactory
-			.getLogger(DefaultInstallPackageService.class);
-	
-	private static final String PACKAGE_FILE_NAME = "packages.gvspki";
+    private static final Logger LOG = LoggerFactory
+            .getLogger(DefaultInstallPackageService.class);
 
-	private Map<PackageInfo, File> packageInfoFileMap = null;
-	private Map<PackageInfo, String> zipEntriesMap = null;
-	private List<PackageInfo> packageInfos = null;
-	private InstallerManager manager;
-	private InstallPackageProviderServices installerProviderServices = null;
+    private static final String PACKAGE_FILE_NAME = "packages.gvspki";
 
-	public DefaultInstallPackageService(DefaultInstallerManager manager) {
-		super();
-		this.manager = manager;
-		this.reset();
-	}
+    private Map<PackageInfo, File> packageInfoFileMap = null;
+    private Map<PackageInfo, String> zipEntriesMap = null;
+    private List<PackageInfo> packageInfos = null;
+    private InstallerManager manager;
+    private InstallPackageProviderServices installerProviderServices = null;
 
-	public void reset() {
-		packageInfoFileMap = new HashMap<PackageInfo, File>();
-		packageInfos = new ArrayList<PackageInfo>();
-		zipEntriesMap = new HashMap<PackageInfo, String>();
-		installerProviderServices = InstallerProviderLocator
-				.getProviderManager().createInstallerProviderServices();
-	}
+    public DefaultInstallPackageService(DefaultInstallerManager manager) {
+        super();
+        this.manager = manager;
+        this.reset();
+    }
 
-	public class InstallerApplicationDirectoryNotFoundException extends
-			InstallPackageServiceException {
+    public void reset() {
+        packageInfoFileMap = new HashMap<PackageInfo, File>();
+        packageInfos = new ArrayList<PackageInfo>();
+        zipEntriesMap = new HashMap<PackageInfo, String>();
+        installerProviderServices = InstallerProviderLocator
+                .getProviderManager().createInstallerProviderServices();
+    }
 
-		private static final long serialVersionUID = -1130408094135962456L;
+    public class InstallerApplicationDirectoryNotFoundException extends
+            InstallPackageServiceException {
 
-		private static final String message = "Aplication directory '%(directory)s' not found";
+        private static final long serialVersionUID = -1130408094135962456L;
 
-		private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
+        private static final String message = "Aplication directory '%(directory)s' not found";
 
-		public InstallerApplicationDirectoryNotFoundException(File file) {
-			super(message, KEY, serialVersionUID);
-			setValue("directory", file.toString());
-		}
+        private static final String KEY = "_aplication_directory_XdirectoryX_not_found";
 
-	}
+        public InstallerApplicationDirectoryNotFoundException(File file) {
+            super(message, KEY, serialVersionUID);
+            setValue("directory", file.toString());
+        }
 
-	public class InstallerNoDirectoryException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = -8685263049644983769L;
+    public class InstallerNoDirectoryException extends
+            InstallPackageServiceException {
 
-		private static final String message = "'%(directory)s' is not a directory";
+        private static final long serialVersionUID = -8685263049644983769L;
 
-		private static final String KEY = "_XdirectoryX_is_not_a_directory";
+        private static final String message = "'%(directory)s' is not a directory";
 
-		public InstallerNoDirectoryException(File file) {
-			super(message, KEY, serialVersionUID);
-			setValue("directory", file.toString());
-		}
+        private static final String KEY = "_XdirectoryX_is_not_a_directory";
 
-	}
+        public InstallerNoDirectoryException(File file) {
+            super(message, KEY, serialVersionUID);
+            setValue("directory", file.toString());
+        }
 
-	public class InstallerFileNotFoundException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = 556517830330132149L;
+    public class InstallerFileNotFoundException extends
+            InstallPackageServiceException {
 
-		private static final String message = "File '%(file)s' not found";
+        private static final long serialVersionUID = 556517830330132149L;
 
-		private static final String KEY = "_file_XfileX_not_found";
+        private static final String message = "File '%(file)s' not found";
 
-		public InstallerFileNotFoundException(File file) {
-			super(message, KEY, serialVersionUID);
-			setValue("file", file.toString());
-		}
+        private static final String KEY = "_file_XfileX_not_found";
 
-	}
+        public InstallerFileNotFoundException(File file) {
+            super(message, KEY, serialVersionUID);
+            setValue("file", file.toString());
+        }
 
-	public class InstallerBundleNotFoundException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = 5065410511582625301L;
+    public class InstallerBundleNotFoundException extends
+            InstallPackageServiceException {
 
-		private static final String message = "File '%(file)s' not found";
+        private static final long serialVersionUID = 5065410511582625301L;
 
-		private static final String KEY = "_file_XfileX_not_found";
+        private static final String message = "File '%(file)s' not found";
 
-		public InstallerBundleNotFoundException(File file,
-				FileNotFoundException e) {
-			super(message, e, KEY, serialVersionUID);
-			setValue("file", file.toString());
-		}
+        private static final String KEY = "_file_XfileX_not_found";
 
-	}
+        public InstallerBundleNotFoundException(File file,
+                FileNotFoundException e) {
+            super(message, e, KEY, serialVersionUID);
+            setValue("file", file.toString());
+        }
 
-	public class InstallerIOException extends InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = 3153613550157712363L;
+    public class InstallerIOException extends InstallPackageServiceException {
 
-		private static final String message = "IO error installing the file '%(file)s'";
+        private static final long serialVersionUID = 3153613550157712363L;
 
-		private static final String KEY = "_IO_error installing_file_XfileX_";
+        private static final String message = "IO error installing the file '%(file)s'";
 
-		public InstallerIOException(File file, IOException e) {
-			super(message, e, KEY, serialVersionUID);
-			setValue("file", file.toString());
-		}
+        private static final String KEY = "_IO_error installing_file_XfileX_";
 
-	}
+        public InstallerIOException(File file, IOException e) {
+            super(message, e, KEY, serialVersionUID);
+            setValue("file", file.toString());
+        }
 
-	public class InstallerFileDownloadException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = 8640183295766490512L;
+    public class InstallerFileDownloadException extends
+            InstallPackageServiceException {
 
-		private static final String message = "File '%(url)s' download error";
+        private static final long serialVersionUID = 8640183295766490512L;
 
-		private static final String KEY = "_File_XurlX_download_error";
+        private static final String message = "File '%(url)s' download error";
 
-		public InstallerFileDownloadException(URL url, IOException e) {
-			super(message, e, KEY, serialVersionUID);
-			setValue("url", url.toString());
-		}
+        private static final String KEY = "_File_XurlX_download_error";
 
-	}
+        public InstallerFileDownloadException(URL url, IOException e) {
+            super(message, e, KEY, serialVersionUID);
+            setValue("url", url.toString());
+        }
 
-	public class InstallerPackageNotFoundException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = 1726608498886963868L;
+    public class InstallerPackageNotFoundException extends
+            InstallPackageServiceException {
 
-		private static final String message = "Package not found";
+        private static final long serialVersionUID = 1726608498886963868L;
 
-		private static final String KEY = "_package_not_found";
+        private static final String message = "Package not found";
 
-		public InstallerPackageNotFoundException() {
-			super(message, KEY, serialVersionUID);
-		}
+        private static final String KEY = "_package_not_found";
 
-	}
+        public InstallerPackageNotFoundException() {
+            super(message, KEY, serialVersionUID);
+        }
 
-	public class InstallerNoPackageException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = -2292735515704746966L;
+    public class InstallerNoPackageException extends
+            InstallPackageServiceException {
 
-		private static final String message = "Package does not exist";
+        private static final long serialVersionUID = -2292735515704746966L;
 
-		private static final String KEY = "_package__does_not_exist";
+        private static final String message = "Package does not exist";
 
-		public InstallerNoPackageException() {
-			super(message, KEY, serialVersionUID);
-		}
+        private static final String KEY = "_package__does_not_exist";
 
-	}
+        public InstallerNoPackageException() {
+            super(message, KEY, serialVersionUID);
+        }
 
-	public class InstallerProviderCreationException extends
-			InstallPackageServiceException {
+    }
 
-		private static final long serialVersionUID = -7985786807492393584L;
+    public class InstallerProviderCreationException extends
+            InstallPackageServiceException {
 
-		private static final String message = "Error creating the provider";
+        private static final long serialVersionUID = -7985786807492393584L;
 
-		private static final String KEY = "_Error_creating_the_provider";
+        private static final String message = "Error creating the provider";
 
-		public InstallerProviderCreationException(ServiceException e) {
-			super(message, e, KEY, serialVersionUID);
-		}
+        private static final String KEY = "_Error_creating_the_provider";
 
-	}
+        public InstallerProviderCreationException(ServiceException e) {
+            super(message, e, KEY, serialVersionUID);
+        }
 
-	public void installPackage(File applicationDirectory,
-			PackageInfo packageInfo) throws InstallPackageServiceException {
-		if (!applicationDirectory.exists()) {
-			LOG.warn("Can install package '"+packageInfo.getCode()+"', application folder '"+applicationDirectory.toString()+"' does not exits.");
-			throw new InstallerApplicationDirectoryNotFoundException(
-					applicationDirectory);
-		}
-		if (!packageInfoFileMap.containsKey(packageInfo)) {
-			LOG.warn("Can install package '"+packageInfo.getCode()+"', package not found.");
-			throw new InstallerPackageNotFoundException();
-		}
+    }
 
-		InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
+    public void installPackage(File applicationDirectory,
+            PackageInfo packageInfo) throws InstallPackageServiceException {
+        if (!applicationDirectory.exists()) {
+            LOG.warn("Can install package '" + packageInfo.getCode() + "', application folder '" + applicationDirectory.toString() + "' does not exits.");
+            throw new InstallerApplicationDirectoryNotFoundException(
+                    applicationDirectory);
+        }
+        if (!packageInfoFileMap.containsKey(packageInfo)) {
+            LOG.warn("Can install package '" + packageInfo.getCode() + "', package not found.");
+            throw new InstallerPackageNotFoundException();
+        }
 
-		// Get the package or package set file
-		File file = packageInfoFileMap.get(packageInfo);
-		if (file == null) {
-			if (packageInfo.getDownloadURL() == null) {
-				throw new InstallerPackageNotFoundException();
-			}
-			this.downloadPackage(packageInfo);
-			file = packageInfoFileMap.get(packageInfo);
-		}
+        InstallPackageProvider installerExecutionProvider = createProvider(packageInfo);
 
-		// Open and install the package or package set file
-		try {
+        // Get the package or package set file
+        File file = packageInfoFileMap.get(packageInfo);
+        if (file == null) {
+            if (packageInfo.getDownloadURL() == null) {
+                throw new InstallerPackageNotFoundException();
+            }
+            this.downloadPackage(packageInfo);
+            file = packageInfoFileMap.get(packageInfo);
+        }
 
-			InputStream packageStream;
-			InputStream fis = new FileInputStream(file);
-			InputStream bis = new BufferedInputStream(fis);
-			if (isPackage(file)) {
-				packageStream = bis;
-			} else {
-				if (!isPackageSet(file)) {
-					LOG.info("Trying to install a package file ({0}) "
-							+ "without a known file extension. Will try "
-							+ "to install it as a package set", file);
-				}
-				packageStream = installerProviderServices.searchPackage(bis,
-						zipEntriesMap.get(packageInfo));
-			}
+        // Open and install the package or package set file
+        try {
 
-			try {
-				installerExecutionProvider.install(applicationDirectory,
-						packageStream, packageInfo);
-			} catch (InstallPackageServiceException e) {
+            InputStream packageStream;
+            InputStream fis = new FileInputStream(file);
+            InputStream bis = new BufferedInputStream(fis);
+            if (isPackage(file)) {
+                packageStream = bis;
+            } else {
+                if (!isPackageSet(file)) {
+                    LOG.info("Trying to install a package file ({0}) "
+                            + "without a known file extension. Will try "
+                            + "to install it as a package set", file);
+                }
+                packageStream = installerProviderServices.searchPackage(bis,
+                        zipEntriesMap.get(packageInfo));
+            }
 
-				packageStream.close();
-				if (bis != packageStream) {
-					bis.close();
-				}
-				fis.close();
+            try {
+                installerExecutionProvider.install(applicationDirectory,
+                        packageStream, packageInfo);
+            } catch (InstallPackageServiceException e) {
 
-				// if fails the installation, zip files need to be reopen
-				// the package will be installed into the update folder for
-				// installation after a gvSIG restart
+                packageStream.close();
+                if (bis != packageStream) {
+                    bis.close();
+                }
+                fis.close();
 
-				fis = new FileInputStream(file);
-				bis = new BufferedInputStream(fis);
-				if (isPackage(file)) {
-					packageStream = bis;
-				} else {
-					if (!isPackageSet(file)) {
-						LOG.info("Trying to install a package file ({0}) "
-								+ "without a known file extension. Will try "
-								+ "to install it as a package set", file);
-					}
-					packageStream = installerProviderServices.searchPackage(
-							bis, zipEntriesMap.get(packageInfo));
-				}
-				installerExecutionProvider.installLater(applicationDirectory,
-						packageStream, packageInfo);
-			}
+                // if fails the installation, zip files need to be reopen
+                // the package will be installed into the update folder for
+                // installation after a gvSIG restart
+                fis = new FileInputStream(file);
+                bis = new BufferedInputStream(fis);
+                if (isPackage(file)) {
+                    packageStream = bis;
+                } else {
+                    if (!isPackageSet(file)) {
+                        LOG.info("Trying to install a package file ({0}) "
+                                + "without a known file extension. Will try "
+                                + "to install it as a package set", file);
+                    }
+                    packageStream = installerProviderServices.searchPackage(
+                            bis, zipEntriesMap.get(packageInfo));
+                }
+                installerExecutionProvider.installLater(applicationDirectory,
+                        packageStream, packageInfo);
+            }
 
-			packageStream.close();
-			if (bis != packageStream) {
-				bis.close();
-			}
-			fis.close();
+            packageStream.close();
+            if (bis != packageStream) {
+                bis.close();
+            }
+            fis.close();
 
-		} catch (FileNotFoundException e) {
-			throw new InstallerFileNotFoundException(file);
-		} catch (IOException e) {
-			throw new InstallerIOException(file, e);
-		}
+        } catch (FileNotFoundException e) {
+            throw new InstallerFileNotFoundException(file);
+        } catch (IOException e) {
+            throw new InstallerIOException(file, e);
+        }
 
-	}
+    }
 
-	public void installPackage(File applicationDirectory, String packageCode)
-			throws InstallPackageServiceException {
-		PackageInfo packageInfo = getPackageInfo(packageCode);
-		if (packageInfo == null) {
-			throw new InstallerNoPackageException();
-		}
-		installPackage(applicationDirectory, packageInfo);
-	}
+    public void installPackage(File applicationDirectory, String packageCode)
+            throws InstallPackageServiceException {
+        PackageInfo packageInfo = getPackageInfo(packageCode);
+        if (packageInfo == null) {
+            throw new InstallerNoPackageException();
+        }
+        installPackage(applicationDirectory, packageInfo);
+    }
 
-	private InstallPackageProvider createProvider(PackageInfo packageInfo)
-			throws InstallPackageServiceException {
-		InstallerProviderManager installerProviderManager = (InstallerProviderManager) ((DefaultInstallerManager) manager)
-				.getProviderManager();
+    private InstallPackageProvider createProvider(PackageInfo packageInfo)
+            throws InstallPackageServiceException {
+        InstallerProviderManager installerProviderManager = (InstallerProviderManager) ((DefaultInstallerManager) manager)
+                .getProviderManager();
 
-		try {
-			return installerProviderManager.createExecutionProvider(packageInfo
-					.getType());
-		} catch (ServiceException e) {
-			throw new InstallerProviderCreationException(e);
-		}
-	}
+        try {
+            return installerProviderManager.createExecutionProvider(packageInfo
+                    .getType());
+        } catch (ServiceException e) {
+            throw new InstallerProviderCreationException(e);
+        }
+    }
 
-	public PackageInfo getPackageInfo(int index) {
-		if (index >= packageInfos.size()) {
-			return null;
-		}
-		return packageInfos.get(index);
-	}
+    public PackageInfo getPackageInfo(int index) {
+        if (index >= packageInfos.size()) {
+            return null;
+        }
+        return packageInfos.get(index);
+    }
 
-	public PackageInfo getPackageInfo(String packageCode) {
-		for (int i = 0; i < getPackageCount(); i++) {
-			if (packageInfos.get(i).getCode().equals(packageCode)) {
-				return packageInfos.get(i);
-			}
-		}
-		return null;
-	}
+    public PackageInfo getPackageInfo(String packageCode) {
+        for (int i = 0; i < getPackageCount(); i++) {
+            if (packageInfos.get(i).getCode().equals(packageCode)) {
+                return packageInfos.get(i);
+            }
+        }
+        return null;
+    }
 
-	public void addBundle(File bundle) throws InstallPackageServiceException {
+    @Override
+    public void addBundle(File bundle, SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
 
-		if (!bundle.exists()) {
-			throw new InstallPackageServiceException();
-		}
+        if (!bundle.exists()) {
+            throw new InstallPackageServiceException();
+        }
 
-		int packageInfoCount = packageInfos.size();
+        int packageInfoCount = packageInfos.size();
 
-		FileInputStream fis;
-		try {
-			fis = new FileInputStream(bundle);
-		} catch (FileNotFoundException e) {
-			throw new InstallerBundleNotFoundException(bundle, e);
-		}
-		BufferedInputStream bis = new BufferedInputStream(fis);
-		if (isPackage(bundle)) {
-			installerProviderServices.readPackageInfo(bis, packageInfos,
-					zipEntriesMap, bundle.getName());
-		} else {
-			if (!isPackageSet(bundle)) {
-				LOG
-						.info(
-								"Trying to add a package file ({0}) without a known "
-										+ "file extension. Will try to add it as a package set",
-								bundle);
-			}
-			installerProviderServices.readPackageSetInfo(fis, packageInfos,
-					zipEntriesMap);
-		}
-		try {
-			bis.close();
-			fis.close();
-		} catch (IOException e) {
-			LOG.info("Error closing the input streams of the package file: "
-					+ bundle, e);
-		}
+        FileInputStream fis;
+        try {
+            fis = new FileInputStream(bundle);
+        } catch (FileNotFoundException e) {
+            throw new InstallerBundleNotFoundException(bundle, e);
+        }
+        BufferedInputStream bis = new BufferedInputStream(fis);
+        if (isPackage(bundle)) {
+            installerProviderServices.readPackageInfo(bis, packageInfos,
+                    zipEntriesMap, bundle.getName(), taskStatus);
+        } else {
+            if (!isPackageSet(bundle)) {
+                LOG
+                        .info(
+                                "Trying to add a package file ({0}) without a known "
+                                + "file extension. Will try to add it as a package set",
+                                bundle);
+            }
+            installerProviderServices.readPackageSetInfo(fis, packageInfos,
+                    zipEntriesMap, taskStatus);
+        }
+        try {
+            bis.close();
+            fis.close();
+        } catch (IOException e) {
+            LOG.info("Error closing the input streams of the package file: "
+                    + bundle, e);
+        }
 
-		for (int i = packageInfoCount; i < packageInfos.size(); i++) {
-			packageInfoFileMap.put(packageInfos.get(i), bundle);
-		}
-	}
+        for (int i = packageInfoCount; i < packageInfos.size(); i++) {
+            packageInfoFileMap.put(packageInfos.get(i), bundle);
+        }
+    }
 
-	private boolean isPackageSet(File file) {
-		return file.getName().endsWith(
-				manager.getDefaultPackageSetFileExtension());
-	}
+    private boolean isPackageSet(File file) {
+        return file.getName().endsWith(
+                manager.getDefaultPackageSetFileExtension());
+    }
 
-	private boolean isPackage(File file) {
-		return file.getName()
-				.endsWith(manager.getDefaultPackageFileExtension());
-	}
+    private boolean isPackage(File file) {
+        return file.getName()
+                .endsWith(manager.getDefaultPackageFileExtension());
+    }
 
-	public void addBundle(URL bundleURL) throws InstallPackageServiceException {
-		File bundle;
-		String urlString = bundleURL.toString(); 
-		if (urlString.endsWith(InstallerManager.PACKAGE_EXTENSION) || urlString.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION)) {
+    @Override
+    public void addBundle(URL bundleURL, SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
+        File bundle;
+        String urlString = bundleURL.toString();
+        if (urlString.endsWith(InstallerManager.PACKAGE_EXTENSION) || urlString.endsWith(InstallerManager.PACKAGE_INDEX_EXTENSION)) {
             manager.setDownloadBaseURL(bundleURL);
-			bundle = downloadFile(bundleURL, PACKAGE_FILE_NAME);
-			addBundle(bundle);
-		} else {
-			if (!urlString.endsWith("/")) {
-				urlString += "/";
-			}
-			
-			Version version = manager.getVersionEx(); 
-			urlString += ("dists/"
-			+ version.getMayor() + "." + version.getMinor() + "."
-			+ version.getRevision() + "/" + PACKAGE_FILE_NAME);
-			
+            bundle = downloadFile(bundleURL, PACKAGE_FILE_NAME);
+            addBundle(bundle,taskStatus);
+        } else {
+            if (!urlString.endsWith("/")) {
+                urlString += "/";
+            }
 
-			URL completeURL;
-			try {
-				completeURL = new URL(urlString);
-			} catch (MalformedURLException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-				return;
-			}
+            Version version = manager.getVersionEx();
+            urlString += ("dists/"
+                    + version.getMayor() + "." + version.getMinor() + "."
+                    + version.getRevision() + "/" + PACKAGE_FILE_NAME);
 
+            URL completeURL;
+            try {
+                completeURL = new URL(urlString);
+            } catch (MalformedURLException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+                return;
+            }
+
             manager.setDownloadBaseURL(completeURL);
-			bundle = downloadFile(completeURL, PACKAGE_FILE_NAME);
-			addBundle(bundle);
-		}
+            bundle = downloadFile(completeURL, PACKAGE_FILE_NAME);
+            addBundle(bundle,taskStatus);
+        }
 
-	}
+    }
 
-	private File downloadFile(URL bundleURL, String defaultFileName)
-			throws InstallPackageServiceException {
-		try {
-			Download download = new Download();
-			return download.downloadFile(bundleURL, defaultFileName);
-		} catch (IOException e) {
-			throw new InstallerFileDownloadException(bundleURL, e);
-		}
-	}
+    private File downloadFile(URL bundleURL, String defaultFileName)
+            throws InstallPackageServiceException {
+        try {
+            Download download = new Download();
+            return download.downloadFile(bundleURL, defaultFileName);
+        } catch (IOException e) {
+            throw new InstallerFileDownloadException(bundleURL, e);
+        }
+    }
 
-	public void addBundlesFromDirectory(File directory)
-			throws InstallPackageServiceException {
-		if (!directory.isDirectory()) {
-			throw new InstallerNoDirectoryException(directory);
-		}
-		List<File> files = new ArrayList<File>();
+    @Override
+    public void addBundlesFromDirectory(File directory, SimpleTaskStatus taskStatus)
+            throws InstallPackageServiceException {
+        if (!directory.isDirectory()) {
+            throw new InstallerNoDirectoryException(directory);
+        }
+        List<File> files = new ArrayList<File>();
 
-		listRecursively(directory, new FileFilter() {
+        listRecursively(directory, new FileFilter() {
 
-			private String packageExt = manager
-					.getDefaultPackageFileExtension();
-			private String packageSetExt = manager
-					.getDefaultPackageSetFileExtension();
+            private String packageExt = manager
+                    .getDefaultPackageFileExtension();
+            private String packageSetExt = manager
+                    .getDefaultPackageSetFileExtension();
 
-			public boolean accept(File file) {
-				String name = file.getName().toLowerCase();
-				return file.isDirectory() || name.endsWith(packageExt)
-						|| name.endsWith(packageSetExt);
-			}
-		}, files);
-		for (int i = 0; i < files.size(); i++) {
-			if (files.get(i).isFile()) {
-				addBundle(files.get(i));
-			}
-		}
-	}
+            public boolean accept(File file) {
+                String name = file.getName().toLowerCase();
+                return file.isDirectory() || name.endsWith(packageExt)
+                        || name.endsWith(packageSetExt);
+            }
+        }, files);
+        for (int i = 0; i < files.size(); i++) {
+            if (files.get(i).isFile()) {
+                addBundle(files.get(i),taskStatus);
+            }
+        }
+    }
 
-	private void listRecursively(File fileOrDir, FileFilter filter,
-			List<File> files) {
-		files.add(fileOrDir);
+    private void listRecursively(File fileOrDir, FileFilter filter,
+            List<File> files) {
+        files.add(fileOrDir);
 
-		if (fileOrDir.isDirectory()) {
+        if (fileOrDir.isDirectory()) {
 
-			File[] dirContents = fileOrDir.listFiles(filter);
+            File[] dirContents = fileOrDir.listFiles(filter);
 
-			for (File f : dirContents) {
-				listRecursively(f, filter, files); // Recursively list.
-			}
-		} else {
-			files.add(fileOrDir);
-		}
-	}
+            for (File f : dirContents) {
+                listRecursively(f, filter, files); // Recursively list.
+            }
+        } else {
+            files.add(fileOrDir);
+        }
+    }
 
-	public int getPackageCount() {
-		if (packageInfos == null) {
-			return 0;
-		}
-		return packageInfos.size();
-	}
+    public int getPackageCount() {
+        if (packageInfos == null) {
+            return 0;
+        }
+        return packageInfos.size();
+    }
 
-	public Manager getManager() {
-		return this.manager;
-	}
+    public Manager getManager() {
+        return this.manager;
+    }
 
-	public void downloadPackage(PackageInfo packageInfo)
-			throws InstallPackageServiceException {
-		this.downloadPackage(packageInfo, null);
-	}
+    public void downloadPackage(PackageInfo packageInfo)
+            throws InstallPackageServiceException {
+        this.downloadPackage(packageInfo, null);
+    }
 
-	public void downloadPackage(PackageInfo packageInfo,
-			SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
-	    
-		File file = null;
-		
-		try {
-            file = packageInfo.downloadFile(taskStatus);
-        } catch (BaseException e) {
-            throw new InstallPackageServiceException(e);
+    public void downloadPackage(PackageInfo packageInfo,
+            SimpleTaskStatus taskStatus) throws InstallPackageServiceException {
+
+        File file = packageInfoFileMap.get(packageInfo);
+        if (file == null) {
+            try {
+                file = packageInfo.downloadFile(taskStatus);
+            } catch (BaseException e) {
+                throw new InstallPackageServiceException(e);
+            }
+            this.packageInfoFileMap.put(packageInfo, file);
         }
-		this.packageInfoFileMap.put(packageInfo, file);
-	}
+    }
 
-	public List<String> getDefaultSelectedPackagesIDs() {
-		return installerProviderServices.getDefaultSelectedPackagesIDs();
-	}
+    public List<String> getDefaultSelectedPackagesIDs() {
+        return installerProviderServices.getDefaultSelectedPackagesIDs();
+    }
 
-	public List<String> getCategories() {
-		Set<String> categories = new HashSet<String>();
+    @Override
+    public Properties getProperties() {
+        return installerProviderServices.getProperties();
+    }
 
-		for (int i = 0; i < packageInfos.size(); i++) {
-			PackageInfo pkginfo = packageInfos.get(i);
-			List<String> pkgcategories = pkginfo.getCategories();
-			categories.addAll(pkgcategories);
-		}
-		try {
-			PackageInfo[] pkgs = manager.getInstalledPackages();
-			for (int i = 0; i < pkgs.length; i++) {
-				PackageInfo pkginfo = pkgs[i];
-				List<String> pkgcategories = pkginfo.getCategories();
-				categories.addAll(pkgcategories);
-			}
-			
-		} catch (MakePluginPackageServiceException e) {
-			// Ignore exceptions
-		}
-		ArrayList<String> l = new ArrayList<String>(categories);
-		Collections.sort(l);
-		return l;
-	}
+    public List<String> getCategories() {
+        Set<String> categories = new HashSet<String>();
 
-	public List<String> getTypes() {
-		Set<String> types = new HashSet<String>();
+        for (int i = 0; i < packageInfos.size(); i++) {
+            PackageInfo pkginfo = packageInfos.get(i);
+            List<String> pkgcategories = pkginfo.getCategories();
+            categories.addAll(pkgcategories);
+        }
+        try {
+            PackageInfo[] pkgs = manager.getInstalledPackages();
+            for (int i = 0; i < pkgs.length; i++) {
+                PackageInfo pkginfo = pkgs[i];
+                List<String> pkgcategories = pkginfo.getCategories();
+                categories.addAll(pkgcategories);
+            }
 
-		for (int i = 0; i < packageInfos.size(); i++) {
-			PackageInfo pkginfo = packageInfos.get(i);
-			types.add(pkginfo.getType());
-		}
-		try {
-			PackageInfo[] pkgs = manager.getInstalledPackages();
-			for (int i = 0; i < pkgs.length; i++) {
-				PackageInfo pkginfo = pkgs[i];
-				types.add(pkginfo.getType());
-			}
-			
-		} catch (MakePluginPackageServiceException e) {
-			// Ignore exceptions
-		}
-		ArrayList<String> l = new ArrayList<String>(types);
-		Collections.sort(l);
-		return l;
-	}
+        } catch (MakePluginPackageServiceException e) {
+            // Ignore exceptions
+        }
+        ArrayList<String> l = new ArrayList<String>(categories);
+        Collections.sort(l);
+        return l;
+    }
 
+    public List<String> getTypes() {
+        Set<String> types = new HashSet<String>();
+
+        for (int i = 0; i < packageInfos.size(); i++) {
+            PackageInfo pkginfo = packageInfos.get(i);
+            types.add(pkginfo.getType());
+        }
+        try {
+            PackageInfo[] pkgs = manager.getInstalledPackages();
+            for (int i = 0; i < pkgs.length; i++) {
+                PackageInfo pkginfo = pkgs[i];
+                types.add(pkginfo.getType());
+            }
+
+        } catch (MakePluginPackageServiceException e) {
+            // Ignore exceptions
+        }
+        List<String> l = new ArrayList<>(types);
+        Collections.sort(l);
+        return l;
+    }
+
+    @Override
+    public boolean needInstallPackageProviders() {
+        boolean need = false;
+        String ss = this.getProperties().getProperty("installers");
+        if (ss != null) {
+            String[] installerNames = StringUtils.split(ss);
+            for (String installerName : installerNames) {
+                InstallerProviderInstallers installer = new InstallerProviderInstallers(this, installerName);
+                if( !installer.isAlreadyRegistered() ) {
+                    need = true;
+                    break;
+                }
+            }
+        }
+        return need;
+    }
+
+    @Override
+    public void installPackageProviders(SimpleTaskStatus taskStatus) {
+        Properties props = this.getProperties();
+        String ss = props.getProperty("installers");
+        if (ss == null) {
+            return;
+        }
+
+        try {
+            String[] installerNames = StringUtils.split(ss);
+            taskStatus.setRangeOfValues(0, installerNames.length);
+            int count=0;
+            for (String installerName : installerNames) {
+                taskStatus.message(installerName);
+                taskStatus.setCurValue(count++);
+                InstallerProviderInstallers installer = new InstallerProviderInstallers(this, installerName);
+                installer.install();
+            }
+            taskStatus.setCurValue(count++);
+        } finally {
+            taskStatus.terminate();
+        }
+    }
+
 }
