Bug 336828: patterns should support delete, remove, direct editing and conditional palette creation entry
diff --git a/plugins/org.eclipse.graphiti.pattern/.settings/.api_filters b/plugins/org.eclipse.graphiti.pattern/.settings/.api_filters
index c9af34c..28eb829 100644
--- a/plugins/org.eclipse.graphiti.pattern/.settings/.api_filters
+++ b/plugins/org.eclipse.graphiti.pattern/.settings/.api_filters
@@ -43,12 +43,6 @@
     <resource path="src/org/eclipse/graphiti/pattern/IPattern.java" type="org.eclipse.graphiti.pattern.IPattern">
         <filter id="571473929">
             <message_arguments>
-                <message_argument value="ILayout"/>
-                <message_argument value="IPattern"/>
-            </message_arguments>
-        </filter>
-        <filter id="571473929">
-            <message_arguments>
                 <message_argument value="IAdd"/>
                 <message_argument value="IPattern"/>
             </message_arguments>
@@ -61,7 +55,19 @@
         </filter>
         <filter id="571473929">
             <message_arguments>
-                <message_argument value="IResizeShape"/>
+                <message_argument value="IDelete"/>
+                <message_argument value="IPattern"/>
+            </message_arguments>
+        </filter>
+        <filter id="571473929">
+            <message_arguments>
+                <message_argument value="IDirectEditing"/>
+                <message_argument value="IPattern"/>
+            </message_arguments>
+        </filter>
+        <filter id="571473929">
+            <message_arguments>
+                <message_argument value="ILayout"/>
                 <message_argument value="IPattern"/>
             </message_arguments>
         </filter>
@@ -73,6 +79,18 @@
         </filter>
         <filter id="571473929">
             <message_arguments>
+                <message_argument value="IRemove"/>
+                <message_argument value="IPattern"/>
+            </message_arguments>
+        </filter>
+        <filter id="571473929">
+            <message_arguments>
+                <message_argument value="IResizeShape"/>
+                <message_argument value="IPattern"/>
+            </message_arguments>
+        </filter>
+        <filter id="571473929">
+            <message_arguments>
                 <message_argument value="IUpdate"/>
                 <message_argument value="IPattern"/>
             </message_arguments>
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
index 410d5af..0296b6b 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/AbstractPattern.java
@@ -9,6 +9,9 @@
  *
  * Contributors:
  *    SAP AG - initial API, implementation and documentation
+ *    Volker Wegert - Bug 336828: patterns should support delete,
+ *                    remove, direct editing and conditional palette
+ *                    creation entry
  *
  * </copyright>
  *
@@ -20,19 +23,28 @@
 import java.util.List;
 
 import org.eclipse.graphiti.features.DefaultResizeConfiguration;
+import org.eclipse.graphiti.features.IDeleteFeature;
 import org.eclipse.graphiti.features.IDirectEditingInfo;
 import org.eclipse.graphiti.features.IReason;
+import org.eclipse.graphiti.features.IRemoveFeature;
 import org.eclipse.graphiti.features.IResizeConfiguration;
 import org.eclipse.graphiti.features.context.IAreaContext;
 import org.eclipse.graphiti.features.context.ICreateContext;
+import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.features.context.IDirectEditingContext;
 import org.eclipse.graphiti.features.context.ILayoutContext;
 import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
 import org.eclipse.graphiti.features.context.IResizeShapeContext;
 import org.eclipse.graphiti.features.context.IUpdateContext;
 import org.eclipse.graphiti.features.context.impl.AddContext;
 import org.eclipse.graphiti.features.context.impl.LayoutContext;
 import org.eclipse.graphiti.features.context.impl.UpdateContext;
+import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
 import org.eclipse.graphiti.features.impl.Reason;
+import org.eclipse.graphiti.func.IDelete;
+import org.eclipse.graphiti.func.IDirectEditing;
+import org.eclipse.graphiti.func.IRemove;
 import org.eclipse.graphiti.mm.algorithms.styles.Point;
 import org.eclipse.graphiti.mm.pictograms.Anchor;
 import org.eclipse.graphiti.mm.pictograms.Connection;
@@ -47,15 +59,47 @@
 import org.eclipse.graphiti.pattern.mapping.data.IImageDataMapping;
 import org.eclipse.graphiti.pattern.mapping.data.ITextDataMapping;
 import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
 
 /**
  * The Class AbstractPattern.
  */
 public abstract class AbstractPattern extends AbstractBasePattern implements IPattern {
 
+	/**
+	 * An empty string array used in direct editing.
+	 */
+	protected static final String[] EMPTY_STRING_ARRAY = new String[0];
+
 	private IPatternConfiguration patternConfiguration;
 
 	/**
+	 * To avoid code duplication, this base class uses a wrapped default
+	 * implementation of an {@link IDeleteFeature} to provide the default
+	 * deletion behaviour. Subclasses may decide to either override
+	 * {@link #createDeleteFeature(IDeleteContext)} to provide another
+	 * {@link IDeleteFeature} implementation or override and extend the
+	 * individual {@link IDelete} methods or return a {@link IDeleteFeature} by
+	 * overriding the method
+	 * {@link DefaultFeatureProviderWithPatterns#getDeleteFeature(IDeleteContext)}
+	 * .
+	 */
+	private IDeleteFeature wrappedDeleteFeature;
+
+	/**
+	 * To avoid code duplication, this base class uses a wrapped default
+	 * implementation of an {@link IRemoveFeature} to provide the default
+	 * removal behavior. Subclasses may decide to either override
+	 * {@link #createRemoveFeature(IRemoveContext)} to provide another
+	 * {@link IRemoveFeature} implementation or override and extend the
+	 * individual {@link IRemove} methods or  return a {@link IRemoveFeature} by
+	 * overriding the method
+	 * {@link DefaultFeatureProviderWithPatterns#getRemoveFeature(IRemoveContext)}
+	 * .
+	 */
+	private IRemoveFeature wrappedRemoveFeature;
+
+	/**
 	 * Creates a new {@link AbstractPattern}.
 	 * 
 	 * @param patternConfiguration
@@ -65,6 +109,11 @@
 		setPatternConfiguration(patternConfiguration);
 	}
 
+	@Override
+	public boolean isPaletteApplicable() {
+		return true;
+	}
+
 	public boolean canCreate(ICreateContext context) {
 		return false;
 	}
@@ -385,4 +434,284 @@
 	public IResizeConfiguration getResizeConfiguration(IResizeShapeContext context) {
 		return new DefaultResizeConfiguration();
 	}
+
+	/**
+	 * Creates the {@link IDeleteFeature} instance that handles the deletion of
+	 * business objects and diagram elements. The default implementation just
+	 * creates a {@link DefaultDeleteFeature}. Concrete pattern implementations
+	 * may either override this method to provide their own subclass of
+	 * {@link DefaultDeleteFeature} or override and extend the individual
+	 * methods provided by {@link IDelete}.
+	 * 
+	 * @param context
+	 *            the deletion context
+	 * @return the {@link IDeleteFeature} instance to use for this pattern
+	 * @see #canDelete(IDeleteContext)
+	 * @see #preDelete(IDeleteContext)
+	 * @see #delete(IDeleteContext)
+	 * @see #postDelete(IDeleteContext)
+	 */
+	protected IDeleteFeature createDeleteFeature(IDeleteContext context) {
+		return new DefaultDeleteFeature(getFeatureProvider());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDelete#canDelete(org.eclipse.graphiti.features
+	 * .context.IDeleteContext)
+	 */
+	public boolean canDelete(IDeleteContext context) {
+		if (wrappedDeleteFeature == null) {
+			wrappedDeleteFeature = createDeleteFeature(context);
+		}
+		return ((wrappedDeleteFeature != null) && wrappedDeleteFeature.canDelete(context));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDelete#preDelete(org.eclipse.graphiti.features
+	 * .context.IDeleteContext)
+	 */
+	public void preDelete(IDeleteContext context) {
+		if (wrappedDeleteFeature == null) {
+			wrappedDeleteFeature = createDeleteFeature(context);
+		}
+		if (wrappedDeleteFeature != null) {
+			wrappedDeleteFeature.preDelete(context);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDelete#delete(org.eclipse.graphiti.features
+	 * .context.IDeleteContext)
+	 */
+	public void delete(IDeleteContext context) {
+		if (wrappedDeleteFeature == null) {
+			wrappedDeleteFeature = createDeleteFeature(context);
+		}
+		if (wrappedDeleteFeature != null) {
+			wrappedDeleteFeature.delete(context);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDelete#postDelete(org.eclipse.graphiti.features
+	 * .context.IDeleteContext)
+	 */
+	public void postDelete(IDeleteContext context) {
+		if (wrappedDeleteFeature == null) {
+			wrappedDeleteFeature = createDeleteFeature(context);
+		}
+		if (wrappedDeleteFeature != null) {
+			wrappedDeleteFeature.postDelete(context);
+		}
+	}
+
+	/**
+	 * Creates the {@link IRemoveFeature} instance that handles the removal of
+	 * diagram elements. The default implementation just creates a
+	 * {@link DefaultRemoveFeature}. Concrete pattern implementations may either
+	 * override this method to provide their own subclass of
+	 * {@link DefaultRemoveFeature} or override and extend the individual
+	 * methods provided by {@link IRemove}.
+	 * 
+	 * @param context
+	 *            the removal context
+	 * @return the {@link IRemoveFeature} instance to use for this pattern
+	 * @see #canRemove(IRemoveContext)
+	 * @see #preRemove(IRemoveContext)
+	 * @see #Remove(IRemoveContext)
+	 * @see #postRemove(IRemoveContext)
+	 */
+	protected IRemoveFeature createRemoveFeature(IRemoveContext context) {
+		return new DefaultRemoveFeature(getFeatureProvider());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IRemove#canRemove(org.eclipse.graphiti.features
+	 * .context.IRemoveContext)
+	 */
+	public boolean canRemove(IRemoveContext context) {
+		if (wrappedRemoveFeature == null) {
+			wrappedRemoveFeature = createRemoveFeature(context);
+		}
+		return wrappedRemoveFeature.canRemove(context);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IRemove#preRemove(org.eclipse.graphiti.features
+	 * .context.IRemoveContext)
+	 */
+	public void preRemove(IRemoveContext context) {
+		if (wrappedRemoveFeature == null) {
+			wrappedRemoveFeature = createRemoveFeature(context);
+		}
+		wrappedRemoveFeature.preRemove(context);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IRemove#remove(org.eclipse.graphiti.features
+	 * .context.IRemoveContext)
+	 */
+	public void remove(IRemoveContext context) {
+		if (wrappedRemoveFeature == null) {
+			wrappedRemoveFeature = createRemoveFeature(context);
+		}
+		wrappedRemoveFeature.remove(context);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IRemove#postRemove(org.eclipse.graphiti.features
+	 * .context.IRemoveContext)
+	 */
+	public void postRemove(IRemoveContext context) {
+		if (wrappedRemoveFeature == null) {
+			wrappedRemoveFeature = createRemoveFeature(context);
+		}
+		wrappedRemoveFeature.postRemove(context);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#canDirectEdit(org.eclipse.graphiti
+	 * .features.context.IDirectEditingContext)
+	 */
+	@Override
+	public boolean canDirectEdit(IDirectEditingContext context) {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#checkValueValid(java.lang.String
+	 * , org.eclipse.graphiti.features.context.IDirectEditingContext)
+	 */
+	@Override
+	public String checkValueValid(String value, IDirectEditingContext context) {
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#completeValue(java.lang.String,
+	 * int, java.lang.String,
+	 * org.eclipse.graphiti.features.context.IDirectEditingContext)
+	 */
+	@Override
+	public String completeValue(String value, int caretPos, String choosenValue, IDirectEditingContext context) {
+		return choosenValue;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#getPossibleValues(org.eclipse
+	 * .graphiti.features.context.IDirectEditingContext)
+	 */
+	@Override
+	public String[] getPossibleValues(IDirectEditingContext context) {
+		return EMPTY_STRING_ARRAY;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#getValueProposals(java.lang.
+	 * String, int, org.eclipse.graphiti.features.context.IDirectEditingContext)
+	 */
+	@Override
+	public String[] getValueProposals(String value, int caretPos, IDirectEditingContext context) {
+		return EMPTY_STRING_ARRAY;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.graphiti.func.IDirectEditing#isAutoCompletionEnabled()
+	 */
+	@Override
+	public boolean isAutoCompletionEnabled() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.graphiti.func.IDirectEditing#isCompletionAvailable()
+	 */
+	@Override
+	public boolean isCompletionAvailable() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.graphiti.func.IDirectEditing#stretchFieldToFitText()
+	 */
+	@Override
+	public boolean stretchFieldToFitText() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.graphiti.func.IDirectEditing#getEditingType()
+	 */
+	public int getEditingType() {
+		return IDirectEditing.TYPE_NONE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.graphiti.func.IDirectEditing#getInitialValue(org.eclipse.
+	 * graphiti.features.context.IDirectEditingContext)
+	 */
+	public String getInitialValue(IDirectEditingContext context) {
+		throw new UnsupportedOperationException("Subclasses must override this method if they want to provide direct editing."); //$NON-NLS-1$ 
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.graphiti.func.IDirectEditing#setValue(java.lang.String,
+	 * org.eclipse.graphiti.features.context.IDirectEditingContext)
+	 */
+	public void setValue(String value, IDirectEditingContext context) {
+		throw new UnsupportedOperationException("Subclasses must override this method if they want to provide direct editing."); //$NON-NLS-1$ 
+	}
+
 }
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DefaultFeatureProviderWithPatterns.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DefaultFeatureProviderWithPatterns.java
index 5fefeea..abc85cd 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DefaultFeatureProviderWithPatterns.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DefaultFeatureProviderWithPatterns.java
@@ -9,6 +9,9 @@
  *
  * Contributors:
  *    SAP AG - initial API, implementation and documentation
+ *    Volker Wegert - Bug 336828: patterns should support delete,
+ *                    remove, direct editing and conditional palette
+ *                    creation entry
  *
  * </copyright>
  *
@@ -22,16 +25,22 @@
 import org.eclipse.graphiti.features.IAddFeature;
 import org.eclipse.graphiti.features.ICreateConnectionFeature;
 import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IDeleteFeature;
+import org.eclipse.graphiti.features.IDirectEditingFeature;
 import org.eclipse.graphiti.features.IDirectEditingInfo;
 import org.eclipse.graphiti.features.IFeature;
 import org.eclipse.graphiti.features.ILayoutFeature;
 import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.IRemoveFeature;
 import org.eclipse.graphiti.features.IResizeShapeFeature;
 import org.eclipse.graphiti.features.IUpdateFeature;
 import org.eclipse.graphiti.features.context.IAddContext;
 import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.features.context.IDirectEditingContext;
 import org.eclipse.graphiti.features.context.ILayoutContext;
 import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.IRemoveContext;
 import org.eclipse.graphiti.features.context.IResizeShapeContext;
 import org.eclipse.graphiti.features.context.IUpdateContext;
 import org.eclipse.graphiti.mm.Property;
@@ -177,7 +186,9 @@
 		List<ICreateFeature> retList = new ArrayList<ICreateFeature>();
 
 		for (IPattern pattern : getPatterns()) {
-			retList.add(new CreateFeatureForPattern(this, pattern));
+			if (pattern.isPaletteApplicable()) {
+				retList.add(new CreateFeatureForPattern(this, pattern));
+			}
 		}
 
 		ICreateFeature[] a = getCreateFeaturesAdditional();
@@ -204,6 +215,86 @@
 	}
 
 	@Override
+	public IDeleteFeature getDeleteFeature(IDeleteContext context) {
+		if (context == null) {
+			throw new IllegalArgumentException("Argument context must not be null."); //$NON-NLS-1$
+		}
+		IDeleteFeature ret = null;
+		for (IPattern pattern : getPatterns()) {
+			if (checkPattern(pattern, getBusinessObjectForPictogramElement(context.getPictogramElement()))) {
+				IPattern choosenPattern = null;
+				IDeleteFeature f = new DeleteFeatureForPattern(this, pattern);
+				if (checkFeatureAndContext(f, context)) {
+					if (ret == null) {
+						ret = f;
+						choosenPattern = pattern;
+					} else {
+						traceWarning("getDeleteFeature", pattern, choosenPattern); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+
+		if (ret == null) {
+			ret = getDeleteFeatureAdditional(context);
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Gets the additional delete feature.
+	 * 
+	 * @param context
+	 *            the delete context
+	 * 
+	 * @return the additional delete feature
+	 */
+	protected IDeleteFeature getDeleteFeatureAdditional(IDeleteContext context) {
+		return super.getDeleteFeature(context);
+	}
+
+	@Override
+	public IRemoveFeature getRemoveFeature(IRemoveContext context) {
+		if (context == null) {
+			throw new IllegalArgumentException("Argument context must not be null."); //$NON-NLS-1$
+		}
+		IRemoveFeature ret = null;
+		for (IPattern pattern : getPatterns()) {
+			if (checkPattern(pattern, getBusinessObjectForPictogramElement(context.getPictogramElement()))) {
+				IPattern choosenPattern = null;
+				IRemoveFeature f = new RemoveFeatureForPattern(this, pattern);
+				if (checkFeatureAndContext(f, context)) {
+					if (ret == null) {
+						ret = f;
+						choosenPattern = pattern;
+					} else {
+						traceWarning("getRemoveFeature", pattern, choosenPattern); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+
+		if (ret == null) {
+			ret = getRemoveFeatureAdditional(context);
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Gets the additional remove feature.
+	 * 
+	 * @param context
+	 *            the remove context
+	 * 
+	 * @return the additional remove feature
+	 */
+	protected IRemoveFeature getRemoveFeatureAdditional(IRemoveContext context) {
+		return super.getRemoveFeature(context);
+	}
+
+	@Override
 	public ILayoutFeature getLayoutFeature(ILayoutContext context) {
 		if (context == null) {
 			throw new IllegalArgumentException("Argument context must not be null."); //$NON-NLS-1$
@@ -439,6 +530,46 @@
 		return super.getCreateConnectionFeatures();
 	}
 
+	@Override
+	public IDirectEditingFeature getDirectEditingFeature(IDirectEditingContext context) {
+		if (context == null) {
+			throw new IllegalArgumentException("Argument context must not be null."); //$NON-NLS-1$
+		}
+		IDirectEditingFeature ret = null;
+		for (IPattern pattern : getPatterns()) {
+			if (checkPattern(pattern, getBusinessObjectForPictogramElement(context.getPictogramElement()))) {
+				IPattern choosenPattern = null;
+				IDirectEditingFeature f = new DirectEditingFeatureForPattern(this, pattern);
+				if (checkFeatureAndContext(f, context)) {
+					if (ret == null) {
+						ret = f;
+						choosenPattern = pattern;
+					} else {
+						traceWarning("getLayoutFeature", pattern, choosenPattern); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+
+		if (ret == null) {
+			ret = getDirectEditingFeatureAdditional(context);
+		}
+
+		return ret;
+	}
+
+	/**
+	 * Gets the additional direct editing feature.
+	 * 
+	 * @param context
+	 *            the direct editing context
+	 * 
+	 * @return the additional direct editing feature
+	 */
+	protected IDirectEditingFeature getDirectEditingFeatureAdditional(IDirectEditingContext context) {
+		return super.getDirectEditingFeature(context);
+	}
+
 	/**
 	 * Trace warning.
 	 * 
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java
new file mode 100644
index 0000000..1fd57dc
--- /dev/null
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/DeleteFeatureForPattern.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * <copyright>
+ *
+ * Copyright (c) 2011 Volker Wegert 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:
+ *    Volker Wegert - initial API, implementation and documentation:
+ *                    Bug 336828: patterns should support delete,
+ *                    remove, direct editing and conditional palette
+ *                    creation entry
+ *
+ * </copyright>
+ *
+ *******************************************************************************/
+package org.eclipse.graphiti.pattern;
+
+import org.eclipse.graphiti.features.IDeleteFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IDeleteContext;
+import org.eclipse.graphiti.ui.features.DefaultDeleteFeature;
+
+/**
+ * This class is used by the {@link DefaultFeatureProviderWithPatterns} to wrap
+ * the deletion behavior provided by an {@link IPattern} into an
+ * {@link IDeleteFeature}.
+ * 
+ * @since 0.8.0
+ */
+public class DeleteFeatureForPattern extends DefaultDeleteFeature {
+
+	private IFeatureForPattern delegate;
+
+	/**
+	 * Creates a new {@link DeleteFeatureForPattern}.
+	 * 
+	 * @param featureProvider
+	 *            the feature provider
+	 * @param pattern
+	 *            the pattern
+	 */
+	public DeleteFeatureForPattern(IFeatureProvider featureProvider, IPattern pattern) {
+		super(featureProvider);
+		delegate = new FeatureForPatternDelegate(pattern);
+	}
+
+	@Override
+	public boolean canDelete(IDeleteContext context) {
+		return delegate.getPattern().canDelete(context);
+	}
+
+	@Override
+	public void preDelete(IDeleteContext context) {
+		delegate.getPattern().preDelete(context);
+	}
+
+	@Override
+	public void delete(IDeleteContext context) {
+		delegate.getPattern().delete(context);
+	}
+
+	@Override
+	public void postDelete(IDeleteContext context) {
+		delegate.getPattern().postDelete(context);
+	}
+
+}
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
index 39c7e39..cc3db5d 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/IPattern.java
@@ -10,6 +10,9 @@
  * Contributors:
  *    SAP AG - initial API, implementation and documentation
  *    Patch 185019 from Bug 332360 contributed by Volker Wegert
+ *    Volker Wegert - Bug 336828: patterns should support delete,
+ *                    remove, direct editing and conditional palette
+ *                    creation entry
  *
  * </copyright>
  *
@@ -23,8 +26,11 @@
 import org.eclipse.graphiti.features.context.IResizeShapeContext;
 import org.eclipse.graphiti.func.IAdd;
 import org.eclipse.graphiti.func.ICreate;
+import org.eclipse.graphiti.func.IDelete;
+import org.eclipse.graphiti.func.IDirectEditing;
 import org.eclipse.graphiti.func.ILayout;
 import org.eclipse.graphiti.func.IMoveShape;
+import org.eclipse.graphiti.func.IRemove;
 import org.eclipse.graphiti.func.IResizeShape;
 import org.eclipse.graphiti.func.IUpdate;
 import org.eclipse.graphiti.mm.pictograms.PictogramElement;
@@ -36,7 +42,17 @@
  * @noextend This interface is not intended to be extended by clients. Extend
  *           {@link AbstractPattern} instead
  */
-public interface IPattern extends ICreate, IAdd, IUpdate, ILayout, IResizeShape, IMoveShape {
+public interface IPattern extends ICreate, IAdd, IDelete, IRemove, IUpdate, ILayout, IResizeShape, IMoveShape, IDirectEditing {
+
+	/**
+	 * Determines whether the pattern supports the creation of new business
+	 * objects from the palette. Setting this to <code>false</code> will
+	 * suppress the creation of a palette item for this pattern.
+	 * 
+	 * @return <code>true</code> if the pattern supports the {@link ICreate}
+	 *         methods and a palette item should be generated
+	 */
+	boolean isPaletteApplicable();
 
 	/**
 	 * Gets the create name.
@@ -104,7 +120,8 @@
 	/**
 	 * Provides configuration object, which describes the resize behavior.
 	 * 
-	 * @param context the resizing context
+	 * @param context
+	 *            the resizing context
 	 * @return the resize configuration object
 	 */
 	IResizeConfiguration getResizeConfiguration(IResizeShapeContext context);
diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java
new file mode 100644
index 0000000..6b099a4
--- /dev/null
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/RemoveFeatureForPattern.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * <copyright>
+ *
+ * Copyright (c) 2011 Volker Wegert 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:
+ *    Volker Wegert - initial API, implementation and documentation:
+ *                    Bug 336828: patterns should support delete,
+ *                    remove, direct editing and conditional palette
+ *                    creation entry
+ *
+ * </copyright>
+ *
+ *******************************************************************************/
+package org.eclipse.graphiti.pattern;
+
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IRemoveFeature;
+import org.eclipse.graphiti.features.context.IRemoveContext;
+import org.eclipse.graphiti.features.impl.DefaultRemoveFeature;
+
+/**
+ * This class is used by the {@link DefaultFeatureProviderWithPatterns} to wrap
+ * the removal behavior provided by an {@link IPattern} into an
+ * {@link IRemoveFeature}.
+ * 
+ * @since 0.8.0
+ */
+public class RemoveFeatureForPattern extends DefaultRemoveFeature {
+
+	private IFeatureForPattern delegate;
+
+	/**
+	 * Creates a new {@link RemoveFeatureForPattern}.
+	 * 
+	 * @param featureProvider
+	 *            the feature provider
+	 * @param pattern
+	 *            the pattern
+	 */
+	public RemoveFeatureForPattern(IFeatureProvider featureProvider, IPattern pattern) {
+		super(featureProvider);
+		delegate = new FeatureForPatternDelegate(pattern);
+	}
+
+	@Override
+	public boolean canRemove(IRemoveContext context) {
+		return delegate.getPattern().canRemove(context);
+	}
+
+	@Override
+	public void preRemove(IRemoveContext context) {
+		delegate.getPattern().preRemove(context);
+	}
+
+	// public void remove(IRemoveContext context)
+	// is final and cannot be overridden...	
+
+	@Override
+	public void postRemove(IRemoveContext context) {
+		delegate.getPattern().postRemove(context);
+	}
+
+}