bug 293715 - filter attribute on feature inclusions/requirements
diff --git a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalFeatureParser.java b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalFeatureParser.java
index 00a734f..a35363f 100644
--- a/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalFeatureParser.java
+++ b/update/org.eclipse.update.core/src/org/eclipse/update/internal/core/InternalFeatureParser.java
@@ -98,6 +98,10 @@
 	private static final String IMPORT = "import"; //$NON-NLS-1$
 	private static final String PLUGIN = "plugin"; //$NON-NLS-1$
 	private static final String DATA = "data"; //$NON-NLS-1$
+	
+	//debug message
+	private static final String UNSUPPORTED_FILTER_MSG = "Unsupported \"filter\" attribute, ignoring {0}, with id {1}, version {2}";
+	
 	// Current State Information
 	Stack stateStack = new Stack();
 
@@ -107,6 +111,7 @@
 
 	private int currentState;
     private String location;
+    private boolean ignoredElement = false;
 	
 	private final static SAXParserFactory parserFactory =
 		SAXParserFactory.newInstance();
@@ -451,10 +456,13 @@
 			case STATE_REQUIRES :
 				stateStack.pop();
 				if (objectStack.peek() instanceof FeatureModel) {
+					boolean foundIgnored = ignoredElement;
+					ignoredElement = false;
 					featureModel = (FeatureModel) objectStack.peek();
 					ImportModel[] importModels = featureModel.getImportModels();
 					if (importModels.length == 0) {
-						internalError(Messages.DefaultFeatureParser_RequireStateWithoutImportElement); 
+						if (!foundIgnored) //don't report error if we ignored something
+							internalError(Messages.DefaultFeatureParser_RequireStateWithoutImportElement);
 					} else {
 						boolean patchMode = false;
 						for (int i = 0; i < importModels.length; i++) {
@@ -838,6 +846,14 @@
 			internalError(NLS.bind(Messages.DefaultFeatureParser_IdOrVersionInvalid, (new String[] { id, ver, getState(currentState)})));
 		}
 
+		String filter = attributes.getValue("filter");
+		if (filter != null) {
+			//unsupported, ignore this element
+			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) 
+				debug(NLS.bind(UNSUPPORTED_FILTER_MSG, new String [] {INCLUDES, id, ver}));
+			return;
+		}
+		
 		IncludedFeatureReferenceModel includedFeature = factory.createIncludedFeatureReferenceModel();
 		includedFeature.setFeatureIdentifier(id);
 		includedFeature.setFeatureVersion(ver);
@@ -933,10 +949,19 @@
 		if (id == null || id.trim().equals("")) //$NON-NLS-1$
 			internalError(NLS.bind(Messages.DefaultFeatureParser_MissingId, (new String[] { getState(currentState) })));
 		else {
-			ImportModel imp = factory.createImportModel();
+			String filter = attributes.getValue("filter");
 			String ver = attributes.getValue("version"); //$NON-NLS-1$
 			String match = attributes.getValue("match"); //$NON-NLS-1$
 			String patch = attributes.getValue("patch"); //$NON-NLS-1$
+			
+			if (filter != null) {
+				//unsupported, ignore this element
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) 
+					debug(NLS.bind(UNSUPPORTED_FILTER_MSG, new String [] {IMPORT + ' ' + (pluginID != null ? PLUGIN : FEATURE), id, ver}));
+				ignoredElement = true;
+				return;
+			}
+			ImportModel imp = factory.createImportModel();
 
 			imp.setPatch(patch != null && patch.equalsIgnoreCase("true")); //$NON-NLS-1$
 
@@ -1006,6 +1031,14 @@
 		|| ver == null || ver.trim().equals("")) { //$NON-NLS-1$
 			internalError(NLS.bind(Messages.DefaultFeatureParser_IdOrVersionInvalid, (new String[] { id, ver, getState(currentState)})));
 		} else {
+			String filter = attributes.getValue("filter");
+			if (filter != null) {
+				//unsupported, ignore this element
+				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) 
+					debug(NLS.bind(UNSUPPORTED_FILTER_MSG, new String [] {PLUGIN, id, ver}));
+				return;
+			}
+			
 			PluginEntryModel pluginEntry = factory.createPluginEntryModel();
 			pluginEntry.setPluginIdentifier(id);
 			pluginEntry.setPluginVersion(ver);
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/FeatureMain.java b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/FeatureMain.java
index 4c2463a..c90f619 100644
--- a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/FeatureMain.java
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/FeatureMain.java
@@ -14,6 +14,7 @@
 import java.net.URL;
 import java.util.ResourceBundle;
 
+import org.eclipse.update.core.IIncludedFeatureReference;
 import org.eclipse.update.core.model.*;
 import org.eclipse.update.tests.UpdateManagerTestCase;
 
@@ -43,6 +44,15 @@
 		System.out.println("Resolving feature using "+base+" ...");
 		ResourceBundle.getBundle("org/eclipse/update/tests/model/test");
 		feature.resolve(new URL(base), new URL(base));
+		
+		ImportModel[] importModels = feature.getImportModels();
+		assertEquals(3, importModels.length);
+		
+		PluginEntryModel[] pluginEntryModels = feature.getPluginEntryModels();
+		assertEquals(3, pluginEntryModels.length);
+		
+		IIncludedFeatureReference[] featureIncluded = feature.getFeatureIncluded();
+		assertEquals(0, featureIncluded.length);
 	}
 	
 //	private static void writeFeature(PrintWriter w, int level, FeatureModel feature) {
diff --git a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/feature.xml b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/feature.xml
index b2d2692..95940df 100644
--- a/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/feature.xml
+++ b/update/org.eclipse.update.tests.core/src/org/eclipse/update/tests/model/feature.xml
@@ -29,12 +29,17 @@
       <import plugin="plugin.1" version="1.0.0" match="perfect"/>
       <import plugin="plugin.2" version="3.2.0"/>
       <import plugin="plugin.3"/>
+      <import plugin="plugin.4" version="1.0.0" filter="(installPlugin=true)" />
+      <import feature="feature.1" version="1.0.0" filter="(installFeature=true)" />
    </requires>
    
    <plugin id="my.plugin.1" version="1.0.0" fragment="true"
            os="Win32" ws="Win32" nl="en_US" download-size="23456" install-size="1234567"/>
    <plugin id="my.plugin.2" version="1.0.1"/>
    <plugin id="my.plugin.3" version="1.0.2"/>
+   <plugin id="my.plugin.4" version="1.0.0" filter="(ignoreThis = true)" />
+   
+   <includes id="some.feature" version="1.0.0" filter="(ignoreThis=also)"/>
    
    <data id="examples.zip" download-size="23456" install-size="1234567"/>
    <data id="custom/rt.jar"/>