/*******************************************************************************
 * 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.*;
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 = SecureXMLUtil.newSecureSAXParserFactory();

	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;
	}
}
