*** empty log message ***
diff --git a/ui/org.eclipse.pde.core/plugin.xml b/ui/org.eclipse.pde.core/plugin.xml
index 6d418ed..eaefa0c 100644
--- a/ui/org.eclipse.pde.core/plugin.xml
+++ b/ui/org.eclipse.pde.core/plugin.xml
@@ -2,7 +2,7 @@
 <plugin
    id="org.eclipse.pde.core"
    name="%name"
-   version="2.0.1"
+   version="2.0.2"
    provider-name="%provider-name"
    class="org.eclipse.pde.internal.core.PDECore">
 
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureChild.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureChild.java
index ccd5918..8f479bb 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureChild.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureChild.java
@@ -3,6 +3,7 @@
 import java.io.PrintWriter;
 
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.pde.core.plugin.IMatchRules;
 import org.eclipse.pde.internal.core.PDECore;
 import org.eclipse.pde.internal.core.ifeature.*;
 import org.w3c.dom.Node;
@@ -18,26 +19,51 @@
 	private IFeature feature;
 	private String name;
 	private boolean optional;
+	private int searchLocation = LOCATION_ROOT;
+	private int match = IMatchRules.PERFECT;
 
 	protected void reset() {
 		super.reset();
 		version = null;
 		optional = false;
 		name = null;
+		searchLocation = LOCATION_ROOT;
+		match = IMatchRules.PERFECT;
 	}
 	protected void parse(Node node) {
 		super.parse(node);
 		version = getNodeAttribute(node, "version");
 		name = getNodeAttribute(node, "name");
 		optional = getBooleanAttribute(node, "optional");
+		String value = getNodeAttribute(node, "search-location");
+		if (value != null) {
+			if (value.equalsIgnoreCase("root")) {
+				searchLocation = LOCATION_ROOT;
+			} else if (value.equalsIgnoreCase("self")) {
+				searchLocation = LOCATION_SELF;
+			} else if (value.equalsIgnoreCase("both")) {
+				searchLocation = LOCATION_BOTH;
+			}
+		}
+		value = getNodeAttribute(node, "match");
+		if (value != null) {
+			for (int i = 0; i < IMatchRules.RULE_NAME_TABLE.length; i++) {
+				if (value.equals(IMatchRules.RULE_NAME_TABLE[i])) {
+					match = i;
+					break;
+				}
+			}
+		}
 		hookWithWorkspace();
 	}
-	
+
 	public void loadFrom(IFeature feature) {
 		id = feature.getId();
 		version = feature.getVersion();
 		optional = false;
 		name = feature.getLabel();
+		match = IMatchRules.PERFECT;
+		searchLocation = LOCATION_ROOT;
 		this.feature = feature;
 	}
 	/**
@@ -46,28 +72,39 @@
 	public String getVersion() {
 		return version;
 	}
-	
+
 	public boolean isOptional() {
 		return optional;
 	}
-	
+
 	public String getName() {
 		return name;
 	}
 
+	public int getMatch() {
+		return match;
+	}
+
+	public int getSearchLocation() {
+		return searchLocation;
+	}
+
 	public IFeature getReferencedFeature() {
-		if (feature==null)
+		if (feature == null)
 			hookWithWorkspace();
 		return feature;
 	}
 
 	private void hookWithWorkspace() {
 		IFeatureModel[] models =
-			PDECore.getDefault().getWorkspaceModelManager().getWorkspaceFeatureModels();
+			PDECore
+				.getDefault()
+				.getWorkspaceModelManager()
+				.getWorkspaceFeatureModels();
 		for (int i = 0; i < models.length; i++) {
 			IFeature feature = models[i].getFeature();
-			
-			if (feature!=null && feature.getId().equals(getId())) {
+
+			if (feature != null && feature.getId().equals(getId())) {
 				if (version == null || feature.getVersion().equals(version)) {
 					this.feature = feature;
 					break;
@@ -86,40 +123,59 @@
 		firePropertyChanged(P_VERSION, oldValue, version);
 		hookWithWorkspace();
 	}
-	
+
 	public void setName(String name) throws CoreException {
 		ensureModelEditable();
 		Object oldValue = this.name;
 		this.name = name;
 		firePropertyChanged(P_NAME, oldValue, name);
 	}
-	
+
 	public void setOptional(boolean optional) throws CoreException {
 		ensureModelEditable();
 		Object oldValue = new Boolean(this.optional);
 		this.optional = optional;
 		firePropertyChanged(P_NAME, oldValue, new Boolean(optional));
 	}
-		
-	
-	public void restoreProperty(String name, Object oldValue, Object newValue) throws CoreException {
+
+	public void restoreProperty(String name, Object oldValue, Object newValue)
+		throws CoreException {
 		if (name.equals(P_VERSION)) {
-			setVersion((String)newValue);
-		}
-		else if (name.equals(P_OPTIONAL)) {
-			setOptional(((Boolean)newValue).booleanValue());
-		}
-		else if (name.equals(P_NAME)) {
-			setName((String)newValue);
-		}
-		else super.restoreProperty(name, oldValue, newValue);
+			setVersion((String) newValue);
+		} else if (name.equals(P_OPTIONAL)) {
+			setOptional(((Boolean) newValue).booleanValue());
+		} else if (name.equals(P_NAME)) {
+			setName((String) newValue);
+		} else if (name.equals(P_SEARCH_LOCATION)) {
+			setSearchLocation(((Integer) newValue).intValue());
+		} else if (name.equals(P_MATCH)) {
+			setMatch(((Integer) newValue).intValue());
+		} else
+			super.restoreProperty(name, oldValue, newValue);
 	}
-	
+
 	public void setId(String id) throws CoreException {
 		super.setId(id);
 		hookWithWorkspace();
 	}
 
+	public void setMatch(int match) throws CoreException {
+		ensureModelEditable();
+		Object oldValue = new Integer(this.match);
+		this.match = match;
+		firePropertyChanged(P_MATCH, oldValue, new Integer(match));
+	}
+
+	public void setSearchLocation(int searchLocation) throws CoreException {
+		ensureModelEditable();
+		Object oldValue = new Integer(this.searchLocation);
+		this.match = match;
+		firePropertyChanged(
+			P_SEARCH_LOCATION,
+			oldValue,
+			new Integer(searchLocation));
+	}
+
 	/**
 	 * @see IWritable#write(String, PrintWriter)
 	 */
@@ -142,6 +198,21 @@
 			writer.println();
 			writer.print(indent2 + "optional=\"true\"");
 		}
+		if (getMatch() != IMatchRules.PERFECT) {
+			writer.println();
+			writer.print(
+				indent2
+					+ "match=\""
+					+ IMatchRules.RULE_NAME_TABLE[match]
+					+ "\"");
+		}
+		if (getSearchLocation() != LOCATION_ROOT) {
+			writer.println();
+			String value = "self";
+			if (getSearchLocation() == LOCATION_BOTH)
+				value = "both";
+			writer.print(indent2 + "search-location=\"" + value + "\"");
+		}
 		writer.println(">");
 		writer.println(indent + "</includes>");
 	}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureImport.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureImport.java
index 225f6eb..c3944d3 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureImport.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/feature/FeatureImport.java
@@ -17,6 +17,8 @@
 	implements IFeatureImport {
 	private int match = NONE;
 	private IPlugin plugin;
+	private int kind = KIND_PLUGIN;
+	private boolean patch = false;
 
 	public FeatureImport() {
 	}
@@ -32,6 +34,12 @@
 	protected void parse(Node node) {
 		super.parse(node);
 		this.id = getNodeAttribute(node, "plugin");
+		if (this.id == null) {
+			this.id = getNodeAttribute(node, "feature");
+			if (this.id != null) {
+				kind = KIND_FEATURE;
+			}
+		}
 		String mvalue = getNodeAttribute(node, "match");
 		if (mvalue != null && mvalue.length() > 0) {
 			String[] choices = RULE_NAME_TABLE;
@@ -42,13 +50,24 @@
 				}
 			}
 		}
-		setPlugin(PDECore.getDefault().findPlugin(id, getVersion(), match));
+		patch = getBooleanAttribute(node, "patch");
+
+		if (kind == KIND_PLUGIN)
+			setPlugin(PDECore.getDefault().findPlugin(id, getVersion(), match));
 	}
 
 	public int getMatch() {
 		return match;
 	}
 
+	public boolean isPatch() {
+		return patch;
+	}
+
+	public int getKind() {
+		return kind;
+	}
+
 	public void setMatch(int match) throws CoreException {
 		ensureModelEditable();
 		Integer oldValue = new Integer(this.match);
@@ -56,22 +75,49 @@
 		firePropertyChanged(P_MATCH, oldValue, new Integer(match));
 	}
 
+	public void setPatch(boolean value) throws CoreException {
+		ensureModelEditable();
+		Boolean oldValue = new Boolean(this.patch);
+		this.patch = value;
+		firePropertyChanged(P_PATCH, oldValue, new Boolean(value));
+	}
+	
+	public void setKind(int kind) throws CoreException {
+		ensureModelEditable();
+		Integer oldValue = new Integer(this.kind);
+		this.kind = kind;
+		firePropertyChanged(P_KIND, oldValue, new Integer(kind));
+	}
+
 	public void restoreProperty(String name, Object oldValue, Object newValue)
 		throws CoreException {
-		if (name.equals(P_MATCH)) {
+		if (name.equals(P_MATCH))
 			setMatch(newValue != null ? ((Integer) newValue).intValue() : 0);
-		} else
+		else if (name.equals(P_PATCH))
+			setPatch(
+				newValue != null ? ((Boolean) newValue).booleanValue() : false);
+		else if (name.equals(P_KIND))
+			setKind(
+				newValue != null
+					? ((Integer) newValue).intValue()
+					: KIND_PLUGIN);
+		else
 			super.restoreProperty(name, oldValue, newValue);
 	}
 
 	public void write(String indent, PrintWriter writer) {
-		writer.print(indent + "<import plugin=\"" + getId() + "\"");
+		String target = "plugin";
+		if (kind==KIND_FEATURE) target = "feature";
+		writer.print(indent + "<import "+target+"=\"" + getId() + "\"");
 		if (getVersion() != null) {
 			writer.print(" version=\"" + getVersion() + "\"");
 		}
 		if (match != NONE) {
 			writer.print(" match=\"" + RULE_NAME_TABLE[match] + "\"");
 		}
+		if (patch) {
+			writer.print(" patch=\"true\"");
+		}
 		writer.println("/>");
 	}
 	public String toString() {
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureChild.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureChild.java
index 7341258..31e80e5 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureChild.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureChild.java
@@ -13,10 +13,22 @@
 	String P_VERSION = "version";
 	String P_OPTIONAL = "optional";
 	String P_NAME = "name";
+	String P_SEARCH_LOCATION = "location";
+	String P_MATCH = "match";
+	
+	int LOCATION_ROOT = 0;
+	int LOCATION_SELF = 1;
+	int LOCATION_BOTH = 2;
 	String getVersion();
 	void setVersion(String version) throws CoreException;
 	boolean isOptional();
 	void setOptional(boolean optional) throws CoreException;
 	String getName();
 	void setName(String name) throws CoreException;
+
+	void setMatch(int match) throws CoreException;
+	int getMatch();
+	
+	void setSearchLocation(int location) throws CoreException;
+	int getSearchLocation();
 }
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureImport.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureImport.java
index 920aa4b..229a601 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureImport.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ifeature/IFeatureImport.java
@@ -6,10 +6,29 @@
  */
 package org.eclipse.pde.internal.core.ifeature;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.pde.core.plugin.IPluginReference;
 /**
  * @version 	1.0
  * @author
  */
 public interface IFeatureImport extends IFeatureObject, IPluginReference {
+	String P_PATCH = "patch";
+	String P_KIND = "kind";
+
+	int KIND_PLUGIN = 0;
+	int KIND_FEATURE = 1;	
+/**
+ * Returns true if this reference entry is used to
+ * declare the feature as a patch of the referenced feature.
+ */
+	boolean isPatch();
+	
+	void setPatch(boolean value) throws CoreException;
+/**
+ * Returns kind of the import (KIND_PLUGIN or KIND_FEATURE).
+ */
+	int getKind();
+	
+	void setKind(int kind) throws CoreException;
 }