Merge "Add TextStyle support to AbstractText in the metamodel"
diff --git a/examples/org.eclipse.graphiti.doc/resources/docu/whats-new.html b/examples/org.eclipse.graphiti.doc/resources/docu/whats-new.html
index f319a4d..58e7636 100644
--- a/examples/org.eclipse.graphiti.doc/resources/docu/whats-new.html
+++ b/examples/org.eclipse.graphiti.doc/resources/docu/whats-new.html
@@ -34,14 +34,126 @@
 

 <body>

 

-	<h1>Graphiti &quot;New and Noteworthy&quot; for Kepler</h1>

-	<p>Last revised August 21, 2012</p>

+	<h1>Graphiti &quot;New and Noteworthy&quot; for Eclipse Kepler</h1>

+	<p>Last revised September 01, 2012</p>

 	<p>This document describes the new development topics that were

 		addressed during the milestones towards the release 0.10.0 within the

 		Kepler release train.</p>

 	<!-- --------------------------------- Table ----------------------------------------- -->

 	<table border="0" cellpadding="10" cellspacing="0" class="news"

 		width="600">

+		<!-- ---------------------------------------- M2 ------------------------------- -->

+		<tr>

+			<td colspan="2">

+				<h2>M2</h2>

+			</td>

+		</tr>

+		<tr>

+			<td colspan="2">The main focus for this milestone has been set

+				on bugfixing and implementing round-offs.</td>

+		</tr>

+		<tr id="bug 385193">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=385193">ID Pattern</a></td>

+			<td class="content">Graphiti offers a new pattern base class, so called ID

+			    patters. They offer the possibility to define shape structures in a diagram

+			    and tag them using IDs. These IDs are later used by the framework to

+			    identify individual shapes again and e.g. trigger update and layout operations

+			    directly for the individual parts. This lowers the effort clients need to

+			    invest into those functionality a lot.  

+			</td>

+		</tr>

+		<tr id="bug 376585">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376585">Removal

+					of Deprecated API</a></td>

+			<td class="content">The deprecated methods in the Graphiti API

+				have been removed. This is an potentially incompatible <b>API

+					change</b>, although clients should have adapted their coding already

+				some time ago.

+			</td>

+		</tr>

+		<tr id="bug 385190">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=385190">New

+					Pattern Constructor</a></td>

+			<td class="content">A new constructor with no parameters has

+				been introduced for Graphiti patterns.</td>

+		</tr>

+		<tr id="bug 388119">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=388119">New

+					Filesystem Example</a></td>

+			<td class="content">The filesystem example shown at the Eclipse

+				Juno demo camps in June has been added as an additional example of

+				Graphiti. It serves as an example of how to use patterns for

+				building a Graphiti editor.</td>

+		</tr>

+		<tr id="bug 382928">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382928">Gradient

+					Definitions</a></td>

+			<td class="content">An additional and more advanced example for

+				gradient definitions has been added to the filesystem example.</td>

+		</tr>

+		<tr id="bug 389426">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=389426">Factory

+					Method for Workspace Synchronizer</a></td>

+			<td class="content">Clients might have the need to use a custom

+				EMF workspace synchronizer to react differently on external file

+				change events. By providing a special factory method for the

+				instance to use in <i>DefaultUpdateBehavior</i> this scenario has

+				been eased.

+			</td>

+		</tr>

+		<tr id="bug 389380">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=389380">Bug

+					389380</a></td>

+			<td class="content">A bug in the undo stack handling in the

+				Graphiti editor has been fixed that caused the wrong feature command

+				to appear at the top of the undo stack under certain conditions.</td>

+		</tr>

+		<tr id="bug 388213">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=388213">Bug

+					388213 </a></td>

+			<td class="content">Two import statements that required a

+				dependency to <i>org.eclipse.ui</i> to be required have been

+				removed. The dependecy causes issues with using Graphiti in an

+				Eclipse 4 based RCP application.

+			</td>

+		</tr>

+		<tr id="bug 388335">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=388335">Bug

+					388335 </a></td>

+			<td class="content">Fixed a wrong JavaDoc comment about

+				potential future extensions to the Graphiti undo/redo handling that

+				actually already exist.</td>

+		</tr>

+		<tr id="bug 388211">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=388211">Bug

+					388211 </a></td>

+			<td class="content">The new plug-in wizard to create a Graphiti

+				diagram editor always added a dependency to <i>org.eclipse.ui</i>,

+				although it is only needed when an activator class should be

+				generated. In case no activator is generated the dependency will now

+				not be added any more. This resolved some issues with using Graphiti

+				for creating an Eclipse 4 based RCP application.

+			</td>

+		</tr>

+		<tr id="bug 387971">

+			<td class="title"><a

+				href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=387971">Bug

+					387971 </a></td>

+			<td class="content">A bug in the action handling which caused

+				that context menu entries like copy and paste did not work when the

+				Graphiti Diagram Editor was embedded inside a multi page editor has

+				been fixed.</td>

+		</tr>

 		<!-- ---------------------------------------- M1 ------------------------------- -->

 		<tr>

 			<td colspan="2">

diff --git a/examples/org.eclipse.graphiti.examples.filesystem.mm/model/filesystem.ecore b/examples/org.eclipse.graphiti.examples.filesystem.mm/model/filesystem.ecore
index 39dcbb6..a7365ca 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem.mm/model/filesystem.ecore
+++ b/examples/org.eclipse.graphiti.examples.filesystem.mm/model/filesystem.ecore
@@ -6,6 +6,7 @@
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

   </eClassifiers>

   <eClassifiers xsi:type="ecore:EClass" name="Filesystem">

+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

     <eStructuralFeatures xsi:type="ecore:EReference" name="folders" upperBound="-1"

         eType="#//Folder" containment="true" resolveProxies="false"/>

     <eStructuralFeatures xsi:type="ecore:EReference" name="files" upperBound="-1"

diff --git a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/Filesystem.java b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/Filesystem.java
index 17091ab..f849a5e 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/Filesystem.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/Filesystem.java
@@ -26,6 +26,7 @@
  * <p>

  * The following features are supported:

  * <ul>

+ *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getName <em>Name</em>}</li>

  *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getFolders <em>Folders</em>}</li>

  *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getFiles <em>Files</em>}</li>

  * </ul>

@@ -44,6 +45,32 @@
 	String copyright = "<copyright>\r\n\r\nCopyright (c) 2012, 2012 SAP AG.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n   SAP AG - initial API, implementation and documentation\r\n\r\n</copyright>";

 

 	/**

+	 * Returns the value of the '<em><b>Name</b></em>' attribute.

+	 * <!-- begin-user-doc -->

+	 * <p>

+	 * If the meaning of the '<em>Name</em>' attribute isn't clear,

+	 * there really should be more of a description here...

+	 * </p>

+	 * <!-- end-user-doc -->

+	 * @return the value of the '<em>Name</em>' attribute.

+	 * @see #setName(String)

+	 * @see org.eclipse.graphiti.examples.mm.filesystem.FilesystemPackage#getFilesystem_Name()

+	 * @model

+	 * @generated

+	 */

+	String getName();

+

+	/**

+	 * Sets the value of the '{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getName <em>Name</em>}' attribute.

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @param value the new value of the '<em>Name</em>' attribute.

+	 * @see #getName()

+	 * @generated

+	 */

+	void setName(String value);

+

+	/**

 	 * Returns the value of the '<em><b>Folders</b></em>' containment reference list.

 	 * The list contents are of type {@link org.eclipse.graphiti.examples.mm.filesystem.Folder}.

 	 * <!-- begin-user-doc -->

diff --git a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/FilesystemPackage.java b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/FilesystemPackage.java
index ffe6242..96e8614 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/FilesystemPackage.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/FilesystemPackage.java
@@ -113,13 +113,22 @@
 	int FILESYSTEM = 1;

 

 	/**

+	 * The feature id for the '<em><b>Name</b></em>' attribute.

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @generated

+	 * @ordered

+	 */

+	int FILESYSTEM__NAME = 0;

+

+	/**

 	 * The feature id for the '<em><b>Folders</b></em>' containment reference list.

 	 * <!-- begin-user-doc -->

 	 * <!-- end-user-doc -->

 	 * @generated

 	 * @ordered

 	 */

-	int FILESYSTEM__FOLDERS = 0;

+	int FILESYSTEM__FOLDERS = 1;

 

 	/**

 	 * The feature id for the '<em><b>Files</b></em>' containment reference list.

@@ -128,7 +137,7 @@
 	 * @generated

 	 * @ordered

 	 */

-	int FILESYSTEM__FILES = 1;

+	int FILESYSTEM__FILES = 2;

 

 	/**

 	 * The number of structural features of the '<em>Filesystem</em>' class.

@@ -137,7 +146,7 @@
 	 * @generated

 	 * @ordered

 	 */

-	int FILESYSTEM_FEATURE_COUNT = 2;

+	int FILESYSTEM_FEATURE_COUNT = 3;

 

 	/**

 	 * The meta object id for the '{@link org.eclipse.graphiti.examples.mm.filesystem.impl.FolderImpl <em>Folder</em>}' class.

@@ -218,6 +227,17 @@
 	EClass getFilesystem();

 

 	/**

+	 * Returns the meta object for the attribute '{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getName <em>Name</em>}'.

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @return the meta object for the attribute '<em>Name</em>'.

+	 * @see org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getName()

+	 * @see #getFilesystem()

+	 * @generated

+	 */

+	EAttribute getFilesystem_Name();

+

+	/**

 	 * Returns the meta object for the containment reference list '{@link org.eclipse.graphiti.examples.mm.filesystem.Filesystem#getFolders <em>Folders</em>}'.

 	 * <!-- begin-user-doc -->

 	 * <!-- end-user-doc -->

@@ -333,6 +353,14 @@
 		EClass FILESYSTEM = eINSTANCE.getFilesystem();

 

 		/**

+		 * The meta object literal for the '<em><b>Name</b></em>' attribute feature.

+		 * <!-- begin-user-doc -->

+		 * <!-- end-user-doc -->

+		 * @generated

+		 */

+		EAttribute FILESYSTEM__NAME = eINSTANCE.getFilesystem_Name();

+

+		/**

 		 * The meta object literal for the '<em><b>Folders</b></em>' containment reference list feature.

 		 * <!-- begin-user-doc -->

 		 * <!-- end-user-doc -->

diff --git a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemImpl.java b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemImpl.java
index 68cd416..1966a83 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemImpl.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemImpl.java
@@ -16,6 +16,7 @@
 

 import java.util.Collection;

 

+import org.eclipse.emf.common.notify.Notification;

 import org.eclipse.emf.common.notify.NotificationChain;

 

 import org.eclipse.emf.common.util.EList;

@@ -23,6 +24,7 @@
 import org.eclipse.emf.ecore.EClass;

 import org.eclipse.emf.ecore.InternalEObject;

 

+import org.eclipse.emf.ecore.impl.ENotificationImpl;

 import org.eclipse.emf.ecore.impl.EObjectImpl;

 

 import org.eclipse.emf.ecore.util.EObjectContainmentEList;

@@ -40,6 +42,7 @@
  * <p>

  * The following features are implemented:

  * <ul>

+ *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.impl.FilesystemImpl#getName <em>Name</em>}</li>

  *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.impl.FilesystemImpl#getFolders <em>Folders</em>}</li>

  *   <li>{@link org.eclipse.graphiti.examples.mm.filesystem.impl.FilesystemImpl#getFiles <em>Files</em>}</li>

  * </ul>

@@ -56,6 +59,26 @@
 	public static final String copyright = "<copyright>\r\n\r\nCopyright (c) 2012, 2012 SAP AG.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n   SAP AG - initial API, implementation and documentation\r\n\r\n</copyright>";

 

 	/**

+	 * The default value of the '{@link #getName() <em>Name</em>}' attribute.

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @see #getName()

+	 * @generated

+	 * @ordered

+	 */

+	protected static final String NAME_EDEFAULT = null;

+

+	/**

+	 * The cached value of the '{@link #getName() <em>Name</em>}' attribute.

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @see #getName()

+	 * @generated

+	 * @ordered

+	 */

+	protected String name = NAME_EDEFAULT;

+

+	/**

 	 * The cached value of the '{@link #getFolders() <em>Folders</em>}' containment reference list.

 	 * <!-- begin-user-doc -->

 	 * <!-- end-user-doc -->

@@ -99,6 +122,27 @@
 	 * <!-- end-user-doc -->

 	 * @generated

 	 */

+	public String getName() {

+		return name;

+	}

+

+	/**

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @generated

+	 */

+	public void setName(String newName) {

+		String oldName = name;

+		name = newName;

+		if (eNotificationRequired())

+			eNotify(new ENotificationImpl(this, Notification.SET, FilesystemPackage.FILESYSTEM__NAME, oldName, name));

+	}

+

+	/**

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @generated

+	 */

 	public EList<Folder> getFolders() {

 		if (folders == null) {

 			folders = new EObjectContainmentEList<Folder>(Folder.class, this, FilesystemPackage.FILESYSTEM__FOLDERS);

@@ -142,6 +186,8 @@
 	@Override

 	public Object eGet(int featureID, boolean resolve, boolean coreType) {

 		switch (featureID) {

+			case FilesystemPackage.FILESYSTEM__NAME:

+				return getName();

 			case FilesystemPackage.FILESYSTEM__FOLDERS:

 				return getFolders();

 			case FilesystemPackage.FILESYSTEM__FILES:

@@ -159,6 +205,9 @@
 	@Override

 	public void eSet(int featureID, Object newValue) {

 		switch (featureID) {

+			case FilesystemPackage.FILESYSTEM__NAME:

+				setName((String)newValue);

+				return;

 			case FilesystemPackage.FILESYSTEM__FOLDERS:

 				getFolders().clear();

 				getFolders().addAll((Collection<? extends Folder>)newValue);

@@ -179,6 +228,9 @@
 	@Override

 	public void eUnset(int featureID) {

 		switch (featureID) {

+			case FilesystemPackage.FILESYSTEM__NAME:

+				setName(NAME_EDEFAULT);

+				return;

 			case FilesystemPackage.FILESYSTEM__FOLDERS:

 				getFolders().clear();

 				return;

@@ -197,6 +249,8 @@
 	@Override

 	public boolean eIsSet(int featureID) {

 		switch (featureID) {

+			case FilesystemPackage.FILESYSTEM__NAME:

+				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);

 			case FilesystemPackage.FILESYSTEM__FOLDERS:

 				return folders != null && !folders.isEmpty();

 			case FilesystemPackage.FILESYSTEM__FILES:

@@ -205,4 +259,20 @@
 		return super.eIsSet(featureID);

 	}

 

+	/**

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @generated

+	 */

+	@Override

+	public String toString() {

+		if (eIsProxy()) return super.toString();

+

+		StringBuffer result = new StringBuffer(super.toString());

+		result.append(" (name: ");

+		result.append(name);

+		result.append(')');

+		return result.toString();

+	}

+

 } //FilesystemImpl

diff --git a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemPackageImpl.java b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemPackageImpl.java
index cb5b3b0..59f6226 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemPackageImpl.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem.mm/src/org/eclipse/graphiti/examples/mm/filesystem/impl/FilesystemPackageImpl.java
@@ -155,8 +155,17 @@
 	 * <!-- end-user-doc -->

 	 * @generated

 	 */

+	public EAttribute getFilesystem_Name() {

+		return (EAttribute)filesystemEClass.getEStructuralFeatures().get(0);

+	}

+

+	/**

+	 * <!-- begin-user-doc -->

+	 * <!-- end-user-doc -->

+	 * @generated

+	 */

 	public EReference getFilesystem_Folders() {

-		return (EReference)filesystemEClass.getEStructuralFeatures().get(0);

+		return (EReference)filesystemEClass.getEStructuralFeatures().get(1);

 	}

 

 	/**

@@ -165,7 +174,7 @@
 	 * @generated

 	 */

 	public EReference getFilesystem_Files() {

-		return (EReference)filesystemEClass.getEStructuralFeatures().get(1);

+		return (EReference)filesystemEClass.getEStructuralFeatures().get(2);

 	}

 

 	/**

@@ -236,6 +245,7 @@
 		createEAttribute(fileEClass, FILE__NAME);

 

 		filesystemEClass = createEClass(FILESYSTEM);

+		createEAttribute(filesystemEClass, FILESYSTEM__NAME);

 		createEReference(filesystemEClass, FILESYSTEM__FOLDERS);

 		createEReference(filesystemEClass, FILESYSTEM__FILES);

 

@@ -279,6 +289,7 @@
 		initEAttribute(getFile_Name(), ecorePackage.getEString(), "name", null, 0, 1, File.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

 

 		initEClass(filesystemEClass, Filesystem.class, "Filesystem", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);

+		initEAttribute(getFilesystem_Name(), ecorePackage.getEString(), "name", null, 0, 1, Filesystem.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

 		initEReference(getFilesystem_Folders(), this.getFolder(), null, "folders", null, 0, -1, Filesystem.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

 		initEReference(getFilesystem_Files(), this.getFile(), null, "files", null, 0, -1, Filesystem.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

 

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/.settings/org.eclipse.jdt.ui.prefs b/examples/org.eclipse.graphiti.examples.filesystem/.settings/org.eclipse.jdt.ui.prefs
index b8e30b3..2dd7d06 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/.settings/org.eclipse.jdt.ui.prefs
+++ b/examples/org.eclipse.graphiti.examples.filesystem/.settings/org.eclipse.jdt.ui.prefs
@@ -1,4 +1,3 @@
-#Wed Oct 05 10:23:21 CEST 2011

 eclipse.preferences.version=1

 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true

 formatter_profile=_Eclipse adapted

@@ -27,7 +26,7 @@
 sp_cleanup.convert_to_enhanced_for_loop=false

 sp_cleanup.correct_indentation=false

 sp_cleanup.format_source_code=true

-sp_cleanup.format_source_code_changes_only=true

+sp_cleanup.format_source_code_changes_only=false

 sp_cleanup.make_local_variable_final=false

 sp_cleanup.make_parameters_final=false

 sp_cleanup.make_private_fields_final=true

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/build.properties b/examples/org.eclipse.graphiti.examples.filesystem/build.properties
index 64c276c..4739c14 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/build.properties
+++ b/examples/org.eclipse.graphiti.examples.filesystem/build.properties
@@ -18,6 +18,7 @@
 bin.includes = plugin.xml,\

                META-INF/,\

                .,\

-               about.html

+               about.html,\

+               plugin.properties

 src.includes = about.html

 jre.compilation.profile = J2SE-1.5
\ No newline at end of file
diff --git a/examples/org.eclipse.graphiti.examples.filesystem/icons/create_file.png b/examples/org.eclipse.graphiti.examples.filesystem/icons/create_file.png
new file mode 100644
index 0000000..6b1ebc0
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/icons/create_file.png
Binary files differ
diff --git a/examples/org.eclipse.graphiti.examples.filesystem/icons/delete_file.png b/examples/org.eclipse.graphiti.examples.filesystem/icons/delete_file.png
new file mode 100644
index 0000000..84be2ca
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/icons/delete_file.png
Binary files differ
diff --git a/examples/org.eclipse.graphiti.examples.filesystem/plugin.xml b/examples/org.eclipse.graphiti.examples.filesystem/plugin.xml
index 854d7b3..7d2d34a 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/plugin.xml
+++ b/examples/org.eclipse.graphiti.examples.filesystem/plugin.xml
@@ -35,6 +35,16 @@
          <diagramType

                id="org.eclipse.graphiti.examples.filesystem.filesystemDiagramType">

          </diagramType>

+         <imageProvider

+               id="org.eclipse.graphiti.examples.filesystem.filesystemImageProvider">

+         </imageProvider>

       </diagramTypeProvider>

    </extension>

+   <extension

+         point="org.eclipse.graphiti.ui.imageProviders">

+      <imageProvider

+            class="org.eclipse.graphiti.examples.filesystem.FilesystemImageProvider"

+            id="org.eclipse.graphiti.examples.filesystem.filesystemImageProvider">

+      </imageProvider>

+   </extension>

 </plugin>

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/FilesystemImageProvider.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/FilesystemImageProvider.java
new file mode 100644
index 0000000..4a4fe82
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/FilesystemImageProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * <copyright>
+ *
+ * Copyright (c) 2012, 2012 SAP AG.
+ * 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:
+ *    SAP AG - initial API, implementation and documentation
+ *
+ * </copyright>
+ *
+ *******************************************************************************/
+package org.eclipse.graphiti.examples.filesystem;
+
+import org.eclipse.graphiti.ui.platform.AbstractImageProvider;
+
+public class FilesystemImageProvider extends AbstractImageProvider {
+
+	protected static final String PREFIX = "org.eclipse.graphiti.examples.filesystem."; //$NON-NLS-1$
+
+	public static final String IMG_CREATE_FILE = PREFIX + "createFile"; //$NON-NLS-1$
+	public static final String IMG_DELETE_FILE = PREFIX + "deleteFile"; //$NON-NLS-1$
+
+	@Override
+	protected void addAvailableImages() {
+		addImageFilePath(IMG_CREATE_FILE, "icons/create_file.png"); //$NON-NLS-1$
+		addImageFilePath(IMG_DELETE_FILE, "icons/delete_file.png"); //$NON-NLS-1$
+	}
+}
diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemFeatureProvider.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemFeatureProvider.java
index 63d9d94..d5a1be6 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemFeatureProvider.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemFeatureProvider.java
@@ -22,8 +22,11 @@
 import org.eclipse.graphiti.dt.IDiagramTypeProvider;

 import org.eclipse.graphiti.examples.filesystem.features.AddContainmentConnectionFeature;

 import org.eclipse.graphiti.examples.filesystem.features.CreateContainmentConnectionFeature;

+import org.eclipse.graphiti.examples.filesystem.features.CreateInnerFileFeature;

+import org.eclipse.graphiti.examples.filesystem.features.DeleteInnerFileFeature;

 import org.eclipse.graphiti.examples.filesystem.features.GradientColorFeature;

 import org.eclipse.graphiti.examples.filesystem.patterns.FilePattern;

+import org.eclipse.graphiti.examples.filesystem.patterns.FilesystemPattern;

 import org.eclipse.graphiti.examples.filesystem.patterns.FolderPattern;

 import org.eclipse.graphiti.examples.filesystem.ui.FilesystemPredefinedColoredAreas;

 import org.eclipse.graphiti.features.IAddFeature;

@@ -42,8 +45,9 @@
 

 	public FilesystemFeatureProvider(IDiagramTypeProvider dtp) {

 		super(dtp);

-		addPattern(new FolderPattern());

+		addPattern(new FilesystemPattern());

 		addPattern(new FilePattern());

+		addPattern(new FolderPattern());

 	}

 

 	@Override

@@ -62,11 +66,18 @@
 	@Override

 	public ICustomFeature[] getCustomFeatures(ICustomContext context) {

 		ICustomFeature[] ret = super.getCustomFeatures(context);

+

+		// Add features to change gradient

 		List<ICustomFeature> retList = new ArrayList<ICustomFeature>();

 		for (String gid : ALL_GRADIENT_IDS) {

 			retList.add(new GradientColorFeature(this, gid));

 		}

+

+		// Add create/delete features for files inside folders

+		retList.add(new CreateInnerFileFeature(this));

+		retList.add(new DeleteInnerFileFeature(this));

+

 		ret = retList.toArray(ret);

 		return ret;

 	}

-}
+}

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemToolBehaviorProvider.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemToolBehaviorProvider.java
index f62d3b2..07a654f 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemToolBehaviorProvider.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/diagram/FilesystemToolBehaviorProvider.java
@@ -19,14 +19,22 @@
 import java.util.List;

 

 import org.eclipse.graphiti.dt.IDiagramTypeProvider;

+import org.eclipse.graphiti.examples.filesystem.FilesystemImageProvider;

+import org.eclipse.graphiti.examples.filesystem.features.CreateInnerFileFeature;

+import org.eclipse.graphiti.examples.filesystem.features.DeleteInnerFileFeature;

 import org.eclipse.graphiti.examples.filesystem.features.GradientColorFeature;

 import org.eclipse.graphiti.examples.mm.filesystem.Folder;

 import org.eclipse.graphiti.features.context.ICustomContext;

+import org.eclipse.graphiti.features.context.IPictogramElementContext;

+import org.eclipse.graphiti.features.context.impl.CustomContext;

 import org.eclipse.graphiti.features.custom.ICustomFeature;

 import org.eclipse.graphiti.mm.pictograms.PictogramElement;

 import org.eclipse.graphiti.mm.pictograms.Shape;

+import org.eclipse.graphiti.tb.ContextButtonEntry;

 import org.eclipse.graphiti.tb.ContextMenuEntry;

 import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;

+import org.eclipse.graphiti.tb.IContextButtonEntry;

+import org.eclipse.graphiti.tb.IContextButtonPadData;

 import org.eclipse.graphiti.tb.IContextMenuEntry;

 import org.eclipse.graphiti.tb.IToolBehaviorProvider;

 import org.eclipse.graphiti.util.ILocationInfo;

@@ -55,7 +63,7 @@
 		ICustomContext customContext = context;

 		ICustomFeature[] customFeatures = getFeatureProvider().getCustomFeatures(customContext);

 

-		// menu groups

+		// Gradient colors submenu

 		ContextMenuEntry changeGradientColorEntry = null;

 

 		for (int i = 0; i < customFeatures.length; i++) {

@@ -70,8 +78,41 @@
 					retList.add(changeGradientColorEntry);

 				}

 				changeGradientColorEntry.add(contextMenuEntry);

+			} else if (customFeature instanceof CreateInnerFileFeature) {

+				retList.add(contextMenuEntry);

+			} else if (customFeature instanceof DeleteInnerFileFeature) {

+				retList.add(contextMenuEntry);

 			}

 		}

 		return retList.toArray(ret);

 	}

+

+	@Override

+	public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {

+		IContextButtonPadData data = super.getContextButtonPad(context);

+		PictogramElement pe = context.getPictogramElement();

+

+		CustomContext customContext = new CustomContext(new PictogramElement[] { pe });

+		ICustomFeature[] customFeatures = getFeatureProvider().getCustomFeatures(customContext);

+		for (int i = 0; i < customFeatures.length; i++) {

+			ICustomFeature customFeature = customFeatures[i];

+			if (customFeature instanceof CreateInnerFileFeature) {

+				IContextButtonEntry button = null;

+				button = new ContextButtonEntry(customFeature, customContext);

+				button.setText(customFeature.getName());

+				button.setDescription(customFeature.getDescription());

+				button.setIconId(FilesystemImageProvider.IMG_CREATE_FILE);

+				data.getDomainSpecificContextButtons().add(button);

+			} else if (customFeature instanceof DeleteInnerFileFeature) {

+				IContextButtonEntry button = null;

+				button = new ContextButtonEntry(customFeature, customContext);

+				button.setText(customFeature.getName());

+				button.setDescription(customFeature.getDescription());

+				button.setIconId(FilesystemImageProvider.IMG_DELETE_FILE);

+				data.getDomainSpecificContextButtons().add(button);

+			}

+		}

+

+		return data;

+	}

 }

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateContainmentConnectionFeature.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateContainmentConnectionFeature.java
index eef35da..1dbb697 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateContainmentConnectionFeature.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateContainmentConnectionFeature.java
@@ -14,6 +14,9 @@
  */

 package org.eclipse.graphiti.examples.filesystem.features;

 

+import org.eclipse.emf.ecore.EObject;

+import org.eclipse.graphiti.examples.mm.filesystem.File;

+import org.eclipse.graphiti.examples.mm.filesystem.Filesystem;

 import org.eclipse.graphiti.examples.mm.filesystem.Folder;

 import org.eclipse.graphiti.features.ICreateConnectionFeature;

 import org.eclipse.graphiti.features.IFeatureProvider;

@@ -23,6 +26,7 @@
 import org.eclipse.graphiti.mm.pictograms.Anchor;

 import org.eclipse.graphiti.mm.pictograms.Connection;

 import org.eclipse.graphiti.mm.pictograms.PictogramElement;

+import org.eclipse.graphiti.mm.pictograms.Shape;

 

 public class CreateContainmentConnectionFeature extends AbstractCreateConnectionFeature implements

 		ICreateConnectionFeature {

@@ -32,25 +36,63 @@
 	}

 

 	public boolean canStartConnection(ICreateConnectionContext context) {

-		return getBusinessObjectForPictogramElement(context.getSourcePictogramElement()) instanceof Folder;

+		// Defines the start of the connection; allowed are objects that may

+		// contain other objects

+		Object domainObject = getBusinessObjectForPictogramElement(context.getSourcePictogramElement());

+		return domainObject instanceof Folder || domainObject instanceof Filesystem;

 	}

 

 	public boolean canCreate(ICreateConnectionContext context) {

 		PictogramElement sourcePictogramElement = context.getSourcePictogramElement();

 		PictogramElement targetPictogramElement = context.getTargetPictogramElement();

 

-		return sourcePictogramElement != null && targetPictogramElement != null

-				&& getBusinessObjectForPictogramElement(sourcePictogramElement) instanceof Folder

-				&& getBusinessObjectForPictogramElement(targetPictogramElement) instanceof Folder;

+		if (sourcePictogramElement == null || targetPictogramElement == null) {

+			return false;

+		}

+

+		Object sourceDomainObject = getBusinessObjectForPictogramElement(sourcePictogramElement);

+		Object targetDomainObject = getBusinessObjectForPictogramElement(targetPictogramElement);

+

+		return (sourceDomainObject instanceof Folder || sourceDomainObject instanceof Filesystem)

+				&& (targetDomainObject instanceof Folder || targetDomainObject instanceof File);

 	}

 

 	public Connection create(ICreateConnectionContext context) {

 		Anchor sourceAnchor = context.getSourceAnchor();

 		Anchor targetAnchor = context.getTargetAnchor();

 

-		Folder sourceFolder = (Folder) getBusinessObjectForPictogramElement(sourceAnchor.getParent());

-		Folder targetFolder = (Folder) getBusinessObjectForPictogramElement(targetAnchor.getParent());

-		sourceFolder.getFolders().add(targetFolder);

+		if (targetAnchor == null) {

+			// Target destination is somewhere inside structured folder

+			// representation

+			Shape shape = (Shape) context.getTargetPictogramElement();

+			while (shape.getAnchors().isEmpty()) {

+				shape = shape.getContainer();

+			}

+			targetAnchor = shape.getAnchors().get(0);

+		}

+

+		EObject sourceObject = (EObject) getBusinessObjectForPictogramElement(sourceAnchor.getParent());

+		EObject targetObject = (EObject) getBusinessObjectForPictogramElement(targetAnchor.getParent());

+

+		if (sourceObject instanceof Filesystem) {

+			if (targetObject instanceof Folder) {

+				((Filesystem) sourceObject).getFolders().add((Folder) targetObject);

+			} else if (targetObject instanceof File) {

+				((Filesystem) sourceObject).getFiles().add((File) targetObject);

+			} else {

+				throw new IllegalStateException("Filesystem may only contain Folders or Files");

+			}

+		} else if (sourceObject instanceof Folder) {

+			if (targetObject instanceof Folder) {

+				((Folder) sourceObject).getFolders().add((Folder) targetObject);

+			} else if (targetObject instanceof File) {

+				((Folder) sourceObject).getFiles().add((File) targetObject);

+			} else {

+				throw new IllegalStateException("Folder may only contain Folders or Files");

+			}

+		} else {

+			throw new IllegalStateException("Unknown container object");

+		}

 

 		AddConnectionContext addContext = new AddConnectionContext(sourceAnchor, targetAnchor);

 		getFeatureProvider().addIfPossible(addContext);

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateInnerFileFeature.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateInnerFileFeature.java
new file mode 100644
index 0000000..2f36cb8
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/CreateInnerFileFeature.java
@@ -0,0 +1,80 @@
+package org.eclipse.graphiti.examples.filesystem.features;

+

+import org.eclipse.graphiti.examples.mm.filesystem.File;

+import org.eclipse.graphiti.examples.mm.filesystem.FilesystemFactory;

+import org.eclipse.graphiti.examples.mm.filesystem.Folder;

+import org.eclipse.graphiti.features.IFeatureProvider;

+import org.eclipse.graphiti.features.context.IContext;

+import org.eclipse.graphiti.features.context.ICustomContext;

+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;

+import org.eclipse.graphiti.mm.pictograms.PictogramElement;

+

+public class CreateInnerFileFeature extends AbstractCustomFeature {

+

+	public CreateInnerFileFeature(IFeatureProvider fp) {

+		super(fp);

+	}

+

+	@Override

+	public String getName() {

+		return "Create File";

+	}

+

+	@Override

+	public String getDescription() {

+		return "Creates a new file inside this folder";

+	}

+

+	@Override

+	public boolean isAvailable(IContext context) {

+		return getFolderDomainObject(context) != null;

+	}

+

+	@Override

+	public boolean canExecute(ICustomContext context) {

+		return getFolderDomainObject(context) != null;

+	}

+

+	public void execute(ICustomContext context) {

+		Folder folder = getFolderDomainObject(context);

+		String newName = createNewName(folder);

+		File file = FilesystemFactory.eINSTANCE.createFile();

+		file.setName(newName);

+		folder.eResource().getContents().add(file);

+		folder.getFiles().add(file);

+	}

+

+	private Folder getFolderDomainObject(IContext context) {

+		if (context instanceof ICustomContext) {

+			PictogramElement[] pictogramElements = ((ICustomContext) context).getPictogramElements();

+			if (pictogramElements.length == 1) {

+				PictogramElement pictogramElement = pictogramElements[0];

+				Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

+				if (domainObject instanceof Folder) {

+					return (Folder) domainObject;

+				}

+			}

+		}

+		return null;

+	}

+

+	private String createNewName(Folder folder) {

+		String initialName = "NewFile";

+		String name = initialName;

+		int number = 0;

+		while (findFile(folder, name) != null) {

+			number++;

+			name = initialName + number;

+		}

+		return name;

+	}

+

+	private File findFile(Folder folder, String name) {

+		for (File file : folder.getFiles()) {

+			if (name.equals(file.getName())) {

+				return file;

+			}

+		}

+		return null;

+	}

+}

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/DeleteInnerFileFeature.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/DeleteInnerFileFeature.java
new file mode 100644
index 0000000..ca63f08
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/features/DeleteInnerFileFeature.java
@@ -0,0 +1,65 @@
+package org.eclipse.graphiti.examples.filesystem.features;

+

+import org.eclipse.emf.ecore.util.EcoreUtil;

+import org.eclipse.graphiti.examples.mm.filesystem.File;

+import org.eclipse.graphiti.examples.mm.filesystem.Folder;

+import org.eclipse.graphiti.features.IFeatureProvider;

+import org.eclipse.graphiti.features.context.IContext;

+import org.eclipse.graphiti.features.context.ICustomContext;

+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;

+import org.eclipse.graphiti.mm.pictograms.ContainerShape;

+import org.eclipse.graphiti.mm.pictograms.PictogramElement;

+import org.eclipse.graphiti.mm.pictograms.Shape;

+

+public class DeleteInnerFileFeature extends AbstractCustomFeature {

+

+	public DeleteInnerFileFeature(IFeatureProvider fp) {

+		super(fp);

+	}

+

+	@Override

+	public String getName() {

+		return "Delete File";

+	}

+

+	@Override

+	public String getDescription() {

+		return "Deletes the selected file inside this folder";

+	}

+

+	@Override

+	public boolean isAvailable(IContext context) {

+		return getFileDomainObject(context) != null;

+	}

+

+	@Override

+	public boolean canExecute(ICustomContext context) {

+		return getFileDomainObject(context) != null;

+	}

+

+	public void execute(ICustomContext context) {

+		File file = getFileDomainObject(context);

+

+		EcoreUtil.delete(file);

+	}

+

+	private File getFileDomainObject(IContext context) {

+		if (context instanceof ICustomContext) {

+			PictogramElement[] pictogramElements = ((ICustomContext) context).getPictogramElements();

+			if (pictogramElements.length == 1) {

+				PictogramElement pictogramElement = pictogramElements[0];

+				Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

+				if (domainObject instanceof File) {

+					if (pictogramElement instanceof Shape && pictogramElement.eContainer() instanceof ContainerShape

+							&& pictogramElement.eContainer().eContainer() instanceof ContainerShape) {

+						if (getBusinessObjectForPictogramElement((ContainerShape) pictogramElement.eContainer()

+								.eContainer()) instanceof Folder) {

+							return (File) domainObject;

+						}

+					}

+				}

+			}

+		}

+		return null;

+	}

+}

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilePattern.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilePattern.java
index 03303cb..3e461e6 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilePattern.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilePattern.java
@@ -2,6 +2,7 @@
 

 import org.eclipse.emf.common.util.EList;

 import org.eclipse.emf.ecore.EObject;

+import org.eclipse.graphiti.examples.filesystem.ui.FilesystemPredefinedColoredAreas;

 import org.eclipse.graphiti.examples.mm.filesystem.File;

 import org.eclipse.graphiti.examples.mm.filesystem.FilesystemFactory;

 import org.eclipse.graphiti.features.IReason;

@@ -19,14 +20,12 @@
 import org.eclipse.graphiti.mm.pictograms.PictogramElement;

 import org.eclipse.graphiti.mm.pictograms.Shape;

 import org.eclipse.graphiti.pattern.IPattern;

-import org.eclipse.graphiti.pattern.id.IdAddContext;

 import org.eclipse.graphiti.pattern.id.IdLayoutContext;

 import org.eclipse.graphiti.pattern.id.IdPattern;

 import org.eclipse.graphiti.pattern.id.IdUpdateContext;

 import org.eclipse.graphiti.services.Graphiti;

 import org.eclipse.graphiti.services.IGaService;

 import org.eclipse.graphiti.services.IPeCreateService;

-import org.eclipse.graphiti.util.PredefinedColoredAreas;

 

 public class FilePattern extends IdPattern implements IPattern {

 

@@ -70,7 +69,7 @@
 	}

 

 	@Override

-	public PictogramElement add(IdAddContext context) {

+	public PictogramElement doAdd(IAddContext context) {

 		Diagram targetDiagram = (Diagram) context.getTargetContainer();

 		File addedDomainObject = (File) context.getNewObject();

 		IPeCreateService peCreateService = Graphiti.getPeCreateService();

@@ -87,13 +86,13 @@
 		RoundedRectangle registerRectangle = gaService.createRoundedRectangle(outerRectangle, 5, 5);

 		gaService.setLocationAndSize(registerRectangle, 0, 0, 20, 20);

 		registerRectangle.setFilled(true);

-		gaService.setRenderingStyle(registerRectangle, PredefinedColoredAreas.getSilverWhiteGlossAdaptions());

+		gaService.setRenderingStyle(registerRectangle, FilesystemPredefinedColoredAreas.getGreenWhiteAdaptions());

 

 		// Main contents area

 		Rectangle mainRectangle = gaService.createRectangle(outerRectangle);

 		setId(mainRectangle, ID_MAIN_RECTANGLE);

 		mainRectangle.setFilled(true);

-		gaService.setRenderingStyle(mainRectangle, PredefinedColoredAreas.getSilverWhiteGlossAdaptions());

+		gaService.setRenderingStyle(mainRectangle, FilesystemPredefinedColoredAreas.getGreenWhiteAdaptions());

 

 		// File name

 		Shape shape = peCreateService.createShape(outerContainerShape, false);

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilesystemPattern.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilesystemPattern.java
new file mode 100644
index 0000000..f4e9ab5
--- /dev/null
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FilesystemPattern.java
@@ -0,0 +1,297 @@
+/**

+ * <copyright>

+ * 

+ * Copyright (c) 2012, 2012 SAP AG.

+ * 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:

+ *    SAP AG - initial API, implementation and documentation

+ *    cbrand - Bug 382928 - Introduce factory method(s) for easier gradient creation

+ * 

+ * </copyright>

+ */

+package org.eclipse.graphiti.examples.filesystem.patterns;

+

+import org.eclipse.emf.common.util.EList;

+import org.eclipse.emf.ecore.EObject;

+import org.eclipse.graphiti.examples.filesystem.ui.FilesystemPredefinedColoredAreas;

+import org.eclipse.graphiti.examples.mm.filesystem.Filesystem;

+import org.eclipse.graphiti.examples.mm.filesystem.FilesystemFactory;

+import org.eclipse.graphiti.features.IReason;

+import org.eclipse.graphiti.features.context.IAddContext;

+import org.eclipse.graphiti.features.context.ICreateContext;

+import org.eclipse.graphiti.features.context.IDirectEditingContext;

+import org.eclipse.graphiti.features.context.ILayoutContext;

+import org.eclipse.graphiti.features.context.IUpdateContext;

+import org.eclipse.graphiti.features.impl.Reason;

+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;

+import org.eclipse.graphiti.mm.algorithms.Rectangle;

+import org.eclipse.graphiti.mm.algorithms.Text;

+import org.eclipse.graphiti.mm.algorithms.styles.Orientation;

+import org.eclipse.graphiti.mm.pictograms.ContainerShape;

+import org.eclipse.graphiti.mm.pictograms.Diagram;

+import org.eclipse.graphiti.mm.pictograms.PictogramElement;

+import org.eclipse.graphiti.mm.pictograms.Shape;

+import org.eclipse.graphiti.pattern.AbstractPattern;

+import org.eclipse.graphiti.pattern.IPattern;

+import org.eclipse.graphiti.services.Graphiti;

+import org.eclipse.graphiti.services.IGaService;

+import org.eclipse.graphiti.services.IPeCreateService;

+

+public class FilesystemPattern extends AbstractPattern implements IPattern {

+

+	public FilesystemPattern() {

+		super(null);

+	}

+

+	@Override

+	public String getCreateName() {

+		return "Filesystem";

+	}

+

+	@Override

+	public boolean isMainBusinessObjectApplicable(Object mainBusinessObject) {

+		return mainBusinessObject instanceof Filesystem;

+	}

+

+	@Override

+	protected boolean isPatternControlled(PictogramElement pictogramElement) {

+		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

+		return isMainBusinessObjectApplicable(domainObject);

+	}

+

+	@Override

+	protected boolean isPatternRoot(PictogramElement pictogramElement) {

+		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

+		return isMainBusinessObjectApplicable(domainObject);

+	}

+

+	@Override

+	public boolean canCreate(ICreateContext context) {

+		return context.getTargetContainer() instanceof Diagram;

+	}

+

+	@Override

+	public Object[] create(ICreateContext context) {

+		Filesystem newFilesystem = FilesystemFactory.eINSTANCE.createFilesystem();

+		newFilesystem.setName(createNewName());

+

+		getDiagram().eResource().getContents().add(newFilesystem);

+

+		addGraphicalRepresentation(context, newFilesystem);

+		return new Object[] { newFilesystem };

+	}

+

+	@Override

+	public boolean canAdd(IAddContext context) {

+		return context.getNewObject() instanceof Filesystem && context.getTargetContainer() instanceof Diagram;

+	}

+

+	@Override

+	public PictogramElement add(IAddContext context) {

+		Diagram targetDiagram = (Diagram) context.getTargetContainer();

+		Filesystem addedDomainObject = (Filesystem) context.getNewObject();

+		IPeCreateService peCreateService = Graphiti.getPeCreateService();

+		IGaService gaService = Graphiti.getGaService();

+

+		// Outer container (invisible)

+		ContainerShape outerContainerShape = peCreateService.createContainerShape(targetDiagram, true);

+		Rectangle outerRectangle = gaService.createInvisibleRectangle(outerContainerShape);

+		gaService.setLocationAndSize(outerRectangle, context.getX(), context.getY(), context.getWidth(),

+				context.getHeight());

+

+		// Register tab

+		Rectangle registerRectangle = gaService.createRectangle(outerRectangle);

+		gaService.setLocationAndSize(registerRectangle, 0, 0, 20, 20);

+		registerRectangle.setFilled(true);

+		gaService.setRenderingStyle(registerRectangle, FilesystemPredefinedColoredAreas.getLightGrayAdaptions());

+

+		// Main contents area

+		Rectangle mainRectangle = gaService.createRectangle(outerRectangle);

+		setLocationAndSizeOfMainContentsArea(outerRectangle, mainRectangle);

+		mainRectangle.setFilled(true);

+		gaService.setRenderingStyle(mainRectangle, FilesystemPredefinedColoredAreas.getLightGrayAdaptions());

+

+		// Folder name

+		Shape shape = peCreateService.createShape(outerContainerShape, false);

+		Text text = gaService.createText(shape, addedDomainObject.getName());

+		text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);

+		text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);

+		setLocationAndSizeOfTextArea(outerRectangle, text);

+

+		peCreateService.createChopboxAnchor(outerContainerShape);

+

+		link(outerContainerShape, addedDomainObject);

+

+		return outerContainerShape;

+	}

+

+	@Override

+	public boolean canLayout(ILayoutContext context) {

+		return context.getPictogramElement() instanceof ContainerShape

+				&& getBusinessObjectForPictogramElement(context.getPictogramElement()) instanceof Filesystem;

+	}

+

+	@Override

+	public boolean layout(ILayoutContext context) {

+		boolean changesDone = false;

+		PictogramElement pictogramElement = context.getPictogramElement();

+		if (pictogramElement instanceof ContainerShape) {

+			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

+			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

+			if (outerGraphicsAlgorithm instanceof Rectangle) {

+				Rectangle outerRectangle = (Rectangle) outerGraphicsAlgorithm;

+

+				// Adapt size of main contents area

+				EList<GraphicsAlgorithm> graphicsAlgorithmChildren = outerRectangle.getGraphicsAlgorithmChildren();

+				if (graphicsAlgorithmChildren.size() > 1) {

+					GraphicsAlgorithm graphicsAlgorithm = graphicsAlgorithmChildren.get(1);

+					if (graphicsAlgorithm instanceof Rectangle) {

+						setLocationAndSizeOfMainContentsArea(outerRectangle, (Rectangle) graphicsAlgorithm);

+						changesDone = true;

+					}

+				}

+			}

+		}

+

+		// Adapt size and location of text field

+		Rectangle outerRectangle = getOuterRectangle(pictogramElement);

+		Text nameText = getNameText(pictogramElement);

+		if (outerRectangle != null && nameText != null) {

+			setLocationAndSizeOfTextArea(outerRectangle, nameText);

+			changesDone = true;

+		}

+

+		return changesDone;

+	}

+

+	@Override

+	public IReason updateNeeded(IUpdateContext context) {

+		Text nameText = getNameText(context.getPictogramElement());

+		Filesystem domainObject = (Filesystem) getBusinessObjectForPictogramElement(context.getPictogramElement());

+		if (domainObject.getName() == null || !domainObject.getName().equals(nameText.getValue())) {

+			return Reason.createTrueReason("Name differs. Expected: '" + domainObject.getName() + "'");

+		}

+		return Reason.createFalseReason();

+	}

+

+	@Override

+	public boolean update(IUpdateContext context) {

+		Text nameText = getNameText(context.getPictogramElement());

+		Filesystem domainObject = (Filesystem) getBusinessObjectForPictogramElement(context.getPictogramElement());

+		nameText.setValue(domainObject.getName());

+		return true;

+	}

+

+	@Override

+	public int getEditingType() {

+		return TYPE_TEXT;

+	}

+

+	@Override

+	public boolean canDirectEdit(IDirectEditingContext context) {

+		Object domainObject = getBusinessObjectForPictogramElement(context.getPictogramElement());

+		GraphicsAlgorithm ga = context.getGraphicsAlgorithm();

+		if (domainObject instanceof Filesystem && ga instanceof Text) {

+			return true;

+		}

+		return false;

+	}

+

+	@Override

+	public String getInitialValue(IDirectEditingContext context) {

+		Filesystem filesystem = (Filesystem) getBusinessObjectForPictogramElement(context.getPictogramElement());

+		return filesystem.getName();

+	}

+

+	@Override

+	public String checkValueValid(String value, IDirectEditingContext context) {

+		if (value == null || value.length() == 0) {

+			return "Folder name must not be empty";

+		}

+

+		Filesystem filesystem = (Filesystem) getBusinessObjectForPictogramElement(context.getPictogramElement());

+		EList<Shape> children = getDiagram().getChildren();

+		for (Shape child : children) {

+			Object domainObject = getBusinessObjectForPictogramElement(child);

+			if (domainObject instanceof Filesystem) {

+				if (!domainObject.equals(filesystem) && value.equals(((Filesystem) domainObject).getName())) {

+					return "A filesystem with name '" + ((Filesystem) domainObject).getName() + "' already exists.";

+				}

+			}

+		}

+		return null;

+	}

+

+	@Override

+	public void setValue(String value, IDirectEditingContext context) {

+		Filesystem filesystem = (Filesystem) getBusinessObjectForPictogramElement(context.getPictogramElement());

+		filesystem.setName(value);

+		updatePictogramElement(context.getPictogramElement());

+	}

+

+	private void setLocationAndSizeOfMainContentsArea(Rectangle outerRectangle, Rectangle mainRectangle) {

+		Graphiti.getGaService().setLocationAndSize(mainRectangle, 0, 10, outerRectangle.getWidth(),

+				outerRectangle.getHeight() - 10);

+	}

+

+	private void setLocationAndSizeOfTextArea(Rectangle outerRectangle, Text text) {

+		Graphiti.getGaService().setLocationAndSize(text, 0, 10, outerRectangle.getWidth(),

+				outerRectangle.getHeight() - 10);

+	}

+

+	private Rectangle getOuterRectangle(PictogramElement pictogramElement) {

+		if (pictogramElement instanceof ContainerShape) {

+			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

+			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

+			if (outerGraphicsAlgorithm instanceof Rectangle) {

+				return (Rectangle) outerGraphicsAlgorithm;

+			}

+		}

+		return null;

+	}

+

+	private Text getNameText(PictogramElement pictogramElement) {

+		if (pictogramElement instanceof ContainerShape) {

+			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

+			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

+			if (outerGraphicsAlgorithm instanceof Rectangle) {

+				EList<Shape> children = outerContainerShape.getChildren();

+				if (children.size() > 0) {

+					Shape shape = children.get(0);

+					GraphicsAlgorithm graphicsAlgorithm = shape.getGraphicsAlgorithm();

+					if (graphicsAlgorithm instanceof Text) {

+						return (Text) graphicsAlgorithm;

+					}

+				}

+			}

+		}

+		return null;

+	}

+

+	private String createNewName() {

+		String initialName = "NewFilesystem";

+		String name = initialName;

+		int number = 0;

+		while (findFilesystem(name) != null) {

+			number++;

+			name = initialName + number;

+		}

+		return name;

+	}

+

+	private Filesystem findFilesystem(String name) {

+		EList<EObject> contents = getDiagram().eResource().getContents();

+		for (EObject eObject : contents) {

+			if (eObject instanceof Filesystem) {

+				if (name.equals(((Filesystem) eObject).getName())) {

+					return (Filesystem) eObject;

+				}

+			}

+		}

+		return null;

+	}

+}

diff --git a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FolderPattern.java b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FolderPattern.java
index c64f5d3..bdc2798 100644
--- a/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FolderPattern.java
+++ b/examples/org.eclipse.graphiti.examples.filesystem/src/org/eclipse/graphiti/examples/filesystem/patterns/FolderPattern.java
@@ -1,51 +1,49 @@
-/**

- * <copyright>

- * 

- * Copyright (c) 2012, 2012 SAP AG.

- * 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:

- *    SAP AG - initial API, implementation and documentation

- *    cbrand - Bug 382928 - Introduce factory method(s) for easier gradient creation

- * 

- * </copyright>

- */

 package org.eclipse.graphiti.examples.filesystem.patterns;

 

+import java.util.List;

+

 import org.eclipse.emf.common.util.EList;

 import org.eclipse.emf.ecore.EObject;

-import org.eclipse.graphiti.examples.filesystem.ui.FilesystemPredefinedColoredAreas;

+import org.eclipse.emf.ecore.util.EcoreUtil;

+import org.eclipse.graphiti.examples.mm.filesystem.File;

 import org.eclipse.graphiti.examples.mm.filesystem.FilesystemFactory;

 import org.eclipse.graphiti.examples.mm.filesystem.Folder;

 import org.eclipse.graphiti.features.IReason;

 import org.eclipse.graphiti.features.context.IAddContext;

 import org.eclipse.graphiti.features.context.ICreateContext;

 import org.eclipse.graphiti.features.context.IDirectEditingContext;

-import org.eclipse.graphiti.features.context.ILayoutContext;

-import org.eclipse.graphiti.features.context.IUpdateContext;

 import org.eclipse.graphiti.features.impl.Reason;

 import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;

+import org.eclipse.graphiti.mm.algorithms.Polyline;

 import org.eclipse.graphiti.mm.algorithms.Rectangle;

-import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;

 import org.eclipse.graphiti.mm.algorithms.Text;

 import org.eclipse.graphiti.mm.algorithms.styles.Orientation;

+import org.eclipse.graphiti.mm.algorithms.styles.Point;

 import org.eclipse.graphiti.mm.pictograms.ContainerShape;

 import org.eclipse.graphiti.mm.pictograms.Diagram;

 import org.eclipse.graphiti.mm.pictograms.PictogramElement;

 import org.eclipse.graphiti.mm.pictograms.Shape;

-import org.eclipse.graphiti.pattern.AbstractPattern;

 import org.eclipse.graphiti.pattern.IPattern;

+import org.eclipse.graphiti.pattern.id.IdLayoutContext;

+import org.eclipse.graphiti.pattern.id.IdPattern;

+import org.eclipse.graphiti.pattern.id.IdUpdateContext;

 import org.eclipse.graphiti.services.Graphiti;

 import org.eclipse.graphiti.services.IGaService;

 import org.eclipse.graphiti.services.IPeCreateService;

+import org.eclipse.graphiti.util.IColorConstant;

+import org.eclipse.graphiti.util.PredefinedColoredAreas;

 

-public class FolderPattern extends AbstractPattern implements IPattern {

+public class FolderPattern extends IdPattern implements IPattern {

+

+	private static final String ID_FOLDER_NAME_TEXT = "folderNameText";

+	private static final String ID_OUTER_RECTANGLE = "outerRectangle";

+	private static final String ID_MAIN_RECTANGLE = "mainRectangle";

+	private static final String ID_NAME_SEPARATOR = "nameSeparator";

+	private static final String ID_FILE_NAMES_RECTANGLE = "fileNamesRectangle";

+	private static final String ID_FILE_NAME_TEXT = "fileNameText";

 

 	public FolderPattern() {

-		super(null);

+		super();

 	}

 

 	@Override

@@ -59,18 +57,6 @@
 	}

 

 	@Override

-	protected boolean isPatternControlled(PictogramElement pictogramElement) {

-		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

-		return isMainBusinessObjectApplicable(domainObject);

-	}

-

-	@Override

-	protected boolean isPatternRoot(PictogramElement pictogramElement) {

-		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

-		return isMainBusinessObjectApplicable(domainObject);

-	}

-

-	@Override

 	public boolean canCreate(ICreateContext context) {

 		return context.getTargetContainer() instanceof Diagram;

 	}

@@ -78,9 +64,8 @@
 	@Override

 	public Object[] create(ICreateContext context) {

 		Folder newFolder = FilesystemFactory.eINSTANCE.createFolder();

-		newFolder.setName(createNewName());

-

 		getDiagram().eResource().getContents().add(newFolder);

+		newFolder.setName(createNewName());

 

 		addGraphicalRepresentation(context, newFolder);

 		return new Object[] { newFolder };

@@ -88,81 +73,90 @@
 

 	@Override

 	public boolean canAdd(IAddContext context) {

-		return context.getNewObject() instanceof Folder && context.getTargetContainer() instanceof Diagram;

+		return super.canAdd(context) && context.getTargetContainer() instanceof Diagram;

 	}

 

 	@Override

-	public PictogramElement add(IAddContext context) {

+	public PictogramElement doAdd(IAddContext context) {

 		Diagram targetDiagram = (Diagram) context.getTargetContainer();

-		Folder addedDomainObject = (Folder) context.getNewObject();

+		Folder addedFolder = (Folder) context.getNewObject();

 		IPeCreateService peCreateService = Graphiti.getPeCreateService();

 		IGaService gaService = Graphiti.getGaService();

 

 		// Outer container (invisible)

 		ContainerShape outerContainerShape = peCreateService.createContainerShape(targetDiagram, true);

 		Rectangle outerRectangle = gaService.createInvisibleRectangle(outerContainerShape);

+		setId(outerRectangle, ID_OUTER_RECTANGLE);

 		gaService.setLocationAndSize(outerRectangle, context.getX(), context.getY(), context.getWidth(),

 				context.getHeight());

 

 		// Register tab

-		RoundedRectangle registerRectangle = gaService.createRoundedRectangle(outerRectangle, 5, 5);

+		Rectangle registerRectangle = gaService.createRectangle(outerRectangle);

 		gaService.setLocationAndSize(registerRectangle, 0, 0, 20, 20);

 		registerRectangle.setFilled(true);

-		gaService.setRenderingStyle(registerRectangle, FilesystemPredefinedColoredAreas.getGreenWhiteAdaptions());

+		gaService.setRenderingStyle(registerRectangle, PredefinedColoredAreas.getSilverWhiteGlossAdaptions());

 

 		// Main contents area

-		RoundedRectangle mainRectangle = gaService.createRoundedRectangle(outerRectangle, 5, 5);

-		setLocationAndSizeOfMainContentsArea(outerRectangle, mainRectangle);

+		Rectangle mainRectangle = gaService.createRectangle(outerRectangle);

+		setId(mainRectangle, ID_MAIN_RECTANGLE);

 		mainRectangle.setFilled(true);

-		gaService.setRenderingStyle(mainRectangle, FilesystemPredefinedColoredAreas.getGreenWhiteAdaptions());

+		gaService.setRenderingStyle(mainRectangle, PredefinedColoredAreas.getSilverWhiteGlossAdaptions());

 

 		// Folder name

-		Shape shape = peCreateService.createShape(outerContainerShape, false);

-		Text text = gaService.createText(shape, addedDomainObject.getName());

-		text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);

-		text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);

-		setLocationAndSizeOfTextArea(outerRectangle, text);

+		Shape textShape = peCreateService.createShape(outerContainerShape, false);

+		Text folderNameText = gaService.createText(textShape, "");

+		setId(folderNameText, ID_FOLDER_NAME_TEXT);

+		folderNameText.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);

+		folderNameText.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);

+

+		// Separating line

+		Shape lineShape = peCreateService.createShape(outerContainerShape, false);

+		Polyline polyline = gaService.createPolyline(lineShape);

+		setId(polyline, ID_NAME_SEPARATOR);

+		polyline.setForeground(manageColor(IColorConstant.BLACK));

+

+		// List of files in folder

+		ContainerShape filesContainerShape = peCreateService.createContainerShape(outerContainerShape, false);

+		Rectangle filesRectangle = gaService.createInvisibleRectangle(filesContainerShape);

+		setId(filesRectangle, ID_FILE_NAMES_RECTANGLE);

 

 		peCreateService.createChopboxAnchor(outerContainerShape);

 

-		link(outerContainerShape, addedDomainObject);

+		link(outerContainerShape, addedFolder);

+		link(textShape, addedFolder);

+		link(filesContainerShape, addedFolder);

 

 		return outerContainerShape;

 	}

 

 	@Override

-	public boolean canLayout(ILayoutContext context) {

-		return context.getPictogramElement() instanceof ContainerShape

-				&& getBusinessObjectForPictogramElement(context.getPictogramElement()) instanceof Folder;

-	}

-

-	@Override

-	public boolean layout(ILayoutContext context) {

+	protected boolean layout(IdLayoutContext context, String id) {

 		boolean changesDone = false;

-		PictogramElement pictogramElement = context.getPictogramElement();

-		if (pictogramElement instanceof ContainerShape) {

-			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

-			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

-			if (outerGraphicsAlgorithm instanceof Rectangle) {

-				Rectangle outerRectangle = (Rectangle) outerGraphicsAlgorithm;

 

-				// Adapt size of main contents area

-				EList<GraphicsAlgorithm> graphicsAlgorithmChildren = outerRectangle.getGraphicsAlgorithmChildren();

-				if (graphicsAlgorithmChildren.size() > 1) {

-					GraphicsAlgorithm graphicsAlgorithm = graphicsAlgorithmChildren.get(1);

-					if (graphicsAlgorithm instanceof RoundedRectangle) {

-						setLocationAndSizeOfMainContentsArea(outerRectangle, (RoundedRectangle) graphicsAlgorithm);

-						changesDone = true;

-					}

-				}

-			}

-		}

+		Rectangle outerRectangle = (Rectangle) context.getRootPictogramElement().getGraphicsAlgorithm();

 

-		// Adapt size and location of text field

-		Rectangle outerRectangle = getOuterRectangle(pictogramElement);

-		Text nameText = getNameText(pictogramElement);

-		if (outerRectangle != null && nameText != null) {

-			setLocationAndSizeOfTextArea(outerRectangle, nameText);

+		GraphicsAlgorithm ga = context.getGraphicsAlgorithm();

+		if (id.equals(ID_MAIN_RECTANGLE)) {

+			Graphiti.getGaService().setLocationAndSize(ga, 0, 10, outerRectangle.getWidth(),

+					outerRectangle.getHeight() - 10);

+			changesDone = true;

+		} else if (id.equals(ID_FOLDER_NAME_TEXT)) {

+			Graphiti.getGaService().setLocationAndSize(ga, 0, 10, outerRectangle.getWidth(), 20);

+			changesDone = true;

+		} else if (id.equals(ID_NAME_SEPARATOR)) {

+			Polyline polyline = (Polyline) ga;

+			polyline.getPoints().clear();

+			List<Point> pointList = Graphiti.getGaService().createPointList(

+					new int[] { 0, 30, outerRectangle.getWidth(), 30 });

+			polyline.getPoints().addAll(pointList);

+			changesDone = true;

+		} else if (id.equals(ID_FILE_NAMES_RECTANGLE)) {

+			Graphiti.getGaService().setLocationAndSize(ga, 0, 30, outerRectangle.getWidth(),

+					outerRectangle.getHeight() - 30);

+			changesDone = true;

+		} else if (id.equals(ID_FILE_NAME_TEXT)) {

+			int index = getIndex(context.getGraphicsAlgorithm());

+			Graphiti.getGaService().setLocationAndSize(ga, 5, 30 + 20 * index, outerRectangle.getWidth() - 10, 20);

 			changesDone = true;

 		}

 

@@ -170,21 +164,64 @@
 	}

 

 	@Override

-	public IReason updateNeeded(IUpdateContext context) {

-		Text nameText = getNameText(context.getPictogramElement());

-		Folder domainObject = (Folder) getBusinessObjectForPictogramElement(context.getPictogramElement());

-		if (domainObject.getName() == null || !domainObject.getName().equals(nameText.getValue())) {

-			return Reason.createTrueReason("Name differs. Expected: '" + domainObject.getName() + "'");

+	protected IReason updateNeeded(IdUpdateContext context, String id) {

+		if (id.equals(ID_FOLDER_NAME_TEXT)) {

+			Text nameText = (Text) context.getGraphicsAlgorithm();

+			Folder domainObject = (Folder) context.getDomainObject();

+			if (domainObject.getName() == null || !domainObject.getName().equals(nameText.getValue())) {

+				return Reason.createTrueReason("Name differs. Expected: '" + domainObject.getName() + "'");

+			}

+		} else if (id.equals(ID_FILE_NAMES_RECTANGLE)) {

+			ContainerShape filesContainerShape = (ContainerShape) context.getPictogramElement();

+			Folder folder = (Folder) context.getDomainObject();

+			if (filesContainerShape.getChildren().size() != folder.getFiles().size()) {

+				return Reason.createTrueReason("Number of files differ. Expected: " + folder.getFiles().size());

+			}

+		} else if (id.equals(ID_FILE_NAME_TEXT)) {

+			Text nameText = (Text) context.getGraphicsAlgorithm();

+			File file = (File) context.getDomainObject();

+			if (file.getName() == null || !file.getName().equals(nameText.getValue())) {

+				return Reason.createTrueReason("Name differs. Expected: '" + file.getName() + "'");

+			}

 		}

+

 		return Reason.createFalseReason();

 	}

 

 	@Override

-	public boolean update(IUpdateContext context) {

-		Text nameText = getNameText(context.getPictogramElement());

-		Folder domainObject = (Folder) getBusinessObjectForPictogramElement(context.getPictogramElement());

-		nameText.setValue(domainObject.getName());

-		return true;

+	protected boolean update(IdUpdateContext context, String id) {

+		if (id.equals(ID_FOLDER_NAME_TEXT)) {

+			Text nameText = (Text) context.getGraphicsAlgorithm();

+			Folder domainObject = (Folder) context.getDomainObject();

+			nameText.setValue(domainObject.getName());

+			return true;

+		} else if (id.equals(ID_FILE_NAMES_RECTANGLE)) {

+			EList<Shape> children = ((ContainerShape) context.getPictogramElement()).getChildren();

+			Shape[] toDelete = children.toArray(new Shape[children.size()]);

+			for (Shape shape : toDelete) {

+				EcoreUtil.delete(shape, true);

+			}

+			EList<File> files = ((Folder) context.getDomainObject()).getFiles();

+			int index = 0;

+			for (File file : files) {

+				Shape shape = Graphiti.getPeCreateService().createShape((ContainerShape) context.getPictogramElement(),

+						true);

+				Text fileNameText = Graphiti.getGaService().createText(shape, file.getName());

+				setId(fileNameText, ID_FILE_NAME_TEXT);

+				setIndex(fileNameText, index);

+				index++;

+				fileNameText.setHorizontalAlignment(Orientation.ALIGNMENT_LEFT);

+				fileNameText.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);

+				link(shape, file);

+			}

+			return true;

+		} else if (id.equals(ID_FILE_NAME_TEXT)) {

+			Text nameText = (Text) context.getGraphicsAlgorithm();

+			File file = (File) context.getDomainObject();

+			nameText.setValue(file.getName());

+			return true;

+		}

+		return false;

 	}

 

 	@Override

@@ -234,45 +271,6 @@
 		updatePictogramElement(context.getPictogramElement());

 	}

 

-	private void setLocationAndSizeOfMainContentsArea(Rectangle outerRectangle, RoundedRectangle mainRectangle) {

-		Graphiti.getGaService().setLocationAndSize(mainRectangle, 0, 10, outerRectangle.getWidth(),

-				outerRectangle.getHeight() - 10);

-	}

-

-	private void setLocationAndSizeOfTextArea(Rectangle outerRectangle, Text text) {

-		Graphiti.getGaService().setLocationAndSize(text, 0, 10, outerRectangle.getWidth(),

-				outerRectangle.getHeight() - 10);

-	}

-

-	private Rectangle getOuterRectangle(PictogramElement pictogramElement) {

-		if (pictogramElement instanceof ContainerShape) {

-			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

-			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

-			if (outerGraphicsAlgorithm instanceof Rectangle) {

-				return (Rectangle) outerGraphicsAlgorithm;

-			}

-		}

-		return null;

-	}

-

-	private Text getNameText(PictogramElement pictogramElement) {

-		if (pictogramElement instanceof ContainerShape) {

-			ContainerShape outerContainerShape = (ContainerShape) pictogramElement;

-			GraphicsAlgorithm outerGraphicsAlgorithm = outerContainerShape.getGraphicsAlgorithm();

-			if (outerGraphicsAlgorithm instanceof Rectangle) {

-				EList<Shape> children = outerContainerShape.getChildren();

-				if (children.size() > 0) {

-					Shape shape = children.get(0);

-					GraphicsAlgorithm graphicsAlgorithm = shape.getGraphicsAlgorithm();

-					if (graphicsAlgorithm instanceof Text) {

-						return (Text) graphicsAlgorithm;

-					}

-				}

-			}

-		}

-		return null;

-	}

-

 	private String createNewName() {

 		String initialName = "NewFolder";

 		String name = initialName;

diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/TypedPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/TypedPattern.java
index f1589a2..888ff4a 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/TypedPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/TypedPattern.java
@@ -33,15 +33,27 @@
  * the key PROPERTY_KEY_PATTERN_TYPE.

  * 

  * @since 0.10

+ * @experimental This API is in an experimental state and should be used by

+ *               clients only with care, as it not final and can be removed or

+ *               changed without prior notice!

  */

 public abstract class TypedPattern extends AbstractPattern {

 

+	/**

+	 * Constant indication the type of pattern, e.g. ID pattern.

+	 */

 	protected static final String PROPERTY_KEY_PATTERN_TYPE = "org.eclipse.graphiti.pattern.patternType";

 

+	/**

+	 * Constructor to be used when no configuration data is needed.

+	 */

 	public TypedPattern() {

 		super();

 	}

 

+	/**

+	 * Constructor to be used when configuration data is needed.

+	 */

 	public TypedPattern(IPatternConfiguration patternConfiguration) {

 		super(patternConfiguration);

 	}

diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdAddContext.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdAddContext.java
deleted file mode 100644
index a2b8df5..0000000
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdAddContext.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************

- * <copyright>

- *

- * Copyright (c) 2012, 2012 SAP AG.

- * 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:

- *    SAP AG - initial API, implementation and documentation

- *

- * </copyright>

- *

- *******************************************************************************/

-package org.eclipse.graphiti.pattern.id;

-

-import org.eclipse.graphiti.features.context.IAreaContext;

-import org.eclipse.graphiti.features.context.impl.AddContext;

-

-/**

- * @since 0.10

- * @experimental This API is in an experimental state and should be used by

- *               clients, as it not final and can be removed or changed without

- *               prior notice!

- */

-public class IdAddContext extends AddContext {

-

-	public IdAddContext() {

-		super();

-	}

-

-	public IdAddContext(IAreaContext context, Object newObject) {

-		super(context, newObject);

-	}

-}

diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdLayoutContext.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdLayoutContext.java
index 7100190..5cb593b 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdLayoutContext.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdLayoutContext.java
@@ -22,8 +22,8 @@
 /**

  * @since 0.10

  * @experimental This API is in an experimental state and should be used by

- *               clients, as it not final and can be removed or changed without

- *               prior notice!

+ *               clients only with care, as it not final and can be removed or

+ *               changed without prior notice!

  */

 public class IdLayoutContext extends LayoutContext {

 

diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdPattern.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdPattern.java
index 90f6cfa..456225b 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdPattern.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdPattern.java
@@ -21,8 +21,8 @@
 import org.eclipse.graphiti.features.context.IDirectEditingContext;

 import org.eclipse.graphiti.features.context.ILayoutContext;

 import org.eclipse.graphiti.features.context.IUpdateContext;

-import org.eclipse.graphiti.features.context.impl.AreaContext;

 import org.eclipse.graphiti.features.context.impl.LayoutContext;

+import org.eclipse.graphiti.features.context.impl.UpdateContext;

 import org.eclipse.graphiti.features.impl.Reason;

 import org.eclipse.graphiti.mm.Property;

 import org.eclipse.graphiti.mm.PropertyContainer;

@@ -32,6 +32,7 @@
 import org.eclipse.graphiti.mm.pictograms.Shape;

 import org.eclipse.graphiti.pattern.IPattern;

 import org.eclipse.graphiti.pattern.TypedPattern;

+import org.eclipse.graphiti.pattern.config.IPatternConfiguration;

 import org.eclipse.graphiti.services.Graphiti;

 

 /**

@@ -40,56 +41,139 @@
  * to identify the parts of that shape and to call the update and layout methods

  * for the shapes with IDs. Clients do not need to search through the shape

  * hierarchy to find the shapes to update and layout.

+ * <p>

+ * Besides IDs this pattern base implementation also supports tagging

+ * {@link PictogramElement}s with an index property that allows to number a

+ * sequence of children using the same ID, e.g. a list of attributes inside a

+ * class.

  * 

  * @since 0.10

  * @experimental This API is in an experimental state and should be used by

- *               clients, as it not final and can be removed or changed without

- *               prior notice!

+ *               clients only with care, as it not final and can be removed or

+ *               changed without prior notice!

  */

 public abstract class IdPattern extends TypedPattern implements IPattern {

 

+	/**

+	 * The property key that stores the information that a

+	 * {@link PictogramElement} is the root object of a {@link IdPattern}

+	 * subclass. The value is set by the {@link #add(IAddContext)} method.

+	 */

 	protected static final String PROPERTY_VALUE_PATTERN_TYPE_ID = "org.eclipse.graphiti.pattern.idpattern"; //$NON-NLS-1$

+

+	/**

+	 * The property key that is used to tag individual {@link PictogramElement}s

+	 * with a specific ID to identify them later during e.g. update or layout.

+	 */

 	protected static final String PROPERTY_KEY_ID = "org.eclipse.graphiti.pattern.id.id"; //$NON-NLS-1$

 

+	/**

+	 * The property key that is used to tag individual {@link PictogramElement}s

+	 * with a specific index beyond the ID to identify them later during e.g.

+	 * update or layout. This can e.g. be used for lists of shapes like the

+	 * attributes of a class.

+	 */

+	protected static final String PROPERTY_KEY_INDEX = "org.eclipse.graphiti.pattern.id.index"; //$NON-NLS-1$

+

+	/**

+	 * Default constructor for a new IdPattern. Clients should call either call

+	 * this or the constructor using a {@link IPatternConfiguration} instance

+	 * from their subclass constructor.

+	 */

 	public IdPattern() {

 		super();

 	}

 

+	/**

+	 * Constructor taking some pattern configuration data for the created

+	 * IdPattern. Clients should call either call this or the null parameter

+	 * constructor from their subclass constructor.

+	 * 

+	 * @param patternConfiguration

+	 *            The configuration data to use

+	 */

+	public IdPattern(IPatternConfiguration patternConfiguration) {

+		super(patternConfiguration);

+	}

+

 	/*

 	 * Base functionality

 	 */

 

+	/**

+	 * Checks if the {@link PictogramElement} is controlled by the pattern. The

+	 * default implementation simply checks if the domain object linked to the

+	 * given {@link PictogramElement} is the one that is controlled by this

+	 * pattern, see {@link #isMainBusinessObjectApplicable(Object)}. Especially

+	 * the default implementation does not traverse up the hierarchy to find a

+	 * suitable parent.

+	 * 

+	 * @param pictogramElement

+	 *            The {@link PictogramElement} to check

+	 * @return <code>true</code> in case the pattern controls the given

+	 *         {@link PictogramElement}, <code>false</code> otherwise.

+	 */

 	@Override

 	protected boolean isPatternControlled(PictogramElement pictogramElement) {

 		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

 		return isMainBusinessObjectApplicable(domainObject);

 	}

 

+	/**

+	 * Checks if the given {@link PictogramElement} is the root object of this

+	 * pattern. The default implementation checks if the domain object linked to

+	 * the given {@link PictogramElement} is the one that is controlled by this

+	 * pattern, see {@link #isMainBusinessObjectApplicable(Object)}. It also

+	 * checks if the object is controlled by an ID pattern by checking the

+	 * according property ({@link TypedPattern#PROPERTY_KEY_PATTERN_TYPE}).

+	 * 

+	 * @param pictogramElement

+	 *            The {@link PictogramElement} to check

+	 * @return <code>true</code> in case the given {@link PictogramElement} is

+	 *         the root shape of this pattern, <code>false</code> otherwise.

+	 */

 	@Override

 	protected boolean isPatternRoot(PictogramElement pictogramElement) {

 		Object domainObject = getBusinessObjectForPictogramElement(pictogramElement);

 		if (!isMainBusinessObjectApplicable(domainObject)) {

 			return false;

 		}

-		EList<Property> properties = pictogramElement.getProperties();

-		boolean rootPropertyFound = false;

-		for (Property property : properties) {

-			if (PROPERTY_KEY_PATTERN_TYPE.equals(property.getKey())

-					&& PROPERTY_VALUE_PATTERN_TYPE_ID.equals(property.getValue())) {

-				rootPropertyFound = true;

-			}

-		}

-		return rootPropertyFound;

+		String patternTypePropertyValue = Graphiti.getPeService().getPropertyValue(pictogramElement,

+				PROPERTY_KEY_PATTERN_TYPE);

+		return PROPERTY_VALUE_PATTERN_TYPE_ID.equals(patternTypePropertyValue);

 	}

 

 	/*

 	 * ID handling

 	 */

 

+	/**

+	 * Set the ID property ({@link #PROPERTY_KEY_ID}) for the given

+	 * {@link PictogramElement}; it can be any {@link PropertyContainer}

+	 * ,especially {@link Shape}s or {@link GraphicsAlgorithm}s are allowed. The

+	 * used ID string can later be used to identify the shape, e.g. in the

+	 * update or layout methods.

+	 * 

+	 * @param container

+	 *            The {@link PictogramElement} to set the ID property for

+	 * @param id

+	 *            The {@link String} ID to set.

+	 */

 	protected void setId(PropertyContainer container, String id) {

 		Graphiti.getPeService().setPropertyValue(container, PROPERTY_KEY_ID, id);

 	}

 

+	/**

+	 * Returns any ID that has been set for the given {@link PictogramElement};

+	 * it can be any {@link PropertyContainer}, especially {@link Shape}s or

+	 * {@link GraphicsAlgorithm}s are allowed.

+	 * 

+	 * @param container

+	 *            The {@link PictogramElement} to get the ID property from

+	 * @return A {@link String} representing the value of the property or

+	 *         <code>null</code> in case the property is not set, see

+	 *         {@link #setId(PropertyContainer, String)}.

+	 */

 	protected String getId(PropertyContainer container) {

 		EList<Property> properties = container.getProperties();

 		for (Property property : properties) {

@@ -100,6 +184,25 @@
 		return null;

 	}

 

+	/**

+	 * Searches for a {@link PictogramElement} that has the given ID starting

+	 * from the given {@link PictogramElement}. First the given element is

+	 * checked, then its {@link GraphicsAlgorithm}; after that the

+	 * {@link PictogramElement} children are checked recursively and last the

+	 * {@link GraphicsAlgorithm} children also recursively. The first

+	 * {@link PictogramElement} that has the given ID is returned, in case none

+	 * is found in the tree spanned by the given {@link PictogramElement},

+	 * <code>null</code> is returned.

+	 * 

+	 * @param pictogramElement

+	 *            The {@link PictogramElement} at which the search shall start,

+	 *            any {@link Shape}s or {@link GraphicsAlgorithm}s on top of

+	 *            this element are ignored.

+	 * @param idToFind

+	 *            A {@link String} representing the ID to search for

+	 * @return The {@link PictogramElement} that has the given ID property, in

+	 *         case none id found <code>null</code>.

+	 */

 	protected PropertyContainer findById(PictogramElement pictogramElement, String idToFind) {

 		if (idToFind == null || idToFind.length() == 0) {

 			return null;

@@ -154,43 +257,142 @@
 		return null;

 	}

 

+	/**

+	 * Set the index property ({@link #PROPERTY_KEY_ID}) for the given

+	 * {@link PictogramElement}; it can be any {@link PropertyContainer}

+	 * ,especially {@link Shape}s or {@link GraphicsAlgorithm}s are allowed. The

+	 * used index can later - together with the ID string - be used to identify

+	 * the concrete shape in case of a list of shapes, e.g. in the update or

+	 * layout methods.

+	 * 

+	 * @param container

+	 *            The {@link PictogramElement} to set the index property for

+	 * @param id

+	 *            The {@link Integer} index to set.

+	 */

+	protected void setIndex(PropertyContainer container, int index) {

+		Graphiti.getPeService().setPropertyValue(container, PROPERTY_KEY_INDEX, Integer.toString(index));

+	}

+

+	/**

+	 * Returns any index that has been set for the given

+	 * {@link PictogramElement}; it can be any {@link PropertyContainer},

+	 * especially {@link Shape}s or {@link GraphicsAlgorithm}s are allowed.

+	 * 

+	 * @param container

+	 *            The {@link PictogramElement} to get the index property from

+	 * @return An {@link Integer} representing the value of the property or -1

+	 *         in case the property is not set, see

+	 *         {@link #setIndex(PropertyContainer, int)}.

+	 */

+	protected int getIndex(PropertyContainer container) {

+		EList<Property> properties = container.getProperties();

+		for (Property property : properties) {

+			if (PROPERTY_KEY_INDEX.equals(property.getKey())) {

+				return Integer.valueOf(property.getValue());

+			}

+		}

+		return -1;

+	}

+

 	/*

 	 * Add functionality

 	 */

 

+	/**

+	 * Checks if adding is possible using this pattern in the given context. The

+	 * default implementation simply checks if the new object passed in the

+	 * context is the main domain object for the pattern, see

+	 * {@link #isMainBusinessObjectApplicable(Object)}.

+	 * 

+	 * @param context

+	 *            An {@link IAddContext} describing the add operation.

+	 * @return <code>true</code> in case adding is possible, <code>false</code>

+	 *         otherwise.

+	 */

 	@Override

 	public boolean canAdd(IAddContext context) {

 		return isMainBusinessObjectApplicable(context.getNewObject());

 	}

 

+	/**

+	 * Adds a {@link PictogramElement} representation for the given context to

+	 * the diagram. The default implementation delegates to

+	 * {@link #doAdd(IAddContext)} (which clients should primarily override) and

+	 * updates and layouts the returned {@link PictogramElement} afterwards.

+	 * 

+	 * @param context

+	 *            An {@link IAddContext} describing the add operation.

+	 * @return The root object of the created {@link PictogramElement} tree.

+	 */

 	@Override

 	public PictogramElement add(IAddContext context) {

-		AreaContext areaContext = new AreaContext();

-		areaContext.setHeight(context.getHeight());

-		areaContext.setWidth(context.getWidth());

-		areaContext.setLocation(context.getX(), context.getY());

-		IdAddContext addContext = new IdAddContext(areaContext, context.getNewObject());

-		addContext.setTargetConnection(context.getTargetConnection());

-		addContext.setTargetConnectionDecorator(context.getTargetConnectionDecorator());

-		addContext.setTargetContainer(context.getTargetContainer());

-		PictogramElement pictogramElement = add(addContext);

+		PictogramElement pictogramElement = doAdd(context);

 		setPatternType(pictogramElement, PROPERTY_VALUE_PATTERN_TYPE_ID);

+		update(new UpdateContext(pictogramElement));

 		layout(new LayoutContext(pictogramElement));

 		return pictogramElement;

 	}

 

-	abstract protected PictogramElement add(IdAddContext context);

+	/**

+	 * Clients should primarily override this method and implement their add

+	 * functionality here. This method is called from within

+	 * {@link #add(IAddContext)}.

+	 * 

+	 * @param context

+	 *            An {@link IAddContext} describing the add operation.

+	 * @return The root object of the created {@link PictogramElement} tree.

+	 */

+	abstract protected PictogramElement doAdd(IAddContext context);

 

 	/*

 	 * Layout functionality

 	 */

 

+	/**

+	 * Checks if layouting a shape is possible using this pattern in the given

+	 * context. The default implementation simply checks if the object passed in

+	 * the context is the main domain object for the pattern, see

+	 * {@link #isMainBusinessObjectApplicable(Object)} and if the

+	 * {@link PictogramElement} given in the context is controlled by an ID

+	 * pattern.

+	 * 

+	 * @param context

+	 *            An {@link ILayoutContext} describing the layout operation.

+	 * @return <code>true</code> in case layouting is possible,

+	 *         <code>false</code> otherwise.

+	 */

 	@Override

 	public boolean canLayout(ILayoutContext context) {

 		return PROPERTY_VALUE_PATTERN_TYPE_ID.equals(getPatternType(context.getPictogramElement()))

 				&& isMainBusinessObjectApplicable(getBusinessObjectForPictogramElement(context.getPictogramElement()));

 	}

 

+	/**

+	 * Layouts a {@link PictogramElement} representation given in the context.

+	 * The default implementation delegates to

+	 * {@link #layout(IdLayoutContext, String)} (which clients should primarily

+	 * override) to actually update individual {@link PictogramElement}s. This

+	 * delegation is done for any {@link PictogramElement} tagged with an ID in

+	 * the following order:

+	 * <ul>

+	 * <li>The {@link PictogramElement} given in the context itself</li>

+	 * <li>The {@link GraphicsAlgorithm} of the {@link PictogramElement} in the

+	 * context</li>

+	 * <li>The {@link PictogramElement} children of the {@link PictogramElement}

+	 * in the context</li>

+	 * <li>The {@link GraphicsAlgorithm} children of the

+	 * {@link GraphicsAlgorithm} of the {@link PictogramElement} in the context.

+	 * For this the method

+	 * {@link #layoutGraphicsAlgorithmChildren(GraphicsAlgorithm, IdLayoutContext)}

+	 * is called which in term calles itself and this method recursively.</li>

+	 * </ul>

+	 * 

+	 * @param context

+	 *            An {@link ILayoutContext} describing the layout operation.

+	 * @return <code>true</code> in case the layout operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

 	@Override

 	public boolean layout(ILayoutContext context) {

 		boolean changesDone = false;

@@ -262,14 +464,29 @@
 		} else {

 			layoutContext = new IdLayoutContext(null, graphicsAlgorithm, rootPictogramElement);

 		}

-		if (checkLayoutChildren(graphicsAlgorithm, layoutContext)) {

+		if (layoutGraphicsAlgorithmChildren(graphicsAlgorithm, layoutContext)) {

 			changesDone = true;

 		}

 

 		return changesDone;

 	}

 

-	protected boolean checkLayoutChildren(GraphicsAlgorithm graphicsAlgorithm, IdLayoutContext context) {

+	/**

+	 * This method implements the part of the layout that deals with the

+	 * {@link GraphicsAlgorithm} children, see {@link #layout(IdLayoutContext)}.

+	 * Clients should primarily override

+	 * {@link #layout(IdLayoutContext, String)} which is called for all found

+	 * {@link PictogramElement}s and {@link GraphicsAlgorithm}s as described

+	 * above that have an ID.

+	 * 

+	 * @param graphicsAlgorithm

+	 *            The {@link GraphicsAlgorithm} to layout.

+	 * @param context

+	 *            An {@link ILayoutContext} describing the layout operation.

+	 * @return <code>true</code> in case the layout operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

+	protected boolean layoutGraphicsAlgorithmChildren(GraphicsAlgorithm graphicsAlgorithm, IdLayoutContext context) {

 		boolean changesDone = false;

 		EList<GraphicsAlgorithm> graphicsAlgorithmChildren = graphicsAlgorithm.getGraphicsAlgorithmChildren();

 		for (GraphicsAlgorithm graphicsAlgorithmChild : graphicsAlgorithmChildren) {

@@ -281,25 +498,75 @@
 					changesDone = true;

 				}

 			}

-			if (checkLayoutChildren(graphicsAlgorithmChild, context)) {

+			if (layoutGraphicsAlgorithmChildren(graphicsAlgorithmChild, context)) {

 				changesDone = true;

 			}

 		}

 		return changesDone;

 	}

 

+	/**

+	 * Clients should primarily override this method and implement their layout

+	 * functionality here. This method is called from within

+	 * {@link #layout(ILayoutContext)} for each of the {@link PictogramElement}s

+	 * and {@link GraphicsAlgorithm}s that have been tagged with an ID.

+	 * 

+	 * @param context

+	 *            An {@link IdLayoutContext} describing the layout operation.

+	 * @return <code>true</code> in case the layout operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

 	abstract protected boolean layout(IdLayoutContext context, String id);

 

 	/*

 	 * Update functionality

 	 */

 

+	/**

+	 * Checks if updating a shape is possible using this pattern in the given

+	 * context. The default implementation simply checks if the object passed in

+	 * the context is the main domain object for the pattern, see

+	 * {@link #isMainBusinessObjectApplicable(Object)} and if the

+	 * {@link PictogramElement} given in the context is controlled by an ID

+	 * pattern.

+	 * 

+	 * @param context

+	 *            An {@link IUpdateContext} describing the update operation.

+	 * @return <code>true</code> in case updating is possible,

+	 *         <code>false</code> otherwise.

+	 */

 	@Override

 	public boolean canUpdate(IUpdateContext context) {

 		return PROPERTY_VALUE_PATTERN_TYPE_ID.equals(getPatternType(context.getPictogramElement()))

 				&& isMainBusinessObjectApplicable(getBusinessObjectForPictogramElement(context.getPictogramElement()));

 	}

 

+	/**

+	 * Checks if an updates is needed for a {@link PictogramElement}

+	 * representation given in the context. The default implementation delegates

+	 * to {@link #updateNeeded(IdUpdateContext, String)} (which clients should

+	 * primarily override) to actually update individual

+	 * {@link PictogramElement}s. This delegation is done for any

+	 * {@link PictogramElement} tagged with an ID in the following order:

+	 * <ul>

+	 * <li>The {@link PictogramElement} given in the context itself</li>

+	 * <li>The {@link GraphicsAlgorithm} of the {@link PictogramElement} in the

+	 * context</li>

+	 * <li>The {@link PictogramElement} children of the {@link PictogramElement}

+	 * in the context</li>

+	 * <li>The {@link GraphicsAlgorithm} children of the

+	 * {@link GraphicsAlgorithm} of the {@link PictogramElement} in the context.

+	 * For this the method

+	 * {@link #updateNeededGraphicsAlgorithmChildren(GraphicsAlgorithm, IdUpdateContext)}

+	 * is called which in term calls itself and this method recursively.</li>

+	 * </ul>

+	 * 

+	 * @param context

+	 *            An {@link IUpdateContext} describing the update operation.

+	 * @return An {@link IReason} indicating <code>true</code> and a

+	 *         {@link String} reason in case the update operation is needed, an

+	 *         {@link IReason} indicating <code>false</code> otherwise.

+	 */

 	@Override

 	public IReason updateNeeded(IUpdateContext context) {

 

@@ -356,7 +623,7 @@
 		} else {

 			updateContext = new IdUpdateContext(null, graphicsAlgorithm, rootPictogramElement, null);

 		}

-		IReason reason = checkUpdateNeededChildren(graphicsAlgorithm, updateContext);

+		IReason reason = updateNeededGraphicsAlgorithmChildren(graphicsAlgorithm, updateContext);

 		if (reason.toBoolean()) {

 			return reason;

 		}

@@ -364,7 +631,23 @@
 		return Reason.createFalseReason();

 	}

 

-	protected IReason checkUpdateNeededChildren(GraphicsAlgorithm graphicsAlgorithm, IdUpdateContext context) {

+	/**

+	 * This method implements the part of the update needed check that deals

+	 * with the {@link GraphicsAlgorithm} children, see

+	 * {@link #updateNeeded(IUpdateContext)}. Clients should primarily override

+	 * {@link #updateNeeded(IdUpdateContext, String)} which is called for all

+	 * found {@link PictogramElement}s and {@link GraphicsAlgorithm}s as

+	 * described above that have an ID.

+	 * 

+	 * @param graphicsAlgorithm

+	 *            The {@link GraphicsAlgorithm} to perform the update check for.

+	 * @param context

+	 *            An {@link IdUpdateContext} describing the update operation.

+	 * @return An {@link IReason} indicating <code>true</code> and a

+	 *         {@link String} reason in case the update operation is needed, an

+	 *         {@link IReason} indicating <code>false</code> otherwise.

+	 */

+	protected IReason updateNeededGraphicsAlgorithmChildren(GraphicsAlgorithm graphicsAlgorithm, IdUpdateContext context) {

 		EList<GraphicsAlgorithm> graphicsAlgorithmChildren = graphicsAlgorithm.getGraphicsAlgorithmChildren();

 		for (GraphicsAlgorithm graphicsAlgorithmChild : graphicsAlgorithmChildren) {

 			String id = getId(graphicsAlgorithmChild);

@@ -377,7 +660,7 @@
 					return reason;

 				}

 			}

-			IReason reason = checkUpdateNeededChildren(graphicsAlgorithmChild, context);

+			IReason reason = updateNeededGraphicsAlgorithmChildren(graphicsAlgorithmChild, context);

 			if (reason.toBoolean()) {

 				return reason;

 			}

@@ -385,10 +668,63 @@
 		return Reason.createFalseReason();

 	}

 

+	/**

+	 * Clients should primarily override this method and implement their update

+	 * check functionality here. This method is called from within

+	 * {@link #updateNeeded(IUpdateContext)} for each of the

+	 * {@link PictogramElement}s and {@link GraphicsAlgorithm}s that have been

+	 * tagged with an ID.

+	 * 

+	 * @param context

+	 *            An {@link IdUpdateContext} describing the update operation.

+	 * @return An {@link IReason} indicating <code>true</code> and a

+	 *         {@link String} reason in case the update operation is needed, an

+	 *         {@link IReason} indicating <code>false</code> otherwise.

+	 */

 	abstract protected IReason updateNeeded(IdUpdateContext context, String id);

 

+	/**

+	 * Updates a {@link PictogramElement} representation given in the context.

+	 * The default implementation only delegates to

+	 * {@link #update(IUpdateContext, boolean)} setting the parameter innerCall

+	 * to <code>false</code>.

+	 * 

+	 * @param context

+	 *            An {@link IUpdateContext} describing the update operation.

+	 * @return <code>true</code> in case the update operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

 	@Override

 	public boolean update(IUpdateContext context) {

+		return update(context, false);

+	}

+

+	/**

+	 * Updates a {@link PictogramElement} representation given in the context

+	 * recursively. The default implementation delegates to

+	 * {@link #update(IdUpdateContext, String)} (which clients should primarily

+	 * override) to actually update individual {@link PictogramElement}s. This

+	 * delegation is done for any {@link PictogramElement} tagged with an ID in

+	 * the following order:

+	 * <ul>

+	 * <li>The {@link PictogramElement} given in the context itself</li>

+	 * <li>The {@link GraphicsAlgorithm} of the {@link PictogramElement} in the

+	 * context</li>

+	 * <li>The {@link PictogramElement} children of the {@link PictogramElement}

+	 * in the context</li>

+	 * <li>The {@link GraphicsAlgorithm} children of the

+	 * {@link GraphicsAlgorithm} of the {@link PictogramElement} in the context.

+	 * For this the method

+	 * {@link #updateGraphicsAlgorithmChildren(GraphicsAlgorithm, IdUpdateContext)}

+	 * is called which in term calls itself and this method recursively.</li>

+	 * </ul>

+	 * 

+	 * @param context

+	 *            An {@link IUpdateContext} describing the update operation.

+	 * @return <code>true</code> in case the update operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

+	protected boolean update(IUpdateContext context, boolean innerCall) {

 		boolean result = false;

 

 		PictogramElement rootPictogramElement;

@@ -428,7 +764,7 @@
 			for (Shape shape : children) {

 				IdUpdateContext updateContext = new IdUpdateContext(shape, shape.getGraphicsAlgorithm(),

 						rootPictogramElement, getBusinessObjectForPictogramElement(shape));

-				if (update(updateContext)) {

+				if (update(updateContext, true)) {

 					result = true;

 				}

 			}

@@ -441,14 +777,33 @@
 		} else {

 			updateContext = new IdUpdateContext(null, graphicsAlgorithm, rootPictogramElement, null);

 		}

-		if (checkUpdateChildren(graphicsAlgorithm, updateContext)) {

+		if (updateGraphicsAlgorithmChildren(graphicsAlgorithm, updateContext)) {

 			result = true;

 		}

 

+		if (result && !innerCall) {

+			layoutPictogramElement(rootPictogramElement);

+		}

+

 		return result;

 	}

 

-	protected boolean checkUpdateChildren(GraphicsAlgorithm graphicsAlgorithm, IdUpdateContext context) {

+	/**

+	 * This method implements the part of the update that deals with the

+	 * {@link GraphicsAlgorithm} children, see

+	 * {@link #update(IUpdateContext, boolean)}. Clients should primarily

+	 * override {@link #update(IdUpdateContext, String)} which is called for all

+	 * found {@link PictogramElement}s and {@link GraphicsAlgorithm}s as

+	 * described above that have an ID.

+	 * 

+	 * @param graphicsAlgorithm

+	 *            The {@link GraphicsAlgorithm} to update.

+	 * @param context

+	 *            An {@link IdUpdateContext} describing the update operation.

+	 * @return <code>true</code> in case the update operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

+	protected boolean updateGraphicsAlgorithmChildren(GraphicsAlgorithm graphicsAlgorithm, IdUpdateContext context) {

 		boolean result = false;

 		EList<GraphicsAlgorithm> graphicsAlgorithmChildren = graphicsAlgorithm.getGraphicsAlgorithmChildren();

 		for (GraphicsAlgorithm graphicsAlgorithmChild : graphicsAlgorithmChildren) {

@@ -461,13 +816,25 @@
 					result = true;

 				}

 			}

-			if (checkUpdateChildren(graphicsAlgorithmChild, context)) {

+			if (updateGraphicsAlgorithmChildren(graphicsAlgorithmChild, context)) {

 				result = true;

 			}

 		}

 		return result;

 	}

 

+	/**

+	 * Clients should primarily override this method and implement their update

+	 * functionality here. This method is called from within

+	 * {@link #update(IUpdateContext, boolean)} for each of the

+	 * {@link PictogramElement}s and {@link GraphicsAlgorithm}s that have been

+	 * tagged with an ID.

+	 * 

+	 * @param context

+	 *            An {@link IdUpdateContext} describing the update operation.

+	 * @return <code>true</code> in case the update operation did changes to the

+	 *         diagram, <code>false</code> otherwise.

+	 */

 	abstract protected boolean update(IdUpdateContext context, String id);

 

 	/*

diff --git a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdUpdateContext.java b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdUpdateContext.java
index b9e8510..9a32cb0 100644
--- a/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdUpdateContext.java
+++ b/plugins/org.eclipse.graphiti.pattern/src/org/eclipse/graphiti/pattern/id/IdUpdateContext.java
@@ -22,8 +22,8 @@
 /**

  * @since 0.10

  * @experimental This API is in an experimental state and should be used by

- *               clients, as it not final and can be removed or changed without

- *               prior notice!

+ *               clients only with care, as it not final and can be removed or

+ *               changed without prior notice!

  */

 public class IdUpdateContext extends UpdateContext {

 

@@ -39,6 +39,16 @@
 		this.setDomainObject(domainObject);

 	}

 

+	@Override

+	public PictogramElement getPictogramElement() {

+		/*

+		 * Overriding this method is necessary because otherwise clients calling

+		 * this method will get access warnings (PictogramElementContext

+		 * offering this method is not part of the API).

+		 */

+		return super.getPictogramElement();

+	}

+

 	public GraphicsAlgorithm getGraphicsAlgorithm() {

 		return graphicsAlgorithm;

 	}

diff --git a/plugins/org.eclipse.graphiti/META-INF/MANIFEST.MF b/plugins/org.eclipse.graphiti/META-INF/MANIFEST.MF
index b9b4578..440c887 100644
--- a/plugins/org.eclipse.graphiti/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.graphiti/META-INF/MANIFEST.MF
@@ -29,7 +29,7 @@
    org.eclipse.graphiti.ui.tests",
  org.eclipse.graphiti.internal.contextbuttons;version="0.10.0";x-friends:="org.eclipse.graphiti.ui",
  org.eclipse.graphiti.internal.datatypes.impl;version="0.10.0";x-friends:="org.eclipse.graphiti.ui,org.eclipse.graphiti.tests,org.eclipse.graphiti.ui.tests",
- org.eclipse.graphiti.internal.features.context.impl.base;version="0.10.0";x-friends:="org.eclipse.graphiti.ui",
+ org.eclipse.graphiti.internal.features.context.impl.base;version="0.10.0";x-friends:="org.eclipse.graphiti.ui,org.eclipse.graphiti.pattern",
  org.eclipse.graphiti.internal.pref;version="0.10.0";x-friends:="org.eclipse.graphiti.ui",
  org.eclipse.graphiti.internal.services;version="0.10.0";x-friends:="org.eclipse.graphiti.ui",
  org.eclipse.graphiti.internal.services.impl;version="0.10.0";x-internal:=true,