/*******************************************************************************
 * Copyright (c) 2006, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Chris Aniszczyk (IBM Corp.) - NL-enabled the site optimizer
 *******************************************************************************/
package org.eclipse.update.internal.provisional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.IIncludedFeatureReference;
import org.eclipse.update.core.IncludedFeatureReference;
import org.eclipse.update.core.model.DefaultSiteParser;
import org.eclipse.update.core.model.FeatureModel;
import org.eclipse.update.core.model.FeatureModelFactory;
import org.eclipse.update.core.model.FeatureReferenceModel;
import org.eclipse.update.core.model.ImportModel;
import org.eclipse.update.core.model.PluginEntryModel;
import org.eclipse.update.core.model.SiteModel;
import org.eclipse.update.core.model.URLEntryModel;
import org.eclipse.update.internal.core.ExtendedSiteURLFactory;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.jarprocessor.JarProcessor;
import org.eclipse.update.internal.jarprocessor.JarProcessorExecutor;
import org.eclipse.update.internal.jarprocessor.Main;
import org.xml.sax.SAXException;

/**
 * The application class used to perform update site optimizations.
 * <p>
 * This class can only be referenced from <code>org.eclipse.runtime.applications</code>
 * extension point. It should not be extended or instantiated.
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 * </p>
 * 
 * @since 3.2
 */
public class SiteOptimizerApplication implements IPlatformRunnable {
	public final static Integer EXIT_ERROR = Integer.valueOf(1);

	public final static String JAR_PROCESSOR = "-jarProcessor"; //$NON-NLS-1$

	public final static String DIGEST_BUILDER = "-digestBuilder"; //$NON-NLS-1$

	public final static String INPUT = "input"; //$NON-NLS-1$

	public final static String OUTPUT_DIR = "-outputDir"; //$NON-NLS-1$

	public final static String VERBOSE = "-verbose"; //$NON-NLS-1$

	public final static String JAR_PROCESSOR_PACK = "-pack"; //$NON-NLS-1$

	public final static String JAR_PROCESSOR_UNPACK = "-unpack"; //$NON-NLS-1$

	public final static String JAR_PROCESSOR_REPACK = "-repack"; //$NON-NLS-1$

	public final static String JAR_PROCESSOR_SIGN = "-sign"; //$NON-NLS-1$

	public final static String JAR_PROCESSOR_PROCESS_ALL = "-processAll"; //$NON-NLS-1$

	public final static String SITE_XML = "-siteXML"; //$NON-NLS-1$

	public final static String SITE_ATTRIBUTES_FILE = "siteAttributes.txt"; //$NON-NLS-1$

	public final static String DIGEST_OUTPUT_DIR = "-digestOutputDir"; //$NON-NLS-1$

	/*
	 * private final static String DESCRIPTION = "DESCRIPTION"; private final
	 * static String LICENCE = "LICENCE"; private final static String COPYRIGHT =
	 * "COPYRIGHT"; private final static String FEATURE_LABEL = "FEATURE_LABEL";
	 */

	/**
	 * Parses the command line in the form: [-key [value]]* [inputvalue] If the
	 * last argument does not start with a "-" then it is taken as the input
	 * value and not the value for a preceding -key
	 * 
	 * @param args
	 * @return
	 */
	private Map parseCmdLine(String[] args) {
		Map cmds = new HashMap();
		for (int i = 0; i < args.length; i++) {
			if (i == args.length - 1 && !args[i].startsWith("-")) { //$NON-NLS-1$
				cmds.put(INPUT, args[i]);
			} else {
				String key = args[i];
				String val = null;
				if (i < args.length - 2 && !args[i + 1].startsWith("-")) { //$NON-NLS-1$
					val = args[++i];
				}

				if (key.startsWith(SITE_XML)) {
					// System.out.println(val.indexOf(":null"));
					val = key.substring(key.indexOf("=") + 1); //$NON-NLS-1$
					// System.out.println(key + ":" + val);
					cmds.put(SITE_XML, val);
				} else if (key.startsWith(DIGEST_OUTPUT_DIR)) {
					val = key.substring(key.indexOf("=") + 1); //$NON-NLS-1$
					// System.out.println(key + ":" + val);
					cmds.put(DIGEST_OUTPUT_DIR, val);
				} else {

					// System.out.println(key + ":" + val);
					cmds.put(key, val);
				}
			}
		}
		return cmds;
	}

	private boolean runJarProcessor(Map params) {
		Main.Options options = new Main.Options();
		options.pack = params.containsKey(JAR_PROCESSOR_PACK);
		options.unpack = params.containsKey(JAR_PROCESSOR_UNPACK);
		options.repack = params.containsKey(JAR_PROCESSOR_REPACK);
		options.processAll = params.containsKey(JAR_PROCESSOR_PROCESS_ALL);
		options.verbose = params.containsKey(VERBOSE);
		options.signCommand = (String) params.get(JAR_PROCESSOR_SIGN);
		options.outputDir = (String) params.get(OUTPUT_DIR);

		String problem = null;

		String input = (String) params.get(INPUT);
		if (input == null)
			problem = Messages.SiteOptimizer_inputNotSpecified;
		else {
			File inputFile = new File(input);
			if (inputFile.exists())
				options.input = inputFile;
			else
				problem = NLS.bind(Messages.SiteOptimizer_inputFileNotFound,
						new String[] { input });
		}

		if (options.unpack) {
			if (!JarProcessor.canPerformUnpack()) {
				problem = Messages.JarProcessor_unpackNotFound;
			} else if (options.pack || options.repack
					|| options.signCommand != null) {
				problem = Messages.JarProcessor_noPackUnpack;
			}
		} else if ((options.pack || options.repack)
				&& !JarProcessor.canPerformPack()) {
			problem = Messages.JarProcessor_packNotFound;
		}

		if (problem != null) {
			System.out.println(problem);
			return false;
		}

		new JarProcessorExecutor().runJarProcessor(options);
		return true;
	}

	private boolean runDigestBuilder(Map params) {

		List featureList = getFeatureList(params);

		if ((featureList == null) || featureList.isEmpty()) {
			System.out.println("no features to process"); //$NON-NLS-1$
			return false;
		}
		Map perFeatureLocales = new HashMap();
		Map availableLocales = getAvailableLocales(featureList,
				perFeatureLocales);
		try {
			openInputStremas(availableLocales);
		} catch (IOException e1) {
			e1.printStackTrace();
			System.out.println("Can not create file in output direcotry"); //$NON-NLS-1$
			return false;
		}

		for(int i = 0; i < featureList.size(); i++) {

			String featureJarFileName = (String) featureList.get(i);

			if (featureJarFileName.endsWith("jar")) { //$NON-NLS-1$
				System.out.println("Processing... " + featureJarFileName); //$NON-NLS-1$
			} else {
				System.out.println("Skipping... " + featureJarFileName); //$NON-NLS-1$
				continue;
			}

			JarFile featureJar = null;
			try {
				featureJar = new JarFile(featureJarFileName);
			} catch (IOException e) {
				System.out.println("Problem with opening jar: " //$NON-NLS-1$
						+ featureJarFileName);
				e.printStackTrace();
				return false;
			}
			FeatureModelFactory fmf = new FeatureModelFactory();

			try {
				ZipEntry featureXMLEntry = featureJar.getEntry("feature.xml"); //$NON-NLS-1$
				Map featureProperties = loadProperties(featureJar,
						featureJarFileName, perFeatureLocales);

				FeatureModel featureModel = fmf.parseFeature(featureJar
						.getInputStream(featureXMLEntry));

				featureList = addFeaturesToList( (String) params.get(SITE_XML), featureList, featureModel.getFeatureIncluded(), availableLocales, perFeatureLocales);

				Iterator availableLocalesIterator = availableLocales.values()
				.iterator();
				while (availableLocalesIterator.hasNext()) {
					((AvailableLocale) availableLocalesIterator.next())
					.writeFeatureDigests(featureModel,
							featureProperties);
				}

			} catch (SAXException e) {
				e.printStackTrace();
				return false;
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			} catch (CoreException e) {
				e.printStackTrace();
				return false;
			}
		}
		Iterator availableLocalesIterator = availableLocales.values()
		.iterator();
		String outputDirectory = (String) params.get(DIGEST_OUTPUT_DIR);

		outputDirectory = outputDirectory.substring(outputDirectory
				.indexOf("=") + 1); //$NON-NLS-1$
		if (!outputDirectory.endsWith(File.separator)) {
			outputDirectory = outputDirectory + File.separator;
		}
		while (availableLocalesIterator.hasNext()) {
			try {
				((AvailableLocale) availableLocalesIterator.next())
				.finishDigest(outputDirectory);
			} catch (IOException e) {
				System.out.println("Can not write in digest output directory: " //$NON-NLS-1$
						+ outputDirectory);
				e.printStackTrace();
				return false;
			}
		}
		System.out.println("Done"); //$NON-NLS-1$
		return true;
	}

	private List addFeaturesToList( String siteXML, List featureList, IIncludedFeatureReference[] iIncludedFeatureReferences, Map availableLocales, Map perFeatureLocales ) throws CoreException {

		String directoryName = (new File(siteXML)).getParent();
		if (!directoryName.endsWith(File.separator)) {
			directoryName = directoryName + File.separator;
		}
		directoryName = directoryName + "features" + File.separator; //$NON-NLS-1$

		for (int i = 0; i < iIncludedFeatureReferences.length; i++) {
			String featureURL = directoryName + iIncludedFeatureReferences[i].getVersionedIdentifier() + ".jar"; //$NON-NLS-1$
			if (!(isFeatureAlreadyInList(featureList, featureURL))) {
				try {
					System.out.println("Extracting locales from included feature " + featureURL); //$NON-NLS-1$
					processLocalesInJar(availableLocales, featureURL, perFeatureLocales, true);
				} catch (IOException e) {
					if (iIncludedFeatureReferences[i].isOptional()) 
						continue;
					System.out.println("Error while extracting locales from included feature " + featureURL);//$NON-NLS-1$	
					e.printStackTrace();
					throw new CoreException( new Status( IStatus.ERROR, UpdateCore.getPlugin().getBundle().getSymbolicName(), IStatus.OK, "Error while extracting locales from included feature " + featureURL, e)); //$NON-NLS-1$ 
				}
				featureList.add(featureURL);
			}
		}

		return featureList;
	}

	private boolean isFeatureAlreadyInList(List featureList, String featureURL) {
		for (int i = 0; i < featureList.size(); i++) {
			String currentFeatureURL = (String)featureList.get(i);
			if (currentFeatureURL.equals(featureURL)) {
				return true;
			}
		}
		return false;
	}

	private Map loadProperties(JarFile featureJar, String featureJarFileName,
			Map perFeatureLocales) {
		// System.out.println(
		// ((List)perFeatureLocales.get(featureJarFileName)).size());
		Iterator it = ((List) perFeatureLocales.get(featureJarFileName))
		.iterator();
		Map result = new HashMap();
		while (it.hasNext()) {
			String propertyFileName = (String) it.next();

			ZipEntry featurePropertiesEntry = featureJar
			.getEntry(propertyFileName);
			Properties featureProperties = new Properties();
			if (featurePropertiesEntry != null) {
				try {
					featureProperties.load(featureJar
							.getInputStream(featurePropertiesEntry));
					String localeString = null;
					if (propertyFileName.endsWith("feature.properties")) { //$NON-NLS-1$
						localeString = ""; //$NON-NLS-1$
					} else {
						localeString = propertyFileName.substring(8,
								propertyFileName.indexOf('.'));
					}
					result.put(localeString, featureProperties);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	private void openInputStremas(Map availableLocales) throws IOException {
		Iterator locales = availableLocales.values().iterator();
		while (locales.hasNext()) {
			AvailableLocale availableLocale = (AvailableLocale) locales.next();
			availableLocale.openLocalizedOutputStream();
		}
	}

	private Map getAvailableLocales(List featureList, Map perFeatureLocales) {
		Iterator features = featureList.iterator();
		Map locales = new HashMap();
		while (features.hasNext()) {
			String feature = (String) features.next();
			try {
				System.out.println("Extracting locales from " + feature); //$NON-NLS-1$
				processLocalesInJar(locales, feature, perFeatureLocales, false);
			} catch (IOException e) {
				System.out.println("Error while extracting locales from " //$NON-NLS-1$
						+ feature);
				e.printStackTrace();
				return null;
			}
		}
		return locales;
	}

	private void processLocalesInJar(Map locales, String feature,
			Map perFeatureLocales, boolean ignoreNewLocales) throws IOException {

		JarFile jar = new JarFile(feature);
		// System.out.println(feature);
		Enumeration files = jar.entries();

		List localesTemp = new ArrayList();
		perFeatureLocales.put(feature, localesTemp);

		while (files.hasMoreElements()) {
			ZipEntry file = (ZipEntry) files.nextElement();
			String localeString = null;
			String name = file.getName();
			// System.out.println("processLocalesInJar:"+name);
			if (name.startsWith("feature") && name.endsWith(".properties")) { //$NON-NLS-1$ //$NON-NLS-2$
				// System.out.println(name);
				localesTemp.add(name);
				// System.out.println(name);
				if (name.endsWith("feature.properties")) { //$NON-NLS-1$
					localeString = ""; //$NON-NLS-1$
				} else {
					localeString = name.substring(8, name.indexOf('.'));
				}
				// System.out.println(name +"::::\"" + localeString + "\"");
				if ( !ignoreNewLocales && !locales.containsKey(localeString)) {
					locales.put(localeString, new AvailableLocale(localeString));
				}
				if (locales.containsKey(localeString)) {
					AvailableLocale currentLocale = (AvailableLocale) locales.get(localeString);
					currentLocale.addFeatures(feature);
				}
			}
		}

	}

	private List getFeatureList(Map params) {
		if (params.containsKey(SITE_XML)
				&& (fileExists((String) params.get(SITE_XML)))) {
			return getFeatureListFromSiteXML((String) params.get(SITE_XML));
		} else if (params.containsKey(INPUT)
				&& isDirectory((String) params
						.get(SiteOptimizerApplication.INPUT))) {
			return getFeatureListFromDirectory((String) params.get(INPUT));
		}
		return null;
	}

	private boolean fileExists(String fileName) {
		// System.out.println("fileExists:"+fileName);
		File file = new File(fileName);
		if ((file != null) && file.exists())
			return true;
		return false;
	}

	private List getFeatureListFromDirectory(String directoryName) {
		List featuresURLs = new ArrayList();
		File directory = new File(directoryName);
		String[] featureJarFileNames = directory.list();
		for (int i = 0; i < featureJarFileNames.length; i++) {
			featuresURLs.add(directoryName + File.separator
					+ featureJarFileNames[i]);
		}
		return featuresURLs;
	}

	private boolean isDirectory(String fileName) {

		File directory = new File(fileName);
		if ((directory != null) && directory.exists()
				&& directory.isDirectory())
			return true;
		return false;
	}

	private List getFeatureListFromSiteXML(String siteXML) {

		List featuresURLs = new ArrayList();
		String directoryName = (new File(siteXML)).getParent();
		if (!directoryName.endsWith(File.separator)) {
			directoryName = directoryName + File.separator;
		}

		DefaultSiteParser siteParser = new DefaultSiteParser();
		siteParser.init(new ExtendedSiteURLFactory());

		try {
			SiteModel site = siteParser.parse(new FileInputStream(siteXML));
			if(site.getFeatureReferenceModels().length > 0) {
				site.getFeatureReferenceModels()[0].getURLString();
				FeatureReferenceModel[] featureReferenceModel = site
				.getFeatureReferenceModels();
				for (int i = 0; i < featureReferenceModel.length; i++) {
					featuresURLs.add(directoryName
							+ featureReferenceModel[i].getURLString());
				}
			}
			return featuresURLs;
		} catch (FileNotFoundException e) {
			System.out.println("File not found: " + e.getMessage()); //$NON-NLS-1$
			e.printStackTrace();
		} catch (SAXException e) {
			System.out.println("Parsing problem: " + e.getMessage()); //$NON-NLS-1$
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Problem while parsing: " + e.getMessage()); //$NON-NLS-1$
			e.printStackTrace();
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IPlatformRunnable#run(java.lang.Object)
	 */
	public Object run(Object args) throws Exception {
		Platform.endSplash();
		if (args == null)
			return EXIT_ERROR;
		if (args instanceof String[]) {
			Map params = parseCmdLine((String[]) args);
			if (params.containsKey(JAR_PROCESSOR)) {
				if (!runJarProcessor(params))
					return EXIT_ERROR;
			}

			if (params.containsKey(DIGEST_BUILDER)) {
				if (!runDigestBuilder(params))
					return EXIT_ERROR;
			}
		}
		return IPlatformRunnable.EXIT_OK;
	}

	private class AvailableLocale {

		private String PREFIX = "temp"; //$NON-NLS-1$

		private String locale;

		private Map /* VersionedIdentifier */features = new HashMap();

		private PrintWriter localizedPrintWriter;

		private File tempDigestDirectory;

		public void finishDigest(String outputDirectory) throws IOException {
			localizedPrintWriter.println("</digest>"); //$NON-NLS-1$
			if (localizedPrintWriter != null) {
				localizedPrintWriter.close();
			}

			File digest = new File(outputDirectory + File.separator + "digest" //$NON-NLS-1$
					+ (locale == null || locale.equals("") ? "" : "_"+locale) + ".zip"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			System.out.println(digest.getAbsolutePath());
			System.out.println(digest.getName());
			if (digest.exists()) {
				digest.delete();
			}
			digest.createNewFile();
			OutputStream os = new FileOutputStream(digest);
			JarOutputStream jos = new JarOutputStream(os);
			jos.putNextEntry(new ZipEntry("digest.xml")); //$NON-NLS-1$
			InputStream is = new FileInputStream(tempDigestDirectory);
			byte[] b = new byte[4096];
			int bytesRead = 0;
			do {
				bytesRead = is.read(b);
				if (bytesRead > 0) {
					jos.write(b, 0, bytesRead);
				}
			} while (bytesRead > 0);

			jos.closeEntry();
			jos.close();
			os.close();
			is.close();
			tempDigestDirectory.delete();

		}

		public AvailableLocale(String locale) {
			this.locale = locale;
		}

		public void addFeatures(String feature) {
			features.put(feature, feature);
		}

		public void openLocalizedOutputStream() throws IOException {
			tempDigestDirectory = File.createTempFile(PREFIX, null);
			FileOutputStream fstream = new FileOutputStream(tempDigestDirectory);
			localizedPrintWriter = new PrintWriter(new OutputStreamWriter(fstream, "UTF-8")); //$NON-NLS-1$
			localizedPrintWriter
			.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <digest>"); //$NON-NLS-1$
			tempDigestDirectory.deleteOnExit();
		}

		public int hashCode() {
			return locale.hashCode();
		}

		public boolean equals(Object obj) {

			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final AvailableLocale other = (AvailableLocale) obj;
			if (locale == null) {
				if (other.locale != null)
					return false;
			} else if (!locale.equals(other.locale))
				return false;
			return true;
		}

		public void writeFeatureDigests(FeatureModel featureModel,
				Map featureProperties) {

			if (this.locale.equals("")) { //$NON-NLS-1$
				writeFeatureDigest(localizedPrintWriter, featureModel,
						(Properties) featureProperties.get("")); //$NON-NLS-1$
				return;
			}
			Properties temp = new Properties();
			if (locale.indexOf("_") < 0) { //$NON-NLS-1$
				temp = combineProperties(
						(Properties) featureProperties.get(""), //$NON-NLS-1$
						(Properties) featureProperties.get(locale), null);
				writeFeatureDigest(localizedPrintWriter, featureModel, temp);
			} else {
				temp = combineProperties(
						(Properties) featureProperties.get(""), //$NON-NLS-1$
						(Properties) featureProperties.get(locale.substring(0, locale.indexOf("_"))), //$NON-NLS-1$
						(Properties) featureProperties.get(locale) );
				writeFeatureDigest(localizedPrintWriter, featureModel, temp);
			}

		}
		
		/**
		 * @param defaults	Should be lang_country
		 * @param secondary	Should be lang
		 * @param preferred	Should be default
		 * @return
		 */

		private Properties combineProperties(Properties defaults,
				Properties secondary, Properties preferred) {
			return new CombinedProperties(preferred, secondary, defaults);

		}

	}

	public static void writeFeatureDigest(PrintWriter digest,
			FeatureModel featureModel, Properties featureProperties) {

		String label = null;
		String provider = null;
		String description = null;
		String license = null;
		String copyright = null;

		if ((featureProperties != null)
				&& featureModel.getLabel().startsWith("%")) { //$NON-NLS-1$
			label = featureProperties.getProperty(featureModel.getLabel()
					.substring(1));
		} else {
			label = featureModel.getLabel();
		}
		if ((featureProperties != null)
				&& (featureModel.getDescriptionModel() != null)
				&& (featureModel.getDescriptionModel().getAnnotation() != null)
				&& featureModel.getDescriptionModel().getAnnotation()
				.startsWith("%")) { //$NON-NLS-1$
			// System.out.println(featureProperties.getProperty(featureModel.getDescriptionModel().getAnnotation().substring(1)));
			description = featureProperties.getProperty(featureModel
					.getDescriptionModel().getAnnotation().substring(1));
		} else {
			URLEntryModel descriptionModel = featureModel.getDescriptionModel();
			if( descriptionModel == null )
				description = "";
			else
				description = descriptionModel.getAnnotation();
		}
		String pvalue = featureModel.getProvider();
		if ((featureProperties != null)
				&& pvalue!=null && pvalue.startsWith("%")) { //$NON-NLS-1$
			provider = featureProperties.getProperty(featureModel.getProvider()
					.substring(1));
		} else {
			provider = pvalue;
		}
		if (provider==null) provider = "";

		if (((featureProperties != null) && featureModel.getCopyrightModel() != null)
				&& featureModel.getCopyrightModel().getAnnotation().startsWith(
				"%")) { //$NON-NLS-1$
			copyright = featureProperties.getProperty(featureModel
					.getCopyrightModel().getAnnotation().substring(1));
		} else {
			if (featureModel.getCopyrightModel() != null) {
				copyright = featureModel.getCopyrightModel().getAnnotation();
			} else {
				copyright = null;
			}
		}

		if ((featureProperties != null)
				&& (featureModel.getLicenseModel() != null)
				&& featureModel.getLicenseModel().getAnnotation().startsWith(
				"%")) { //$NON-NLS-1$
			license = featureProperties.getProperty(featureModel
					.getLicenseModel().getAnnotation().substring(1));
		} else {
			license = featureModel.getLicenseModel().getAnnotation();
		}

		digest.print("<feature "); //$NON-NLS-1$
		digest.print("label=\"" + getUTF8String(label) + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
		digest.print("provider-name=\"" + getUTF8String(provider) + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
		digest.print("id=\"" + featureModel.getFeatureIdentifier() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
		digest.print("version=\"" + featureModel.getFeatureVersion() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
		if (featureModel.getOS() != null)
			digest.print("os=\"" + featureModel.getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
		if (featureModel.getNL() != null)
			digest.print("nl=\"" + featureModel.getNL() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
		if (featureModel.getWS() != null)
			digest.print("ws=\"" + featureModel.getWS() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
		if (featureModel.getOSArch() != null)
			digest.print("arch=\"" + featureModel.getOSArch() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
		if (featureModel.isExclusive())
			digest.print("exclusive=\"" + featureModel.isExclusive() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$

		if (((featureModel.getImportModels() == null) || (featureModel
				.getImportModels().length == 0))
				&& ((featureModel.getDescriptionModel() == null)
						|| (featureModel.getDescriptionModel().getAnnotation() == null) || (featureModel
								.getDescriptionModel().getAnnotation().trim().length() == 0))
								&& ((featureModel.getCopyrightModel() == null)
										|| (featureModel.getCopyrightModel().getAnnotation() == null) || (featureModel
												.getCopyrightModel().getAnnotation().trim().length() == 0))
												&& ((featureModel.getLicenseModel() == null)
														|| (featureModel.getLicenseModel().getAnnotation() == null) || (featureModel
																.getLicenseModel().getAnnotation().trim().length() == 0)) 
																&& ((featureModel.getFeatureIncluded() == null) || (featureModel
																		.getFeatureIncluded().length == 0))){
			digest.println("/> "); //$NON-NLS-1$
		} else {
			digest.println("> "); //$NON-NLS-1$
			if (featureModel.getImportModels().length > 0) {

				digest.println("\t<requires> "); //$NON-NLS-1$
				ImportModel[] imports = featureModel.getImportModels();
				for (int j = 0; j < imports.length; j++) {
					digest.print("\t\t<import "); //$NON-NLS-1$
					if (imports[j].isFeatureImport()) {
						digest.print("feature=\""); //$NON-NLS-1$
					} else {
						digest.print("plugin=\""); //$NON-NLS-1$
					}
					digest.print(imports[j].getIdentifier() + "\" "); //$NON-NLS-1$
					digest.print("version=\""); //$NON-NLS-1$
					digest.print(imports[j].getVersion() + "\" "); //$NON-NLS-1$
					digest.print("match=\""); //$NON-NLS-1$
					digest.print(imports[j].getMatchingRuleName() + "\" "); //$NON-NLS-1$
					if (imports[j].isPatch()) {
						digest.print("patch=\"true\" "); //$NON-NLS-1$
					}
					digest.println(" />"); //$NON-NLS-1$
				}

				digest.println("\t</requires>"); //$NON-NLS-1$

			}

			if ((featureModel.getDescriptionModel() != null)
					&& (featureModel.getDescriptionModel().getAnnotation() != null)
					&& (featureModel.getDescriptionModel().getAnnotation()
							.trim().length() != 0)) {
				digest.println("\t<description>"); //$NON-NLS-1$
				digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(description)); //$NON-NLS-1$
				digest.println("\t</description>"); //$NON-NLS-1$
			}

			if (featureModel.getCopyrightModel() != null) {
				if (featureModel.getCopyrightModel().getAnnotation() != null) {
					// if
					// (featureModel.getDescriptionModel().getAnnotation().length()
					// != 0) {
					digest.println("\t<copyright>"); //$NON-NLS-1$
					digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(copyright)); //$NON-NLS-1$
					digest.println("\t</copyright>"); //$NON-NLS-1$
					// }
				}
			}

			if ((featureModel.getLicenseModel() != null)
					&& (featureModel.getLicenseModel().getAnnotation() != null)
					&& (featureModel.getLicenseModel().getAnnotation()
							.trim().length() != 0)) {
				digest.println("\t<license>"); //$NON-NLS-1$
				digest.println("\t\t" + UpdateManagerUtils.getWritableXMLString(license)); //$NON-NLS-1$
				digest.println("\t</license>"); //$NON-NLS-1$
			}

			PluginEntryModel[] plugins = featureModel.getPluginEntryModels();
			if ((plugins != null) && (plugins.length != 0)) {
				for (int i = 0; i < plugins.length; i++) {
					digest.print("\t<plugin "); //$NON-NLS-1$
					digest.print("id=\"" + plugins[i].getPluginIdentifier() //$NON-NLS-1$
							+ "\" "); //$NON-NLS-1$
					digest.print("version=\"" + plugins[i].getPluginVersion() //$NON-NLS-1$
							+ "\" "); //$NON-NLS-1$
					if (plugins[i].getOS() != null)
						digest.print("os=\"" + plugins[i].getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
					if (plugins[i].getNL() != null)
						digest.print("nl=\"" + plugins[i].getNL() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
					if (plugins[i].getWS() != null)
						digest.print("ws=\"" + plugins[i].getWS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
					if (plugins[i].getOSArch() != null)
						digest
						.print("arch=\"" + plugins[i].getOSArch() //$NON-NLS-1$
								+ "\" "); //$NON-NLS-1$
					if (plugins[i].getDownloadSize() > 0)
						digest.print("download-size=\"" //$NON-NLS-1$
								+ plugins[i].getDownloadSize() + "\" "); //$NON-NLS-1$
					if (plugins[i].getInstallSize() > 0)
						digest.print("install-size=\"" //$NON-NLS-1$
								+ plugins[i].getInstallSize() + "\" "); //$NON-NLS-1$
					if (!plugins[i].isUnpack())
						digest.print("unpack=\"" + plugins[i].isUnpack() //$NON-NLS-1$
								+ "\" "); //$NON-NLS-1$

					digest.println("/> "); //$NON-NLS-1$
				}
			}	

			IIncludedFeatureReference[] includedFeatures = featureModel.getFeatureIncluded();

			if ((includedFeatures != null) && (includedFeatures.length != 0)) {
				for (int i = 0; i < includedFeatures.length; i++) {
					try {
						digest.print("\t<includes "); //$NON-NLS-1$

						digest.print("id=\"" + includedFeatures[i].getVersionedIdentifier().getIdentifier() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
						digest.print("version=\"" + includedFeatures[i].getVersionedIdentifier().getVersion() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
						if (includedFeatures[i].getOS() != null)
							digest.print("os=\"" + includedFeatures[i].getOS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
						if (includedFeatures[i].getNL() != null)
							digest.print("nl=\"" + includedFeatures[i].getNL() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
						if (includedFeatures[i].getWS() != null)
							digest.print("ws=\"" + includedFeatures[i].getWS() + "\" ");  //$NON-NLS-1$//$NON-NLS-2$
						if (includedFeatures[i].getOSArch() != null)
							digest.print("arch=\"" + includedFeatures[i].getOSArch() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$											
						if ( (includedFeatures[i] instanceof IncludedFeatureReference) && (((IncludedFeatureReference)includedFeatures[i]).getLabel() != null))
							digest.print("name=\"" + includedFeatures[i].getName() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$									
						if (includedFeatures[i].isOptional())
							digest.print("optional=\"true\" "); //$NON-NLS-1$
						digest.print("search-location=\"" + includedFeatures[i].getSearchLocation() + "\" "); //$NON-NLS-1$ //$NON-NLS-2$

						digest.println("/> "); //$NON-NLS-1$
					} catch (CoreException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			digest.println("</feature>"); //$NON-NLS-1$
		}
	}

	private class CombinedProperties extends Properties {

		private Properties properties1;

		private Properties properties2;

		private Properties properties3;

		/**
		 * @param preferred preferred, such as lang_country
		 * @param secondary secondary, such as lang
		 * @param defaults default,
		 */
		public CombinedProperties(Properties preferred,
				Properties secondary, Properties defaults) {
			this.properties1 = preferred;
			this.properties2 = secondary;
			this.properties3 = defaults;
		}

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public String getProperty(String key) {
			String result = null;
			if (properties3 != null && properties3.containsKey(key))
				result = properties3.getProperty(key);
			if (properties2 != null && properties2.containsKey(key))
				result = properties2.getProperty(key);
			if (properties1 != null && properties1.containsKey(key))
				result = properties1.getProperty(key);
			return result;
		}

	}
	
	public static final String getUTF8String(String s) {
		if(s == null)
			return "";
		return UpdateManagerUtils.getWritableXMLString(s);
	}

}
