/*******************************************************************************
 * Copyright (c) 2005, 2015 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
 *     Code 9 - Additional function and fixes
 *     EclipseSource - ongoing development
 *     Felix Riegger (SAP AG) - consolidation of publishers for PDE formats (bug 331974)
 *     SAP AG - ongoing development
 *     Rapicorp - additional features
 *     Red Hat Inc. - Bug 460967
 *******************************************************************************/

package org.eclipse.equinox.internal.p2.publisher.eclipse;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.Map.Entry;
import javax.xml.parsers.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.p2.core.helpers.URLUtil;
import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.equinox.p2.metadata.VersionedId;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.IRepositoryReference;
import org.eclipse.equinox.p2.repository.spi.RepositoryReference;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.publishing.Activator;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

/**
 *  Used to parse a .product file.
 */
public class ProductFile extends DefaultHandler implements IProductDescriptor {
	public final static String GENERIC_VERSION_NUMBER = "0.0.0"; //$NON-NLS-1$

	private static final String ATTRIBUTE_PATH = "path"; //$NON-NLS-1$
	private static final String ATTRIBUTE_ICON = "icon"; //$NON-NLS-1$
	protected static final String ATTRIBUTE_FRAGMENT = "fragment"; //$NON-NLS-1$
	private static final String ATTRIBUTE_APPLICATION = "application"; //$NON-NLS-1$
	private static final String ATTRIBUTE_INCLUDE_LAUNCHERS = "includeLaunchers"; //$NON-NLS-1$
	private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
	private static final String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
	private static final String ATTRIBUTE_LOCATION = "location"; //$NON-NLS-1$
	private static final String ATTRIBUTE_AUTO_START = "autoStart"; //$NON-NLS-1$
	private static final String ATTRIBUTE_START_LEVEL = "startLevel"; //$NON-NLS-1$
	protected static final String ATTRIBUTE_VERSION = "version"; //$NON-NLS-1$
	protected static final String ATTRIBUTE_ID = "id"; //$NON-NLS-1$
	private static final String ATTRIBUTE_UID = "uid"; //$NON-NLS-1$
	private static final String ATTRIBUTE_CONTENT_TYPE = "type"; //$NON-NLS-1$
	private static final String ATTRIBUTE_OS = "os"; //$NON-NLS-1$
	private static final String ATTRIBUTE_ARCH = "arch"; //$NON-NLS-1$
	private static final String ATTRIBUTE_ENABLED = "enabled"; //$NON-NLS-1$
	private static final String ATTRIBUTE_FEATURE_INSTALL_MODE = "installMode"; //$NON-NLS-1$

	private static final String PROPERTY_ECLIPSE_APPLICATION = "eclipse.application"; //$NON-NLS-1$
	private static final String PROPERTY_ECLIPSE_PRODUCT = "eclipse.product"; //$NON-NLS-1$

	private final static SAXParserFactory parserFactory = SAXParserFactory.newInstance();

	private static final String PROGRAM_ARGS = "programArgs"; //$NON-NLS-1$
	private static final String PROGRAM_ARGS_LINUX = "programArgsLin"; //$NON-NLS-1$
	private static final String PROGRAM_ARGS_MAC = "programArgsMac"; //$NON-NLS-1$
	private static final String PROGRAM_ARGS_SOLARIS = "programArgsSol"; //$NON-NLS-1$
	private static final String PROGRAM_ARGS_WIN = "programArgsWin"; //$NON-NLS-1$
	private static final String VM_ARGS = "vmArgs"; //$NON-NLS-1$
	private static final String VM_ARGS_LINUX = "vmArgsLin"; //$NON-NLS-1$
	private static final String VM_ARGS_MAC = "vmArgsMac"; //$NON-NLS-1$
	private static final String VM_ARGS_SOLARIS = "vmArgsSol"; //$NON-NLS-1$
	private static final String VM_ARGS_WIN = "vmArgsWin"; //$NON-NLS-1$

	private static final String SOLARIS_LARGE = "solarisLarge"; //$NON-NLS-1$
	private static final String SOLARIS_MEDIUM = "solarisMedium"; //$NON-NLS-1$
	private static final String SOLARIS_SMALL = "solarisSmall"; //$NON-NLS-1$
	private static final String SOLARIS_TINY = "solarisTiny"; //$NON-NLS-1$
	private static final String WIN32_16_LOW = "winSmallLow"; //$NON-NLS-1$
	private static final String WIN32_16_HIGH = "winSmallHigh"; //$NON-NLS-1$
	private static final String WIN32_24_LOW = "win24Low"; //$NON-NLS-1$
	private static final String WIN32_32_LOW = "winMediumLow"; //$NON-NLS-1$
	private static final String WIN32_32_HIGH = "winMediumHigh"; //$NON-NLS-1$
	private static final String WIN32_48_LOW = "winLargeLow"; //$NON-NLS-1$
	private static final String WIN32_48_HIGH = "winLargeHigh"; //$NON-NLS-1$
	private static final String WIN32_256_HIGH = "winExtraLargeHigh"; //$NON-NLS-1$

	private static final String OS_WIN32 = "win32";//$NON-NLS-1$
	private static final String OS_LINUX = "linux";//$NON-NLS-1$
	private static final String OS_SOLARIS = "solaris";//$NON-NLS-1$
	private static final String OS_MACOSX = "macosx";//$NON-NLS-1$

	// These must match Platform constant values
	private static final String ARCH_X86 = "x86"; //$NON-NLS-1$
	private static final String ARCH_X86_64 = "x86_64"; //$NON-NLS-1$
	private static final String ARCH_PPC = "ppc"; //$NON-NLS-1$
	private static final String ARCH_IA_64 = "ia64"; //$NON-NLS-1$
	private static final String ARCH_IA_64_32 = "ia64_32"; //$NON-NLS-1$
	private static final String ARCH_PA_RISC = "PA_RISC"; //$NON-NLS-1$
	private static final String ARCH_SPARC = "sparc"; //$NON-NLS-1$

	//element names
	private static final String EL_FEATURES = "features"; //$NON-NLS-1$
	private static final String EL_FEATURE = "feature"; //$NON-NLS-1$
	private static final String EL_PLUGINS = "plugins"; //$NON-NLS-1$
	private static final String EL_PLUGIN = "plugin"; //$NON-NLS-1$
	private static final String EL_PRODUCT = "product"; //$NON-NLS-1$
	private static final String EL_PROPERTY = "property"; //$NON-NLS-1$
	private static final String EL_CONFIG_INI = "configIni"; //$NON-NLS-1$
	private static final String EL_LAUNCHER = "launcher"; //$NON-NLS-1$
	private static final String EL_LAUNCHER_ARGS = "launcherArgs"; //$NON-NLS-1$
	private static final String EL_SPLASH = "splash"; //$NON-NLS-1$
	private static final String EL_CONFIGURATIONS = "configurations"; //$NON-NLS-1$
	private static final String EL_LICENSE = "license"; //$NON-NLS-1$
	private static final String EL_URL = "url"; //$NON-NLS-1$
	private static final String EL_TEXT = "text"; //$NON-NLS-1$
	private static final String EL_ARCH_X86 = "argsX86"; //$NON-NLS-1$
	private static final String EL_ARCH_X86_64 = "argsX86_64"; //$NON-NLS-1$
	private static final String EL_ARCH_PPC = "argsPPC"; //$NON-NLS-1$
	private static final String EL_ARCH_IA_64 = "argsIA_64"; //$NON-NLS-1$
	private static final String EL_ARCH_IA_64_32 = "argsIA_64_32"; //$NON-NLS-1$
	private static final String EL_ARCH_PA_RISC = "argsPA_RISC"; //$NON-NLS-1$
	private static final String EL_ARCH_SPARC = "argsSPARC"; //$NON-NLS-1$
	private static final String EL_REPOSITORIES = "repositories"; //$NON-NLS-1$
	private static final String EL_REPOSITORY = "repository"; //$NON-NLS-1$

	//These constants form a small state machine to parse the .product file
	private static final int STATE_START = 0;
	private static final int STATE_PRODUCT = 1;
	private static final int STATE_LAUNCHER = 2;
	private static final int STATE_LAUNCHER_ARGS = 3;
	private static final int STATE_PLUGINS = 4;
	private static final int STATE_FEATURES = 5;
	private static final int STATE_PROGRAM_ARGS = 6;
	private static final int STATE_PROGRAM_ARGS_LINUX = 7;
	private static final int STATE_PROGRAM_ARGS_MAC = 8;
	private static final int STATE_PROGRAM_ARGS_SOLARIS = 9;
	private static final int STATE_PROGRAM_ARGS_WIN = 10;
	private static final int STATE_VM_ARGS = 11;
	private static final int STATE_VM_ARGS_LINUX = 12;
	private static final int STATE_VM_ARGS_MAC = 13;
	private static final int STATE_VM_ARGS_SOLARIS = 14;
	private static final int STATE_VM_ARGS_WIN = 15;
	private static final int STATE_CONFIG_INI = 16;
	private static final int STATE_CONFIGURATIONS = 17;
	private static final int STATE_LICENSE = 18;
	private static final int STATE_LICENSE_URL = 19;
	private static final int STATE_LICENSE_TEXT = 20;
	private static final int STATE_ARCH_X86 = 21;
	private static final int STATE_ARCH_X86_64 = 22;
	private static final int STATE_ARCH_PPC = 23;
	private static final int STATE_ARCH_IA_64 = 24;
	private static final int STATE_ARCH_IA_64_32 = 25;
	private static final int STATE_ARCH_PA_RISC = 26;
	private static final int STATE_ARCH_SPARC = 27;
	private static final int STATE_REPOSITORIES = 28;

	private static final String PI_PDEBUILD = "org.eclipse.pde.build"; //$NON-NLS-1$
	private final static int EXCEPTION_PRODUCT_FORMAT = 23;
	private final static int EXCEPTION_PRODUCT_FILE = 24;

	private int state = STATE_START;
	private int outerState = STATE_START;
	private String platformKeyPrefix = null;

	private SAXParser parser;
	private String launcherName = null;
	//	private boolean useIco = false;
	private final Map<String, Collection<String>> icons = new HashMap<String, Collection<String>>(6);
	private String configPath = null;
	private final Map<String, String> platformSpecificConfigPaths = new HashMap<String, String>();
	private String configPlatform = null;
	private String platformConfigPath = null;
	private String id = null;
	private String uid = null;
	private ProductContentType productContentType = null;
	protected List<FeatureEntry> plugins = new ArrayList<FeatureEntry>();
	protected List<FeatureEntry> fragments = new ArrayList<FeatureEntry>();
	private final List<FeatureEntry> features = new ArrayList<FeatureEntry>();
	private final List<FeatureEntry> rootFeatures = new ArrayList<FeatureEntry>();
	private String splashLocation = null;
	private String productName = null;
	private String application = null;
	private String version = null;
	private Properties launcherArgs = new Properties();
	private final File location;
	private List<BundleInfo> bundleInfos;
	private Map<String, String> properties;
	private HashMap<String, HashMap<String, String>> filteredProperties;
	private boolean includeLaunchers = true;
	private String licenseURL;
	private String licenseText = null;
	private String currentOS;
	private final List<IRepositoryReference> repositories = new ArrayList<IRepositoryReference>();

	private static String normalize(String text) {
		if (text == null || text.trim().length() == 0)
			return ""; //$NON-NLS-1$

		StringBuffer result = new StringBuffer(text.length());
		boolean haveSpace = false;
		for (int i = 0; i < text.length(); i++) {
			char c = text.charAt(i);
			if (Character.isWhitespace(c)) {
				if (haveSpace)
					continue;
				haveSpace = true;
				result.append(" "); //$NON-NLS-1$
			} else {
				haveSpace = false;
				result.append(c);
			}
		}
		return result.toString();
	}

	public ProductFile(String location, String os) throws CoreException {
		super();
		this.currentOS = os;
		this.location = new File(location);
		try {
			parserFactory.setNamespaceAware(true);
			parser = parserFactory.newSAXParser();
			InputStream in = new BufferedInputStream(new FileInputStream(location));
			try {
				parser.parse(new InputSource(in), this);
			} finally {
				try {
					in.close();
				} catch (IOException e) {
					// ignore exception on close (as it was done by Utils.close() before)
				}
			}
		} catch (ParserConfigurationException e) {
			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(Messages.exception_productParse, location), e));
		} catch (SAXException e) {
			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(Messages.exception_productParse, location), e));
		} catch (FileNotFoundException e) {
			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PRODUCT_FILE, NLS.bind(Messages.exception_missingElement, location), null));
		} catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PRODUCT_FORMAT, NLS.bind(Messages.exception_productParse, location), e));
		}
	}

	/**
	 * Constructs a product file parser.
	 */
	public ProductFile(String location) throws Exception {
		super();
		this.location = new File(location);

		parserFactory.setNamespaceAware(true);
		parser = parserFactory.newSAXParser();
		InputStream in = new BufferedInputStream(new FileInputStream(location));
		try {
			parser.parse(new InputSource(in), this);
		} finally {
			in.close();
		}
		parser = null;
	}

	/**
	 * Gets the name of the launcher specified in the .product file.
	 */
	public String getLauncherName() {
		return launcherName;
	}

	/**
	 * Gets the location of the .product file.
	 */
	public File getLocation() {
		return location;
	}

	/**
	 * Returns the properties found in .product file.  Properties
	 * are located in the <configurations> block of the file
	 */
	public Map<String, String> getConfigurationProperties() {
		return getConfigurationProperties(null, null);
	}

	/**
	 * Returns the properties found in .product file that are valid
	 * for the specified platform os and architecture.  If there is no
	 * platform os and/or architecture specified, return only the properties
	 * that are not filtered by the unspecified os and/or arch. 
	 * Properties are located in the <configurations> block of the file
	 */
	public Map<String, String> getConfigurationProperties(String os, String arch) {
		// add all generic properties
		Map<String, String> result = properties != null ? properties : new HashMap<String, String>();
		// add any properties filtered on os and/or arch
		if (filteredProperties != null) {
			String[] filteredKeys = new String[3]; // ".arch", "os.", "os.arch"
			if (os == null) {
				// only arch is specified. Provide properties defined for
				// all os and a specific architecture
				if (arch != null && arch.length() > 0) {
					filteredKeys[0] = "." + arch; //$NON-NLS-1$
				}
			} else {
				if (arch == null) {
					// only os is specified. Provide properties defined for 
					// specific os and all architectures.
					filteredKeys[1] = os + "."; //$NON-NLS-1$
				} else {
					// os and arch specified. Provide properties defined for
					// the os, for the arch, and for both
					filteredKeys[0] = "." + arch; //$NON-NLS-1$
					filteredKeys[1] = os + "."; //$NON-NLS-1$
					filteredKeys[2] = os + "." + arch; //$NON-NLS-1$
				}
			}
			for (int i = 0; i < filteredKeys.length; i++) {
				if (filteredKeys[i] != null) {
					// copy all mappings that are filtered for this os and/or arch
					HashMap<String, String> innerMap = filteredProperties.get(filteredKeys[i]);
					if (innerMap != null) {
						result.putAll(innerMap);
					}
				}

			}
		}
		if (application != null && !result.containsKey(PROPERTY_ECLIPSE_APPLICATION))
			result.put(PROPERTY_ECLIPSE_APPLICATION, application);
		if (id != null && !result.containsKey(PROPERTY_ECLIPSE_PRODUCT))
			result.put(PROPERTY_ECLIPSE_PRODUCT, id);

		return result;
	}

	/**
	 * Returns a List<VersionedName> for each bundle that makes up this product.
	 * @param includeFragments Indicates whether or not fragments should
	 * be included in the list
	 */
	public List<IVersionedId> getBundles(boolean includeFragments) {
		List<IVersionedId> result = new LinkedList<IVersionedId>();

		for (FeatureEntry plugin : plugins) {
			result.add(new VersionedId(plugin.getId(), plugin.getVersion()));
		}

		if (includeFragments) {
			for (FeatureEntry fragment : fragments) {
				result.add(new VersionedId(fragment.getId(), fragment.getVersion()));
			}
		}

		return result;
	}

	public boolean hasBundles(boolean includeFragments) {
		// implement directly; don't call the potentially overridden getBundles
		return !plugins.isEmpty() || (includeFragments && !fragments.isEmpty());
	}

	private List<FeatureEntry> getBundleEntries(boolean includeFragments) {
		List<FeatureEntry> result = new LinkedList<FeatureEntry>();
		result.addAll(plugins);
		if (includeFragments)
			result.addAll(fragments);
		return result;
	}

	/**
	 * Returns a List<BundleInfo> for each bundle that has custom configuration data
	 * in the product file.
	 * @return A List<BundleInfo>
	 */
	public List<BundleInfo> getBundleInfos() {
		return bundleInfos != null ? bundleInfos : Collections.<BundleInfo> emptyList();
	}

	/**
	 * Returns a list<VersionedName> of fragments that constitute this product.
	 */
	public List<IVersionedId> getFragments() {
		List<IVersionedId> result = new LinkedList<IVersionedId>();

		for (FeatureEntry fragment : fragments) {
			result.add(new VersionedId(fragment.getId(), fragment.getVersion()));
		}

		return result;
	}

	/**
	 * Returns a List<VersionedName> of features that constitute this product.
	 */
	public List<IVersionedId> getFeatures() {
		return getFeatures(INCLUDED_FEATURES);
	}

	public boolean hasFeatures() {
		// implement directly; don't call the potentially overridden getFeatures
		return !features.isEmpty();
	}

	public List<IVersionedId> getFeatures(int options) {
		List<IVersionedId> result = new LinkedList<IVersionedId>();

		if ((options & INCLUDED_FEATURES) != 0) {
			for (FeatureEntry feature : features) {
				result.add(new VersionedId(feature.getId(), feature.getVersion()));
			}
		}
		if ((options & ROOT_FEATURES) != 0) {
			for (FeatureEntry feature : rootFeatures) {
				result.add(new VersionedId(feature.getId(), feature.getVersion()));
			}
		}

		return result;
	}

	public List<FeatureEntry> getProductEntries() {
		if (useFeatures()) {
			return features;
		}
		return getBundleEntries(true);
	}

	public boolean containsPlugin(String plugin) {
		List<IVersionedId> bundles = getBundles(true);
		for (IVersionedId versionedId : bundles) {
			if (versionedId.getId().equals(plugin)) {
				return true;
			}
		}
		return false;
	}

	public String[] getIcons() {
		return getIcons(currentOS);
	}

	public String[] getIcons(String os) {
		Collection<String> result = icons.get(os);
		if (result == null)
			return new String[0];
		return result.toArray(new String[result.size()]);
	}

	public String getConfigIniPath(String os) {
		String specific = platformSpecificConfigPaths.get(os);
		return specific == null ? configPath : specific;
	}

	public String getConfigIniPath() {
		return configPath;
	}

	public boolean haveCustomConfig() {
		return configPath != null || platformSpecificConfigPaths.size() > 0;
	}

	/**
	 * Returns the ID for this product.
	 */
	public String getId() {
		if (uid != null)
			return uid;
		return id;
	}

	public String getProductId() {
		return id;
	}

	/**
	 * Returns the location (the bundle) that defines the splash screen
	 */
	public String getSplashLocation() {
		return splashLocation;
	}

	/**
	 * Returns the product name.
	 */
	public String getProductName() {
		return productName;
	}

	/**
	 * Returns the application identifier for this product.
	 */
	public String getApplication() {
		return application;
	}

	/**
	 * Returns true if this product is built using feature, 
	 * false otherwise.
	 */
	public boolean useFeatures() {
		return productContentType == ProductContentType.FEATURES;
	}

	/**
	 * Returns the version of the product
	 */
	public String getVersion() {
		return (version == null || version.length() == 0) ? "0.0.0" : version; //$NON-NLS-1$
	}

	public boolean includeLaunchers() {
		return includeLaunchers;
	}

	public Map<String, BundleInfo> getConfigurationInfo() {
		Map<String, BundleInfo> result = new HashMap<String, BundleInfo>();
		for (BundleInfo info : getBundleInfos()) {
			result.put(info.getSymbolicName(), info);
		}
		return result;
	}

	public Properties getConfigProperties() {
		Properties props = new Properties();
		for (Entry<String, String> property : getConfigurationProperties().entrySet()) {
			props.setProperty(property.getKey(), property.getValue());
		}
		return props;
	}

	/**
	 * Returns the VM arguments for a specific platform.
	 * If the empty string is used for the OS, this returns
	 * the default VM arguments
	 */
	public String getVMArguments(String os) {
		return getVMArguments(os, null);
	}

	/**
	 * Returns the VM arguments for a specific platform and architecture
	 * combination. If the empty string is used for the architecture, this
	 * returns the default arguments for the platform.  If the empty string is
	 * used for the OS, this returns the default VM arguments.
	 */
	public String getVMArguments(String os, String arch) {
		os = os == null ? "" : os; //$NON-NLS-1$
		String key = null;
		if (os.equals(OS_WIN32)) {
			key = VM_ARGS_WIN;
		} else if (os.equals(OS_LINUX)) {
			key = VM_ARGS_LINUX;
		} else if (os.equals(OS_MACOSX)) {
			key = VM_ARGS_MAC;
		} else if (os.equals(OS_SOLARIS)) {
			key = VM_ARGS_SOLARIS;
		}

		arch = arch == null ? "" : arch; //$NON-NLS-1$
		String archKey = null;
		if (arch.equals(ARCH_X86)) {
			archKey = EL_ARCH_X86;
		} else if (arch.equals(ARCH_X86_64)) {
			archKey = EL_ARCH_X86_64;
		} else if (arch.equals(ARCH_PPC)) {
			archKey = EL_ARCH_PPC;
		} else if (arch.equals(ARCH_IA_64)) {
			archKey = EL_ARCH_IA_64;
		} else if (arch.equals(ARCH_IA_64_32)) {
			archKey = EL_ARCH_IA_64_32;
		} else if (arch.equals(ARCH_PA_RISC)) {
			archKey = EL_ARCH_PA_RISC;
		} else if (arch.equals(ARCH_SPARC)) {
			archKey = EL_ARCH_SPARC;
		}

		String platformArchKey = null;
		String defaults = launcherArgs.getProperty(VM_ARGS);
		// architecture arguments independent of platform should be part
		// of the defaults.
		if (archKey != null) {
			String archOnAllPlatforms = launcherArgs.getProperty(VM_ARGS + "." + archKey); //$NON-NLS-1$
			if (archOnAllPlatforms != null && archOnAllPlatforms.length() > 0) {
				defaults = defaults + " " + archOnAllPlatforms; //$NON-NLS-1$
			}
		}
		String platform = null, platformAndArch = null, args = null;
		if (key != null) {
			// a platform with no arch specified
			platform = launcherArgs.getProperty(key);
			// platform + arch
			if (archKey != null) {
				platformArchKey = key + "." + archKey; //$NON-NLS-1$
				platformAndArch = launcherArgs.getProperty(platformArchKey);
			}
		}
		if (defaults != null) {
			if (platform != null)
				args = platformAndArch != null ? defaults + " " + platform + " " + platformAndArch : defaults + " " + platform; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			else
				args = defaults;
		} else {
			if (platform != null)
				args = platformAndArch != null ? platform + " " + platformAndArch : platform; //$NON-NLS-1$
			else
				args = platformAndArch != null ? platformAndArch : ""; //$NON-NLS-1$
		}
		return normalize(args);
	}

	/**
	 * Returns the program arguments for a specific platform.
	 * If the empty string is used for the OS, this returns
	 * the default program arguments
	 */
	public String getProgramArguments(String os) {
		return getProgramArguments(os, null);
	}

	/**
	 * Returns the program arguments for a specific platform.
	 * If the empty string is used for the OS, this returns
	 * the default program arguments
	 */
	public String getProgramArguments(String os, String arch) {
		os = os == null ? "" : os; //$NON-NLS-1$
		String key = null;
		if (os.equals(OS_WIN32)) {
			key = PROGRAM_ARGS_WIN;
		} else if (os.equals(OS_LINUX)) {
			key = PROGRAM_ARGS_LINUX;
		} else if (os.equals(OS_MACOSX)) {
			key = PROGRAM_ARGS_MAC;
		} else if (os.equals(OS_SOLARIS)) {
			key = PROGRAM_ARGS_SOLARIS;
		}

		arch = arch == null ? "" : arch; //$NON-NLS-1$
		String archKey = null;
		if (arch.equals(ARCH_X86)) {
			archKey = EL_ARCH_X86;
		} else if (arch.equals(ARCH_X86_64)) {
			archKey = EL_ARCH_X86_64;
		} else if (arch.equals(ARCH_PPC)) {
			archKey = EL_ARCH_PPC;
		} else if (arch.equals(ARCH_IA_64)) {
			archKey = EL_ARCH_IA_64;
		} else if (arch.equals(ARCH_IA_64_32)) {
			archKey = EL_ARCH_IA_64_32;
		} else if (arch.equals(ARCH_PA_RISC)) {
			archKey = EL_ARCH_PA_RISC;
		} else if (arch.equals(ARCH_SPARC)) {
			archKey = EL_ARCH_SPARC;
		}

		String platformArchKey = null;
		String defaults = launcherArgs.getProperty(PROGRAM_ARGS);
		// architecture arguments independent of platform should be part
		// of the defaults.
		if (archKey != null) {
			String archOnAllPlatforms = launcherArgs.getProperty(PROGRAM_ARGS + "." + archKey); //$NON-NLS-1$
			if (archOnAllPlatforms != null && archOnAllPlatforms.length() > 0) {
				defaults = defaults + " " + archOnAllPlatforms; //$NON-NLS-1$
			}
		}
		String platform = null, platformAndArch = null, args = null;
		if (key != null) {
			// a platform with no arch specified
			platform = launcherArgs.getProperty(key);
			// platform + arch
			if (archKey != null) {
				platformArchKey = key + "." + archKey; //$NON-NLS-1$
				platformAndArch = launcherArgs.getProperty(platformArchKey);
			}
		}
		if (defaults != null) {
			if (platform != null)
				args = platformAndArch != null ? defaults + " " + platform + " " + platformAndArch : defaults + " " + platform; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			else
				args = defaults;
		} else {
			if (platform != null)
				args = platformAndArch != null ? platform + " " + platformAndArch : platform; //$NON-NLS-1$
			else
				args = platformAndArch != null ? platformAndArch : ""; //$NON-NLS-1$
		}
		return normalize(args);
	}

	public String getLicenseText() {
		return licenseText;
	}

	public String getLicenseURL() {
		return licenseURL;
	}

	public List<IRepositoryReference> getRepositoryEntries() {
		return repositories;
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) {
		switch (state) {
			case STATE_START :
				if (EL_PRODUCT.equals(localName)) {
					processProduct(attributes);
					state = STATE_PRODUCT;
				}
				break;

			case STATE_PRODUCT :
				if (EL_CONFIG_INI.equals(localName)) {
					processConfigIni(attributes);
					state = STATE_CONFIG_INI;
				} else if (EL_LAUNCHER.equals(localName)) {
					processLauncher(attributes);
					state = STATE_LAUNCHER;
				} else if (EL_PLUGINS.equals(localName)) {
					state = STATE_PLUGINS;
				} else if (EL_FEATURES.equals(localName)) {
					state = STATE_FEATURES;
				} else if (EL_LAUNCHER_ARGS.equals(localName)) {
					state = STATE_LAUNCHER_ARGS;
				} else if (EL_SPLASH.equals(localName)) {
					splashLocation = attributes.getValue(ATTRIBUTE_LOCATION);
				} else if (EL_CONFIGURATIONS.equals(localName)) {
					state = STATE_CONFIGURATIONS;
				} else if (EL_LICENSE.equals(localName)) {
					state = STATE_LICENSE;
				} else if (EL_REPOSITORIES.equals(localName)) {
					state = STATE_REPOSITORIES;
				}
				break;

			case STATE_CONFIG_INI :
				processConfigIniPlatform(localName, true);
				break;

			case STATE_LAUNCHER :
				if (OS_SOLARIS.equals(localName)) {
					processSolaris(attributes);
				} else if ("win".equals(localName)) { //$NON-NLS-1$
					processWin(attributes);
				} else if (OS_LINUX.equals(localName)) {
					processLinux(attributes);
				} else if (OS_MACOSX.equals(localName)) {
					processMac(attributes);
				}
				if ("ico".equals(localName)) { //$NON-NLS-1$
					processIco(attributes);
				} else if ("bmp".equals(localName)) { //$NON-NLS-1$
					processBmp(attributes);
				}
				break;

			case STATE_LAUNCHER_ARGS :
				if (PROGRAM_ARGS.equals(localName)) {
					state = STATE_PROGRAM_ARGS;
				} else if (PROGRAM_ARGS_LINUX.equals(localName)) {
					state = STATE_PROGRAM_ARGS_LINUX;
				} else if (PROGRAM_ARGS_MAC.equals(localName)) {
					state = STATE_PROGRAM_ARGS_MAC;
				} else if (PROGRAM_ARGS_SOLARIS.equals(localName)) {
					state = STATE_PROGRAM_ARGS_SOLARIS;
				} else if (PROGRAM_ARGS_WIN.equals(localName)) {
					state = STATE_PROGRAM_ARGS_WIN;
				} else if (VM_ARGS.equals(localName)) {
					state = STATE_VM_ARGS;
				} else if (VM_ARGS_LINUX.equals(localName)) {
					state = STATE_VM_ARGS_LINUX;
				} else if (VM_ARGS_MAC.equals(localName)) {
					state = STATE_VM_ARGS_MAC;
				} else if (VM_ARGS_SOLARIS.equals(localName)) {
					state = STATE_VM_ARGS_SOLARIS;
				} else if (VM_ARGS_WIN.equals(localName)) {
					state = STATE_VM_ARGS_WIN;
				}
				break;

			// For all argument states.  Set a platform key prefix representing 
			// the outer state (platform) of the launcher arguments and then 
			// set the state of the inner state (architecture).
			case STATE_PROGRAM_ARGS :
				platformKeyPrefix = PROGRAM_ARGS;
				setArchState(localName);
				break;

			case STATE_PROGRAM_ARGS_LINUX :
				platformKeyPrefix = PROGRAM_ARGS_LINUX;
				setArchState(localName);
				break;

			case STATE_PROGRAM_ARGS_MAC :
				platformKeyPrefix = PROGRAM_ARGS_MAC;
				setArchState(localName);
				break;

			case STATE_PROGRAM_ARGS_SOLARIS :
				platformKeyPrefix = PROGRAM_ARGS_SOLARIS;
				setArchState(localName);
				break;

			case STATE_PROGRAM_ARGS_WIN :
				platformKeyPrefix = PROGRAM_ARGS_WIN;
				setArchState(localName);
				break;

			case STATE_VM_ARGS :
				platformKeyPrefix = VM_ARGS;
				setArchState(localName);
				break;

			case STATE_VM_ARGS_LINUX :
				platformKeyPrefix = VM_ARGS_LINUX;
				setArchState(localName);
				break;

			case STATE_VM_ARGS_MAC :
				platformKeyPrefix = VM_ARGS_MAC;
				setArchState(localName);
				break;

			case STATE_VM_ARGS_SOLARIS :
				platformKeyPrefix = VM_ARGS_SOLARIS;
				setArchState(localName);
				break;

			case STATE_VM_ARGS_WIN :
				platformKeyPrefix = VM_ARGS_WIN;
				setArchState(localName);
				break;

			case STATE_PLUGINS :
				if (EL_PLUGIN.equals(localName)) {
					processPlugin(attributes);
				}
				break;

			case STATE_REPOSITORIES :
				if (EL_REPOSITORY.equals(localName)) {
					processRepositoryInformation(attributes);
				}
				break;

			case STATE_LICENSE :
				if (EL_URL.equals(localName)) {
					state = STATE_LICENSE_URL;
				} else if (EL_TEXT.equals(localName)) {
					licenseText = ""; //$NON-NLS-1$
					state = STATE_LICENSE_TEXT;
				}
				break;

			case STATE_FEATURES :
				if (EL_FEATURE.equals(localName)) {
					processFeature(attributes);
				}
				break;
			case STATE_CONFIGURATIONS :
				if (EL_PLUGIN.equals(localName)) {
					processPluginConfiguration(attributes);
				} else if (EL_PROPERTY.equals(localName)) {
					processPropertyConfiguration(attributes);
				}
				break;
		}
	}

	private void setArchState(String archName) {
		outerState = state;
		if (EL_ARCH_X86.equals(archName)) {
			state = STATE_ARCH_X86;
		} else if (EL_ARCH_X86_64.equals(archName)) {
			state = STATE_ARCH_X86_64;
		} else if (EL_ARCH_PPC.equals(archName)) {
			state = STATE_ARCH_PPC;
		} else if (EL_ARCH_IA_64.equals(archName)) {
			state = STATE_ARCH_IA_64;
		} else if (EL_ARCH_IA_64_32.equals(archName)) {
			state = STATE_ARCH_IA_64_32;
		} else if (EL_ARCH_PA_RISC.equals(archName)) {
			state = STATE_ARCH_PA_RISC;
		} else if (EL_ARCH_SPARC.equals(archName)) {
			state = STATE_ARCH_SPARC;
		}
	}

	/**
	 * Processes the property tag in the .product file.  These tags contain
	 * a Name and Value pair.  For each tag (with a non-null name), a property 
	 * is created.
	 */
	private void processPropertyConfiguration(Attributes attributes) {
		String name = attributes.getValue(ATTRIBUTE_NAME);
		String value = attributes.getValue(ATTRIBUTE_VALUE);
		String os = attributes.getValue(ATTRIBUTE_OS);
		if (os == null)
			os = ""; //$NON-NLS-1$
		String arch = attributes.getValue(ATTRIBUTE_ARCH);
		if (arch == null)
			arch = ""; //$NON-NLS-1$
		String propOSArchKey = os + "." + arch; //$NON-NLS-1$
		if (name == null)
			return;
		if (value == null)
			value = ""; //$NON-NLS-1$
		if (propOSArchKey.length() <= 1) {
			// this is a generic property for all platforms and arch
			if (properties == null)
				properties = new HashMap<String, String>();
			properties.put(name, value);
		} else {
			// store the property in the filtered map, keyed by "os.arch"
			if (filteredProperties == null)
				filteredProperties = new HashMap<String, HashMap<String, String>>();
			HashMap<String, String> filteredMap = filteredProperties.get(propOSArchKey);
			if (filteredMap == null) {
				filteredMap = new HashMap<String, String>();
				filteredProperties.put(propOSArchKey, filteredMap);
			}
			filteredMap.put(name, value);
		}
	}

	private void processPluginConfiguration(Attributes attributes) {
		BundleInfo info = new BundleInfo();
		info.setSymbolicName(attributes.getValue(ATTRIBUTE_ID));
		info.setVersion(attributes.getValue(ATTRIBUTE_VERSION));
		String value = attributes.getValue(ATTRIBUTE_START_LEVEL);
		if (value != null) {
			int startLevel = Integer.parseInt(value);
			if (startLevel > 0)
				info.setStartLevel(startLevel);
		}
		value = attributes.getValue(ATTRIBUTE_AUTO_START);
		if (value != null)
			info.setMarkedAsStarted(Boolean.parseBoolean(value));
		if (bundleInfos == null)
			bundleInfos = new ArrayList<BundleInfo>();
		bundleInfos.add(info);
	}

	private void processRepositoryInformation(Attributes attributes) {
		try {
			URI uri = URIUtil.fromString(attributes.getValue(ATTRIBUTE_LOCATION));
			boolean enabled = Boolean.parseBoolean(attributes.getValue(ATTRIBUTE_ENABLED));
			// First add a metadata repository
			repositories.add(new RepositoryReference(uri, null, IRepository.TYPE_METADATA, enabled ? IRepository.ENABLED : IRepository.NONE));
			// Now a colocated artifact repository
			repositories.add(new RepositoryReference(uri, null, IRepository.TYPE_ARTIFACT, enabled ? IRepository.ENABLED : IRepository.NONE));
		} catch (URISyntaxException e) {
			// ignore malformed URI's. These should have already been caught by the UI
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) {
		switch (state) {
			case STATE_PLUGINS :
				if (EL_PLUGINS.equals(localName))
					state = STATE_PRODUCT;
				break;
			case STATE_FEATURES :
				if (EL_FEATURES.equals(localName))
					state = STATE_PRODUCT;
				break;
			case STATE_LAUNCHER_ARGS :
				if (EL_LAUNCHER_ARGS.equals(localName))
					state = STATE_PRODUCT;
				break;
			case STATE_LAUNCHER :
				if (EL_LAUNCHER.equals(localName))
					state = STATE_PRODUCT;
				break;
			case STATE_CONFIGURATIONS :
				if (EL_CONFIGURATIONS.equals(localName))
					state = STATE_PRODUCT;
				break;
			case STATE_LICENSE :
				if (EL_LICENSE.equals(localName))
					state = STATE_PRODUCT;
				break;

			case STATE_PROGRAM_ARGS :
			case STATE_PROGRAM_ARGS_LINUX :
			case STATE_PROGRAM_ARGS_MAC :
			case STATE_PROGRAM_ARGS_SOLARIS :
			case STATE_PROGRAM_ARGS_WIN :
			case STATE_VM_ARGS :
			case STATE_VM_ARGS_LINUX :
			case STATE_VM_ARGS_MAC :
			case STATE_VM_ARGS_SOLARIS :
			case STATE_VM_ARGS_WIN :
				state = STATE_LAUNCHER_ARGS;
				break;
			case STATE_LICENSE_URL :
			case STATE_LICENSE_TEXT :
				state = STATE_LICENSE;
				break;

			case STATE_ARCH_X86 :
			case STATE_ARCH_X86_64 :
			case STATE_ARCH_PPC :
			case STATE_ARCH_IA_64 :
			case STATE_ARCH_IA_64_32 :
			case STATE_ARCH_PA_RISC :
			case STATE_ARCH_SPARC :
				state = outerState;
				break;

			case STATE_CONFIG_INI :
				if (EL_CONFIG_INI.equals(localName))
					state = STATE_PRODUCT;
				else
					processConfigIniPlatform(localName, false);
				break;

			case STATE_REPOSITORIES :
				if (EL_REPOSITORIES.equals(localName))
					state = STATE_PRODUCT;
				break;

		}
	}

	@Override
	public void characters(char[] ch, int start, int length) {
		switch (state) {
			case STATE_PROGRAM_ARGS :
				addLaunchArgumentToMap(PROGRAM_ARGS, String.valueOf(ch, start, length));
				break;
			case STATE_PROGRAM_ARGS_LINUX :
				addLaunchArgumentToMap(PROGRAM_ARGS_LINUX, String.valueOf(ch, start, length));
				break;
			case STATE_PROGRAM_ARGS_MAC :
				addLaunchArgumentToMap(PROGRAM_ARGS_MAC, String.valueOf(ch, start, length));
				break;
			case STATE_PROGRAM_ARGS_SOLARIS :
				addLaunchArgumentToMap(PROGRAM_ARGS_SOLARIS, String.valueOf(ch, start, length));
				break;
			case STATE_PROGRAM_ARGS_WIN :
				addLaunchArgumentToMap(PROGRAM_ARGS_WIN, String.valueOf(ch, start, length));
				break;
			case STATE_VM_ARGS :
				addLaunchArgumentToMap(VM_ARGS, String.valueOf(ch, start, length));
				break;
			case STATE_VM_ARGS_LINUX :
				addLaunchArgumentToMap(VM_ARGS_LINUX, String.valueOf(ch, start, length));
				break;
			case STATE_VM_ARGS_MAC :
				addLaunchArgumentToMap(VM_ARGS_MAC, String.valueOf(ch, start, length));
				break;
			case STATE_VM_ARGS_SOLARIS :
				addLaunchArgumentToMap(VM_ARGS_SOLARIS, String.valueOf(ch, start, length));
				break;
			case STATE_VM_ARGS_WIN :
				addLaunchArgumentToMap(VM_ARGS_WIN, String.valueOf(ch, start, length));
				break;
			case STATE_ARCH_X86 :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_X86, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_X86_64 :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_X86_64, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_PPC :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_PPC, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_IA_64 :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_IA_64, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_IA_64_32 :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_IA_64_32, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_PA_RISC :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_PA_RISC, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_ARCH_SPARC :
				addLaunchArgumentToMap(platformKeyPrefix + "." + EL_ARCH_SPARC, String.valueOf(ch, start, length)); //$NON-NLS-1$
				break;
			case STATE_CONFIG_INI :
				if (platformConfigPath != null)
					platformConfigPath += String.valueOf(ch, start, length);
				break;
			case STATE_LICENSE_URL :
				licenseURL = String.valueOf(ch, start, length);
				break;
			case STATE_LICENSE_TEXT :
				if (licenseText != null)
					licenseText += String.valueOf(ch, start, length);
				break;
		}
	}

	private void addLaunchArgumentToMap(String key, String value) {
		if (launcherArgs == null)
			launcherArgs = new Properties();

		String oldValue = launcherArgs.getProperty(key);
		if (oldValue != null)
			launcherArgs.setProperty(key, oldValue + value);
		else
			launcherArgs.setProperty(key, value);
	}

	protected void processPlugin(Attributes attributes) {
		String fragment = attributes.getValue(ATTRIBUTE_FRAGMENT);
		String pluginId = attributes.getValue(ATTRIBUTE_ID);
		String pluginVersion = attributes.getValue(ATTRIBUTE_VERSION);

		FeatureEntry entry = new FeatureEntry(pluginId, pluginVersion != null ? pluginVersion : GENERIC_VERSION_NUMBER, true);
		entry.setFragment(Boolean.parseBoolean(fragment));

		if (fragment != null && Boolean.parseBoolean(fragment)) {
			fragments.add(entry);
		} else {
			plugins.add(entry);
		}
	}

	private void processFeature(Attributes attributes) {
		String featureId = attributes.getValue(ATTRIBUTE_ID);
		String featureVersion = attributes.getValue(ATTRIBUTE_VERSION);
		FeatureInstallMode installMode = FeatureInstallMode.parse(attributes.getValue(ATTRIBUTE_FEATURE_INSTALL_MODE));
		FeatureEntry featureEntry = new FeatureEntry(featureId, featureVersion != null ? featureVersion : GENERIC_VERSION_NUMBER, false);

		switch (installMode) {
			case ROOT :
				rootFeatures.add(featureEntry);
				break;
			default :
				features.add(featureEntry);
		}
	}

	private void processProduct(Attributes attributes) {
		id = attributes.getValue(ATTRIBUTE_ID);
		uid = attributes.getValue(ATTRIBUTE_UID);
		productName = attributes.getValue(ATTRIBUTE_NAME);
		application = attributes.getValue(ATTRIBUTE_APPLICATION);
		if (attributes.getIndex(ATTRIBUTE_INCLUDE_LAUNCHERS) >= 0)
			includeLaunchers = Boolean.valueOf(attributes.getValue(ATTRIBUTE_INCLUDE_LAUNCHERS));
		String contentTypeString = attributes.getValue(ATTRIBUTE_CONTENT_TYPE);
		if (contentTypeString != null)
			productContentType = ProductContentType.toProductContentType(contentTypeString);
		if (productContentType == null) { // useFeatures attribute is taken into account only if the contentType attribute is missing
			String use = attributes.getValue("useFeatures"); //$NON-NLS-1$
			// for backward compatibility with the old behavior 
			if (use != null && Boolean.parseBoolean(use))
				productContentType = ProductContentType.FEATURES;
			else
				productContentType = ProductContentType.BUNDLES;
		}

		version = attributes.getValue(ATTRIBUTE_VERSION);
	}

	private void processConfigIni(Attributes attributes) {
		String path = null;
		if ("custom".equals(attributes.getValue("use"))) { //$NON-NLS-1$//$NON-NLS-2$
			path = attributes.getValue(ATTRIBUTE_PATH);
		}
		String os = attributes.getValue("os"); //$NON-NLS-1$
		if (os != null && os.length() > 0) {
			// TODO should we allow a platform-specific default to over-ride a custom generic path?
			if (path != null)
				platformSpecificConfigPaths.put(os, path);
		} else if (path != null) {
			configPath = path;
		}
	}

	private void processConfigIniPlatform(String key, boolean begin) {
		if (begin) {
			configPlatform = key;
			platformConfigPath = ""; //$NON-NLS-1$
		} else if (configPlatform.equals(key) && platformConfigPath.length() > 0) {
			platformSpecificConfigPaths.put(key, platformConfigPath);
			platformConfigPath = null;
		}
	}

	private void processLauncher(Attributes attributes) {
		launcherName = attributes.getValue(ATTRIBUTE_NAME);
	}

	private void addIcon(String os, String value) {
		if (value == null)
			return;

		File iconFile = new File(value);
		if (!iconFile.isFile()) {
			//workspace
			Location instanceLocation = ServiceHelper.getService(Activator.getContext(), Location.class, Location.INSTANCE_FILTER);
			if (instanceLocation != null && instanceLocation.getURL() != null) {
				File workspace = URLUtil.toFile(instanceLocation.getURL());
				if (workspace != null)
					iconFile = new File(workspace, value);
			}
		}
		if (!iconFile.isFile())
			iconFile = new File(location.getParentFile(), value);

		Collection<String> list = icons.get(os);
		if (list == null) {
			list = new ArrayList<String>(6);
			icons.put(os, list);
		}
		list.add(iconFile.getAbsolutePath());
	}

	private void processSolaris(Attributes attributes) {
		addIcon(OS_SOLARIS, attributes.getValue(SOLARIS_LARGE));
		addIcon(OS_SOLARIS, attributes.getValue(SOLARIS_MEDIUM));
		addIcon(OS_SOLARIS, attributes.getValue(SOLARIS_SMALL));
		addIcon(OS_SOLARIS, attributes.getValue(SOLARIS_TINY));
	}

	private void processWin(Attributes attributes) {
		//		useIco = Boolean.parseBoolean(attributes.getValue(P_USE_ICO));
	}

	private void processIco(Attributes attributes) {
		addIcon(OS_WIN32, attributes.getValue(ATTRIBUTE_PATH));
	}

	private void processBmp(Attributes attributes) {
		addIcon(OS_WIN32, attributes.getValue(WIN32_16_HIGH));
		addIcon(OS_WIN32, attributes.getValue(WIN32_16_LOW));
		addIcon(OS_WIN32, attributes.getValue(WIN32_24_LOW));
		addIcon(OS_WIN32, attributes.getValue(WIN32_32_HIGH));
		addIcon(OS_WIN32, attributes.getValue(WIN32_32_LOW));
		addIcon(OS_WIN32, attributes.getValue(WIN32_48_HIGH));
		addIcon(OS_WIN32, attributes.getValue(WIN32_48_LOW));
		addIcon(OS_WIN32, attributes.getValue(WIN32_256_HIGH));
	}

	private void processLinux(Attributes attributes) {
		addIcon(OS_LINUX, attributes.getValue(ATTRIBUTE_ICON));
	}

	private void processMac(Attributes attributes) {
		addIcon(OS_MACOSX, attributes.getValue(ATTRIBUTE_ICON));
	}

	public ProductContentType getProductContentType() {
		return productContentType;
	}
}
