/*******************************************************************************
 * Copyright (c) 2008, 2017 Code 9 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: 
 *   Code 9 - initial API and implementation
 *   IBM - ongoing development
 *   SAP - ongoing development
 *   Pascal Rapicault - Support for bundled macosx http://bugs.eclipse.org/57349
 ******************************************************************************/
package org.eclipse.equinox.p2.publisher;

import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactDescriptor;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils.IPathComputer;
import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.internal.p2.metadata.*;
import org.eclipse.equinox.internal.p2.publisher.Activator;
import org.eclipse.equinox.internal.p2.publisher.QuotedTokenizer;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.*;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.publisher.actions.*;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.artifact.*;
import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.spi.ProcessingStepDescriptor;
import org.eclipse.equinox.spi.p2.publisher.PublisherHelper;

public abstract class AbstractPublisherAction implements IPublisherAction {
	public static final String CONFIG_ANY = "ANY"; //$NON-NLS-1$
	public static final String CONFIG_SEGMENT_SEPARATOR = "."; //$NON-NLS-1$

	protected IPublisherInfo info;

	/**
	 * Convert a list of tokens into an array. The list separator has to be
	 * specified.
	 */
	public static String[] getArrayFromString(String list, String separator) {
		if (list == null || list.trim().equals("")) //$NON-NLS-1$
			return new String[0];
		List<String> result = new ArrayList<>();
		for (QuotedTokenizer tokens = new QuotedTokenizer(list, separator); tokens.hasMoreTokens();) {
			String token = tokens.nextToken().trim();
			if (!token.equals("")) //$NON-NLS-1$
				result.add(token);
		}
		return result.toArray(new String[result.size()]);
	}

	/**
	 * Returns a string array of { ws, os, arch } as parsed from the given string
	 * @param configSpec the string to parse
	 * @return the ws, os, arch form of the given string
	 */
	public static String[] parseConfigSpec(String configSpec) {
		String[] result = getArrayFromString(configSpec, CONFIG_SEGMENT_SEPARATOR);
		for (int i = 0; i < result.length; i++)
			if (result[i].equals("*")) //$NON-NLS-1$
				result[i] = CONFIG_ANY;

		if (result.length < 3) {
			String[] temp = new String[3];
			System.arraycopy(result, 0, temp, 0, result.length);
			for (int i = result.length; i < temp.length; i++) {
				temp[i] = CONFIG_ANY;
			}
			result = temp;
		}
		return result;
	}

	/**
	 * Returns the canonical form of config spec with the given ws, os and arch.
	 * Note that the result is intended to be machine readable (i.e., parseConfigSpec
	 * will parse the the result).
	 * @param ws the window system
	 * @param os the operating system
	 * @param arch the machine architecture
	 * @return the machine readable format of the given config spec
	 */
	public static String createConfigSpec(String ws, String os, String arch) {
		return ws + '.' + os + '.' + arch;
	}

	protected void addSelfCapability(InstallableUnitDescription root) {
		root.setCapabilities(new IProvidedCapability[] {createSelfCapability(root.getId(), root.getVersion())});
	}

	/**
	 * Returns the LDAP filter form that matches the given config spec.  Returns
	 * an empty String if the spec does not identify an ws, os or arch.
	 * @param configSpec a config spec to filter
	 * @return the LDAP filter for the given spec.  <code>null</code> if the given spec does not 
	 * parse into a filter.
	 */
	protected IMatchExpression<IInstallableUnit> createFilterSpec(String configSpec) {
		String ldap = createLDAPString(configSpec);
		if (ldap == null)
			return null;
		return InstallableUnit.parseFilter(ldap);
	}

	protected String createLDAPString(String configSpec) {
		String[] config = parseConfigSpec(configSpec);
		if (config[0] != null || config[1] != null || config[2] != null) {
			String filterWs = config[0] != null && !CONFIG_ANY.equalsIgnoreCase(config[0]) ? "(osgi.ws=" + config[0] + ")" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			String filterOs = config[1] != null && !CONFIG_ANY.equalsIgnoreCase(config[1]) ? "(osgi.os=" + config[1] + ")" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			String filterArch = config[2] != null && !CONFIG_ANY.equalsIgnoreCase(config[2]) ? "(osgi.arch=" + config[2] + ")" : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			if (filterWs.length() == 0 && filterOs.length() == 0 && filterArch.length() == 0)
				return null;
			return "(& " + filterWs + filterOs + filterArch + ")"; //$NON-NLS-1$ //$NON-NLS-2$
		}
		return null;
	}

	protected boolean filterMatches(IMatchExpression<IInstallableUnit> filter, String configSpec) {
		if (filter == null)
			return true;

		String[] config = parseConfigSpec(configSpec);
		return filter.isMatch(InstallableUnit.contextIU(config[0], config[1], config[2]));
	}

	/**
	 * Returns the normalized string form of the given config spec.  This is useful for putting
	 * in IU ids etc. Note that the result is not intended to be machine readable (i.e., parseConfigSpec
	 * may not work on the result).
	 * @param configSpec the config spec to format
	 * @return the readable format of the given config spec
	 */
	protected String createIdString(String configSpec) {
		String[] config = parseConfigSpec(configSpec);
		return config[0] + '.' + config[1] + '.' + config[2];
	}

	protected String createCUIdString(String id, String type, String flavor, String configSpec) {
		return flavor + id + "." + type + "." + createIdString(configSpec); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Creates and returns a collection of RequiredCapabilities for the IUs represented
	 * by the given collection.  The collection may include a mixture of IInstallableUnits
	 * or VersionedNames.
	 * @param children descriptions of the IUs on which requirements are to be made
	 * @return a collection of RequiredCapabilities representing the given IUs
	 */
	protected Collection<IRequirement> createIURequirements(Collection<? extends IVersionedId> children) {
		ArrayList<IRequirement> result = new ArrayList<>(children.size());
		for (IVersionedId next : children) {
			if (next instanceof IInstallableUnit) {
				IInstallableUnit iu = (IInstallableUnit) next;
				VersionRange range = new VersionRange(iu.getVersion(), true, iu.getVersion(), true);
				result.add(MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, iu.getId(), range, iu.getFilter() == null ? null : iu.getFilter(), false, false));
			} else {
				Version version = next.getVersion();
				VersionRange range = (version == null || Version.emptyVersion.equals(version)) ? VersionRange.emptyRange : new VersionRange(version, true, version, true);
				IMatchExpression<IInstallableUnit> filter = getFilterAdvice(next);
				result.add(MetadataFactory.createRequirement(IInstallableUnit.NAMESPACE_IU_ID, next.getId(), range, filter, false, false));
			}
		}
		return result;
	}

	private IMatchExpression<IInstallableUnit> getFilterAdvice(IVersionedId name) {
		if (info == null)
			return null;
		Collection<IFilterAdvice> filterAdvice = info.getAdvice(CONFIG_ANY, true, name.getId(), name.getVersion(), IFilterAdvice.class);
		for (IFilterAdvice advice : filterAdvice) {
			IMatchExpression<IInstallableUnit> result = advice.getFilter(name.getId(), name.getVersion(), false);
			if (result != null)
				return result;
		}
		return null;
	}

	protected InstallableUnitDescription createIUShell(String id, Version version) {
		InstallableUnitDescription root = new MetadataFactory.InstallableUnitDescription();
		root.setId(id);
		root.setVersion(version);
		return root;
	}

	protected IArtifactDescriptor createPack200ArtifactDescriptor(IArtifactKey key, File pathOnDisk, String installSize) {
		ArtifactDescriptor result = (ArtifactDescriptor) PublisherHelper.createArtifactDescriptor(info, key, pathOnDisk);
		//TODO this size calculation is bogus
		if (pathOnDisk != null) {
			result.setProperty(IArtifactDescriptor.ARTIFACT_SIZE, installSize);
			// TODO - this is wrong but I'm testing a work-around for bug 205842
			result.setProperty(IArtifactDescriptor.DOWNLOAD_SIZE, Long.toString(pathOnDisk.length()));
		}
		IProcessingStepDescriptor[] steps = new IProcessingStepDescriptor[] {new ProcessingStepDescriptor("org.eclipse.equinox.p2.processing.Pack200Unpacker", null, true)}; //$NON-NLS-1$
		result.setProcessingSteps(steps);
		result.setProperty(IArtifactDescriptor.FORMAT, IArtifactDescriptor.FORMAT_PACKED);
		return result;
	}

	protected InstallableUnitDescription createParentIU(Collection<? extends IVersionedId> children, String id, Version version) {
		InstallableUnitDescription root = createIUShell(id, version);
		root.addRequirements(createIURequirements(children));
		addSelfCapability(root);
		return root;
	}

	//This is to hide FileUtils from other actions
	protected IPathComputer createParentPrefixComputer(int segmentsToKeep) {
		return FileUtils.createParentPrefixComputer(segmentsToKeep);
	}

	//This is to hide FileUtils from other actions
	protected IPathComputer createRootPrefixComputer(final File root) {
		return FileUtils.createRootPathComputer(root);
	}

	protected IProvidedCapability createSelfCapability(String installableUnitId, Version installableUnitVersion) {
		return MetadataFactory.createProvidedCapability(PublisherHelper.IU_NAMESPACE, installableUnitId, installableUnitVersion);
	}

	protected static InstallableUnitDescription[] processAdditionalInstallableUnitsAdvice(IInstallableUnit iu, IPublisherInfo publisherInfo) {
		Collection<IAdditionalInstallableUnitAdvice> advice = publisherInfo.getAdvice(null, false, iu.getId(), iu.getVersion(), IAdditionalInstallableUnitAdvice.class);
		if (advice.isEmpty())
			return null;

		List<InstallableUnitDescription> ius = new ArrayList<>();
		for (IAdditionalInstallableUnitAdvice entry : advice) {
			InstallableUnitDescription[] others = entry.getAdditionalInstallableUnitDescriptions(iu);
			if (others != null)
				ius.addAll(Arrays.asList(others));
		}
		return ius.toArray(new InstallableUnitDescription[ius.size()]);
	}

	/**
	 * Add all of the advised artifact properties for the given IU and artifact descriptor.
	 * @param iu the IU
	 * @param descriptor the descriptor to decorate
	 * @param info the publisher info supplying the advice
	 */
	protected static void processArtifactPropertiesAdvice(IInstallableUnit iu, IArtifactDescriptor descriptor, IPublisherInfo info) {
		if (!(descriptor instanceof SimpleArtifactDescriptor))
			return;

		Collection<IPropertyAdvice> advice = info.getAdvice(null, false, iu.getId(), iu.getVersion(), IPropertyAdvice.class);
		for (IPropertyAdvice entry : advice) {
			Map<String, String> props = entry.getArtifactProperties(iu, descriptor);
			if (props == null)
				continue;
			for (Entry<String, String> pe : props.entrySet()) {
				((SimpleArtifactDescriptor) descriptor).setRepositoryProperty(pe.getKey(), pe.getValue());
			}
		}
	}

	/**
	 * Add all of the advised IU properties for the given IU.
	 * @param iu the IU to decorate
	 * @param info the publisher info supplying the advice
	 */
	protected static void processInstallableUnitPropertiesAdvice(InstallableUnitDescription iu, IPublisherInfo info) {
		Collection<IPropertyAdvice> advice = info.getAdvice(null, false, iu.getId(), iu.getVersion(), IPropertyAdvice.class);
		for (IPropertyAdvice entry : advice) {
			Map<String, String> props = entry.getInstallableUnitProperties(iu);
			if (props == null)
				continue;
			for (Entry<String, String> pe : props.entrySet()) {
				iu.setProperty(pe.getKey(), pe.getValue());
			}
		}
	}

	/**
	 * Add any update descriptor advice to the given IU
	 * @param iu the IU to decorate
	 * @param info the publisher info supplying the advice
	 */
	protected static void processUpdateDescriptorAdvice(InstallableUnitDescription iu, IPublisherInfo info) {
		Collection<IUpdateDescriptorAdvice> advice = info.getAdvice(null, false, iu.getId(), iu.getVersion(), IUpdateDescriptorAdvice.class);

		if (advice.isEmpty())
			return;

		for (IUpdateDescriptorAdvice entry : advice) {
			//process the IU Descriptor
			IUpdateDescriptor updateDescriptor = entry.getUpdateDescriptor(iu);
			if (updateDescriptor != null) {
				iu.setUpdateDescriptor(updateDescriptor);
			}
		}
	}

	/**
	 * Add all of the advised provided and required capabilities for the given installable unit.
	 * @param iu the IU to decorate
	 * @param info the publisher info supplying the advice
	 */
	protected static void processCapabilityAdvice(InstallableUnitDescription iu, IPublisherInfo info) {
		Collection<ICapabilityAdvice> advice = info.getAdvice(null, false, iu.getId(), iu.getVersion(), ICapabilityAdvice.class);
		if (advice.isEmpty())
			return;

		for (ICapabilityAdvice entry : advice) {
			//process required capabilities
			IRequirement[] requiredAdvice = entry.getRequiredCapabilities(iu);
			if (requiredAdvice != null) {
				List<IRequirement> current = iu.getRequirements();
				Set<IRequirement> resultRequiredCapabilities = new HashSet<>(current);

				// remove current required capabilities that match (same name and namespace) advice.
				for (IRequirement currReq : current) {
					IRequiredCapability currentRequiredCapability = toRequiredCapability(currReq);
					if (currentRequiredCapability == null) {
						continue;
					}

					for (IRequirement currReqAdvice : requiredAdvice) {
						IRequiredCapability requiredCapability = toRequiredCapability(currReqAdvice);
						if (requiredCapability == null) {
							continue;
						}

						if (requiredCapability.getNamespace().equals(currentRequiredCapability.getNamespace()) && requiredCapability.getName().equals(currentRequiredCapability.getName())) {
							resultRequiredCapabilities.remove(currentRequiredCapability);
							break;
						}
					}
				}
				// add all advice
				resultRequiredCapabilities.addAll(Arrays.asList(requiredAdvice));
				iu.setRequirements(resultRequiredCapabilities.toArray(new IRequirement[resultRequiredCapabilities.size()]));
			}

			//process meta required capabilities
			IRequirement[] metaRequiredAdvice = entry.getMetaRequiredCapabilities(iu);
			if (metaRequiredAdvice != null) {
				Collection<IRequirement> current = iu.getMetaRequirements();
				Set<IRequirement> resultMetaRequiredCapabilities = new HashSet<>(current);

				// remove current meta-required capabilities that match (same name and namespace) advice.
				for (IRequirement currMetaReq : current) {
					IRequiredCapability currentMetaRequiredCapability = toRequiredCapability(currMetaReq);
					if (currentMetaRequiredCapability == null) {
						continue;
					}

					for (IRequirement currMetaReqAdvice : metaRequiredAdvice) {
						IRequiredCapability metaRequiredCapability = toRequiredCapability(currMetaReqAdvice);
						if (metaRequiredCapability == null) {
							continue;
						}

						if (metaRequiredCapability.getNamespace().equals(currentMetaRequiredCapability.getNamespace()) && metaRequiredCapability.getName().equals(currentMetaRequiredCapability.getName())) {
							resultMetaRequiredCapabilities.remove(currentMetaRequiredCapability);
							break;
						}
					}
				}

				// add all advice
				resultMetaRequiredCapabilities.addAll(Arrays.asList(metaRequiredAdvice));
				iu.setMetaRequirements(resultMetaRequiredCapabilities.toArray(new IRequirement[resultMetaRequiredCapabilities.size()]));
			}

			//process provided capabilities
			IProvidedCapability[] providedAdvice = entry.getProvidedCapabilities(iu);
			if (providedAdvice != null) {
				Collection<IProvidedCapability> current = iu.getProvidedCapabilities();
				Set<IProvidedCapability> resultProvidedCapabilities = new HashSet<>(current);
				for (IProvidedCapability currentProvidedCapability : current) {
					for (int k = 0; k < providedAdvice.length; k++) {
						IProvidedCapability providedCapability = providedAdvice[k];
						if (providedCapability.getNamespace().equals(currentProvidedCapability.getNamespace()) && providedCapability.getName().equals(currentProvidedCapability.getName())) {
							resultProvidedCapabilities.remove(currentProvidedCapability);
							break;
						}
					}
				}
				resultProvidedCapabilities.addAll(Arrays.asList(providedAdvice));
				iu.setCapabilities(resultProvidedCapabilities.toArray(new IProvidedCapability[resultProvidedCapabilities.size()]));
			}
		}
	}

	protected static IRequiredCapability toRequiredCapability(IRequirement requirement) {
		if (!(requirement instanceof IRequiredCapability)) {
			return null;
		}

		IRequiredCapability requiredCapability = (IRequiredCapability) requirement;
		if (!RequiredCapability.isVersionRangeRequirement(requiredCapability.getMatches())) {
			return null;
		}

		return requiredCapability;
	}

	/**
	 * Adds all applicable touchpoint advice to the given installable unit.
	 * @param iu The installable unit to add touchpoint advice to
	 * @param currentInstructions The set of touchpoint instructions assembled for this IU so far
	 * @param info The publisher info
	 */
	protected static void processTouchpointAdvice(InstallableUnitDescription iu, Map<String, ? extends Object> currentInstructions, IPublisherInfo info) {
		processTouchpointAdvice(iu, currentInstructions, info, null);
	}

	protected static void processTouchpointAdvice(InstallableUnitDescription iu, Map<String, ? extends Object> currentInstructions, IPublisherInfo info, String configSpec) {
		Collection<ITouchpointAdvice> advice = info.getAdvice(configSpec, false, iu.getId(), iu.getVersion(), ITouchpointAdvice.class);
		if (currentInstructions == null) {
			if (advice == null || advice.isEmpty())
				return;
			currentInstructions = Collections.emptyMap();
		}

		ITouchpointData result = MetadataFactory.createTouchpointData(currentInstructions);
		if (advice != null) {
			for (ITouchpointAdvice entry : advice) {
				result = entry.getTouchpointData(result);
			}
		}
		iu.addTouchpointData(result);
	}

	/**
	 * Publishes the artifact by zipping the <code>files</code> using <code>root</code>
	 * as a base for relative paths. Then copying the zip into the repository.
	 * @param descriptor used to identify the zip.
	 * @param inclusion the file to be published. files can be <code>null</code> but no action is taken.
	 * @param publisherInfo the publisher info.
	 */
	protected void publishArtifact(IArtifactDescriptor descriptor, File inclusion, IPublisherInfo publisherInfo) {
		// no files to publish so this is done.
		if (inclusion == null)
			return;
		// if the destination already contains the descriptor, there is nothing to do.
		IArtifactRepository destination = publisherInfo.getArtifactRepository();
		if (destination == null || destination.contains(descriptor))
			return;

		// if all we are doing is indexing things then add the descriptor and get on with it
		if ((publisherInfo.getArtifactOptions() & IPublisherInfo.A_PUBLISH) == 0) {
			destination.addDescriptor(descriptor, new NullProgressMonitor());
			return;
		}

		// if the file is already in the same location the repo will put it, just add the descriptor and exit
		if (destination instanceof IFileArtifactRepository) {
			File descriptorFile = ((IFileArtifactRepository) destination).getArtifactFile(descriptor);
			if (inclusion.equals(descriptorFile)) {
				destination.addDescriptor(descriptor, new NullProgressMonitor());
				return;
			}
		}

		try {
			OutputStream output = destination.getOutputStream(descriptor);
			if (output == null)
				return;
			output = new BufferedOutputStream(output);
			FileUtils.copyStream(new BufferedInputStream(new FileInputStream(inclusion)), true, output, true);
		} catch (ProvisionException e) {
			LogHelper.log(e.getStatus());
		} catch (IOException e) {
			LogHelper.log(new Status(IStatus.ERROR, Activator.ID, "Error publishing artifacts", e)); //$NON-NLS-1$
		}
	}

	/**
	 * Publishes the artifact by zipping the <code>files</code> using <code>root</code>
	 * as a base for relative paths. Then copying the zip into the repository.
	 * @param descriptor used to identify the zip.
	 * @param inclusions and folders to be included in the zip. files can be null.
	 * @param exclusions and folders to be excluded in the zip. files can be null.
	 * @param publisherInfo the publisher info.
	 * @param prefixComputer
	 */
	protected void publishArtifact(IArtifactDescriptor descriptor, File[] inclusions, File[] exclusions, IPublisherInfo publisherInfo, IPathComputer prefixComputer) {
		// no files to publish so this is done.
		if (inclusions == null || inclusions.length < 1)
			return;
		// if the destination already contains the descriptor, there is nothing to do.
		IArtifactRepository destination = publisherInfo.getArtifactRepository();
		if (destination == null || destination.contains(descriptor))
			return;
		// if all we are doing is indexing things then add the descriptor and get on with it
		if ((publisherInfo.getArtifactOptions() & IPublisherInfo.A_PUBLISH) == 0) {
			destination.addDescriptor(descriptor, new NullProgressMonitor());
			return;
		}

		// TODO need to implement the overwrite story in the repos
		//		boolean overwrite = (info.getArtifactOptions() & IPublisherInfo.A_OVERWRITE) > 0;
		// if there is just one file and the mode is as-is, just copy the file into the repo
		// otherwise, zip up the files and copy the zip into the repo
		File tempFile = null;
		try {
			OutputStream output = destination.getOutputStream(descriptor);
			if (output == null)
				return;
			output = new BufferedOutputStream(output);
			tempFile = File.createTempFile("p2.generator", ""); //$NON-NLS-1$ //$NON-NLS-2$
			FileUtils.zip(inclusions, exclusions, tempFile, prefixComputer);
			if (output != null)
				FileUtils.copyStream(new BufferedInputStream(new FileInputStream(tempFile)), true, output, true);
		} catch (ProvisionException e) {
			LogHelper.log(e.getStatus());
		} catch (IOException e) {
			LogHelper.log(new Status(IStatus.ERROR, Activator.ID, "Error publishing artifacts", e)); //$NON-NLS-1$
			e.printStackTrace();
		} finally {
			if (tempFile != null)
				tempFile.delete();
		}
	}

	/**
	 * Loop over the known metadata repositories looking for the given IU.
	 * Return the first IU found.
	 * @param iuId  the id of the IU to look for
	 * @return the first matching IU or <code>null</code> if none.
	 */
	protected IInstallableUnit queryForIU(IPublisherResult publisherResult, String iuId, Version version) {
		IQuery<IInstallableUnit> query = QueryUtil.createIUQuery(iuId, version);
		if (version == null || Version.emptyVersion.equals(version))
			query = QueryUtil.createLatestQuery(query);

		IQueryResult<IInstallableUnit> collector = Collector.emptyCollector();
		NullProgressMonitor progress = new NullProgressMonitor();
		if (publisherResult != null)
			collector = publisherResult.query(query, progress);
		if (collector.isEmpty() && info.getMetadataRepository() != null)
			collector = info.getMetadataRepository().query(query, progress);
		if (collector.isEmpty() && info.getContextMetadataRepository() != null)
			collector = info.getContextMetadataRepository().query(query, progress);
		if (!collector.isEmpty())
			return collector.iterator().next();
		return null;
	}

	/**
	 * Loop over the known metadata repositories looking for the given IU within a particular range
	 * @param publisherResult
	 * @param iuId the id of the IU to look for
	 * @param versionRange the version range to consider
	 * @return The the IUs with the matching ids in the given range
	 */
	protected IQueryResult<IInstallableUnit> queryForIUs(IPublisherResult publisherResult, String iuId, VersionRange versionRange) {
		IQuery<IInstallableUnit> query = null;
		IQueryResult<IInstallableUnit> queryResult = Collector.emptyCollector();
		query = QueryUtil.createIUQuery(iuId, versionRange);
		NullProgressMonitor progress = new NullProgressMonitor();
		if (publisherResult != null)
			queryResult = publisherResult.query(query, progress);
		if (queryResult.isEmpty() && info.getMetadataRepository() != null)
			queryResult = info.getMetadataRepository().query(query, progress);
		if (queryResult.isEmpty() && info.getContextMetadataRepository() != null)
			queryResult = info.getContextMetadataRepository().query(query, progress);
		return queryResult;
	}

	@Override
	public abstract IStatus perform(IPublisherInfo publisherInfo, IPublisherResult results, IProgressMonitor monitor);

	public void setPublisherInfo(IPublisherInfo info) {
		this.info = info;
	}
}
