[gatein-commits] gatein SVN: r47 - in components/mop/trunk: api and 64 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Aug 25 02:06:38 EDT 2009


Author: julien_viet
Date: 2009-08-25 02:06:36 -0400 (Tue, 25 Aug 2009)
New Revision: 47

Added:
   components/mop/trunk/api/
   components/mop/trunk/api/pom.xml
   components/mop/trunk/api/src/
   components/mop/trunk/api/src/main/
   components/mop/trunk/api/src/main/java/
   components/mop/trunk/api/src/main/java/org/
   components/mop/trunk/api/src/main/java/org/gatein/
   components/mop/trunk/api/src/main/java/org/gatein/mop/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/Attributes.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/Key.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/Model.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/ValueType.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/ComponentIterator.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/IterationType.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIterator.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategies.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategy.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/StructureIterator.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Content.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentManager.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentType.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Customization.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/CustomizationContext.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/AccessMode.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CloneCustomization.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationMode.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationPolicy.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/UpdateCustomization.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/WriteOperation.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Navigation.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ObjectType.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Page.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Site.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Templatized.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/TemplatizedObject.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Workspace.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceCustomizationContext.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceObject.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/ContentLink.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/Link.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/PageLink.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/URLLink.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIBody.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIComponent.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIContainer.java
   components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIWindow.java
   components/mop/trunk/api/src/main/resources/
   components/mop/trunk/api/src/test/
   components/mop/trunk/api/src/test/java/
   components/mop/trunk/api/src/test/resources/
   components/mop/trunk/core/
   components/mop/trunk/core/nul
   components/mop/trunk/core/pom.xml
   components/mop/trunk/core/src/
   components/mop/trunk/core/src/main/
   components/mop/trunk/core/src/main/java/
   components/mop/trunk/core/src/main/java/org/
   components/mop/trunk/core/src/main/java/org/gatein/
   components/mop/trunk/core/src/main/java/org/gatein/mop/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPFormatter.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPService.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/ModelImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ComparisonException.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerRegistry.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentRegistration.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextComparator.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextProviderRegistry.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextResolver.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSite.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSiteContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/LinkImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageLinkImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSite.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSiteContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSite.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSiteContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIBodyImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIComponentImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIContainerImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIWindowImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/URLLinkImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSite.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSiteContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceObjectImpl.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/AbstractCustomization.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContentState.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextSpecialization.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextType.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextTypeContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationContainer.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationState.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceClone.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceCustomization.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceSpecialization.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferenceState.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferencesState.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preference.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preferences.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/PreferencesBuilder.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/notes.txt
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/content/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/content/WorkspaceCustomizationPolicy.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/AbstractAttributes.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/SimpleAttributes.java
   components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/Tools.java
   components/mop/trunk/core/src/main/resources/
   components/mop/trunk/core/src/main/resources/conf/
   components/mop/trunk/core/src/main/resources/conf/standalone/
   components/mop/trunk/core/src/main/resources/conf/standalone/nodetypes.xml
   components/mop/trunk/core/src/test/
   components/mop/trunk/core/src/test/java/
   components/mop/trunk/core/src/test/java/org/
   components/mop/trunk/core/src/test/java/org/gatein/
   components/mop/trunk/core/src/test/java/org/gatein/mop/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/AbstractPOMTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/POMFormatterTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/composer/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/composer/StructureIteratorTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/BiltoTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationContextComparatorTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/AttributesTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/ObjectTypeTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/POMTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/WorkspaceTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/content/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/content/CustomizationTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletContentProvider.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletDefinition.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/KeyTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ToolsTestCase.java
   components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ValueTypeTestCase.java
   components/mop/trunk/core/src/test/resources/
   components/mop/trunk/core/src/test/resources/conf/
   components/mop/trunk/core/src/test/resources/conf/standalone/
   components/mop/trunk/core/src/test/resources/conf/standalone/configuration-sjdbc.xml
   components/mop/trunk/core/src/test/resources/conf/standalone/jcr-config-sjdbc.xml
   components/mop/trunk/core/src/test/resources/indexing-configuration.xml
   components/mop/trunk/core/src/test/resources/synonyms.properties
   components/mop/trunk/parent/
   components/mop/trunk/parent/pom.xml
   components/mop/trunk/pom.xml
   components/mop/trunk/spi/
   components/mop/trunk/spi/pom.xml
   components/mop/trunk/spi/src/
   components/mop/trunk/spi/src/main/
   components/mop/trunk/spi/src/main/java/
   components/mop/trunk/spi/src/main/java/org/
   components/mop/trunk/spi/src/main/java/org/gatein/
   components/mop/trunk/spi/src/main/java/org/gatein/mop/
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/ContentProvider.java
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/GetState.java
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/customization/
   components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/customization/CustomizationContextProvider.java
   components/mop/trunk/spi/src/main/resources/
   components/mop/trunk/spi/src/test/
   components/mop/trunk/spi/src/test/java/
   components/mop/trunk/spi/src/test/resources/
Log:
GTNMOP-1 : Source code initial import


Added: components/mop/trunk/api/pom.xml
===================================================================
--- components/mop/trunk/api/pom.xml	                        (rev 0)
+++ components/mop/trunk/api/pom.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,50 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <modelVersion>4.0.0</modelVersion>
+
+   <parent>
+      <groupId>org.gatein.mop</groupId>
+      <artifactId>mop.parent</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+      <relativePath>../parent/pom.xml</relativePath>
+   </parent>
+   
+   <!-- ****************** -->
+   <!-- Project Definition -->
+   <!-- ****************** -->
+   
+   <groupId>org.gatein.mop</groupId>
+   <artifactId>mop.api</artifactId>
+   <version>1.0.0-SNAPSHOT</version>
+   <packaging>jar</packaging>
+
+   <name>MOP API</name>
+   <description>API of the Object Model for Portal</description>
+
+   <scm>
+      <connection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/api/</connection>
+      <developerConnection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/api/</developerConnection>
+      <url>http://fisheye.exoplatform.org/browse/projects-internal/exorh/exo-portal/mop/trunk/api/</url>
+   </scm>
+
+</project>

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/Attributes.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/Attributes.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/Attributes.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,67 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api;
+
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * <p>This interface extends a map to provide convenient method for dealing with attribute values in a type safe
+ * manner when the interface client knows the type of an attribute and wants to deal with it accordingly.</p>
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Attributes {
+
+  Set<String> getKeys();
+
+  String getString(String name);
+
+  void setString(String name, String value);
+
+  Boolean getBoolean(String name);
+
+  void setBoolean(String name, Boolean value);
+
+  Integer getInteger(String name);
+
+  void setInteger(String name, Integer value);
+
+  Date getDate(String name);
+
+  void setDate(String name, Date value);
+
+  Double getDouble(String name);
+
+  void setDouble(String name, Double value);
+
+  Object getObject(String name);
+
+  <T> void setObject(String name, T value);
+
+  ValueType<?> getType(String name);
+
+  <T> T getValue(Key<T> key);
+
+  <T> T getValue(Key<T> key, T defaultValue);
+
+  <T> void setValue(Key<T> key, T value);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/Key.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/Key.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/Key.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,99 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api;
+
+/**
+ * A key is a typed name. This class is immutable and is therefore thread safe.
+ * 
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class Key<T> {
+
+  public static <T> Key<T> create(java.lang.String name, ValueType<T> type) {
+    if (type == null) {
+      throw new NullPointerException();
+    }
+    return new Key<T>(name, type);
+  }
+
+  /** The key name. */
+  private final java.lang.String name;
+
+  /** The type. */
+  private final ValueType<T> type;
+
+  /**
+   * Creates a new key.
+   *
+   * @param name the key name
+   * @param type the key type
+   * @throws NullPointerException if the name is null
+   */
+  protected Key(java.lang.String name, ValueType<T> type) throws NullPointerException {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    if (type == null) {
+      throw new NullPointerException();
+    }
+    this.name = name;
+    this.type = type;
+  }
+
+  /**
+   * Returns the key type.
+   *
+   * @return the type
+   */
+  public ValueType<T> getType() {
+    return type;
+  }
+
+  /**
+   * Returns the key name.
+   *
+   * @return the name
+   */
+  public final java.lang.String getName() {
+    return name;
+  }
+
+  @Override
+  public int hashCode() {
+    return getType().hashCode() + name.hashCode();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj.getClass() == getClass()) {
+      Key that = (Key)obj;
+      return name.equals(that.name);
+    }
+    return false;
+  }
+
+  @Override
+  public java.lang.String toString() {
+    return "Key[name=" + name + ",type=" + getType() + "]";
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/Model.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/Model.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/Model.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api;
+
+import org.gatein.mop.api.workspace.Workspace;
+
+/**
+ * Provides access to the model.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Model {
+
+  /**
+   * Returns the workspace.
+   *
+   * @return the workspace
+   */
+  Workspace getWorkspace();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/ValueType.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/ValueType.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/ValueType.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,162 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Date;
+
+/**
+ * The enumeration of value type that are permitted for attributes state. The generic type is used to represent
+ * the relevant associated java type for the runtime values.
+ *
+ * @param <T> the value java type
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class ValueType<T> {
+
+  /** . */
+  public static final ValueType<String> STRING = new ValueType<String>() {};
+
+  /** . */
+  public static final ValueType<Integer> INTEGER = new ValueType<Integer>() {};
+
+  /** . */
+  public static final ValueType<Boolean> BOOLEAN = new ValueType<Boolean>() {};
+
+  /** . */
+  public static final ValueType<Date> DATE = new ValueType<Date>() {};
+
+  /** . */
+  public static final ValueType<Double> DOUBLE = new ValueType<Double>() {};
+
+  /** . */
+  private final Class<T> javaType;
+
+  @SuppressWarnings("unchecked")
+  private ValueType() {
+    Type type = getClass().getGenericSuperclass();
+    ParameterizedType parameterizedType = (ParameterizedType)type;
+    javaType = (Class<T>)parameterizedType.getActualTypeArguments()[0];
+  }
+
+  /**
+   * Returns the java type.
+   *
+   * @return the java type
+   */
+  public Class<T> getJavaType() {
+    return javaType;
+  }
+
+  /**
+   * Returns true if the object matches the type.
+   *
+   * @param o the object
+   * @return true when the value matches the type
+   */
+  public boolean isInstance(Object o) {
+    return javaType.isInstance(o);
+  }
+
+  /**
+   * Casts the object to the underlying java type.
+   *
+   * @param o the object to cast
+   * @return the casted object
+   * @throws ClassCastException if the object cannot be casted
+   */
+  public T cast(Object o) throws ClassCastException {
+    if (o == null) {
+      return null;
+    }
+    if (javaType.isInstance(o)) {
+      return javaType.cast(o);
+    }
+    throw new ClassCastException("Object " + o + " cannot be casted to " + javaType.getName());
+  }
+
+  /**
+   * Returns the corresponding value type for the specified object or null if no valid one can be found.
+   *
+   * @param t the object to decode type for
+   * @param <T> the java type
+   * @return the decoded type
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> ValueType<T> decode(T t) {
+    if (t == null) {
+      return null;
+    }
+    if (t instanceof String) {
+      return (ValueType<T>)ValueType.STRING;
+    }
+    if (t instanceof Integer) {
+      return (ValueType<T>)ValueType.INTEGER;
+    }
+    if (t instanceof Boolean) {
+      return (ValueType<T>)ValueType.BOOLEAN;
+    }
+    if (t instanceof Date) {
+      return (ValueType<T>)ValueType.DATE;
+    }
+    if (t instanceof Double) {
+      return (ValueType<T>)ValueType.DOUBLE;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the corresponding value type for the specified object.
+   *
+   * @param t the object to get the type for
+   * @param <T> the java type
+   * @return the decoded type
+   * @throws NullPointerException if the argument is null
+   * @throws IllegalArgumentException if the argument does not match a valid type
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> ValueType<T> get(T t) throws NullPointerException, IllegalArgumentException {
+    if (t == null) {
+      throw new NullPointerException();
+    }
+    if (t instanceof String) {
+      return (ValueType<T>)ValueType.STRING;
+    }
+    if (t instanceof Integer) {
+      return (ValueType<T>)ValueType.INTEGER;
+    }
+    if (t instanceof Boolean) {
+      return (ValueType<T>)ValueType.BOOLEAN;
+    }
+    if (t instanceof Date) {
+      return (ValueType<T>)ValueType.DATE;
+    }
+    if (t instanceof Double) {
+      return (ValueType<T>)ValueType.DOUBLE;
+    }
+    throw new IllegalArgumentException("Java class " + t.getClass().getName() + " cannot be used as a value type");
+  }
+
+  @Override
+  public String toString() {
+    return "ValueType[" + javaType.getSimpleName() + "]";
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/ComponentIterator.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/ComponentIterator.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/ComponentIterator.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ComponentIterator implements StructureIterator {
+
+  /** . */
+  private final UIComponent root;
+
+  /** . */
+  private final LinkedList<ContainerVisit> stack;
+
+  /** . */
+  private UIComponent current;
+
+  /** . */
+  private IterationType type;
+
+  public ComponentIterator(UIComponent root) {
+    this.root = root;
+    this.stack = new LinkedList<ContainerVisit>();
+    this.type = null;
+  }
+
+  public UIComponent getComponent() {
+    return current;
+  }
+
+  public IterationType next() {
+
+    if (type == null) {
+      current = root;
+      type = IterationType.START;
+    } else {
+      if (type == IterationType.START) {
+        if (current instanceof UIContainer) {
+          UIContainer container = (UIContainer)current;
+          Iterator<? extends UIComponent> iterator = container.getChildren().iterator();
+          if (iterator.hasNext()) {
+            stack.add(new ContainerVisit(container, iterator));
+            current = iterator.next();
+          } else {
+            type = IterationType.END;
+          }
+        } else {
+          type = IterationType.END;
+        }
+      } else {
+        if (stack.size() > 0) {
+          ContainerVisit visit = stack.getLast();
+          if (visit.iterator.hasNext()) {
+            type = IterationType.START;
+            current = visit.iterator.next();
+          } else {
+            stack.removeLast();
+            current = visit.container;
+          }
+        } else {
+          current = null;
+          return IterationType.DONE;
+        }
+      }
+    }
+
+    //
+    return type;
+  }
+
+  private static class ContainerVisit {
+
+    /** . */
+    private final UIContainer container;
+
+    /** . */
+    private final Iterator<? extends UIComponent> iterator;
+
+    private ContainerVisit(UIContainer container, Iterator<? extends UIComponent> iterator) {
+      this.container = container;
+      this.iterator = iterator;
+    }
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/IterationType.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/IterationType.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/IterationType.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public enum IterationType {
+
+  START,
+
+  END,
+
+  DONE
+
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIterator.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIterator.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIterator.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ui.UIBody;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class PageIterator implements StructureIterator {
+
+  /** . */
+  private final ArrayList<PageVisit> list;
+
+  /** . */
+  private int index;
+
+  /** . */
+  private UIComponent current;
+
+  public PageIterator(Page page, PageIteratorStrategy strategy) {
+    ArrayList<PageVisit> list = new ArrayList<PageVisit>();
+    Iterator<Page> iterator = strategy.iterator(page);
+    while (iterator.hasNext()) {
+      Page p = iterator.next();
+      list.add(new PageVisit(p, new ComponentIterator(p.getRootComponent())));
+    }
+
+    //
+    this.list = list;
+    this.index = list.size() - 1;
+    this.current = null;
+  }
+
+  public UIComponent getComponent() {
+    return current;
+  }
+
+  public IterationType next() {
+    while (index < list.size()) {
+      PageVisit visit = list.get(index);
+      switch (visit.iterator.next()) {
+        case START: {
+          UIComponent current = visit.iterator.getComponent();
+          if (current instanceof UIBody) {
+            index--;
+            break;
+          } else {
+            this.current = current;
+            return IterationType.START;
+          }
+        }
+        case END: {
+          UIComponent current = visit.iterator.getComponent();
+          if (current instanceof UIBody) {
+            break;
+          } else {
+            this.current = current;
+            return IterationType.END;
+          }
+        }
+        case DONE: {
+          current = null;
+          index++;
+          break;
+        }
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    //
+    return IterationType.DONE;
+  }
+
+  private static class PageVisit {
+
+    /** . */
+    private final Page page;
+
+    /** . */
+    private final ComponentIterator iterator;
+
+    private PageVisit(Page page, ComponentIterator iterator) {
+      this.page = page;
+      this.iterator = iterator;
+    }
+  }
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategies.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategies.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategies.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,71 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+import org.gatein.mop.api.workspace.Page;
+
+import java.util.Iterator;
+import java.util.Collections;
+import java.util.NoSuchElementException;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public enum PageIteratorStrategies implements PageIteratorStrategy {
+
+  SIMPLE {
+    public Iterator<Page> iterator(Page page) {
+      return Collections.singletonList(page).iterator();
+    }},
+
+  PAGE_TEMPLATE {
+    public Iterator<Page> iterator(final Page page) {
+      return new Iterator<Page>() {
+        Page current = page;
+        public boolean hasNext() {
+          return current != null;
+        }
+        public Page next() {
+          if (current == null) {
+            throw new NoSuchElementException();
+          }
+          Page next = null;
+          for (Page p = current;p != null;p = p.getParent()) {
+            Page template = p.getTemplate();
+            if (template != null) {
+              next = template;
+              break;
+            }
+          }
+          Page tmp = current;
+          current = next;
+          return tmp;
+        }
+        public void remove() {
+          throw new UnsupportedOperationException();
+        }
+      };
+    }},
+
+  PAGE_AND_SITE_TEMPLATE {
+    public Iterator<Page> iterator(Page page) {
+      throw new UnsupportedOperationException();
+    }}
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategy.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategy.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/PageIteratorStrategy.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+import org.gatein.mop.api.workspace.Page;
+
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface PageIteratorStrategy {
+
+  Iterator<Page> iterator(Page page);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/StructureIterator.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/StructureIterator.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/composer/StructureIterator.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.composer;
+
+import org.gatein.mop.api.workspace.ui.UIComponent;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface StructureIterator {
+
+  IterationType next();
+
+  UIComponent getComponent();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Content.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Content.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Content.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content;
+
+/**
+ * Representation of a content.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ * @param <S> the content state type parameter
+ */
+public interface Content<S> {
+
+  /**
+   * Returns the content id.
+   *
+   * @return the id
+   */
+  String getId();
+
+  /**
+   * Returns the content type.
+   *
+   * @return the content type
+   */
+  ContentType<S> getType();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentManager.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentManager.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentManager.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content;
+
+/**
+ * Provides access to content as seen by the framework.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface ContentManager {
+
+  /**
+   * Returns the representation of a specified content or null if it cannot be found.
+   *
+   * @param contentType the content type
+   * @param contentId the content id
+   * @return the content
+   * @param <S> the state type
+   */
+  <S> Content<S> getContent(ContentType<S> contentType, String contentId);
+
+  /**
+   * Returns the representation of a specified content or null if it cannot be found.
+   *
+   * @param mimeType the mime type
+   * @param contentId the content id
+   * @return the content
+   */
+  Content<?> getContent(String mimeType, String contentId);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentType.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentType.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/ContentType.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content;
+
+/**
+ * Represents a content type.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ * @param <S> the content state type parameter
+ */
+public final class ContentType<S> {
+
+  /** . */
+  private final String mimeType;
+
+  /** . */
+  private final Class<S> stateClass;
+
+  /**
+   * Create a new content type.
+   *
+   * @param mimeType the mime type
+   * @param stateClass the state class
+   * @throws NullPointerException if any argument is null
+   */
+  public ContentType(String mimeType, Class<S> stateClass) throws NullPointerException {
+    if (mimeType == null) {
+      throw new NullPointerException("No null mime type accepted");
+    }
+    if (stateClass == null) {
+      throw new NullPointerException("No null state class accepted");
+    }
+
+    //
+    this.mimeType = mimeType;
+    this.stateClass = stateClass;
+  }
+
+  public String getMimeType() {
+    return mimeType;
+  }
+
+  public Class<S> getStateClass() {
+    return stateClass;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof ContentType) {
+      ContentType that = (ContentType)obj;
+      return mimeType.equals(that.mimeType);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return mimeType.hashCode();
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Customization.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Customization.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/Customization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,109 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content;
+
+import org.gatein.mop.api.content.customization.CustomizationMode;
+
+import java.util.Set;
+import java.util.Collection;
+
+/**
+ * An entity representing the customization of a content.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ * @param <S> the content state type parameter
+ */
+public interface Customization<S> {
+
+  /**
+   * Returns the customization name or null if it does not have any name.
+   *
+   * @return the customization name
+   */
+  String getName();
+
+  /**
+   * Returns the content id this customization refers to.
+   *
+   * @return the content id
+   */
+  String getContentId();
+
+  /**
+   * Returns the content type this customization refers to.
+   *
+   * @return The content type
+   */
+  ContentType<S> getType();
+
+  /**
+   * Returns the contexts that are associated with that customization. Note that the set returned
+   * maintains the hierararchy order of the set from the most specific to the least specific.
+   *
+   * @return the contexts
+   */
+  Set<CustomizationContext> getContexts();
+
+  /**
+   * <p>Returns the stateful content associated with the specified customization contexts or null
+   * if no customization can be created for the desired contexts. The returned customization
+   * may not honour all provided the customization contexts.</p>
+   *
+   * <p>Calling the method with an empty set returns the default customization of the
+   * content or null if none is available.</p>
+   *
+   * <p>Calling the method with a set of contexts that is not consistent will trigger an
+   * <tt>IllegalArgumentException</tt> to be thrown. For instance two workspace contexts
+   * specifying different pages cannot lead to determine a final context.</p>
+   *
+   * @param contexts the customization contexts
+   * @return the content state
+   */
+  Customization<S> getCustomization(Set<CustomizationContext> contexts);
+
+  /**
+   * Customize the state with respect to the provided customization context.
+   *
+   * @param mode the customization mode
+   * @param contexts the customization context
+   * @return the customization
+   */
+  Customization<S> customize(CustomizationMode mode, Collection<CustomizationContext> contexts);
+
+  /**
+   * Returns the customization state.
+   *
+   * @return the state
+   */
+  S getState();
+
+  /**
+   * Updates the customization state.
+   *
+   * @param state the customization state
+   */
+  void setState(S state);
+
+  /**
+   * Destroys the customization.
+   */
+  void destroy();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/CustomizationContext.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/CustomizationContext.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/CustomizationContext.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content;
+
+/**
+ * <p>The customization context defines where customization applies, it can be an entity, an identity, or anything
+ * else that is subject to customization.</p>
+ *
+ * <p>Contexts are partitionned by their type, i.e all the context that share the same value returned by the
+ * invocation of the method {@link #getContextType()} are considered to belong to the same type.</p>
+ *
+ * <p>Within a partition it is possible to find out the relationship between two contexts thanks to the
+ * {@link #contains(CustomizationContext)} method.
+ * <ul>
+ * <li>Two contexts are considered equals when they contain each other.</li>
+ * <li>Two contexts are not related when no context contains the other one.</li>
+ * <li>Otherwise one contexts belongs to the other.</li>
+ * </ul>
+ * The <tt>contains</tt> relationship is transitive.</p>
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface CustomizationContext {
+
+  /**
+   * Returns the identifier of the context.
+   *
+   * @return the context identifier
+   */
+  String getContextId();
+
+  /**
+   * Returns the customization context type.
+   *
+   * @return the customization context type
+   */
+  String getContextType();
+
+  /**
+   * Returns true if the context contains the provided context.
+   *
+   * @param that the context to test
+   * @return a boolean indicated whether the provided context is contained by this context
+   */
+  boolean contains(CustomizationContext that);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/AccessMode.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/AccessMode.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/AccessMode.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public enum AccessMode {
+
+  READ_ONLY, READ_WRITE
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CloneCustomization.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CloneCustomization.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CloneCustomization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+import org.gatein.mop.api.content.CustomizationContext;
+
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class CloneCustomization extends WriteOperation {
+
+  /** . */
+  private final Set<CustomizationContext> contexts;
+
+  /** . */
+  private final CustomizationMode mode;
+
+  public CloneCustomization(Set<CustomizationContext> contexts, CustomizationMode mode) {
+    this.contexts = contexts;
+    this.mode = mode;
+  }
+
+  public Set<CustomizationContext> getContexts() {
+    return contexts;
+  }
+
+  public CustomizationMode getMode() {
+    return mode;
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationMode.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationMode.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationMode.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public enum CustomizationMode {
+
+  CLONE, SPECIALIZE
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationPolicy.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationPolicy.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/CustomizationPolicy.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+import org.gatein.mop.api.content.Customization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface CustomizationPolicy {
+
+  WriteOperation onWrite(Customization customization);
+
+  AccessMode accessMode(Customization customization);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/UpdateCustomization.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/UpdateCustomization.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/UpdateCustomization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class UpdateCustomization extends WriteOperation {
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/WriteOperation.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/WriteOperation.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/content/customization/WriteOperation.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.content.customization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class WriteOperation {
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Navigation.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Navigation.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Navigation.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,105 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import org.gatein.mop.api.workspace.link.Link;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Navigation extends TemplatizedObject {
+
+  /**
+   * Returns the navigation name.
+   *
+   * @return the navigation name
+   */
+  String getName();
+
+  /**
+   * Extends the object type to navigation.
+   *
+   * @return the object type
+   */
+  ObjectType<? extends Navigation> getObjectType();
+
+  /**
+   * Returns the site this navigation belongs to
+   *
+   * @return the site
+   */
+  Site getSite();
+
+  /**
+   * Return the navigation parent or null if it is a root.
+   *
+   * @return the navigation parent
+   */
+  Navigation getParent();
+
+  /**
+   * Returns the child navigations.
+   *
+   * @return the child navigations
+   */
+  Collection<? extends Navigation> getChildren();
+
+  /**
+   * Returns a specified navigation.
+   *
+   * @param name the navigation name
+   * @return a child navigation
+   */
+  Navigation getChild(String name);
+
+  /**
+   * Adds a child navigation
+   *
+   * @param name the child name
+   * @return the child navigation
+   * @throws NullPointerException when a null name is provided
+   * @throws IllegalArgumentException when an illegal name is provided
+   */
+  Navigation addChild(String name) throws NullPointerException, IllegalArgumentException;
+
+  /**
+   * Destroys this navigation.
+   */
+  void destroy();
+
+  /**
+   * Returns the current link related to this navitation object.
+   *
+   * @return the link
+   */
+  Link getLink();
+
+  /**
+   * Link the navigation to a specifed type and returns the corresponding link subclass that
+   * allows the configuration of the link.
+   *
+   * @param linkType the link type
+   * @param <L> the link type parameter
+   * @return the link object
+   */
+  <L extends Link> L linkTo(ObjectType<L> linkType);
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ObjectType.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ObjectType.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ObjectType.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIBody;
+import org.gatein.mop.api.workspace.link.PageLink;
+import org.gatein.mop.api.workspace.link.URLLink;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * A type safe interface for the type of a workspace object.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ObjectType<O extends WorkspaceObject> {
+
+  /** . */
+  public static final ObjectType<WorkspaceObject> ANY = new ObjectType<WorkspaceObject>(WorkspaceObject.class);
+
+  /** . */
+  public static final ObjectType<Workspace> WORKSPACE = new ObjectType<Workspace>(Workspace.class);
+
+  /** . */
+  public static final ObjectType<Site> SITE = new ObjectType<Site>(Site.class);
+
+  /** . */
+  public static final ObjectType<Site> PORTAL_SITE = new ObjectType<Site>(Site.class, SITE);
+
+  /** . */
+  public static final ObjectType<Site> GROUP_SITE = new ObjectType<Site>(Site.class, SITE);
+
+  /** . */
+  public static final ObjectType<Site> USER_SITE = new ObjectType<Site>(Site.class, SITE);
+
+  /** . */
+  public static final ObjectType<Site> SHARED_SITE = new ObjectType<Site>(Site.class, SITE);
+
+  /** . */
+  public static final ObjectType<Page> PAGE = new ObjectType<Page>(Page.class);
+
+  /** . */
+  public static final ObjectType<Page> TEMPLATE = new ObjectType<Page>(Page.class, PAGE);
+
+  /** . */
+  public static final ObjectType<Page> CONFIGURATION = new ObjectType<Page>(Page.class, PAGE);
+
+  /** . */
+  public static final ObjectType<Page> CONTENT = new ObjectType<Page>(Page.class, PAGE);
+
+  /** . */
+  public static final ObjectType<Navigation> NAVIGATION = new ObjectType<Navigation>(Navigation.class);
+
+  /** . */
+  public static final ObjectType<UIComponent> COMPONENT = new ObjectType<UIComponent>(UIComponent.class);
+
+  /** . */
+  public static final ObjectType<UIBody> BODY = new ObjectType<UIBody>(UIBody.class, COMPONENT);
+
+  /** . */
+  public static final ObjectType<UIContainer> CONTAINER = new ObjectType<UIContainer>(UIContainer.class, COMPONENT);
+
+  /** . */
+  public static final ObjectType<UIWindow> WINDOW = new ObjectType<UIWindow>(UIWindow.class, COMPONENT);
+
+  /** . */
+  public static final ObjectType<PageLink> PAGE_LINK = new ObjectType<PageLink>(PageLink.class);
+
+  /** . */
+  public static final ObjectType<URLLink> URL_LINK = new ObjectType<URLLink>(URLLink.class);
+
+  /** . */
+  private final Class<O> javaType;
+
+  /** . */
+  private final Set<ObjectType<?>> superTypes;
+
+  private ObjectType(Class<O> javaType, ObjectType<?>... superTypes) {
+    for (ObjectType<?> superType : superTypes) {
+      if (!superType.javaType.isAssignableFrom(javaType)) {
+        throw new AssertionError();
+      }
+    }
+
+    //
+    Set<ObjectType<?>> tmp = new HashSet<ObjectType<?>>();
+    for (ObjectType<?> superType : superTypes) {
+      tmp.add(superType);
+    }
+
+    //
+    this.javaType = javaType;
+    this.superTypes = tmp;
+  }
+
+  public Class<O> getJavaType() {
+    return javaType;
+  }
+
+  public boolean isAssignableFrom(ObjectType<?> other) {
+    if (other == null) {
+      throw new NullPointerException();
+    }
+    if (this == ANY) {
+      return true;
+    }
+    return other == this || other.superTypes.contains(this);
+  }
+
+  public O cast(Object o) {
+    if (o == null) {
+      return null;
+    } if (javaType.isInstance(o)) {
+      return javaType.cast(o);
+    } else {
+      throw new ClassCastException();
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "ObjectType[" + javaType + "]";
+  }
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Page.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Page.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Page.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,127 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.link.PageLink;
+import org.gatein.mop.api.Attributes;
+
+import java.util.Collection;
+
+/**
+ * <p>A page is a pointer with useful information pointing to a component structure.</p>
+ *
+ * <p>Page can be organized as hierarchies  used for the single purpose of performing
+ * property inheritance. The pages of a same hierarchy belong to the same site.</p>
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Page extends TemplatizedObject, WorkspaceCustomizationContext {
+
+  /**
+   * Returns the page name.
+   *
+   * @return the page name
+   */
+  String getName();
+
+  /**
+   * Returns the page type.
+   *
+   * @return the page type
+   */
+  ObjectType<? extends Page> getObjectType();
+
+  /**
+   * Returns the page attributes.
+   *
+   * @return the attributes
+   */
+  Attributes getCascadingAttributes();
+
+  /**
+   * Returns the site that owns the page.
+   *
+   * @return the owner site
+   */
+  Site getSite();
+  
+  /**
+   * Returns the parent page
+   *
+   * @return the parent page
+   */
+  Page getParent();
+
+  /**
+   * Returns the children.
+   *
+   * @return the children
+   */
+  Collection<? extends Page> getChildren();
+
+  /**
+   * Returns a named child or null if it does not exist.
+   *
+   * @param name the child name
+   * @return a child
+   */
+  Page getChild(String name);
+
+  /**
+   * Create a child page and returns it.
+   *
+   * @param name the child name
+   * @return the child page
+   * @throws NullPointerException if the name is null
+   * @throws IllegalArgumentException if a child with such name already exists
+   */
+  Page addChild(String name) throws NullPointerException, IllegalArgumentException;
+
+  /**
+   * Returns the layout of the page. A layout is automatically when the page is created and is bound to the page
+   * life cycle.
+   *
+   * @return the page layout.
+   */
+  UIContainer getRootComponent();
+
+  /**
+   * Returns the set of navigations pointing to this page.
+   *
+   * @return the related navigations
+   */
+  Collection<PageLink> getNavigations();
+
+  /**
+   * Destroys the page.
+   */
+  void destroy();
+
+  /**
+   * Returns the templatized objects for this page.
+   *
+   * @param templatizedType the type of templatized
+   * @param <T> the templatized workspace object type parameter
+   * @return the collection of templatized objects
+   */
+  <T extends TemplatizedObject> Collection<? extends T> getTemplatizedObjects(ObjectType<T> templatizedType);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Site.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Site.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Site.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+/**
+ * A site is a collection of pages and navigations.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Site extends WorkspaceObject, WorkspaceCustomizationContext {
+
+  /**
+   * Returns the site id.
+   *
+   * @return the site id
+   */
+  String getObjectId();
+
+  /**
+   * Returns the site name.
+   *
+   * @return the site name
+   */
+  String getName();
+
+  /**
+   * Returns a type that extends the site.
+   *
+   * @return the objec type
+   */
+  ObjectType<? extends Site> getObjectType();
+
+  /**
+   * Returns the site root navigation.
+   *
+   * @return the site navigation
+   */
+  Navigation getRootNavigation();
+
+  /**
+   * Returns the site root page.
+   *
+   * @return the site root page
+   */
+  Page getRootPage();
+
+  /**
+   * Returns the site workspace.
+   *
+   * @return the site workspace
+   */
+  Workspace getWorkspace();
+
+  /**
+   * Destroy the site.
+   */
+  void destroy();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Templatized.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Templatized.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Templatized.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Templatized {
+
+  /**
+   * Returns the page template or null if no page template exists.
+   *
+   * @return the page template
+   */
+  Page getTemplate();
+
+  /**
+   * Updates the page template.
+   *
+   * @param template the page template
+   */
+  void setTemplate(Page template);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/TemplatizedObject.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/TemplatizedObject.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/TemplatizedObject.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+/**
+ * A workspace object that can use a template.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface TemplatizedObject extends WorkspaceObject, Templatized {
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Workspace.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Workspace.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/Workspace.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import java.util.Collection;
+
+/**
+ * The workspace.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Workspace extends WorkspaceObject, WorkspaceCustomizationContext {
+
+  /**
+   * Returns the default share site.
+   *
+   * @return the default shared site
+   */
+  Site getSharedSite();
+
+  /**
+   * Returns a specified site or null if it cannot be found.
+   *
+   * @param siteType the site type
+   * @param siteName the site name
+   * @return the site
+   */
+  <S extends Site> S getSite(ObjectType<S> siteType, String siteName);
+
+  /**
+   * Returns the sites of a given type.
+   *
+   * @param siteType the site type
+   * @return the sites
+   */
+  <S extends Site> Collection<S> getSites(ObjectType<S> siteType);
+
+  /**
+   * Returns all the sites.
+   *
+   * @return the sites
+   */
+  Collection<Site> getSites();
+
+  /**
+   * Creates a new site.
+   *
+   * @param siteType the site type
+   * @param name the site name
+   * @return the new site
+   */
+  <S extends Site> S addSite(ObjectType<S> siteType, String name);
+
+  /**
+   * Returns a specified object or null if it cannot be found.
+   *
+   * @param type the object type
+   * @param id the object id
+   * @param <O> the object type parameter
+   * @return the object
+   */
+  <O extends WorkspaceObject> O getObject(ObjectType<O> type, String id);
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceCustomizationContext.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceCustomizationContext.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceCustomizationContext.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+
+/**
+ * A workspace customization context define root customization contexts.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface WorkspaceCustomizationContext extends CustomizationContext {
+
+  /**
+   * The context type returned that must be returned by implementations of the {@link #getContextType()} method.
+   */
+  String TYPE = "workspace";
+
+  /**
+   * The root customization.
+   *
+   * @param name the customization name
+   * @return the root customization
+   */
+  Customization<?> getCustomization(String name);
+
+  /**
+   * Configure a root customization for the specified content.
+   *
+   * @param name the customization name
+   * @param contentType the content type
+   * @param contentId the content id
+   * @param state the customization state
+   * @param <S> the content state typa parameter
+   * @return the customization
+   */
+  <S> Customization<S> customize(String name, ContentType<S> contentType, String contentId, S state);
+
+  /**
+   * Configure a customization for extending the specified customization.
+   *
+   * @param name the customization name
+   * @param customization the customization to extend
+   * @param <S> the content state typa parameter
+   * @return the customization
+   */
+  <S> Customization<S> customize(String name, Customization<S> customization);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceObject.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceObject.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/WorkspaceObject.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace;
+
+import org.gatein.mop.api.Attributes;
+
+/**
+ * A common interface for object living in the workspace.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface WorkspaceObject {
+
+  /**
+   * Returns an id that uniquely identify the object in the workspace.
+   *
+   * @return the id
+   */
+  String getObjectId();
+
+  /**
+   * Returns the object type.
+   *
+   * @return the object type
+   */
+  ObjectType<? extends WorkspaceObject> getObjectType();
+
+  /**
+   * Returns the object attributes.
+   *
+   * @return the attributes
+   */
+  Attributes getAttributes();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/ContentLink.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/ContentLink.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/ContentLink.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.link;
+
+import org.gatein.mop.api.content.Content;
+
+/**
+ * A link to a content.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface ContentLink extends Link {
+
+  /**
+   * Returns the link to a content.
+   *
+   * @return the content
+   */
+  Content getContent();
+
+  /**
+   * Updates the content linked.
+   *
+   * @param content the content to link
+   */
+  void setContent(Content content);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/Link.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/Link.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/Link.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,30 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.link;
+
+import org.gatein.mop.api.workspace.WorkspaceObject;
+
+/**
+ * Symbolizes a link.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface Link extends WorkspaceObject {
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/PageLink.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/PageLink.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/PageLink.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.link;
+
+import org.gatein.mop.api.workspace.Page;
+
+/**
+ * A link to a page.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface PageLink extends Link {
+
+  /**
+   * The target page.
+   *
+   * @return the page
+   */
+  Page getPage();
+
+  /**
+   * Updates the target page.
+   *
+   * @param page the page to update
+   */
+  void setPage(Page page);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/URLLink.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/URLLink.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/link/URLLink.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,42 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.link;
+
+/**
+ * A link to an URL.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface URLLink extends Link {
+
+  /**
+   * Returns the link URL.
+   *
+   * @return the link URL
+   */
+  String getURL();
+
+  /**
+   * Sets the link URL.
+   *
+   * @param url the link URL
+   */
+  void setURL(String url);
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIBody.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIBody.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIBody.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.ui;
+
+/**
+ * The ui body denotes a place holder in a user interface structure. Usually it is used by template
+ * mechanisms.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface UIBody extends UIComponent {
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIComponent.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIComponent.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIComponent.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.ui;
+
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.WorkspaceObject;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface UIComponent extends WorkspaceObject {
+
+  String getName();
+
+  ObjectType<? extends UIComponent> getObjectType();
+
+  UIContainer getParent();
+  
+  Page getPage();
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIContainer.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIContainer.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.ui;
+
+import org.gatein.mop.api.workspace.ObjectType;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface UIContainer extends UIComponent {
+
+  Collection<? extends UIComponent> getChildren();
+
+  <T extends UIComponent> T addChild(ObjectType<T> componentType, String componentName);
+
+  UIComponent getChild(String componentName);
+
+  <T extends UIComponent> T getChild(ObjectType<T> componentType, String componentName);
+
+}

Added: components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIWindow.java
===================================================================
--- components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIWindow.java	                        (rev 0)
+++ components/mop/trunk/api/src/main/java/org/gatein/mop/api/workspace/ui/UIWindow.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,60 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.api.workspace.ui;
+
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+
+/**
+ * The window is user interface component that points to a content.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface UIWindow extends UIComponent, CustomizationContext {
+
+  /**
+   * Returns the customization of this window or null if no customization exists.
+   *
+   * @return the window customization
+   */
+  Customization<?> getCustomization();
+
+  /**
+   * Customizes the specified content.
+   *
+   * @param contentType the content type
+   * @param contentId the content id
+   * @param state the content state
+   * @param <S> the content type parameter
+   * @return the created customization
+   */
+  <S> Customization<S> customize(ContentType<S> contentType, String contentId, S state);
+
+  /**
+   * Specialize the specified customization.
+   *
+   * @param customization the customization to specialise
+   * @param <S> the content type parameter
+   * @return the created customization
+   */
+  <S> Customization<S> customize(Customization<S> customization);
+
+}

Added: components/mop/trunk/core/nul
===================================================================

Added: components/mop/trunk/core/pom.xml
===================================================================
--- components/mop/trunk/core/pom.xml	                        (rev 0)
+++ components/mop/trunk/core/pom.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,104 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <modelVersion>4.0.0</modelVersion>
+
+   <parent>
+      <groupId>org.gatein.mop</groupId>
+      <artifactId>mop.parent</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+      <relativePath>../parent/pom.xml</relativePath>
+   </parent>
+
+   <!-- ****************** -->
+   <!-- Project Definition -->
+   <!-- ****************** -->
+
+   <groupId>org.gatein.mop</groupId>
+   <artifactId>mop.core</artifactId>
+   <version>1.0.0-SNAPSHOT</version>
+   <packaging>jar</packaging>
+
+   <name>MOP Core</name>
+   <description>Model Object for Portal Core</description>
+
+   <scm>
+      <connection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/core/</connection>
+      <developerConnection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/core/</developerConnection>
+      <url>http://fisheye.exoplatform.org/browse/projects-internal/exorh/exo-portal/mop/trunk/core/</url>
+   </scm>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>org.gatein.mop</groupId>
+         <artifactId>mop.api</artifactId>
+         <version>1.0.0-SNAPSHOT</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.gatein.mop</groupId>
+         <artifactId>mop.spi</artifactId>
+         <version>1.0.0-SNAPSHOT</version>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.jcr</groupId>
+         <artifactId>jcr</artifactId>
+         <version>1.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.chromattic</groupId>
+         <artifactId>chromattic.api</artifactId>
+         <version>1.0.0-beta1</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.chromattic</groupId>
+         <artifactId>chromattic.core</artifactId>
+         <version>1.0.0-beta1</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.chromattic</groupId>
+         <artifactId>chromattic.apt</artifactId>
+         <version>1.0.0-beta1</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.chromattic</groupId>
+         <artifactId>chromattic.exo</artifactId>
+         <version>1.0.0-beta1</version>
+         <scope>test</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>junit</groupId>
+         <artifactId>junit</artifactId>
+         <version>3.8</version>
+         <scope>test</scope>
+      </dependency>
+
+   </dependencies>
+
+</project>

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPFormatter.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPFormatter.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPFormatter.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,146 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api;
+
+import org.chromattic.api.format.ObjectFormatter;
+import org.chromattic.api.format.FormatterContext;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class MOPFormatter implements ObjectFormatter {
+
+  private static boolean isSpecialChar(char c) {
+    return getCode(c) != null;
+  }
+
+  private static String getCode(char c) {
+    if (c == 0x9
+      || c == 0xA
+      ||  c == 0xD
+      || (c >= 0x20 && c <= 0xD7FF)
+      || (c >= 0xE000 && c <= 0xFFFD)
+      || (c >= 0x10000 && c <= 0x10FFFF)) {
+      switch (c) {
+        case '{':
+          return "00";
+        case '}':
+          return "01";
+        case '.':
+          return "02";
+        case '/':
+          return "03";
+        case ':':
+          return "04";
+        case '[':
+          return "05";
+        case ']':
+          return "06";
+        case '|':
+          return "07";
+        case '*':
+          return "08";
+        case '%':
+          return "09";
+        default:
+          return null;
+      }
+    } else {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  private static final char[] table = new char[] {
+    '{', '}', '.', '/', ':', '[', ']', '|', '*', '%'
+  };
+
+  private String decode(String s, int from) {
+    StringBuffer buffer = new StringBuffer(s.length());
+    buffer.append(s, 0, from);
+    int to = s.length();
+    while (from < to) {
+      char c = s.charAt(from++);
+      if (c == '%') {
+        if (from + 1 >= to) {
+          throw new IllegalStateException("Cannot decode wrong name " + s);
+        }
+        char c1 = s.charAt(from++);
+        if (c1 != '0') {
+          throw new IllegalStateException("Cannot decode wrong name " + s);
+        }
+        char c2 = s.charAt(from++);
+        if (c2 < '0' || c2 > '9') {
+          throw new IllegalStateException("Cannot decode wrong name " + s);
+        }
+        buffer.append(table[c2 - '0']);
+      } else {
+        buffer.append(c);
+      }
+    }
+    return buffer.toString();
+  }
+
+  public String decodeNodeName(FormatterContext context, String internalName) {
+    int length = internalName.length();
+    for (int i = 0;i < length;i++) {
+      char c = internalName.charAt(i);
+      if (c == '%') {
+        return decode(internalName, i);
+      }
+    }
+    return internalName;
+  }
+
+  private String encode(String s, int from) {
+    StringBuffer buffer = new StringBuffer((s.length() * 5) >> 2);
+    buffer.append(s, 0, from);
+    int to = s.length();
+    while (from < to) {
+      char c = s.charAt(from++);
+      String code = getCode(c);
+      if (code != null) {
+        buffer.append('%');
+        buffer.append(code);
+      } else {
+        buffer.append(c);
+      }
+    }
+    return buffer.toString();
+  }
+
+  public String encodeNodeName(FormatterContext context, String externalName) {
+    int length = externalName.length();
+    for (int i = 0;i < length;i++) {
+      char c = externalName.charAt(i);
+      if (isSpecialChar(c)) {
+        return encode(externalName, i);
+      }
+    }
+    return externalName;
+  }
+
+  public String decodePropertyName(FormatterContext context, String internalName) {
+    return internalName;
+  }
+
+  public String encodePropertyName(FormatterContext context, String externalName) {
+    return externalName;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPService.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPService.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/MOPService.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,138 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api;
+
+import org.chromattic.api.ChromatticBuilder;
+import org.chromattic.api.Chromattic;
+import org.chromattic.api.ChromatticSession;
+import org.gatein.mop.core.api.workspace.WorkspaceImpl;
+import org.gatein.mop.core.api.workspace.UIContainerImpl;
+import org.gatein.mop.core.api.workspace.UIWindowImpl;
+import org.gatein.mop.core.api.workspace.UIBodyImpl;
+import org.gatein.mop.core.api.workspace.PageImpl;
+import org.gatein.mop.core.api.workspace.NavigationImpl;
+import org.gatein.mop.core.api.workspace.PageLinkImpl;
+import org.gatein.mop.core.api.workspace.URLLinkImpl;
+import org.gatein.mop.core.api.workspace.PortalSiteContainer;
+import org.gatein.mop.core.api.workspace.PortalSite;
+import org.gatein.mop.core.api.workspace.GroupSiteContainer;
+import org.gatein.mop.core.api.workspace.GroupSite;
+import org.gatein.mop.core.api.workspace.PageContainer;
+import org.gatein.mop.core.api.workspace.NavigationContainer;
+import org.gatein.mop.core.api.workspace.UserSiteContainer;
+import org.gatein.mop.core.api.workspace.UserSite;
+import org.gatein.mop.core.api.workspace.content.CustomizationContainer;
+import org.gatein.mop.core.api.workspace.content.ContextType;
+import org.gatein.mop.core.api.workspace.content.ContextTypeContainer;
+import org.gatein.mop.core.api.workspace.content.ContextSpecialization;
+import org.gatein.mop.core.api.workspace.content.WorkspaceClone;
+import org.gatein.mop.core.api.workspace.content.WorkspaceSpecialization;
+import org.gatein.mop.core.api.workspace.content.portlet.PortletPreferencesState;
+import org.gatein.mop.core.api.workspace.content.portlet.PortletPreferenceState;
+import org.gatein.mop.core.api.content.ContentManagerRegistry;
+import org.gatein.mop.core.api.content.CustomizationContextProviderRegistry;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class MOPService {
+
+  /** . */
+  private Chromattic chrome;
+
+  /** . */
+  private ContentManagerRegistry contentManagerRegistry;
+
+  /** . */
+  private CustomizationContextProviderRegistry customizationContextResolvers;
+
+  /** . */
+  private final ChromatticBuilder builder;
+
+  public MOPService() {
+    ChromatticBuilder builder = ChromatticBuilder.create();
+//    builder.setOption(ChromatticBuilder.INSTRUMENTOR_CLASSNAME, "org.chromattic.cglib.CGLibInstrumentor");
+    builder.setOption(ChromatticBuilder.INSTRUMENTOR_CLASSNAME, "org.chromattic.apt.InstrumentorImpl");
+    builder.setOption(ChromatticBuilder.OBJECT_NAME_FORMATTER_CLASSNAME, MOPFormatter.class.getName());
+
+    //
+    this.builder = builder;
+  }
+
+  public <T> void setOption(ChromatticBuilder.Option<T> option, T value) {
+    builder.setOption(option, value);
+  }
+
+  public CustomizationContextProviderRegistry getCustomizationContextResolvers() {
+    return customizationContextResolvers;
+  }
+
+  public ContentManagerRegistry getContentManagerRegistry() {
+    return contentManagerRegistry;
+  }
+
+  public void start() throws Exception {
+    builder.add(WorkspaceImpl.class);
+    builder.add(UIContainerImpl.class);
+    builder.add(UIWindowImpl.class);
+    builder.add(UIBodyImpl.class);
+    builder.add(PageImpl.class);
+    builder.add(PageContainer.class);
+    builder.add(NavigationImpl.class);
+    builder.add(NavigationContainer.class);
+    builder.add(PageLinkImpl.class);
+    builder.add(URLLinkImpl.class);
+    builder.add(PortalSiteContainer.class);
+    builder.add(PortalSite.class);
+    builder.add(GroupSiteContainer.class);
+    builder.add(GroupSite.class);
+    builder.add(UserSiteContainer.class);
+    builder.add(UserSite.class);
+
+    //
+    builder.add(CustomizationContainer.class);
+    builder.add(ContextTypeContainer.class);
+    builder.add(ContextType.class);
+    builder.add(ContextSpecialization.class);
+    builder.add(WorkspaceClone.class);
+    builder.add(WorkspaceSpecialization.class);
+    builder.add(PortletPreferencesState.class);
+    builder.add(PortletPreferenceState.class);
+
+    //
+    chrome = builder.build();
+    
+    //
+    CustomizationContextProviderRegistry customizationContextResolvers = new CustomizationContextProviderRegistry();
+
+    //
+    this.chrome = builder.build();
+    this.contentManagerRegistry = new ContentManagerRegistry();
+    this.customizationContextResolvers = customizationContextResolvers;
+  }
+
+  public ModelImpl getModel() {
+    ChromatticSession chromeSession = chrome.openSession();
+    return new ModelImpl(
+      chromeSession,
+      contentManagerRegistry,
+      customizationContextResolvers);
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/ModelImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/ModelImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/ModelImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api;
+
+import org.gatein.mop.core.api.content.ContentManagerImpl;
+import org.gatein.mop.core.api.content.ContentManagerRegistry;
+import org.gatein.mop.core.api.content.CustomizationContextProviderRegistry;
+import org.gatein.mop.core.api.content.CustomizationContextResolver;
+import org.gatein.mop.core.api.workspace.WorkspaceImpl;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.core.api.workspace.UIWindowImpl;
+import org.gatein.mop.core.api.workspace.content.ContextSpecialization;
+import org.gatein.mop.core.api.workspace.content.WorkspaceClone;
+import org.gatein.mop.api.content.ContentManager;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.WorkspaceObject;
+import org.gatein.mop.api.Model;
+import org.chromattic.api.LifeCycleListener;
+import org.chromattic.api.ChromatticSession;
+import org.chromattic.api.query.QueryLanguage;
+import org.chromattic.api.query.Query;
+
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ModelImpl implements Model {
+
+  /** . */
+  private final ChromatticSession session;
+
+  /** . */
+  private final ContentManagerRegistry contentManagers;
+
+  /** . */
+  private final CustomizationContextProviderRegistry customizationContextResolvers;
+
+  /** . */
+  private final ContentManagerImpl contentManager;
+
+  /** . */
+  private WorkspaceImpl workspace;
+
+  /** . */
+  private final CustomizationContextResolver customizationContextResolver = new CustomizationContextResolver() {
+    public CustomizationContext resolve(String contextType, String contextId) {
+      if (WorkspaceCustomizationContext.TYPE.equals(contextType)) {
+        return getWorkspace().getObject(ObjectType.WINDOW, contextId);
+      } else {
+        return customizationContextResolvers.resolve(contextType, contextId);
+      }
+    }
+  };
+
+  public ModelImpl(ChromatticSession session, ContentManagerRegistry contentManagers, CustomizationContextProviderRegistry customizationContextResolvers) {
+
+    //
+    this.session = session;
+    this.contentManagers = contentManagers;
+    this.customizationContextResolvers = customizationContextResolvers;
+    this.contentManager = new ContentManagerImpl(contentManagers, customizationContextResolvers, session);
+
+    //
+    session.addLifeCycleListener(contextualizer);
+  }
+
+  public Workspace getWorkspace() {
+    return getWorkspaceImpl();
+  }
+
+  private WorkspaceImpl getWorkspaceImpl() {
+    if (workspace == null) {
+      workspace = session.findByPath(WorkspaceImpl.class, "workspace");
+      if (workspace == null) {
+        workspace = session.insert(WorkspaceImpl.class, "workspace");
+      }
+    }
+    return workspace;
+  }
+
+  public ContentManager getContentManager() {
+    return contentManager;
+  }
+
+  public void save() {
+    session.save();
+  }
+
+  public void close() {
+    session.close();
+  }
+
+  private final LifeCycleListener<Object> contextualizer = new LifeCycleListener<Object>() {
+    public void created(Object o) {
+      inject(o, false);
+    }
+    public void loaded(Object o) {
+      inject(o, true);
+    }
+    public void persisted(Object o) {
+      inject(o, true);
+    }
+    public void removed(Object o) {
+    }
+  };
+
+  public <O extends WorkspaceObject> Iterator<O> findObject(ObjectType<O> type, String statement) {
+    Query q = session.createQuery(QueryLanguage.SQL, statement);
+    return q.execute(type.getJavaType());
+  }
+
+  public String getPath(Object o) {
+    return session.getPath(o);
+  }
+
+  private void inject(Object o, boolean persistent) {
+    if (o instanceof UIWindowImpl) {
+      ((UIWindowImpl)o).setContentManager(contentManager);
+    } else if (o instanceof ContextSpecialization) {
+        ((ContextSpecialization)o).setCustomizationContextResolver(customizationContextResolver);
+    } else if (o instanceof WorkspaceClone && persistent) {
+      ((WorkspaceClone)o).registry = contentManagers;
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ComparisonException.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ComparisonException.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ComparisonException.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ComparisonException extends RuntimeException {
+
+  public ComparisonException() {
+  }
+
+  public ComparisonException(String message) {
+    super(message);
+  }
+
+  public ComparisonException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public ComparisonException(Throwable cause) {
+    super(cause);
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.api.content.ContentManager;
+import org.gatein.mop.api.content.Content;
+import org.gatein.mop.api.content.ContentType;
+import org.chromattic.api.ChromatticSession;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ContentManagerImpl implements ContentManager {
+
+  /** . */
+  final ContentManagerRegistry contentManagers;
+
+  /** . */
+  final CustomizationContextProviderRegistry customizationContextResolvers;
+
+  /** . */
+  private final ChromatticSession session;
+
+  public ContentManagerImpl(
+    ContentManagerRegistry contentManagers,
+    CustomizationContextProviderRegistry customizationContextResolvers,
+    ChromatticSession session) {
+
+    //
+    this.contentManagers = contentManagers;
+    this.session = session;
+    this.customizationContextResolvers = customizationContextResolvers;
+  }
+
+  public <S> Content<S> getContent(ContentType<S> contentType, String contentId) {
+    throw new UnsupportedOperationException();
+  }
+
+  public Content<?> getContent(String mimeType, String contentId) {
+    throw new UnsupportedOperationException();
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerRegistry.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerRegistry.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentManagerRegistry.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.spi.content.ContentProvider;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * A global registry.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ContentManagerRegistry {
+
+  /** The various providers. */
+  public final transient Map<String, ContentRegistration> providers;
+
+  public ContentManagerRegistry() {
+    providers = new HashMap<String, ContentRegistration>();
+  }
+
+  public synchronized void register(ContentType<?> contentType, ContentProvider contentProvider) {
+    if (contentType == null) {
+      throw new NullPointerException();
+    }
+    if (contentProvider == null) {
+      throw new NullPointerException();
+    }
+    providers.put(contentType.getMimeType(), new ContentRegistration(contentType, contentProvider));
+  }
+
+  public synchronized void unregister(ContentType contentType) {
+    if (contentType == null) {
+      throw new NullPointerException();
+    }
+    providers.remove(contentType.getMimeType());
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentRegistration.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentRegistration.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/ContentRegistration.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.spi.content.ContentProvider;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ContentRegistration {
+
+  /** . */
+  private final ContentType<?> contentType;
+
+  /** . */
+  private final ContentProvider provider;
+
+  public ContentRegistration(ContentType<?> contentType, ContentProvider provider) {
+    this.contentType = contentType;
+    this.provider = provider;
+  }
+
+  public ContentType<?> getContentType() {
+    return contentType;
+  }
+
+  public ContentProvider getProvider() {
+    return provider;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextComparator.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextComparator.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextComparator.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.api.content.CustomizationContext;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Arrays;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class CustomizationContextComparator implements Comparator<CustomizationContext> {
+
+  /** . */
+  private List<String> contextOrder;
+
+  public CustomizationContextComparator(List<String> contextOrder) {
+    this.contextOrder = contextOrder;
+  }
+
+  public CustomizationContextComparator(String... contextOrder) {
+    this(Arrays.asList(contextOrder));
+  }
+
+  public int compare(CustomizationContext c1, CustomizationContext c2) {
+    String t1 = c1.getContextType();
+    int i1 = contextOrder.indexOf(t1);
+    if (i1 == -1) {
+      throw new ComparisonException("Context type " + t1 + " cannot be used for comparison");
+    }
+
+    //
+    String t2 = c2.getContextType();
+    int i2 = contextOrder.indexOf(t2);
+    if (i2 == -1) {
+      throw new ComparisonException("Context type " + t1 + " cannot be used for comparison");
+    }
+
+    //
+    if (i1 < i2) {
+      return -1;
+    } else if (i1 > i2) {
+      return 1;
+    }
+
+    //
+    if (c1.contains(c2)) {
+      if (c2.contains(c1)) {
+        return 0;
+      } else {
+        return -1;
+      }
+    } else {
+      if (c2.contains(c1)) {
+        return 1;
+      } else {
+        throw new ComparisonException("Cannot compare customization contexts " + c1 + " and " + c2);
+      }
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextProviderRegistry.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextProviderRegistry.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextProviderRegistry.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.spi.customization.CustomizationContextProvider;
+import org.gatein.mop.api.content.CustomizationContext;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * A global registry.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class CustomizationContextProviderRegistry implements CustomizationContextResolver {
+
+  /** The various providers. */
+  final transient Map<String, CustomizationContextProvider> resolvers;
+
+  public CustomizationContextProviderRegistry() {
+    resolvers = new HashMap<String, CustomizationContextProvider>();
+  }
+
+  public synchronized void register(String contextType, CustomizationContextProvider contentProvider) {
+    if (contextType == null) {
+      throw new NullPointerException();
+    }
+    if (contentProvider == null) {
+      throw new NullPointerException();
+    }
+    resolvers.put(contextType, contentProvider);
+  }
+
+  public synchronized void unregister(String contextType) {
+    if (contextType == null) {
+      throw new NullPointerException();
+    }
+    resolvers.remove(contextType);
+  }
+
+  public CustomizationContext resolve(String contextType, String contextId) {
+    if (contextType == null) {
+      throw new NullPointerException();
+    }
+    if (contextId == null) {
+      throw new NullPointerException();
+    }
+
+    //
+    CustomizationContextProvider provider = resolvers.get(contextType);
+
+    //
+    if (provider != null) {
+      return provider.resolveContext(contextId);
+    }
+
+    //
+    return null;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextResolver.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextResolver.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/content/CustomizationContextResolver.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.api.content.CustomizationContext;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface CustomizationContextResolver {
+
+  CustomizationContext resolve(String contextType, String contextId);
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSite.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSite.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSite.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.core.api.workspace.SiteImpl;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:groupsite")
+public abstract class GroupSite extends SiteImpl {
+
+  // Site implementation ***********************************************************************************************
+
+  public ObjectType<? extends Site> getObjectType() {
+    return ObjectType.GROUP_SITE;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSiteContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSiteContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/GroupSiteContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.gatein.mop.core.api.workspace.SiteContainer;
+import org.gatein.mop.core.api.workspace.WorkspaceImpl;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:groupsites")
+public abstract class GroupSiteContainer extends SiteContainer<GroupSite> {
+
+  @RelatedMappedBy("groupsites")
+  public abstract WorkspaceImpl getWorkspace();
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/LinkImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/LinkImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/LinkImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.api.workspace.link.Link;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class LinkImpl extends WorkspaceObjectImpl implements Link {
+
+  public abstract ObjectType<? extends Link> getObjectType();
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.Create;
+import org.chromattic.api.annotations.RelatedMappedBy;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:navigationcontainer")
+public abstract class NavigationContainer {
+
+  @OneToOne
+  @RelatedMappedBy("navigations")
+  public abstract NavigationImpl getOwner();
+
+  @OneToMany
+  public abstract Map<String, NavigationImpl> getNavigations();
+
+  @Create
+  public abstract NavigationImpl createNavigation();
+
+  public NavigationImpl addNavigation(String name) {
+    NavigationImpl page = createNavigation();
+    getNavigations().put(name, page);
+    return page;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/NavigationImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,146 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.Create;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.Destroy;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.chromattic.api.RelationshipType;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.link.Link;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.link.PageLink;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:navigation")
+public abstract class NavigationImpl extends WorkspaceObjectImpl implements Navigation {
+
+  @OneToOne
+  @RelatedMappedBy("rootnavigation")
+  public abstract SiteImpl getParentSite();
+
+  @OneToOne
+  @MappedBy("children")
+  public abstract NavigationContainer getChildrenContainer();
+
+  @ManyToOne
+  public abstract NavigationContainer getParentContainer();
+
+  @OneToOne
+  @MappedBy("link")
+  public abstract LinkImpl getLink();
+
+  public abstract LinkImpl setLink(LinkImpl target);
+
+  @Create
+  public abstract NavigationImpl createNavigation(String name);
+
+  @Create
+  public abstract URLLinkImpl createURLTarget();
+
+  @Create
+  public abstract PageLinkImpl createPageLink();
+
+  @ManyToOne(type = RelationshipType.PATH)
+  @MappedBy("template")
+  public abstract PageImpl getPageTemplate();
+
+  public abstract void setPageTemplate(PageImpl template);
+
+  @Destroy
+  public abstract void destroy();
+
+  public ObjectType<? extends Navigation> getObjectType() {
+    return ObjectType.NAVIGATION;
+  }
+
+  public Page getTemplate() {
+    return getPageTemplate();
+  }
+
+  public void setTemplate(Page template) {
+    setPageTemplate((PageImpl)template);
+  }
+
+  public Navigation getParent() {
+    NavigationContainer parent = getParentContainer();
+    if (parent != null) {
+      return parent.getOwner();
+    } else {
+      return null;
+    }
+  }
+
+  public Collection<? extends Navigation> getChildren() {
+    NavigationContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.getNavigations().values();
+  }
+
+  public Navigation getChild(String name) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    NavigationContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.getNavigations().get(name);
+  }
+
+  public NavigationImpl addChild(String name) {
+    NavigationContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.addNavigation(name);
+  }
+
+  public <L extends Link> L linkTo(ObjectType<L> linkType) {
+    setLink(null);
+
+    //
+    L link = null;
+    if (linkType != null) {
+      if (linkType.getJavaType().equals(PageLink.class)) {
+        PageLinkImpl pl = createPageLink();
+        setLink(pl);
+        link = (L)pl;
+      } else {
+        throw new UnsupportedOperationException("Links of type " + linkType + " are not supported");
+      }
+    }
+
+    //
+    return link;
+  }
+
+  public Site getSite() {
+    SiteImpl parent = getParentSite();
+    if (parent != null) {
+      return parent;
+    } else {
+      return getParent().getSite();
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.Create;
+import org.chromattic.api.annotations.RelatedMappedBy;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:pagecontainer")
+public abstract class PageContainer {
+
+  @OneToOne
+  @RelatedMappedBy("pages")
+  public abstract PageImpl getOwner();
+
+  @OneToMany
+  public abstract Map<String, PageImpl> getPages();
+
+  @Create
+  public abstract PageImpl createPage();
+
+  public PageImpl addPage(String name) {
+    PageImpl page = createPage();
+    getPages().put(name, page);
+    return page;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,221 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.Destroy;
+import org.chromattic.api.RelationshipType;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.WorkspaceObject;
+import org.gatein.mop.api.workspace.TemplatizedObject;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.api.workspace.link.PageLink;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.api.Attributes;
+import org.gatein.mop.core.util.AbstractAttributes;
+import org.gatein.mop.core.api.workspace.content.CustomizationContainer;
+
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:page")
+public abstract class PageImpl extends WorkspaceObjectImpl implements Page, WorkspaceCustomizationContext {
+
+  /** . */
+  private final Attributes cascadingAttributes = new AbstractAttributes() {
+    public Set<String> getKeys() {
+      throw new UnsupportedOperationException("todo ?");
+    }
+    protected Object get(String name) {
+      return getCascadedPropertyValue(name);
+    }
+    protected void set(String name, Object o) {
+      throw new UnsupportedOperationException("read only");
+    }
+  };
+
+  @ManyToOne(type = RelationshipType.PATH)
+  @MappedBy("template")
+  public abstract PageImpl getPageTemplate();
+
+  public abstract void setPageTemplate(PageImpl template);
+
+  @OneToMany(type = RelationshipType.PATH)
+  @RelatedMappedBy("template")
+  public abstract Collection<NavigationImpl> getTemplatizedNavigations();
+
+  @OneToMany(type = RelationshipType.PATH)
+  @RelatedMappedBy("template")
+  public abstract Collection<PageImpl> getTemplatizedPages();
+
+  @OneToMany(type = RelationshipType.PATH)
+  @RelatedMappedBy("template")
+  public abstract Collection<? extends WorkspaceObject> getTemplatizedObjects();
+
+  @OneToOne
+  @MappedBy("children")
+  public abstract PageContainer getChildrenContainer();
+
+  @OneToOne
+  @RelatedMappedBy("children")
+  public abstract PageContainer getParentContainer();
+
+  @OneToOne
+  @RelatedMappedBy("rootpage")
+  public abstract SiteImpl getSiteParent();
+
+  @OneToOne
+  @MappedBy("rootcomponent")
+  public abstract UIContainerImpl getRootComponent();
+
+  @Destroy
+  public abstract void destroy();
+
+  @OneToOne
+  @MappedBy("customizations")
+  public abstract CustomizationContainer getCustomizations();
+
+  // WorkspaceCustomizationContext implementation **********************************************************************
+
+  public String getContextType() {
+    return WorkspaceCustomizationContext.TYPE;
+  }
+
+  public String getContextId() {
+    return getObjectId();
+  }
+
+  public boolean contains(CustomizationContext that) {
+    return contains(this, that);
+  }
+
+  public Customization<?> getCustomization(String name) {
+    return getCustomizations().getCustomization(name);
+  }
+
+  public <S> Customization<S> customize(String name, ContentType<S> contentType, String contentId, S state) {
+    return getCustomizations().customize(name, contentType, contentId, state);
+  }
+
+  public <S> Customization<S> customize(String name, Customization<S> customization) {
+    return getCustomizations().customize(name, customization);
+  }
+
+  // *******************************************************************************************************************
+
+  public <T extends TemplatizedObject> Collection<? extends T> getTemplatizedObjects(ObjectType<T> templatizedType) {
+    if (Page.class.equals(templatizedType.getJavaType())) {
+      ArrayList bilto = new ArrayList();
+      for (Page page : getTemplatizedPages()) {
+        bilto.add(page);
+      }
+      return bilto;
+    } else if (Navigation.class.isAssignableFrom(templatizedType.getJavaType())) {
+      ArrayList bilto = new ArrayList();
+      for (Navigation page : getTemplatizedNavigations()) {
+        bilto.add(page);
+      }
+      return bilto;
+    } else {
+      throw new IllegalArgumentException("Unaccepted templatized type");
+    }
+  }
+
+  public ObjectType<? extends Page> getObjectType() {
+    return ObjectType.PAGE;
+  }
+
+  public Attributes getCascadingAttributes() {
+    return cascadingAttributes;
+  }
+
+  public SiteImpl getSite() {
+    PageContainer parent = getParentContainer();
+    if (parent != null) {
+      return parent.getOwner().getSite();
+    } else {
+      return getSiteParent();
+    }
+  }
+
+  public PageImpl getParent() {
+    PageContainer parent = getParentContainer();
+    if (parent != null) {
+      return parent.getOwner();
+    } else {
+      return null;
+    }
+  }
+
+  public PageImpl addChild(String name) throws NullPointerException, IllegalArgumentException {
+    PageContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.addPage(name);
+  }
+
+  public Collection<? extends Page> getChildren() {
+    PageContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.getPages().values(); 
+  }
+
+  public PageImpl getChild(String name) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    PageContainer childrenContainer = getChildrenContainer();
+    return childrenContainer.getPages().get(name);
+  }
+
+  public Collection<PageLink> getNavigations() {
+    throw new UnsupportedOperationException();
+  }
+
+  public void setTemplate(Page template) {
+    setPageTemplate((PageImpl)template);
+  }
+
+  public Page getTemplate() {
+    return getPageTemplate();
+  }
+
+  private Object getCascadedPropertyValue(String propertyName) {
+    Attributes attributes = getAttributes();
+    Object value = attributes.getObject(propertyName);
+    if (value == null) {
+      PageImpl parent = getParent();
+      if (parent != null) {
+        value = parent.getCascadedPropertyValue(propertyName);
+      }
+    }
+    return value;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageLinkImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageLinkImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PageLinkImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.Property;
+import org.chromattic.api.annotations.Path;
+import org.chromattic.api.RelationshipType;
+import org.gatein.mop.api.workspace.link.PageLink;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:pagelink")
+public abstract class PageLinkImpl extends LinkImpl implements PageLink {
+
+  @ManyToOne(type = RelationshipType.PATH)
+  @MappedBy("page")
+  public abstract PageImpl getPage();
+
+  public abstract void setPage(PageImpl page);
+
+  @Path
+  @Property(name = "path")
+  public abstract String getPathPath();
+
+  public abstract void setPagePath(String path);
+
+  public void setPage(Page page) {
+    setPage((PageImpl)page);
+  }
+
+  public ObjectType<? extends PageLink> getObjectType() {
+    return ObjectType.PAGE_LINK;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSite.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSite.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSite.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:portalsite")
+public abstract class PortalSite extends SiteImpl {
+
+  // Site implementation ***********************************************************************************************
+
+  public ObjectType<? extends Site> getObjectType() {
+    return ObjectType.PORTAL_SITE;
+  }
+
+  // Portal implementation *********************************************************************************************
+
+  public String getSkinId() {
+    throw new UnsupportedOperationException();
+  }
+
+  public String getTitle() {
+    throw new UnsupportedOperationException();
+  }
+
+  public String getLocale() {
+    throw new UnsupportedOperationException();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSiteContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSiteContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/PortalSiteContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.gatein.mop.core.api.workspace.SiteContainer;
+import org.gatein.mop.core.api.workspace.WorkspaceImpl;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:portalsites")
+public abstract class PortalSiteContainer extends SiteContainer<PortalSite> {
+
+  @RelatedMappedBy("portalsites")
+  public abstract WorkspaceImpl getWorkspace();
+  
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSite.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSite.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSite.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.core.api.workspace.SiteImpl;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:sharedsite")
+public abstract class SharedSite extends SiteImpl {
+
+  // Site implementation ***********************************************************************************************
+
+  public ObjectType<? extends Site> getObjectType() {
+    return ObjectType.SHARED_SITE;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSiteContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSiteContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SharedSiteContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.gatein.mop.core.api.workspace.SiteContainer;
+import org.gatein.mop.core.api.workspace.WorkspaceImpl;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:sharedsites")
+public abstract class SharedSiteContainer extends SiteContainer<SharedSite> {
+
+  @RelatedMappedBy("sharedsites")
+  public abstract WorkspaceImpl getWorkspace();
+
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.Create;
+import org.gatein.mop.api.workspace.Site;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class SiteContainer<T extends Site> {
+
+  @OneToMany
+  public abstract Map<String, T> getSites();
+
+  @OneToOne
+  public abstract WorkspaceImpl getWorkspace();
+
+  public T addSite(String siteName) {
+    T site = createSite();
+    getSites().put(siteName, site);
+    return site;
+  }
+
+  @Create
+  public abstract T createSite();
+
+  public T getSite(String name) {
+    Map<String, T> sites = getSites();
+    return sites.get(name);
+  }
+
+  public Collection<T> getAllSites() {
+    Map<String, T> sites = getSites();
+    return sites.values();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/SiteImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.Destroy;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.core.api.workspace.content.CustomizationContainer;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class SiteImpl extends WorkspaceObjectImpl implements Site, WorkspaceCustomizationContext {
+
+  @OneToOne
+  @MappedBy("rootpage")
+  public abstract PageImpl getRoot();
+
+  @OneToOne
+  @MappedBy("rootnavigation")
+  public abstract NavigationImpl getRootNavigation();
+
+  @ManyToOne
+  public abstract SiteContainer getSites();
+
+  @Destroy
+  public abstract void destroy();
+
+  @OneToOne
+  @MappedBy("customizations")
+  public abstract CustomizationContainer getCustomizations();
+
+  public abstract ObjectType<? extends Site> getObjectType();
+
+  // Site implementation ***********************************************************************************************
+
+  public WorkspaceImpl getWorkspace() {
+    SiteContainer sites = getSites();
+    return sites.getWorkspace();
+  }
+
+  public Page getRootPage() {
+    return getRoot();
+  }
+
+  // WorkspaceCustomizationContext implementation **********************************************************************
+
+  public String getContextType() {
+    return WorkspaceCustomizationContext.TYPE;
+  }
+
+  public String getContextId() {
+    return getObjectId();
+  }
+
+  public boolean contains(CustomizationContext that) {
+    return contains(this, that);
+  }
+
+  public Customization<?> getCustomization(String name) {
+    return getCustomizations().getCustomization(name);
+  }
+
+  public <S> Customization<S> customize(String name, ContentType<S> contentType, String contentId, S state) {
+    return getCustomizations().customize(name, contentType, contentId, state);
+  }
+
+  public <S> Customization<S> customize(String name, Customization<S> customization) {
+    return getCustomizations().customize(name, customization);
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIBodyImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIBodyImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIBodyImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.api.workspace.ui.UIBody;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:uibody")
+public abstract class UIBodyImpl extends UIComponentImpl implements UIBody {
+
+  public ObjectType<? extends UIBody> getObjectType() {
+    return ObjectType.BODY;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIComponentImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIComponentImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIComponentImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.chromattic.api.annotations.ManyToOne;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class UIComponentImpl extends WorkspaceObjectImpl implements UIComponent {
+
+  @ManyToOne
+  public abstract UIContainerImpl getParentContainer();
+
+  @ManyToOne
+  public abstract PageImpl getParentPage();
+
+  public abstract ObjectType<? extends UIComponent> getObjectType();
+
+  public final UIContainerImpl getParent() {
+    return getParentContainer();
+  }
+
+  public final PageImpl getPage() {
+    UIContainerImpl container = getParentContainer();
+    if (container != null) {
+      return container.getPage();
+    } else {
+      return getParentPage();
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIContainerImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIContainerImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIContainerImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.Create;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ObjectType;
+
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:uicontainer")
+public abstract class UIContainerImpl extends UIComponentImpl implements UIContainer {
+
+  @Create
+  public abstract UIContainerImpl createContainer();
+
+  @Create
+  public abstract UIBodyImpl createInsertion();
+
+  @Create
+  public abstract UIWindowImpl createWindow();
+
+  @OneToMany
+  public abstract Map<String, UIComponentImpl> getComponents();
+
+  public ObjectType<? extends UIContainer> getObjectType() {
+    return ObjectType.CONTAINER;
+  }
+
+  public UIComponent getChild(String componentName) {
+    Map<String, UIComponentImpl> children = getComponents();
+    return children.get(componentName);
+  }
+
+  public <T extends UIComponent> T addChild(ObjectType<T> componentType, String name) {
+    UIComponentImpl child;
+    if (componentType == ObjectType.WINDOW) {
+      child = createWindow();
+    } else if (componentType == ObjectType.CONTAINER) {
+      child = createContainer();
+    } else if (componentType == ObjectType.BODY) {
+      child = createInsertion();
+    } else {
+      throw new UnsupportedOperationException();
+    }
+    Map<String, UIComponentImpl> children = getComponents();
+    children.put(name, child);
+    return componentType.cast(child);
+  }
+
+  public Collection<? extends UIComponent> getChildren() {
+    return getComponents().values();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIWindowImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIWindowImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UIWindowImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,130 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.Create;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.api.content.ContentManager;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.core.api.workspace.content.WorkspaceClone;
+import org.gatein.mop.core.api.workspace.content.WorkspaceSpecialization;
+import org.gatein.mop.core.api.workspace.content.WorkspaceCustomization;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:uiwindow")
+public abstract class UIWindowImpl extends UIComponentImpl implements UIWindow, CustomizationContext {
+
+  /** The content manager. */
+  private ContentManager contentManager;
+
+  public ContentManager getContentManager() {
+    return contentManager;
+  }
+
+  public void setContentManager(ContentManager contentManager) {
+    this.contentManager = contentManager;
+  }
+
+  public ObjectType<? extends UIWindow> getObjectType() {
+    return ObjectType.WINDOW;
+  }
+
+  // Abstract **********************************************************************************************************
+
+  @OneToOne
+  @MappedBy("customization")
+  public abstract WorkspaceCustomization getCustomization();
+
+  public abstract void setCustomization(WorkspaceCustomization customization);
+
+/*
+  @ManyToOne(type = RelationshipType.PATH)
+  @MappedBy("relatedcustomization")
+  public abstract Customization getRelatedCustomization();
+
+  public abstract void setRelatedCustomization(Customization relatedCustomization);
+*/
+
+  @Create
+  public abstract WorkspaceClone create();
+
+  @Create
+  public abstract WorkspaceSpecialization create2();
+
+  // UIWindow implementation *******************************************************************************************
+
+  public <S> Customization<S> customize(ContentType<S> contentType, String contentId, S state) {
+    if (getCustomization() != null) {
+      throw new IllegalStateException("Already customized");
+    }
+/*
+    if (getRelatedCustomization() != null) {
+      throw new IllegalStateException("Referencing a customization context");
+    }
+*/
+    WorkspaceClone customization = create();
+    setCustomization(customization);
+    customization.setMimeType(contentType.getMimeType());
+    customization.setContentId(contentId);
+    customization.setState(state);
+    return (Customization<S>)customization;
+  }
+
+  public <S> Customization<S> customize(Customization<S> customization) {
+    if (customization == null) {
+      throw new NullPointerException();
+    } else if (customization instanceof WorkspaceCustomization) {
+      if (getCustomization() != null) {
+        throw new IllegalStateException("Already customized");
+      }
+
+      //
+      WorkspaceSpecialization specialization = create2();
+      setCustomization(specialization);
+      specialization.setCustomization((WorkspaceCustomization)customization);
+      return (Customization<S>)specialization;
+    } else {
+      throw new IllegalArgumentException("implement customization of "+ customization);
+    }
+  }
+
+  // WorkspaceCustomizationContext implementation **********************************************************************
+
+  public String getContextType() {
+    return WorkspaceCustomizationContext.TYPE;
+  }
+
+  public String getContextId() {
+    return getObjectId();
+  }
+
+  public boolean contains(CustomizationContext that) {
+    return contains(this, that);
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/URLLinkImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/URLLinkImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/URLLinkImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.Property;
+import org.gatein.mop.api.workspace.link.URLLink;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:urllink")
+public abstract class URLLinkImpl extends LinkImpl implements URLLink {
+
+  @Property(name = "url")
+  public abstract String getURL();
+
+  public abstract void setURL(String url);
+
+  public ObjectType<? extends URLLink> getObjectType() {
+    return ObjectType.URL_LINK;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSite.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSite.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSite.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.core.api.workspace.SiteImpl;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:usersite")
+public abstract class UserSite extends SiteImpl {
+
+  // Site implementation ***********************************************************************************************
+
+  public ObjectType<? extends Site> getObjectType() {
+    return ObjectType.USER_SITE;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSiteContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSiteContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/UserSiteContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.RelatedMappedBy;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:usersites")
+public abstract class UserSiteContainer extends SiteContainer<UserSite> {
+
+  @RelatedMappedBy("usersites")
+  public abstract WorkspaceImpl getWorkspace();
+
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,152 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.FindById;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.WorkspaceObject;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.core.api.workspace.content.CustomizationContainer;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:workspace")
+public abstract class WorkspaceImpl extends WorkspaceObjectImpl implements Workspace, WorkspaceCustomizationContext {
+
+  public ObjectType<? extends Workspace> getObjectType() {
+    return ObjectType.WORKSPACE;
+  }
+
+  // Abstract **********************************************************************************************************
+
+  @OneToOne
+  @MappedBy("portalsites")
+  public abstract PortalSiteContainer getPortalSites();
+
+  @OneToOne
+  @MappedBy("groupsites")
+  public abstract GroupSiteContainer getGroupSites();
+
+  @OneToOne
+  @MappedBy("usersites")
+  public abstract UserSiteContainer getUserSites();
+
+  @OneToOne
+  @MappedBy("sharedsites")
+  public abstract UserSiteContainer getSharedSites();
+
+  @OneToOne
+  @MappedBy("customizations")
+  public abstract CustomizationContainer getCustomizations();
+
+  // CustomizationContextResolver implementation ***********************************************************************
+
+  @FindById
+  public abstract WorkspaceObject getObject(String objectId);
+
+  @FindById
+  public abstract CustomizationContext resolveContext(String contextId);
+
+  // WorkspaceCustomizationContext implementation **********************************************************************
+
+  public String getContextType() {
+    return WorkspaceCustomizationContext.TYPE;
+  }
+
+  public String getContextId() {
+    return getObjectId();
+  }
+
+  public boolean contains(CustomizationContext that) {
+    return contains(this, that);
+  }
+
+  public Customization<?> getCustomization(String name) {
+    return getCustomizations().getCustomization(name);
+  }
+
+  public <S> Customization<S> customize(String name, ContentType<S> contentType, String contentId, S state) {
+    return getCustomizations().customize(name, contentType, contentId, state);
+  }
+
+  public <S> Customization<S> customize(String name, Customization<S> customization) {
+    return getCustomizations().customize(name, customization);
+  }
+
+  // Workspace implementation ******************************************************************************************
+
+  @SuppressWarnings("unchecked")
+  private <S extends Site> SiteContainer<S> getSiteContainer(ObjectType<S> siteType) {
+    if (siteType == ObjectType.PORTAL_SITE) {
+      return (SiteContainer<S>)getPortalSites();
+    } else if (siteType == ObjectType.GROUP_SITE) {
+      return (SiteContainer<S>)getGroupSites();
+    } else if (siteType == ObjectType.USER_SITE) {
+      return (SiteContainer<S>)getUserSites();
+    } else if (siteType == ObjectType.SHARED_SITE) {
+      return (SiteContainer<S>)getSharedSites();
+    } else {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  public <S extends Site> S getSite(ObjectType<S> siteType, String siteName) {
+    SiteContainer<S> sites = getSiteContainer(siteType);
+    return sites.getSite(siteName);
+  }
+
+  public Collection<Site> getSites() {
+    throw new UnsupportedOperationException();
+  }
+
+  public <S extends Site> Collection<S> getSites(ObjectType<S> siteType) {
+    SiteContainer<S> sites = getSiteContainer(siteType);
+    return sites.getAllSites();
+  }
+
+  public <S extends Site> S addSite(ObjectType<S> siteType, String name) {
+    SiteContainer<S> sites = getSiteContainer(siteType);
+    return sites.addSite(name);
+  }
+
+  public <O extends WorkspaceObject> O getObject(ObjectType<O> type, String id) {
+    WorkspaceObject object = getObject(id);
+    if (object != null) {
+      return type.cast(object);
+    } else {
+      return null;
+    }
+  }
+
+  public Site getSharedSite() {
+    return getSite(ObjectType.SHARED_SITE, "default");
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceObjectImpl.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceObjectImpl.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/WorkspaceObjectImpl.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,152 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.api.workspace.WorkspaceObject;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.Attributes;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.core.util.AbstractAttributes;
+import org.chromattic.api.annotations.Id;
+import org.chromattic.api.annotations.Name;
+import org.chromattic.api.annotations.Properties;
+import org.chromattic.common.AbstractFilterIterator;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.AbstractSet;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class WorkspaceObjectImpl implements WorkspaceObject {
+
+  /** . */
+  private final Set<String> keys = new AbstractSet<String>() {
+    @Override
+    public Iterator<String> iterator() {
+      Map<String, Object> properties = getProperties();
+      return new AbstractFilterIterator<String, String>(properties.keySet().iterator()) {
+        protected String adapt(String internal) {
+          if (internal.startsWith("mop:")) {
+            return internal.substring(4);
+          } else {
+            return null;
+          }
+        }
+      };
+    }
+    public int size() {
+      Map<String, Object> properties = getProperties();
+      int count = 0;
+      for (String key : properties.keySet()) {
+        if (key.startsWith("mop:")) {
+          count++;
+        }
+      }
+      return count;
+    }
+  };
+
+  /** . */
+  private final AbstractAttributes attributes = new AbstractAttributes() {
+    @Override
+    protected Object get(String name) {
+      Map<String, Object> properties = getProperties();
+      return properties.get("mop:" + name);
+    }
+
+    @Override
+    protected void set(String name, Object o) {
+      Map<String, Object> properties = getProperties();
+      properties.put("mop:" + name, o);
+    }
+
+    public Set<String> getKeys() {
+      return keys;
+    }
+  };
+
+  public Attributes getAttributes() {
+    return attributes;
+  }
+
+  @Name
+  public abstract String getName();
+
+  @Id
+  public abstract String getObjectId();
+
+  @Properties
+  public abstract Map<String, Object> getProperties();
+
+  @Override
+  public String toString() {
+    ObjectType<?> objectType = getObjectType();
+    Class<? extends WorkspaceObject> javaType = objectType.getJavaType();
+    String typeName = javaType.getSimpleName();
+    String name = getName();
+    String id = getObjectId();
+    return typeName + "[name=" + name + ",id=" + id + "]";
+  }
+
+  static boolean contains(CustomizationContext container, CustomizationContext contained) {
+    if (container == null) {
+      throw new NullPointerException("No null container accepted");
+    }
+    if (contained == null) {
+      throw new NullPointerException("No null contained accepted");
+    }
+
+    //
+    if (container == contained) {
+      return true;
+    }
+    if (container instanceof WorkspaceImpl) {
+      if (contained instanceof SiteImpl) {
+        SiteImpl site = (SiteImpl)contained;
+        return contains(container, site.getWorkspace());
+      } else if (contained instanceof PageImpl) {
+        PageImpl page = (PageImpl)contained;
+        return contains(container, page.getSite());
+      }  else if (contained instanceof UIWindowImpl) {
+        UIWindowImpl window = (UIWindowImpl)contained;
+        return contains(container, window.getPage());
+      }
+    }
+    if (container instanceof SiteImpl) {
+      if (contained instanceof PageImpl) {
+        PageImpl page = (PageImpl)contained;
+        return contains(container, page.getSite());
+      }  else if (contained instanceof UIWindowImpl) {
+        UIWindowImpl window = (UIWindowImpl)contained;
+        return contains(container, window.getPage());
+      }
+    }
+    if (container instanceof PageImpl) {
+      if (contained instanceof UIWindowImpl) {
+        UIWindowImpl window = (UIWindowImpl)contained;
+        return contains(container, window.getPage());
+      }
+    }
+    return false;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/AbstractCustomization.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/AbstractCustomization.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/AbstractCustomization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,219 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.customization.CustomizationMode;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.core.api.content.CustomizationContextComparator;
+import org.gatein.mop.core.api.workspace.content.portlet.PortletPreferencesState;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.annotations.Create;
+
+import java.util.Set;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.Map;
+import java.util.LinkedHashSet;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class AbstractCustomization implements Customization<Object> {
+
+  /** . */
+  protected static final CustomizationContextComparator comparator;
+
+  static {
+    CustomizationContextComparator _comparator = new CustomizationContextComparator(
+      WorkspaceCustomizationContext.TYPE
+    );
+
+    //
+    comparator = _comparator;
+  }
+
+  @OneToOne
+  @MappedBy("state")
+  public abstract CustomizationState getContentState();
+
+  public abstract void setContentState(CustomizationState state);
+
+  @OneToOne
+  @MappedBy("contexttypes")
+  abstract ContextTypeContainer getContextTypes();
+
+  @Create
+  abstract ContextType create();
+
+  @Create
+  abstract ContextSpecialization create2();
+
+  @Create
+  public abstract PortletPreferencesState createPS();
+
+  public abstract CustomizationContext getCustomizationContext();
+
+  public abstract AbstractCustomization getParentCustomization();
+
+
+  public Object getState() {
+
+    CustomizationState state = getContentState();
+    if (state != null) {
+      return getContentState().getPayload();
+    } else {
+      AbstractCustomization parent = getParentCustomization();
+      if (parent != null) {
+        return parent.getState();
+      } else {
+        return null;
+      }
+    }
+
+  }
+
+  public void setState(Object state) {
+    if (state == null) {
+      setContentState(null);
+    } else {
+      CustomizationState contentState = getContentState();
+
+      //
+      if (contentState == null) {
+        contentState = createPS();
+        setContentState(contentState);
+      }
+
+      //
+      contentState.setPayload(state);
+    }
+  }
+
+  public void destroy() {
+    throw new UnsupportedOperationException("todo");
+  }
+
+  public Customization<Object> getCustomization(Set<CustomizationContext> contexts) {
+    return get(contexts, false);
+  }
+
+  public Customization<Object> customize(CustomizationMode mode, Collection<CustomizationContext> contexts) {
+    if (mode == null) {
+      throw new NullPointerException();
+    }
+    if (contexts == null) {
+      throw new NullPointerException();
+    }
+    if (mode == CustomizationMode.CLONE) {
+      throw new UnsupportedOperationException("todo : support cloning");
+    }
+    return get(contexts, true);
+  }
+
+  public Set<CustomizationContext> getContexts() {
+    //
+    AbstractCustomization current = this;
+    LinkedHashSet<CustomizationContext> contexts = new LinkedHashSet<CustomizationContext>();
+
+    //
+    while (true) {
+      CustomizationContext currentContext = current.getCustomizationContext();
+      if (currentContext == null) {
+        throw new IllegalStateException("Could not resolve customization context for customization " +  this);
+      }
+
+      //
+      contexts.add(currentContext);
+
+      //
+      AbstractCustomization parent = current.getParentCustomization();
+      if (parent != null) {
+        current = parent;
+      } else {
+        break;
+      }
+    }
+
+    //
+    return contexts;
+  }
+
+  //
+
+  protected final Customization<Object> get(Collection<CustomizationContext> contexts, boolean create) {
+
+    // The sorted contexts
+    TreeSet<CustomizationContext> sortedContexts = new TreeSet<CustomizationContext>(comparator);
+
+    // Contexts up to this node
+    Set<CustomizationContext> existingContexts = getContexts();
+
+    // Add all existing contexts
+    sortedContexts.addAll(existingContexts);
+
+    // Sort everything and check consistency
+    sortedContexts.addAll(contexts);
+
+    // Remove existing contexts
+    sortedContexts.removeAll(existingContexts);
+
+    //
+    return get(sortedContexts.iterator(), create);
+  }
+
+  protected final Customization<Object> get(Iterator<CustomizationContext> contexts, boolean create) {
+    if (contexts.hasNext()) {
+      CustomizationContext context = contexts.next();
+      String type = context.getContextType();
+      ContextTypeContainer typeContainer = getContextTypes();
+      Map<String, ContextType> contextTypes = typeContainer.getContextTypes();
+      ContextType tmp = contextTypes.get(type);
+      if (tmp == null) {
+        if (create) {
+          tmp = create();
+          contextTypes.put(type, tmp);
+        } else {
+          return null;
+        }
+      }
+      Map<String, ContextSpecialization> c = tmp.getSpecializations();
+      String id = context.getContextId();
+      ContextSpecialization blah = c.get(id);
+
+      //
+      if (blah != null || !create) {
+        return blah;
+      }
+
+      //
+      blah = create2();
+      c.put(id, blah);
+
+      //
+      return blah.get(contexts, create);
+    } else {
+      return this;
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContentState.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContentState.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContentState.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class ContentState {
+
+  public abstract Object getPayload();
+
+  public abstract void setPayload(Object payload);
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextSpecialization.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextSpecialization.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextSpecialization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.Name;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.NodeMapping;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.core.api.content.CustomizationContextResolver;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:contextspecialization")
+public abstract class ContextSpecialization extends AbstractCustomization {
+
+  /** . */
+  private CustomizationContextResolver customizationContextResolver;
+
+  public CustomizationContextResolver getCustomizationContextResolver() {
+    return customizationContextResolver;
+  }
+
+  public void setCustomizationContextResolver(CustomizationContextResolver customizationContextResolver) {
+    this.customizationContextResolver = customizationContextResolver;
+  }
+
+  @Name
+  public abstract String getContextId();
+
+  @ManyToOne
+  public abstract ContextType getContextType();
+
+  public String getName() {
+    return getParentCustomization().getName();
+  }
+
+  public CustomizationContext getCustomizationContext() {
+    ContextType currentContextType = getContextType();
+    String contextType = currentContextType.getName();
+    return customizationContextResolver.resolve(contextType, getContextId());
+  }
+
+  public AbstractCustomization getParentCustomization() {
+    ContextType contextType = getContextType();
+    return contextType.getContainer().getCustomization();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextType.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextType.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextType.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,44 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.Name;
+import org.chromattic.api.annotations.ManyToOne;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:contexttype")
+public abstract class ContextType {
+
+  @Name
+  public abstract String getName();
+
+  @OneToMany
+  public abstract Map<String, ContextSpecialization> getSpecializations();
+
+  @ManyToOne
+  public abstract ContextTypeContainer getContainer();
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextTypeContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextTypeContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/ContextTypeContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.NodeMapping;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:contexttypecontainer")
+public abstract class ContextTypeContainer {
+
+  @OneToMany
+  public abstract Map<String, ContextType> getContextTypes();
+
+  @ManyToOne
+  public abstract AbstractCustomization getCustomization();
+
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationContainer.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationContainer.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationContainer.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.chromattic.api.annotations.Create;
+import org.chromattic.api.annotations.OneToOne;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.RelatedMappedBy;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:customizationcontainer")
+public abstract class CustomizationContainer {
+
+  @OneToOne
+  @RelatedMappedBy("customizations")
+  public abstract WorkspaceCustomizationContext getOwner();
+
+  @OneToMany
+  public abstract Map<String, WorkspaceCustomization> getCustomizations();
+
+  @Create
+  public abstract WorkspaceClone createClone();
+
+  @Create
+  public abstract WorkspaceSpecialization createSpecialization();
+
+  public Customization<?> getCustomization(String name) {
+    Map<String, WorkspaceCustomization> customizations = getCustomizations();
+    return customizations.get(name);
+  }
+
+  public <S> Customization<S> customize(String name, ContentType<S> contentType, String contentId, S state) {
+    Map<String, WorkspaceCustomization> contents = getCustomizations();
+    WorkspaceClone content = createClone();
+    contents.put(name, content);
+    content.setContentId(contentId);
+    content.setMimeType(contentType.getMimeType());
+    content.setState(state);
+    return (Customization<S>)content;
+  }
+
+  public <S> Customization<S> customize(String name, Customization<S> customization) {
+    Map<String, WorkspaceCustomization> contents = getCustomizations();
+    WorkspaceSpecialization content = createSpecialization();
+    contents.put(name, content);
+    content.setCustomization((WorkspaceCustomization)customization);
+    return (Customization<S>)content;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationState.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationState.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/CustomizationState.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class CustomizationState {
+
+  public abstract Object getPayload();
+
+  public abstract void setPayload(Object payload);
+
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceClone.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceClone.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceClone.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.Property;
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.Name;
+import org.chromattic.api.annotations.RelatedMappedBy;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.RelationshipType;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+import org.gatein.mop.core.api.content.ContentManagerRegistry;
+import org.gatein.mop.core.api.content.ContentRegistration;
+
+import java.util.Set;
+import java.util.Collections;
+import java.util.Collection;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:workspaceclone")
+public abstract class WorkspaceClone extends WorkspaceCustomization {
+
+  public ContentManagerRegistry registry;
+
+  public Set<CustomizationContext> getContexts() {
+    return Collections.emptySet();
+  }
+
+  @Name
+  public abstract String getFooName();
+
+  @Property(name = "mimetype")
+  public abstract String getMimeType();
+
+  public abstract void setMimeType(String mimeType);
+
+  @Property(name = "contentid")
+  public abstract String getContentId();
+
+  public abstract void setContentId(String contentId);
+
+  @OneToMany(type = RelationshipType.PATH)
+  @RelatedMappedBy("customization")
+  public abstract Collection<WorkspaceSpecialization> getSpecializations();
+
+  //
+
+  public String getName() {
+    CustomizationContext customizationContext = getCustomizationContext();
+    if (customizationContext instanceof WorkspaceCustomizationContext) {
+      return getFooName();
+    } else {
+      return null;
+    }
+  }
+
+  public AbstractCustomization getParentCustomization() {
+    return null;
+  }
+
+  @Override
+  public void destroy() {
+    // Get specializations (clone for now because of bug with concurrent modif in chromattic)
+    Collection<WorkspaceSpecialization> specializations = new ArrayList<WorkspaceSpecialization>(getSpecializations());
+
+    //
+    for (WorkspaceSpecialization specialization : specializations) {
+      // Compute flat state
+      Object state = specialization.getState();
+
+      // Update with flat state
+      specialization.setState(state);
+
+      // Clear ref
+      specialization.setCustomization(null);
+    }
+
+    //
+    doDestroy();
+  }
+
+  public ContentType<Object> getType() {
+    ContentRegistration registration = registry.providers.get(getMimeType());
+    if (registration != null) {
+      return (ContentType<Object>)registration.getContentType();
+    } else {
+      return null;
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceCustomization.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceCustomization.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceCustomization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.Destroy;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.core.api.workspace.UIWindowImpl;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class WorkspaceCustomization extends AbstractCustomization {
+
+  @ManyToOne
+  public abstract Object getParent();
+
+  @Destroy
+  public abstract void doDestroy();
+
+  public CustomizationContext getCustomizationContext() {
+    Object parent = getParent();
+    if (parent instanceof CustomizationContainer) {
+      return ((CustomizationContainer)parent).getOwner();
+    } else if (parent instanceof UIWindowImpl) {
+      return (UIWindowImpl)parent;
+    } else {
+      throw new AssertionError();
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceSpecialization.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceSpecialization.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/WorkspaceSpecialization.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.MappedBy;
+import org.chromattic.api.RelationshipType;
+import org.gatein.mop.api.content.ContentType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:workspacespecialization")
+public abstract class WorkspaceSpecialization extends WorkspaceCustomization {
+
+  @ManyToOne(type = RelationshipType.PATH)
+  @MappedBy("customization")
+  public abstract WorkspaceCustomization getCustomization();
+
+  public abstract void setCustomization(WorkspaceCustomization customization);
+
+  public String getName() {
+    AbstractCustomization parent = getParentCustomization();
+    if (parent == null) {
+      return null;
+    } else {
+      return parent.getName();
+    }
+  }
+
+  public String getContentId() {
+    AbstractCustomization parent = getParentCustomization();
+    if (parent == null) {
+      return null;
+    } else {
+      return parent.getContentId();
+    }
+  }
+
+  public ContentType<Object> getType() {
+    AbstractCustomization parent = getParentCustomization();
+    if (parent == null) {
+      return null;
+    } else {
+      return parent.getType();
+    }
+  }
+
+  public AbstractCustomization getParentCustomization() {
+    return getCustomization();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferenceState.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferenceState.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferenceState.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content.portlet;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.ManyToOne;
+import org.chromattic.api.annotations.Name;
+import org.chromattic.api.annotations.Property;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:portletpreference")
+public abstract class PortletPreferenceState {
+
+  @ManyToOne
+  public abstract PortletPreferenceState getParent();
+
+  @Name
+  public abstract String getName();
+
+  @Property(name = "value")
+  public abstract List<String> getValue();
+
+  public abstract void setValue(List<String> value);
+
+  @Property(name = "value")
+  public abstract List<String> getValues();
+
+  public abstract void setValues(List<String> value);
+
+  @Property(name = "readonly")
+  public abstract boolean getReadOnly();
+
+  public abstract void setReadOnly(boolean readOnly);
+
+
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferencesState.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferencesState.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/api/workspace/content/portlet/PortletPreferencesState.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content.portlet;
+
+import org.chromattic.api.annotations.NodeMapping;
+import org.chromattic.api.annotations.OneToMany;
+import org.chromattic.api.annotations.Create;
+import org.gatein.mop.core.api.workspace.content.CustomizationState;
+import org.gatein.mop.core.content.portlet.Preferences;
+import org.gatein.mop.core.content.portlet.Preference;
+import org.gatein.mop.core.content.portlet.PreferencesBuilder;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+ at NodeMapping(name = "mop:portletpreferences")
+public abstract class PortletPreferencesState extends CustomizationState {
+
+  /** . */
+  private Preferences payload;
+
+  @OneToMany
+  public abstract Map<String, PortletPreferenceState> getChildren();
+
+  @Create
+  public abstract PortletPreferenceState create();
+
+  private void setPayload(Preferences payload) {
+
+    this.payload = payload;
+
+    //
+    Map<String, PortletPreferenceState> entries = getChildren();
+    entries.clear();
+
+    for (Preference pref : payload.getEntries()) {
+      PortletPreferenceState prefState = create();
+      entries.put(pref.getName(), prefState);
+      prefState.setValue(pref.getValues());
+      prefState.setReadOnly(pref.isReadOnly());
+    }
+  }
+
+  public void setPayload(Object payload) {
+    setPayload((Preferences)payload);
+  }
+
+  public Object getPayload() {
+    if (payload == null) {
+      PreferencesBuilder builder = new PreferencesBuilder();
+      for (PortletPreferenceState entry : getChildren().values()) {
+        builder.add(entry.getName(), entry.getValues(), entry.getReadOnly());
+      }
+      payload = builder.build();
+    }
+    return payload;
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preference.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preference.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preference.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.content.portlet;
+
+import java.util.List;
+import java.util.Collections;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public final class Preference {
+
+  /** . */
+  private final String name;
+
+  /** . */
+  private final List<String> values;
+
+  /** . */
+  private final boolean readOnly;
+
+  public Preference(String name, List<String> values, boolean readOnly) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    if (values == null) {
+      throw new NullPointerException();
+    }
+
+    // Clone and check state
+    values = Collections.unmodifiableList(new ArrayList<String>(values));
+    if (values.size() == 0) {
+      throw new IllegalArgumentException();
+    }
+    for (String value : values) {
+      if (value == null) {
+        throw new IllegalArgumentException();
+      }
+    }
+
+    //
+    this.name = name;
+    this.values = values;
+    this.readOnly = readOnly;
+  }
+
+  public Preference(String name, String value, boolean readOnly) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    if (value == null) {
+      throw new NullPointerException();
+    }
+
+    //
+    this.name = name;
+    this.values = Collections.singletonList(value);
+    this.readOnly = readOnly;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public List<String> getValues() {
+    return values;
+  }
+
+  public boolean isReadOnly() {
+    return readOnly;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof Preference) {
+      Preference that = (Preference)obj;
+      return this.name.equals(that.name) && this.getValues().equals(that.getValues()) && this.readOnly == that.isReadOnly();
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return name.hashCode() ^ values.hashCode() ^ (readOnly ? -1 : 0);
+  }
+
+  @Override
+  public String toString() {
+    return "Preference[name=" + name + ",values=" + values + ",readOnly=" + readOnly + "]";
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preferences.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preferences.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/Preferences.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,85 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.content.portlet;
+
+import org.gatein.mop.api.content.ContentType;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashMap;
+
+/**
+ * A set of preferences.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public final class Preferences {
+
+  /** . */
+  public static final ContentType<Preferences> CONTENT_TYPE = new ContentType<Preferences>("application/portlet", Preferences.class);
+
+  /** . */
+  final Map<String, Preference> state;
+
+  /** . */
+  private final Map<String, Preference> entries;
+
+  public Preferences() {
+    this.state = new HashMap<String, Preference>();
+    this.entries = Collections.unmodifiableMap(this.state);
+  }
+
+  public Preferences(Map<String, Preference> state) {
+    if (state == null) {
+      throw new NullPointerException();
+    }
+
+    //
+    this.state = new HashMap<String, Preference>(state);
+    this.entries = Collections.unmodifiableMap(this.state);
+  }
+
+  public Collection<Preference> getEntries() {
+    return entries.values();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) {
+      return true;
+    }
+    if (obj instanceof Preferences) {
+      Preferences that = (Preferences)obj;
+      return state.equals(that.state);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return state.hashCode();
+  }
+
+  @Override
+  public String toString() {
+    return "Preferences[state=" + state.toString() + "]";
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/PreferencesBuilder.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/PreferencesBuilder.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/content/portlet/PreferencesBuilder.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,91 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.content.portlet;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class PreferencesBuilder {
+
+  /** The state being configured. */
+  private Preferences prefs;
+
+  public PreferencesBuilder() {
+    this.prefs = new Preferences();
+  }
+
+  /**
+   * Initialize the builder with the provided preferences.
+   *
+   * @param that the preferences to clone
+   */
+  public PreferencesBuilder(Preferences that) {
+    Preferences prefs = new Preferences();
+    prefs.state.putAll(that.state);
+
+    //
+    this.prefs = prefs;
+  }
+
+  public PreferencesBuilder add(Preference preference) {
+    if (preference == null) {
+      throw new NullPointerException();
+    }
+    prefs.state.put(preference.getName(), preference);
+    return this;
+  }
+
+  public PreferencesBuilder add(String name, List<String> values, boolean readOnly) {
+    return add(new Preference(name, values, readOnly));
+  }
+
+  public PreferencesBuilder add(String name, List<String> values) {
+    return add(new Preference(name, values, false));
+  }
+
+  public PreferencesBuilder add(String name, String value, boolean readOnly) {
+    return add(new Preference(name, value, readOnly));
+  }
+
+  public PreferencesBuilder add(String name, String value) {
+    return add(name, value, false);
+  }
+
+  public PreferencesBuilder remove(String name) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    prefs.state.remove(name);
+    return this;
+  }
+
+  public PreferencesBuilder clear() {
+    prefs.state.clear();
+    return this;
+  }
+
+  public Preferences build() {
+    Preferences tmp = prefs;
+    prefs = new Preferences();
+    return tmp;
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/notes.txt
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/notes.txt	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/notes.txt	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1 @@
+- perhaps page subclasses to specify functionnalities would be a good idea
\ No newline at end of file

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/content/WorkspaceCustomizationPolicy.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/content/WorkspaceCustomizationPolicy.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/spi/content/WorkspaceCustomizationPolicy.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.spi.content;
+
+import org.gatein.mop.api.workspace.WorkspaceCustomizationContext;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class WorkspaceCustomizationPolicy {
+
+  public boolean contains(WorkspaceCustomizationContext c1, WorkspaceCustomizationContext c2) {
+/*
+    if (c1 instanceof Workspace) {
+      if (c2 instanceof Workspace) {
+        return c1 == c2;
+      } else if (c2 instanceof Site) {
+        Site s2 = (Site)c2;
+        return c1 == s2.getWorkspace();
+      } else if (c2 instanceof Page) {
+        Page p2 = (Page)c2;
+        return contains(c1, p2.getSite());
+      } else if (c2 instanceof UIWindow) {
+        UIWindow w2 = (UIWindow)c2;
+        return contains(c1, w2.getPage());
+      } else {
+        throw new AssertionError();
+      }
+    } else if (c1 instanceof Site) {
+      if (c2 instanceof Site) {
+        return c1 == c2;
+      } else if (c2 instanceof Page) {
+        Page p2 = (Page)c2;
+        return c1 == p2.getSite();
+      } else if (c2 instanceof UIWindow) {
+        UIWindow w2 = (UIWindow)c2;
+        return contains(c1, w2.getPage());
+      } else {
+        throw new AssertionError();
+      }
+    } else if (c1 instanceof Page) {
+      if (c2 instanceof Page) {
+        return c1 == c2;
+      } else if (c2 instanceof UIWindow) {
+        UIWindow w2 = (UIWindow)c2;
+        return c1 == w2.getPage();
+      } else {
+        throw new AssertionError();
+      }
+    } else if (c1 instanceof UIWindow) {
+      if (c2 instanceof UIWindow) {
+        return c1 == c2;
+      } else {
+        throw new AssertionError();
+      }
+    } else {
+      throw new AssertionError();
+    }
+*/
+    throw new UnsupportedOperationException();
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/AbstractAttributes.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/AbstractAttributes.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/AbstractAttributes.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,137 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import org.gatein.mop.api.Key;
+import org.gatein.mop.api.Attributes;
+import org.gatein.mop.api.ValueType;
+
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class AbstractAttributes implements Attributes {
+
+  protected abstract Object get(String name);
+
+  protected abstract void set(String name, Object o);
+
+  private <T> T getObject(String name, ValueType<T> type, T defaultValue) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    Object o = get(name);
+    if (o == null) {
+      return defaultValue;
+    } else {
+      return type.cast(o);
+    }
+  }
+
+  public final Object getObject(String name) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    Object o = get(name);
+    if (o == null) {
+      return null;
+    } else {
+      ValueType.get(o);
+      return o;
+    }
+  }
+
+  public final <T> void setObject(String name, T value) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    if (value == null) {
+      set(name, null);
+    } else {
+      ValueType.get(value);
+      set(name, value);
+    }
+  }
+
+  public final ValueType<?> getType(String name) {
+    if (name == null) {
+      throw new NullPointerException();
+    }
+    Object o = get(name);
+    if (o == null) {
+      return null;
+    } else {
+      return ValueType.get(o);
+    }
+  }
+
+  public final String getString(String name) {
+    return getObject(name, ValueType.STRING, null);
+  }
+
+  public final void setString(String name, String value) {
+    setObject(name, value);
+  }
+
+  public final Boolean getBoolean(String name) {
+    return getObject(name, ValueType.BOOLEAN, null);
+  }
+
+  public final void setBoolean(String name, Boolean value) {
+    setObject(name, value);
+  }
+
+  public final Integer getInteger(String name) {
+    return getObject(name, ValueType.INTEGER, null);
+  }
+
+  public final void setInteger(String name, Integer value) {
+    setObject(name, value);
+  }
+
+  public final Date getDate(String name) {
+    return getObject(name, ValueType.DATE, null);
+  }
+
+  public final void setDate(String name, Date value) {
+    setObject(name, value);
+  }
+
+  public final Double getDouble(String name) {
+    return getObject(name, ValueType.DOUBLE, null);
+  }
+
+  public final void setDouble(String name, Double value) {
+    setObject(name, value);
+  }
+
+  public final <T> T getValue(Key<T> key, T defaultValue) {
+    return getObject(key.getName(), key.getType(), defaultValue);
+  }
+
+  public final <T> T getValue(Key<T> key) {
+    return getObject(key.getName(), key.getType(), null);
+  }
+
+  public final <T> void setValue(Key<T> key, T value) {
+    setObject(key.getName(), value);
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/SimpleAttributes.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/SimpleAttributes.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/SimpleAttributes.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class SimpleAttributes extends AbstractAttributes {
+
+  private final Map<String, Object> map;
+
+  public SimpleAttributes(Map<String, Object> map) {
+    this.map = map;
+  }
+
+  public SimpleAttributes() {
+    this(new HashMap<String, Object>());
+  }
+
+  public Set<String> getKeys() {
+    return map.keySet();
+  }
+
+  protected Object get(String name) {
+    return map.get(name);
+  }
+
+  protected void set(String name, Object o) {
+    if (o == null) {
+      map.remove(name);
+    } else {
+      map.put(name, o);
+    }
+  }
+}

Added: components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/Tools.java
===================================================================
--- components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/Tools.java	                        (rev 0)
+++ components/mop/trunk/core/src/main/java/org/gatein/mop/core/util/Tools.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,119 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class Tools {
+
+  public static <N> List<N> list(Iterator<N> iterable) {
+    ArrayList<N> set = new ArrayList<N>();
+    while (iterable.hasNext()) {
+      set.add(iterable.next());
+    }
+    return set;
+  }
+
+  public static <N> Set<N> set(Iterable<N> iterable) {
+    HashSet<N> set = new HashSet<N>();
+    for (N n : iterable) {
+      set.add(n);
+    }
+    return set;
+  }
+
+  public static <N> Set<N> set(Iterator<N> iterator) {
+    HashSet<N> set = new HashSet<N>();
+    while (iterator.hasNext()) {
+      set.add(iterator.next());
+    }
+    return set;
+  }
+
+  public static <N> Set<N> set() {
+    return new HashSet<N>();
+  }
+
+  public static <N> Set<N> set(N object) {
+    HashSet<N> set = new HashSet<N>();
+    set.add(object);
+    return set;
+  }
+
+  public static <N> Set<N> set(N... objects) throws NullPointerException {
+    if (objects == null) {
+      throw new NullPointerException();
+    }
+    HashSet<N> set = new HashSet<N>();
+    for (N object : objects) {
+      set.add(object);
+    }
+    return set;
+  }
+
+  public static int max(int value, int... values) {
+    int max = value;
+    for (int v : values) {
+      if (v > max) {
+        max = v;
+      }
+    }
+    return max;
+  }
+
+  public static <E> Iterator<E> iterator(final Iterator<? extends E>... iterators) {
+    return new Iterator<E>() {
+
+      int index = 0;
+
+      public boolean hasNext() {
+        while (index < iterators.length) {
+          if (iterators[index].hasNext()) {
+            return true;
+          }
+          index++;
+        }
+        return false;
+      }
+
+      public E next() {
+        while (index < iterators.length) {
+          if (iterators[index].hasNext()) {
+            return iterators[index].next();
+          }
+          index++;
+        }
+        throw new NoSuchElementException();
+      }
+
+      public void remove() {
+        throw new UnsupportedOperationException();
+      }
+    };
+  }
+}

Added: components/mop/trunk/core/src/main/resources/conf/standalone/nodetypes.xml
===================================================================
--- components/mop/trunk/core/src/main/resources/conf/standalone/nodetypes.xml	                        (rev 0)
+++ components/mop/trunk/core/src/main/resources/conf/standalone/nodetypes.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,481 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<nodeTypes xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0">
+
+  <nodeType name="mop:customizationstate" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:portletpreferences" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:customizationstate</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:portletpreference" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:portletpreference</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:portletpreference" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="value" requiredType="String" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="true">
+        <valueConstraints/>
+      </propertyDefinition>
+      <propertyDefinition name="readonly" requiredType="Boolean" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:contexttypecontainer" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:contexttype" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:contexttype</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:contexttype" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:contextspecialization" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:contextspecialization</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:customization" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="contexttypes" defaultPrimaryType="mop:contexttypecontainer" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:contexttypecontainer</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="state" defaultPrimaryType="mop:customizationstate" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:customizationstate</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <!-- -->
+
+  <nodeType name="mop:workspacecustomization" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:customization</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:workspaceclone" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspacecustomization</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="contentid" requiredType="String" autoCreated="false" mandatory="true" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+      <propertyDefinition name="mimetype" requiredType="String" autoCreated="false" mandatory="true" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:workspacespecialization" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspacecustomization</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="customization" requiredType="Path" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:contextspecialization" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:customization</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:customizationcontainer" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:workspacecustomization" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:workspacecustomization</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:customizationcontext" isMixin="true" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="customizations" defaultPrimaryType="mop:customizationcontainer" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:customizationcontainer</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <!-- -->
+
+  <nodeType name="mop:workspaceobject" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="*" requiredType="undefined" autoCreated="false" mandatory="false" onParentVersion="COPY"
+        protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:uicomponent" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:uicontainer" isMixin="false" hasOrderableChildNodes="true" primaryItemName="">
+    <supertypes>
+      <supertype>mop:uicomponent</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:uicomponent</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:uiwindow" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:uicomponent</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="customization" defaultPrimaryType="mop:workspacecustomization" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:workspacecustomization</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:uibody" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:uicomponent</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:templatized" isMixin="true" hasOrderableChildNodes="false" primaryItemName="">
+    <propertyDefinitions>
+      <propertyDefinition name="template" requiredType="Path" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:navigation" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+      <supertype>mop:templatized</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="children" defaultPrimaryType="mop:navigationcontainer" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:navigationcontainer</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="link" defaultPrimaryType="mop:link" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:link</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:navigationcontainer" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:navigation" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:navigation</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:link" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:pagelink" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:link</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="page" requiredType="Path" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:urllink" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:link</supertype>
+    </supertypes>
+    <propertyDefinitions>
+      <propertyDefinition name="url" requiredType="String" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false">
+        <valueConstraints/>
+      </propertyDefinition>
+    </propertyDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:page" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+      <supertype>mop:templatized</supertype>
+      <supertype>mop:customizationcontext</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="children" defaultPrimaryType="mop:pagecontainer" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:pagecontainer</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="rootcomponent" defaultPrimaryType="mop:uicontainer" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:uicontainer</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:pagecontainer" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:page" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:page</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:site" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+      <supertype>mop:customizationcontext</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="rootpage" defaultPrimaryType="mop:page" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:page</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="rootnavigation" defaultPrimaryType="mop:navigation" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:navigation</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:portalsite" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:site</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:groupsite" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:site</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:usersite" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:site</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:sharedsite" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:site</supertype>
+    </supertypes>
+  </nodeType>
+
+  <nodeType name="mop:portalsites" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:portalsite" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:portalsite</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:groupsites" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:groupsite" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:groupsite</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:usersites" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:usersite" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:usersite</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:sharedsites" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>nt:base</supertype>
+      <supertype>mix:referenceable</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="*" defaultPrimaryType="mop:sharedsite" autoCreated="false" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:sharedsite</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+  <nodeType name="mop:workspace" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+    <supertypes>
+      <supertype>mop:workspaceobject</supertype>
+      <supertype>mop:customizationcontext</supertype>
+    </supertypes>
+    <childNodeDefinitions>
+      <childNodeDefinition name="portalsites" defaultPrimaryType="mop:portalsites" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:portalsites</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="groupsites" defaultPrimaryType="mop:groupsites" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:groupsites</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="usersites" defaultPrimaryType="mop:usersites" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:usersites</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+      <childNodeDefinition name="sharedsites" defaultPrimaryType="mop:sharedsites" autoCreated="true" mandatory="false"
+        onParentVersion="COPY" protected="false" sameNameSiblings="false">
+        <requiredPrimaryTypes>
+          <requiredPrimaryType>mop:sharedsites</requiredPrimaryType>
+        </requiredPrimaryTypes>
+      </childNodeDefinition>
+    </childNodeDefinitions>
+  </nodeType>
+
+</nodeTypes>
+  
\ No newline at end of file

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/AbstractPOMTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/AbstractPOMTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/AbstractPOMTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api;
+
+import junit.framework.TestCase;
+
+import java.util.Collections;
+
+import org.gatein.mop.core.content.portlet.Preference;
+import org.gatein.mop.core.content.portlet.Preferences;
+import org.gatein.mop.core.impl.portlet.PortletContentProvider;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class AbstractPOMTestCase extends TestCase {
+
+  /** . */
+  protected MOPService pomService;
+
+  @Override
+  protected void setUp() throws Exception {
+    Preferences weatherPreferences = new Preferences(Collections.<String, Preference>singletonMap(
+      "zip", new Preference("zip", Collections.singletonList("marseille"), false)));
+    PortletContentProvider portletContentProvider = new PortletContentProvider();
+    portletContentProvider.addPortletDefinition("WeatherPortlet", weatherPreferences);
+
+    //
+    MOPService pomService = new MOPService();
+
+    //
+    pomService.start();
+
+    //
+    pomService.getContentManagerRegistry().register(Preferences.CONTENT_TYPE, portletContentProvider);
+
+    //
+    this.pomService = pomService;
+  }
+
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/POMFormatterTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/POMFormatterTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/POMFormatterTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api;
+
+import junit.framework.TestCase;
+import org.chromattic.api.format.ObjectFormatter;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class POMFormatterTestCase extends TestCase {
+
+  /** . */
+  private final ObjectFormatter formatter = new MOPFormatter();
+
+  private void assertString(String expected, String s) {
+    assertEquals(expected, formatter.encodeNodeName(null, s));
+    assertEquals(s, formatter.decodeNodeName(null, expected));
+  }
+
+  private void assertCannotDecode(String s) {
+    try {
+      formatter.decodeNodeName(null, s);
+      fail();
+    }
+    catch (IllegalStateException ignore) {
+    }
+  }
+
+  public void testStrings() {
+    assertString("", "");
+    assertString("a", "a");
+    assertString("%00", "{");
+    assertString("%01", "}");
+    assertString("%02", ".");
+    assertString("%03", "/");
+    assertString("%04", ":");
+    assertString("%05", "[");
+    assertString("%06", "]");
+    assertString("%07", "|");
+    assertString("%08", "*");
+    assertString("%09", "%");
+    assertString("a%03b", "a/b");
+  }
+
+  public void testDecodeFailure() {
+    assertCannotDecode("%0");
+    assertCannotDecode("%0" + (char)('0' - 1));
+    assertCannotDecode("%0" + (char)('9' + 1));
+    assertCannotDecode("%1");
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/composer/StructureIteratorTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/composer/StructureIteratorTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/composer/StructureIteratorTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,162 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.composer;
+
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+import org.gatein.mop.core.api.ModelImpl;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.composer.ComponentIterator;
+import org.gatein.mop.api.composer.IterationType;
+import org.gatein.mop.api.composer.PageIterator;
+import org.gatein.mop.api.composer.StructureIterator;
+import org.gatein.mop.api.composer.PageIteratorStrategies;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class StructureIteratorTestCase extends AbstractPOMTestCase {
+
+  public void testCompoundPage() {
+    ModelImpl model = pomService.getModel();
+    Site site = model.getWorkspace().addSite(ObjectType.PORTAL_SITE, "site");
+    Page root = site.getRootPage();
+
+    //
+    Page t = root.addChild("t");
+    UIContainer t0 = t.getRootComponent();
+    UIComponent t1 = t0.addChild(ObjectType.WINDOW, "t1");
+    UIComponent t2 = t0.addChild(ObjectType.BODY, "t2");
+    UIComponent t3 = t0.addChild(ObjectType.WINDOW, "t3");
+
+    //
+    Page u = root.addChild("u");
+    UIContainer u0 = u.getRootComponent();
+    UIComponent u1 = u0.addChild(ObjectType.WINDOW, "u1");
+    UIComponent u2 = u0.addChild(ObjectType.BODY, "u2");
+
+    //
+    Page a = root.addChild("a");
+    a.setTemplate(t);
+    UIContainer a0 = a.getRootComponent();
+    UIComponent a1 = a0.addChild(ObjectType.WINDOW, "a1");
+    UIComponent a2 = a0.addChild(ObjectType.WINDOW, "a2");
+    PageIterator ia = new PageIterator(a, PageIteratorStrategies.PAGE_TEMPLATE);
+    assertStart(ia, t0);
+    assertStart(ia, t1);
+    assertEnd(ia, t1);
+    assertStart(ia, a0);
+    assertStart(ia, a1);
+    assertEnd(ia, a1);
+    assertStart(ia, a2);
+    assertEnd(ia, a2);
+    assertEnd(ia, a0);
+    assertStart(ia, t3);
+    assertEnd(ia, t3);
+    assertEnd(ia, t0);
+    assertDone(ia);
+
+    //
+    Page b = root.addChild("b");
+    UIContainer b0 = b.getRootComponent();
+    UIComponent b1 = b0.addChild(ObjectType.WINDOW, "b1");
+    UIComponent b2 = b0.addChild(ObjectType.WINDOW, "b2");
+
+    //
+    Page c = root.addChild("c");
+    c.setTemplate(u);
+
+
+  }
+
+  private void assertStart(StructureIterator i, UIComponent expectedComponent) {
+    IterationType type = i.next();
+    assertEquals(IterationType.START, type);
+    UIComponent component = i.getComponent();
+    assertSame(expectedComponent, component);
+  }
+
+  private void assertEnd(StructureIterator i, UIComponent expectedComponent) {
+    IterationType type = i.next();
+    assertEquals(IterationType.END, type);
+    UIComponent component = i.getComponent();
+    assertSame(expectedComponent, component);
+  }
+
+  private void assertDone(StructureIterator i) {
+    IterationType type = i.next();
+    assertEquals(IterationType.DONE, type);
+    UIComponent component = i.getComponent();
+    assertSame(null, component);
+  }
+
+  public void testSimplePage() {
+    ModelImpl model = pomService.getModel();
+    Site site = model.getWorkspace().addSite(ObjectType.PORTAL_SITE, "site");
+    Page root = site.getRootPage();
+    UIContainer c0 = root.getRootComponent();
+    UIComponent c1 = c0.addChild(ObjectType.WINDOW, "c1");
+
+    //
+    PageIterator i = new PageIterator(root, PageIteratorStrategies.PAGE_TEMPLATE);
+    assertStart(i, c0);
+    assertStart(i, c1);
+    assertEnd(i, c1);
+    assertEnd(i, c0);
+    assertDone(i);
+  }
+
+  public void testComponents() {
+    ModelImpl model = pomService.getModel();
+    Site site = model.getWorkspace().addSite(ObjectType.PORTAL_SITE, "site");
+    Page root = site.getRootPage();
+    UIContainer c0 = root.getRootComponent();
+    UIComponent c1 = c0.addChild(ObjectType.WINDOW, "c1");
+    UIContainer c2 = c0.addChild(ObjectType.CONTAINER, "c2");
+    UIComponent c3 = c2.addChild(ObjectType.WINDOW, "c3");
+    UIComponent c4 = c2.addChild(ObjectType.WINDOW, "c4");
+    UIComponent c5 = c0.addChild(ObjectType.WINDOW, "c5");
+
+    //
+    ComponentIterator i0 = new ComponentIterator(c1);
+    assertStart(i0, c1);
+    assertEnd(i0, c1);
+    assertDone(i0);
+
+    //
+    ComponentIterator i1 = new ComponentIterator(c0);
+    assertStart(i1, c0);
+    assertStart(i1, c1);
+    assertEnd(i1, c1);
+    assertStart(i1, c2);
+    assertStart(i1, c3);
+    assertEnd(i1, c3);
+    assertStart(i1, c4);
+    assertEnd(i1, c4);
+    assertEnd(i1, c2);
+    assertStart(i1, c5);
+    assertEnd(i1, c5);
+    assertEnd(i1, c0);
+    assertDone(i1);
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/BiltoTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/BiltoTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/BiltoTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,162 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+import org.gatein.mop.api.content.ContentType;
+import org.gatein.mop.core.content.portlet.Preferences;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class BiltoTestCase extends AbstractPOMTestCase {
+
+  /** . */
+  private final ContentType portletContentType = Preferences.CONTENT_TYPE;
+
+/*
+  public void testBar() throws Exception {
+
+    POM model = pomService.getModel();
+
+    //
+    ContentManager manager = model.getContentManager();
+    assertNotNull(manager);
+
+    Content content = manager.getContent(portletContentType, "WeatherPortlet", FetchCondition.ALWAYS);
+    assertNotNull(content);
+
+    Customization customization = content.getCustomization();
+
+    assertNotNull(customization);
+
+    Object state = customization.getState();
+    assertNotNull(state);
+
+    Workspace workspace = model.getWorkspace();
+    Set<CustomizationContext> contexts = Collections.singleton((CustomizationContext)workspace);
+    Customization wcustomization = customization.customize(CustomizationMode.SPECIALIZE, contexts);
+    assertNotNull(wcustomization);
+
+    Set<CustomizationContext> wcontexts = wcustomization.getContexts();
+    assertEquals(1, wcontexts.size());
+    assertTrue(wcontexts.contains(workspace));
+
+    Site site = workspace.addSite(ObjectType.PORTAL_SITE, "site");
+
+    Page root = site.getRootPage();
+    UIContainer layout = root.getLayout();
+    UIWindow window = layout.addComponent(ObjectType.WINDOW, "window");
+
+    Collection<CustomizationContext> wincontexts = Arrays.asList((CustomizationContext)workspace, site, root, window);
+
+    Customization wincust = wcustomization.customize(CustomizationMode.SPECIALIZE, wincontexts);
+
+    assertNotNull(wincust);
+
+    Set<CustomizationContext> allc = wincust.getContexts();
+    assertEquals(4, allc.size());
+    assertTrue(allc.contains(workspace));
+    assertTrue(allc.contains(site));
+    assertTrue(allc.contains(root));
+    assertTrue(allc.contains(window));
+
+
+
+
+*/
+/*
+    ContentManager contentManager = model.getContentManager();
+    Content content = contentManager.getContent(ContentType.create("portlet"), "WeatherPortlet");
+    assertNotNull(content);
+
+    //
+    Workspace workspace = model.getWorkspace();
+    Portal portal = (Portal)workspace.createSite("portal", SiteType.PORTAL);
+    Page rootPage = portal.getRootPage();
+    UIContainer layout = rootPage.getLayout();
+    UIWindow window = layout.addWindow("window");
+    window.setContent(content);
+
+    //
+    Content other = window.getContent();
+    assertNotNull(other);
+
+    //
+    ContentCustomization customization = content.getCustomization();
+*/
+/*
+  }
+
+  public void testWindowContent() throws Exception {
+    POM model = pomService.getModel();
+    Content content = model.getContentManager().getContent(Preferences.CONTENT_TYPE, "WeatherPortlet", FetchCondition.ALWAYS);
+    assertNotNull(content);
+    Workspace workpace = model.getWorkspace();
+    Site site = workpace.addSite(ObjectType.PORTAL_SITE, "portal");
+    UIWindow window = site.getRootPage().getLayout().addComponent(ObjectType.WINDOW, "window");
+    window.setContent(content);
+
+//    model.save();
+//    model.close();
+
+    //
+//    model = pomService.getModel();
+    window = (UIWindow)model.getWorkspace().getSite(ObjectType.PORTAL_SITE, "portal").getRootPage().getLayout().getComponent("window");
+    content = window.getContent();
+    assertNotNull(content);
+    assertEquals("WeatherPortlet", content.getId());
+    assertEquals(Preferences.CONTENT_TYPE, content.getType());
+  }
+
+*/
+/*
+  public void testNoContentProvider() throws Exception {
+
+  }
+*/
+/*
+
+  public void testFooo() throws Exception {
+*/
+/*
+    POM model = pomService.getModel();
+    Workspace workspace = model.getWorkspace();
+    CustomizationContainer container = model.getContainer();
+
+    //
+    assertNotNull(container.getCustomizations());
+    Customization customization = container.add("foo");
+    assertNotNull(customization);
+*/
+/*
+
+    //
+    // workspace.setCustomization(customization);
+
+    //
+//    session.save();
+
+    // customization.customize(CustomizationMode.SPECIALIZE, );
+
+
+  }
+*/
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationContextComparatorTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationContextComparatorTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationContextComparatorTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,162 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import junit.framework.TestCase;
+import org.gatein.mop.api.content.CustomizationContext;
+import org.gatein.mop.core.api.content.CustomizationContextComparator;
+import org.gatein.mop.core.api.content.ComparisonException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Arrays;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class CustomizationContextComparatorTestCase extends TestCase {
+
+  /** . */
+  private final SimpleCustomizationContext s2 = new SimpleCustomizationContext("foo", 2);
+
+  /** . */
+  private final SimpleCustomizationContext s3 = new SimpleCustomizationContext("foo", 3);
+
+  /** . */
+  private final SimpleCustomizationContext s4 = new SimpleCustomizationContext("foo", 4);
+
+  /** . */
+  private final SimpleCustomizationContext b2 = new SimpleCustomizationContext("bar", 2);
+
+  /** . */
+  private final SimpleCustomizationContext b3 = new SimpleCustomizationContext("bar", 3);
+
+  /** . */
+  private final SimpleCustomizationContext b4 = new SimpleCustomizationContext("bar", 4);
+
+  public void testKeepOrder() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo");
+    List<SimpleCustomizationContext> contexts = new ArrayList<SimpleCustomizationContext>();
+    contexts.add(s2);
+    contexts.add(s4);
+    Collections.sort(contexts, comparator);
+    List<SimpleCustomizationContext> blah = Arrays.asList(s2, s4);
+    assertEquals(blah, contexts);
+  }
+
+  public void testSort() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo");
+    List<SimpleCustomizationContext> contexts = new ArrayList<SimpleCustomizationContext>();
+    contexts.add(s4);
+    contexts.add(s2);
+    Collections.sort(contexts, comparator);
+    List<SimpleCustomizationContext> blah = Arrays.asList(s2, s4);
+    assertEquals(blah, contexts);
+  }
+
+  public void testFailWhenNotComparable() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo");
+    List<SimpleCustomizationContext> contexts = new ArrayList<SimpleCustomizationContext>();
+    contexts.add(s2);
+    contexts.add(s3);
+    try {
+      Collections.sort(contexts, comparator);
+      fail();
+    }
+    catch (ComparisonException e) {
+    }
+  }
+
+  public void testFailWhenNonExpectedType() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo");
+    List<SimpleCustomizationContext> contexts = new ArrayList<SimpleCustomizationContext>();
+    contexts.add(s2);
+    contexts.add(b4);
+    try {
+      Collections.sort(contexts, comparator);
+      fail();
+    }
+    catch (ComparisonException e) {
+    }
+  }
+
+  public void testSortByTypes() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo","bar");
+    List<SimpleCustomizationContext> contexts = new ArrayList<SimpleCustomizationContext>();
+    contexts.add(b4);
+    contexts.add(s2);
+    contexts.add(s4);
+    contexts.add(b2);
+    Collections.sort(contexts, comparator);
+    List<?> blah = Arrays.asList(s2, s4, b2, b4);
+    assertEquals(blah, contexts);
+  }
+
+  public void testRemoveDuplicates() {
+    CustomizationContextComparator comparator = new CustomizationContextComparator("foo");
+    SortedSet<SimpleCustomizationContext> contexts = new TreeSet<SimpleCustomizationContext>(comparator);
+    contexts.add(s2);
+    contexts.add(s2);
+    assertEquals(1, contexts.size());
+  }
+
+  private static class SimpleCustomizationContext implements CustomizationContext {
+
+    /** . */
+    private final String type;
+
+    /** . */
+    private final int value;
+
+    private SimpleCustomizationContext(String type, int value) {
+      if (type == null) {
+        throw new NullPointerException();
+      }
+      if (value < 1) {
+        throw new IllegalArgumentException();
+      }
+
+      //
+      this.type = type;
+      this.value = value;
+    }
+
+    public String getContextId() {
+      return type + "/" + value;
+    }
+
+    public String getContextType() {
+      return type;
+    }
+
+    public boolean contains(CustomizationContext that) {
+      if (that instanceof SimpleCustomizationContext) {
+        SimpleCustomizationContext thatSimple = (SimpleCustomizationContext)that;
+        if (thatSimple.type.equals(type)) {
+          return thatSimple.value % value == 0;
+        }
+      }
+      return false;
+    }
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/content/CustomizationTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,93 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.content;
+
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class CustomizationTestCase extends AbstractPOMTestCase {
+
+/*
+  public void tesGetPersistedCustomization() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "NonExistingPortlet", FetchCondition.PERSISTED);
+    assertNull(content);
+  }
+
+  public void testGetNonExistingState() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "NonExistingPortlet", FetchCondition.ALWAYS);
+    assertNotNull(content);
+  }
+
+  public void testGetResolvableState() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "WeatherPortlet", FetchCondition.RESOLVABLE);
+    assertNotNull(content);
+  }
+
+  public void testCustomize() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "NonExistingPortlet", FetchCondition.ALWAYS);
+    Set<CustomizationContext> contexts = Collections.<CustomizationContext>singleton(model.getWorkspace());
+
+    //
+    Customization rootCustomization = content.getCustomization();
+    assertNull(content.getCustomization().getCustomization(contexts));
+    assertNotNull(rootCustomization);
+
+    //
+    Customization workspaceCustomization = rootCustomization.customize(CustomizationMode.CLONE, contexts);
+    assertNotNull(workspaceCustomization);
+    assertSame(content.getCustomization().getCustomization(contexts), workspaceCustomization);
+  }
+
+  public void testDestroyDescendantCustomization() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "WeatherPortlet", FetchCondition.RESOLVABLE);
+    Set<CustomizationContext> contexts = Collections.<CustomizationContext>singleton(model.getWorkspace());
+    Customization rootCustomization = content.getCustomization();
+    Customization workspaceCustomization = rootCustomization.customize(CustomizationMode.CLONE, contexts);
+    workspaceCustomization.destroy();
+    assertNull(rootCustomization.getCustomization(contexts));
+  }
+
+  public void testCannotDestroyRootCustomization() {
+    POM model = pomService.getModel();
+    ContentManager manager = model.getContentManager();
+    Content content = manager.getContent(Preferences.CONTENT_TYPE, "WeatherPortlet", FetchCondition.RESOLVABLE);
+    Customization rootCustomization = content.getCustomization();
+    try {
+      rootCustomization.destroy();
+      fail();
+    }
+    catch (IllegalStateException ignore) {
+    }
+  }
+*/
+
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/AttributesTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/AttributesTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/AttributesTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.core.api.ModelImpl;
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.Attributes;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class AttributesTestCase extends AbstractPOMTestCase {
+
+  public void testAttributes() {
+    ModelImpl model = pomService.getModel();
+    Site portal = model.getWorkspace().addSite(ObjectType.PORTAL_SITE, "portal");
+    Attributes portalAttributes = portal.getAttributes();
+    portalAttributes.setString("foo", "bar");
+    assertEquals("bar", portalAttributes.getString("foo"));
+    Attributes pageAttributes = portal.getRootPage().getAttributes();
+    pageAttributes.setString("foo", "bar");
+    assertEquals("bar", pageAttributes.getString("foo"));
+  }
+
+  public void testCascadedAttributes() {
+    ModelImpl model = pomService.getModel();
+    Site portal = model.getWorkspace().addSite(ObjectType.PORTAL_SITE, "portal");
+    Page root = portal.getRootPage();
+    Page a = root.addChild("a");
+    Attributes rootAttrs = root.getAttributes();
+    Attributes aAttrs = a.getAttributes();
+    rootAttrs.setString("foo", "foo_root");
+    aAttrs.setString("bar", "bar_a");
+    rootAttrs.setString("juu", "juu_root");
+    aAttrs.setString("juu", "juu_a");
+    Attributes combinedAttrs = a.getCascadingAttributes();
+    assertEquals("foo_root", combinedAttrs.getString("foo"));
+    assertEquals("bar_a", combinedAttrs.getString("bar"));
+    assertEquals("juu_a", combinedAttrs.getString("juu"));
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/ObjectTypeTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/ObjectTypeTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/ObjectTypeTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import junit.framework.TestCase;
+import org.gatein.mop.api.workspace.ObjectType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ObjectTypeTestCase extends TestCase {
+
+  public void testAssignability() {
+    assertFalse(ObjectType.WORKSPACE.isAssignableFrom(ObjectType.SITE));
+    assertFalse(ObjectType.SITE.isAssignableFrom(ObjectType.WORKSPACE));
+
+    //
+    assertTrue(ObjectType.SITE.isAssignableFrom(ObjectType.SITE));
+
+    //
+    assertTrue(ObjectType.SITE.isAssignableFrom(ObjectType.PORTAL_SITE));
+    assertFalse(ObjectType.PORTAL_SITE.isAssignableFrom(ObjectType.SITE));
+
+    //
+    assertTrue(ObjectType.SITE.isAssignableFrom(ObjectType.GROUP_SITE));
+    assertFalse(ObjectType.GROUP_SITE.isAssignableFrom(ObjectType.SITE));
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/POMTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/POMTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/POMTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,113 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.core.api.ModelImpl;
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class POMTestCase extends AbstractPOMTestCase {
+
+  public void testPortals() throws Exception {
+    test(0);
+  }
+
+  public void testGroups() throws Exception {
+    test(1);
+  }
+
+  private void test(int type) throws Exception {
+
+    ModelImpl model = pomService.getModel();
+
+    Workspace workspace = model.getWorkspace();
+
+    //
+    ObjectType<? extends Site> siteType;
+    if (type == 0) {
+      siteType = ObjectType.PORTAL_SITE;
+    } else if (type == 1) {
+      siteType = ObjectType.GROUP_SITE;
+    } else {
+      throw new UnsupportedOperationException();
+    }
+
+    //
+    Site site = workspace.addSite(siteType, "default");
+    Page root = site.getRootPage();
+    assertNotNull(root);
+    Page template = root.addChild("template");
+    assertNotNull(template);
+
+    UIContainer container = template.getRootComponent();
+    assertNotNull(container);
+    container.addChild(ObjectType.WINDOW, "window");
+
+    //
+    Page page = root.addChild("page");
+    assertNotNull(page);
+    page.setTemplate(template);
+
+    //
+    NavigationImpl nav = (NavigationImpl)site.getRootNavigation();
+    assertNotNull(nav);
+//    assertNull(nav.getLink());
+
+    //
+    nav.setTemplate(template);
+
+    //
+    PageLinkImpl pageTarget = nav.createPageLink();
+//    nav.setLink(pageTarget);
+//    pageTarget.setPage(page);
+
+    //
+    NavigationImpl subnav = nav.addChild("subnav");
+    URLLinkImpl urlTarget = nav.createURLTarget();
+//    subnav.setLink(urlTarget);
+//    urlTarget.setURL("http://www.exoplatform.com");
+
+    // Try something with template relationships
+
+    Collection<? extends Page> templatizedPages = template.getTemplatizedObjects(ObjectType.PAGE);
+    assertNotNull(templatizedPages);
+    assertEquals(1, templatizedPages.size());
+
+    Collection<? extends Navigation> templatizedNavigations = template.getTemplatizedObjects(ObjectType.NAVIGATION);
+    assertNotNull(templatizedNavigations);
+    assertEquals(1, templatizedNavigations.size());
+
+/*
+    Collection<Templatized> templatizedObjects = template.getTemplatizedObjects(Templatized.class);
+    assertNotNull(templatizedObjects);
+    assertEquals(2, templatizedObjects.size());
+*/
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/WorkspaceTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/WorkspaceTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/WorkspaceTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,204 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace;
+
+import org.gatein.mop.core.util.Tools;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.link.PageLink;
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+import org.gatein.mop.core.api.ModelImpl;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class WorkspaceTestCase extends AbstractPOMTestCase {
+
+  public void testGetSite() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site site = workspace.addSite(ObjectType.GROUP_SITE, "site");
+    assertNotNull(site);
+    Site s2 = workspace.getObject(ObjectType.SITE, site.getObjectId());
+    assertEquals(site, s2);
+    assertEquals(workspace, site.getWorkspace());
+  }
+
+  public void testGetPortal() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    assertNotNull(portal);
+    Site s2 = workspace.getObject(ObjectType.SITE, portal.getObjectId());
+    assertEquals(portal, s2);
+  }
+
+  public void testGetSites() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site s1 = workspace.addSite(ObjectType.GROUP_SITE, "foo");
+    assertNotNull(s1);
+    Site s2 = workspace.addSite(ObjectType.GROUP_SITE, "bar");
+    assertNotNull(s2);
+    assertEquals(Tools.set(workspace.getSites(ObjectType.GROUP_SITE)), Tools.set(s1, s2));
+  }
+
+  public void testRootPage() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Page root = portal.getRootPage();
+    assertEquals(portal, root.getSite());
+  }
+
+  public void testPageAddChild() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Page root = portal.getRootPage();
+    assertEquals(portal, root.getSite());
+    Page foo = root.addChild("foo");
+    assertNotNull(foo);
+    assertEquals(root, foo.getParent());
+    assertEquals(portal, foo.getSite());
+    Collection<? extends Page> children = root.getChildren();
+    assertEquals(Tools.set(foo), new HashSet<Page>(children));
+  }
+
+  public void testPortalTemplate() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Page template = portal.getRootPage().addChild("template");
+    portal.getRootNavigation().setTemplate(template);
+    assertEquals(template, portal.getRootNavigation().getTemplate());
+  }
+
+  public void testPageTemplate() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Page template = portal.getRootPage().addChild("template");
+    Page foo = portal.getRootPage().addChild("foo");
+    foo.setTemplate(template);
+    assertEquals(template, foo.getTemplate());
+  }
+
+  public void testLoading() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    String portalId = portal.getObjectId();
+    Page root = portal.getRootPage();
+    String rootId = root.getObjectId();
+    Page foo = root.addChild("foo");
+    String fooId= foo.getObjectId();
+
+/*
+    // Test loading
+    Workspace workspace2 = getWorkspace(workspace);
+
+    //
+    foo = workspace2.getPage(fooId);
+    assertNotNull(foo);
+    root = workspace2.getPage(rootId);
+    assertNotNull(root);
+    portal = workspace2.getSite(portalId);
+    assertEquals(root, foo.getParent());
+    assertEquals(portal, foo.getSite());
+    assertEquals(portal, root.getSite());
+*/
+  }
+
+  public void testNavigationHierarchy() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Navigation rootNav = portal.getRootNavigation();
+    assertNotNull(rootNav);
+    assertNotNull(rootNav.getAttributes());
+    assertNull(rootNav.getParent());
+    assertTrue(rootNav.getChildren().isEmpty());
+    Navigation fooNav = rootNav.addChild("foo");
+    assertNotNull(fooNav);
+    assertNotNull(fooNav.getAttributes());
+    assertSame(rootNav, fooNav.getParent());
+    assertTrue(fooNav.getChildren().isEmpty());
+    assertEquals(Collections.singleton(fooNav), new HashSet<Navigation>(rootNav.getChildren()));
+  }
+
+  public void testLink() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Navigation rootNav = portal.getRootNavigation();
+    assertNull(rootNav.getLink());
+
+    //
+    PageLink link = rootNav.linkTo(ObjectType.PAGE_LINK);
+    assertNotNull(link);
+    assertSame(link, rootNav.getLink());
+    Page rootPage = portal.getRootPage();
+    link.setPage(rootPage);
+    assertEquals(rootPage, link.getPage());
+  }
+
+  public void testNavigationClear() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Navigation rootNav = portal.getRootNavigation();
+    rootNav.addChild("a");
+    rootNav.addChild("b");
+    assertEquals(2, rootNav.getChildren().size());
+    rootNav.getChildren().clear();
+    assertEquals(0, rootNav.getChildren().size());
+  }
+
+  public void testNavigationGetSite() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Navigation rootNav = portal.getRootNavigation();
+    Navigation a = rootNav.addChild("a");
+    Site site = a.getSite();
+    assertSame(portal, site);
+  }
+
+  public void testRemoveReferencedTemplate() {
+    ModelImpl pom = pomService.getModel();
+    Workspace workspace = pom.getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Page root = portal.getRootPage();
+    Page template = root.addChild("template");
+    portal.getRootNavigation().setTemplate(template);
+    pom.save();
+
+    pom = pomService.getModel();
+    portal = workspace.getSite(ObjectType.PORTAL_SITE, "portal");
+    portal.getRootPage().getChild("template").destroy();
+    pom.save();
+
+    //
+    pom = pomService.getModel();
+    portal = workspace.getSite(ObjectType.PORTAL_SITE, "portal");
+    portal.destroy();
+    pom.save();
+
+    pom = pomService.getModel();
+    workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+
+  }
+}
\ No newline at end of file

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/content/CustomizationTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/content/CustomizationTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/api/workspace/content/CustomizationTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,145 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.api.workspace.content;
+
+import org.gatein.mop.core.api.AbstractPOMTestCase;
+import org.gatein.mop.core.content.portlet.Preferences;
+import org.gatein.mop.core.content.portlet.PreferencesBuilder;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.content.CustomizationContext;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class CustomizationTestCase extends AbstractPOMTestCase {
+
+  /** . */
+  private final Preferences prefs1 = new PreferencesBuilder().add("foo", "foo1").add("bar", "bar1", true).build();
+
+  /** . */
+  private final Preferences prefs2 = new PreferencesBuilder().add("foo", "foo2").add("bar", "bar2", true).build();
+
+  /** . */
+  private final Preferences prefs3 = new PreferencesBuilder().add("foo", "foo3").add("bar", "bar3").build();
+
+  public void testCustmizeWorkspace() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    assertNull(workspace.getCustomization("marseille"));
+    Customization<Preferences> customization = workspace.customize("marseille", Preferences.CONTENT_TYPE, "WeatherPortlet", prefs1);
+    assertNotNull(customization);
+    Preferences b = customization.getState();
+    assertEquals(prefs1, b);
+    assertEquals(0, customization.getContexts().size());
+    assertEquals("WeatherPortlet", customization.getContentId());
+    assertEquals(Preferences.CONTENT_TYPE, customization.getType());
+    assertEquals("marseille", customization.getName());
+  }
+
+  public void testCustomizeWindow() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    UIContainer layout = portal.getRootPage().getRootComponent();
+    UIWindow window = layout.addChild(ObjectType.WINDOW, "window");
+    Customization<Preferences> customization = window.customize(Preferences.CONTENT_TYPE, "WeatherPortlet", prefs1);
+    assertSame(customization, window.getCustomization());
+    assertEquals(null, customization.getName());
+    assertEquals(prefs1, customization.getState());
+  }
+
+  public void testCustomizeWindowByCloneWithNoState() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    UIContainer layout = portal.getRootPage().getRootComponent();
+    UIWindow window = layout.addChild(ObjectType.WINDOW, "window");
+    Customization<Preferences> customization = window.customize(Preferences.CONTENT_TYPE, "WeatherPortlet", null);
+    assertSame(customization, window.getCustomization());
+    assertEquals(null, customization.getName());
+    assertNull(customization.getState());
+  }
+
+  public void testCustomizeWindowBySpecialization() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Customization<Preferences> workspaceCustomization = portal.customize("marseille", Preferences.CONTENT_TYPE, "WeatherPortlet", prefs1);
+    UIContainer layout = portal.getRootPage().getRootComponent();
+    UIWindow window = layout.addChild(ObjectType.WINDOW, "window");
+    Customization<Preferences> windowCustomization = window.customize(workspaceCustomization);
+
+    //
+    assertNotNull(windowCustomization);
+    assertEquals(Arrays.asList(window, portal), new ArrayList<CustomizationContext>(windowCustomization.getContexts()));
+    assertSame(windowCustomization, window.getCustomization());
+    assertTrue(((Customization)windowCustomization) instanceof WorkspaceSpecialization);
+    assertEquals("marseille", windowCustomization.getName());
+
+    //
+    assertPreferences(prefs1, windowCustomization.getState());
+    assertPreferences(prefs1, workspaceCustomization.getState());
+
+    //
+    workspaceCustomization.setState(prefs2);
+    assertPreferences(prefs2, windowCustomization.getState());
+    assertPreferences(prefs2, workspaceCustomization.getState());
+
+    //
+    windowCustomization.setState(prefs3);
+    assertPreferences(prefs3, windowCustomization.getState());
+    assertPreferences(prefs2, workspaceCustomization.getState());
+  }
+
+  public void testDestroySpecializedCustomization() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Customization<Preferences> workspaceCustomization = portal.customize("marseille", Preferences.CONTENT_TYPE, "WeatherPortlet", prefs1);
+    UIContainer layout = portal.getRootPage().getRootComponent();
+    UIWindow window = layout.addChild(ObjectType.WINDOW, "window");
+    Customization<Preferences> windowCustomization = window.customize(workspaceCustomization);
+
+    //
+    workspaceCustomization.destroy();
+    assertEquals(prefs1, windowCustomization.getState());
+  }
+
+/*
+  public void testDeleteSpecializedCustomization() {
+    Workspace workspace = pomService.getModel().getWorkspace();
+    Site portal = workspace.addSite(ObjectType.PORTAL_SITE, "portal");
+    Customization<Preferences> workspaceCustomization = portal.customize("marseille", Preferences.CONTENT_TYPE, "WeatherPortlet", prefs1);
+    UIContainer layout = portal.getRootPage().getLayout();
+    UIWindow window = layout.addComponent(ObjectType.WINDOW, "window");
+    Customization<Preferences> windowCustomization = window.customize(workspaceCustomization);
+
+    //
+    workspaceCustomization.destroy();
+  }
+*/
+
+  private void assertPreferences(Preferences expectedPrefs, Preferences prefs) {
+    assertEquals("Was expecting to have prefs " + prefs + " equals to " + expectedPrefs, expectedPrefs, prefs);
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletContentProvider.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletContentProvider.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletContentProvider.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.impl.portlet;
+
+import org.gatein.mop.spi.content.ContentProvider;
+import org.gatein.mop.spi.content.GetState;
+import org.gatein.mop.core.content.portlet.Preference;
+import org.gatein.mop.core.content.portlet.Preferences;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class PortletContentProvider implements ContentProvider<Preferences> {
+
+  /** . */
+  private Map<String, PortletDefinition> definitions;
+
+  public PortletContentProvider() {
+    definitions = new HashMap<String, PortletDefinition>();
+  }
+
+  public void addPortletDefinition(String name, Preferences preferences) {
+    definitions.put(name, new PortletDefinition(name, preferences));
+  }
+
+  public GetState<Preferences> getState(String contentId) {
+    PortletDefinition def = definitions.get(contentId);
+    if (def != null) {
+      return new GetState<Preferences>(def.getPreferences());
+    } else {
+      return null;
+    }
+  }
+
+  public Preferences combine(List<Preferences> states) {
+    Map<String, Preference> entries = new HashMap<String, Preference>();
+
+    //
+    for (Preferences preferences : states) {
+      for (Preference entry : preferences.getEntries()) {
+        Preference previous = entries.get(entry.getName());
+        if (previous == null || !previous.isReadOnly()) {
+          entries.put(entry.getName(), entry);
+        }
+      }
+    }
+
+    //
+    return new Preferences(entries);
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletDefinition.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletDefinition.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/impl/portlet/PortletDefinition.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.impl.portlet;
+
+import org.gatein.mop.core.content.portlet.Preferences;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class PortletDefinition {
+
+  /** . */
+  private final String name;
+
+  /** . */
+  private final Preferences preferences;
+
+  public PortletDefinition(String name, Preferences preferences) {
+    this.name = name;
+    this.preferences = preferences;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Preferences getPreferences() {
+    return preferences;
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/KeyTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/KeyTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/KeyTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import junit.framework.TestCase;
+
+import java.util.Date;
+
+import org.gatein.mop.api.Key;
+import org.gatein.mop.api.ValueType;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class KeyTestCase extends TestCase {
+
+  public void testCreate() {
+    Key<String> a = Key.create("a", ValueType.STRING);
+    assertNotNull(a);
+    assertEquals("a", a.getName());
+
+    //
+    Key<Integer> b = Key.create("a", ValueType.INTEGER);
+    assertNotNull(b);
+    assertEquals("a", b.getName());
+
+    //
+    Key<Boolean> c = Key.create("a", ValueType.BOOLEAN);
+    assertNotNull(c);
+    assertEquals("a", c.getName());
+
+    //
+    Key<Date> d = Key.create("a", ValueType.DATE);
+    assertNotNull(d);
+    assertEquals("a", d.getName());
+
+    //
+    Key<Double> e = Key.create("a", ValueType.DOUBLE);
+    assertNotNull(e);
+    assertEquals("a", e.getName());
+
+    //
+    try {
+      Key.create("a", null);
+      fail();
+    }
+    catch (NullPointerException ignore) {
+    }
+  }
+
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ToolsTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ToolsTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ToolsTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ToolsTestCase extends TestCase {
+
+  public void testIterators() {
+    List<String> s1 = Arrays.asList();
+    List<String> s2 = Arrays.asList("a");
+    List<String> s3 = Arrays.asList("b", "c");
+    Iterator<String> it = Tools.iterator(s1.iterator(), s2.iterator(), s3.iterator());
+    assertEquals(Arrays.asList("a", "b", "c"), Tools.list(it));
+  }
+}

Added: components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ValueTypeTestCase.java
===================================================================
--- components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ValueTypeTestCase.java	                        (rev 0)
+++ components/mop/trunk/core/src/test/java/org/gatein/mop/core/util/ValueTypeTestCase.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,112 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.core.util;
+
+import junit.framework.TestCase;
+import org.gatein.mop.api.ValueType;
+
+import java.util.Date;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class ValueTypeTestCase extends TestCase {
+
+
+  public void testGet() {
+    assertEquals(ValueType.INTEGER, ValueType.get(5));
+    assertEquals(ValueType.BOOLEAN, ValueType.get(true));
+    assertEquals(ValueType.STRING, ValueType.get(""));
+    assertEquals(ValueType.DATE, ValueType.get(new Date()));
+    assertEquals(ValueType.DOUBLE, ValueType.get(0.5D));
+    try {
+      ValueType.get(null);
+      fail();
+    }
+    catch (NullPointerException ignore) {
+    }
+    try {
+      ValueType.get(new Object());
+      fail();
+    }
+    catch (IllegalArgumentException ignore) {
+    }
+  }
+
+  public void testDecode() {
+    assertEquals(ValueType.INTEGER, ValueType.decode(5));
+    assertEquals(ValueType.BOOLEAN, ValueType.decode(true));
+    assertEquals(ValueType.STRING, ValueType.decode(""));
+    assertEquals(ValueType.DATE, ValueType.decode(new Date()));
+    assertEquals(ValueType.DOUBLE, ValueType.decode(0.5D));
+    assertEquals(null, ValueType.decode(null));
+    assertEquals(null, ValueType.decode(new Object()));
+  }
+
+  public void testAccept() {
+    assertTrue(ValueType.INTEGER.isInstance(5));
+    assertFalse(ValueType.INTEGER.isInstance(""));
+    assertFalse(ValueType.INTEGER.isInstance(new Date()));
+    assertFalse(ValueType.INTEGER.isInstance(true));
+    assertFalse(ValueType.INTEGER.isInstance(0.5D));
+    assertFalse(ValueType.INTEGER.isInstance(null));
+    assertFalse(ValueType.INTEGER.isInstance(new Object()));
+
+    //
+    assertFalse(ValueType.BOOLEAN.isInstance(5));
+    assertFalse(ValueType.BOOLEAN.isInstance(""));
+    assertFalse(ValueType.BOOLEAN.isInstance(new Date()));
+    assertTrue(ValueType.BOOLEAN.isInstance(true));
+    assertFalse(ValueType.BOOLEAN.isInstance(0.5D));
+    assertFalse(ValueType.BOOLEAN.isInstance(null));
+    assertFalse(ValueType.BOOLEAN.isInstance(new Object()));
+
+    //
+    assertFalse(ValueType.DATE.isInstance(5));
+    assertFalse(ValueType.DATE.isInstance(""));
+    assertTrue(ValueType.DATE.isInstance(new Date()));
+    assertFalse(ValueType.DATE.isInstance(true));
+    assertFalse(ValueType.DATE.isInstance(0.5D));
+    assertFalse(ValueType.DATE.isInstance(null));
+    assertFalse(ValueType.DATE.isInstance(new Object()));
+
+    //
+    assertFalse(ValueType.STRING.isInstance(5));
+    assertTrue(ValueType.STRING.isInstance(""));
+    assertFalse(ValueType.STRING.isInstance(new Date()));
+    assertFalse(ValueType.STRING.isInstance(true));
+    assertFalse(ValueType.STRING.isInstance(0.5D));
+    assertFalse(ValueType.STRING.isInstance(null));
+    assertFalse(ValueType.STRING.isInstance(new Object()));
+
+    //
+    assertFalse(ValueType.DOUBLE.isInstance(5));
+    assertFalse(ValueType.DOUBLE.isInstance(""));
+    assertFalse(ValueType.DOUBLE.isInstance(new Date()));
+    assertFalse(ValueType.DOUBLE.isInstance(true));
+    assertTrue(ValueType.DOUBLE.isInstance(0.5D));
+    assertFalse(ValueType.DOUBLE.isInstance(null));
+    assertFalse(ValueType.DOUBLE.isInstance(new Object()));
+  }
+
+  public void testCast() {
+    // todo
+  }
+}

Added: components/mop/trunk/core/src/test/resources/conf/standalone/configuration-sjdbc.xml
===================================================================
--- components/mop/trunk/core/src/test/resources/conf/standalone/configuration-sjdbc.xml	                        (rev 0)
+++ components/mop/trunk/core/src/test/resources/conf/standalone/configuration-sjdbc.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<configuration
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+   xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
+  <component>
+    <key>org.exoplatform.services.log.LogConfigurationInitializer</key>
+    <type>org.exoplatform.services.log.LogConfigurationInitializer</type>
+    <init-params>
+      <value-param>
+        <name>logger</name>
+        <value>org.exoplatform.services.log.impl.BufferedLog4JLogger</value>
+      </value-param>
+      <value-param>
+        <name>configurator</name>
+        <value>org.exoplatform.services.log.impl.Log4JConfigurator</value>
+      </value-param>
+      <properties-param>
+        <name>properties</name>
+        <description>Log4J properties</description>
+        <property name="log4j.rootLogger" value="INFO, stdout, file"/>
+
+        <property name="log4j.appender.stdout" value="org.apache.log4j.ConsoleAppender"/>
+        <property name="log4j.appender.stdout.threshold" value="INFO"/>
+
+        <property name="log4j.appender.stdout.layout" value="org.apache.log4j.PatternLayout"/>
+        <property name="log4j.appender.stdout.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n"/>
+
+        <property name="log4j.appender.file" value="org.apache.log4j.FileAppender"/>
+        <property name="log4j.appender.file.File" value="target/jcr.log"/>
+
+        <property name="log4j.appender.file.layout" value="org.apache.log4j.PatternLayout"/>
+        <property name="log4j.appender.file.layout.ConversionPattern" value="%d{dd.MM.yyyy HH:mm:ss} *%-5p* [%t] %c{1}: %m (%F, line %L) %n"/>
+
+		<!-- property name="log4j.category.jcr.DBInitializer" value="DEBUG"/ -->
+
+        <!-- property name="log4j.category.jcr.SessionDataManager" value="DEBUG"/>
+        <property name="log4j.category.jcr.JDBCStorageConnection" value="DEBUG"/>
+        <property name="log4j.category.jcr.NodeImpl" value="DEBUG"/ -->
+
+        <!-- property name="log4j.category.jcr.WorkspaceStorageCacheImpl" value="DEBUG"/ -->
+        <!-- property name="log4j.category.database.DBSchemaCreator" value="DEBUG"/ -->
+        <!-- property name="log4j.category.jcr.WorkspaceDataReplicator" value="DEBUG"/ -->
+
+        <!-- property name="log4j.category.jcr.WorkspacePersistentDataManager" value="DEBUG"/ -->
+
+      </properties-param>
+
+      <!-- value-param>
+        <name>logger</name>
+        <value>org.exoplatform.services.log.impl.BufferedSimpleLog</value>
+      </value-param>
+      <value-param>
+        <name>configurator</name>
+        <value>org.exoplatform.services.log.impl.SimpleLogConfigurator</value>
+      </value-param>
+      <properties-param>
+        <name>properties</name>
+        <description>SimpleLog properties</description>
+        <property name="org.apache.commons.logging.simplelog.defaultlog" value="debug"/>
+        <property name="org.apache.commons.logging.simplelog.showdatetime" value="true"/>
+      </properties-param -->
+
+      <!-- value-param>
+        <name>logger</name>
+        <value>org.exoplatform.services.log.impl.BufferedJdk14Logger</value>
+      </value-param>
+      <value-param>
+        <name>configurator</name>
+        <value>org.exoplatform.services.log.impl.Jdk14Configurator</value>
+      </value-param>
+      <properties-param>
+        <name>properties</name>
+        <description>jdk1.4 Logger properties</description>
+        <property name="handlers" value="java.util.logging.ConsoleHandler"/>
+        <property name=".level" value="FINE"/>
+        <property name="java.util.logging.ConsoleHandler.level" value="FINE"/>
+      </properties-param -->
+
+    </init-params>
+  </component>
+    <component>
+      <key>org.exoplatform.services.jcr.RepositoryService</key>
+      <type>org.exoplatform.services.jcr.impl.RepositoryServiceImpl</type>
+      <component-plugins>
+        <component-plugin>
+            <name>add.namespaces</name>
+            <set-method>addPlugin</set-method>
+            <type>org.exoplatform.services.jcr.impl.AddNamespacesPlugin</type>
+            <init-params>
+              <properties-param>
+                <name>namespaces</name>
+                <property name="test" value="http://www.apache.org/jackrabbit/test"/>
+                <property name="exojcrtest" value="http://www.exoplatform.org/jcr/test/1.0"/>
+                <property name="rma" value="http://www.rma.com/jcr/"/>
+                <property name="metadata" value="http://www.exoplatform.com/jcr/metadata/1.1/"/>
+                <property name="mop" value="http://www.gatein.org/jcr/mop/1.0/"/>
+              </properties-param>
+            </init-params>
+        </component-plugin>
+        <component-plugin>
+          <name>add.nodeType</name>
+          <set-method>addPlugin</set-method>
+          <type>org.exoplatform.services.jcr.impl.AddNodeTypePlugin</type>
+          <init-params>
+          <values-param>
+            <name>autoCreatedInNewRepository</name>
+            <description>Node types configuration file</description>
+            <value>jar:/conf/standalone/nodetypes.xml</value>
+          </values-param>
+        </init-params>
+        </component-plugin>
+      </component-plugins>
+    </component>
+
+    <component>
+	    <key>org.exoplatform.services.jcr.config.RepositoryServiceConfiguration</key>
+	    <type>org.exoplatform.services.jcr.impl.config.RepositoryServiceConfigurationImpl</type>
+	    <init-params>
+	      <value-param>
+	        <name>conf-path</name>
+	        <description>JCR configuration file</description>
+	        <value>jar:/conf/standalone/jcr-config-sjdbc.xml</value>
+	        </value-param>
+	    </init-params>
+  </component>
+
+  <component>
+    <type>org.exoplatform.services.organization.impl.mock.DummyOrganizationService</type>
+  </component>
+
+  <component>
+    <key>org.exoplatform.services.security.Authenticator</key>
+    <type>org.exoplatform.services.organization.auth.OrganizationAuthenticatorImpl</type>
+  </component>
+
+  <component>
+      <type>org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog</type>
+  </component>
+
+  <component>
+      <key>org.exoplatform.services.transaction.TransactionService</key>
+      <type>org.exoplatform.services.transaction.impl.jotm.TransactionServiceJotmImpl</type>
+      <init-params>
+        <value-param>
+          <name>timeout</name>
+          <value>5</value>
+        </value-param>
+      </init-params>
+  </component>
+
+  <external-component-plugins>
+    <target-component>org.exoplatform.services.naming.InitialContextInitializer</target-component>
+      <component-plugin>
+        <name>bind.datasource</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+        <init-params>
+          <value-param>
+            <name>bind-name</name>
+            <value>jdbcjcr</value>
+          </value-param>
+          <value-param>
+            <name>class-name</name>
+            <value>javax.sql.DataSource</value>
+          </value-param>
+          <value-param>
+            <name>factory</name>
+            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+          </value-param>
+          <properties-param>
+            <name>ref-addresses</name>
+            <description>ref-addresses</description>
+            <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+            <property name="url" value="jdbc:hsqldb:file:target/temp/data/portal"/>
+            <property name="username" value="sa"/>
+            <property name="password" value=""/>
+          </properties-param>
+        </init-params>
+      </component-plugin>
+      <component-plugin>
+        <name>bind.datasource</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+        <init-params>
+          <value-param>
+            <name>bind-name</name>
+            <value>jdbcjcrtck</value>
+          </value-param>
+          <value-param>
+            <name>class-name</name>
+            <value>javax.sql.DataSource</value>
+          </value-param>
+          <value-param>
+            <name>factory</name>
+            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+          </value-param>
+          <properties-param>
+            <name>ref-addresses</name>
+            <description>ref-addresses</description>
+            <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+            <property name="url" value="jdbc:hsqldb:file:target/temp/data/portaltck"/>
+            <property name="username" value="sa"/>
+            <property name="password" value=""/>
+          </properties-param>
+        </init-params>
+      </component-plugin>
+    <!-- Resource configuration for UserTransaction
+       use JOTM
+    -->
+      <component-plugin>
+        <name>jotm.tx</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+        <init-params>
+          <value-param>
+            <name>bind-name</name>
+            <value>UserTransaction</value>
+          </value-param>
+          <value-param>
+            <name>class-name</name>
+            <value>javax.transaction.UserTransaction</value>
+          </value-param>
+          <value-param>
+            <name>factory</name>
+            <value>org.objectweb.jotm.UserTransactionFactory</value>
+          </value-param>
+          <properties-param>
+            <name>ref-addresses</name>
+            <description>ref-addresses</description>
+            <property name="jotm.timeout" value="60"/>
+          </properties-param>
+        </init-params>
+     </component-plugin>
+     <component-plugin>
+        <name>bind.jcr</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+        <init-params>
+          <value-param>
+            <name>bind-name</name>
+            <value>repo</value>
+          </value-param>
+          <value-param>
+            <name>class-name</name>
+            <value>javax.jcr.Repository</value>
+          </value-param>
+          <value-param>
+            <name>factory</name>
+            <value>org.exoplatform.services.jcr.impl.jndi.BindableRepositoryFactory</value>
+          </value-param>
+          <properties-param>
+            <name>ref-addresses</name>
+            <description>ref-addresses</description>
+            <property name="repositoryName" value="db1"/>
+            <!-- property name="containerConfig" value="exo-configuration.xml"/ -->
+          </properties-param>
+        </init-params>
+       </component-plugin>
+       <component-plugin>
+        <name>rmi.jcr</name>
+        <set-method>addPlugin</set-method>
+        <type>org.exoplatform.services.naming.BindReferencePlugin</type>
+        <init-params>
+          <value-param>
+            <name>bind-name</name>
+            <value>rmirepository</value>
+          </value-param>
+          <value-param>
+            <name>class-name</name>
+            <value>javax.jcr.Repository</value>
+          </value-param>
+          <value-param>
+            <name>factory</name>
+            <value>org.exoplatform.services.jcr.rmi.RepositoryFactory</value>
+          </value-param>
+          <properties-param>
+            <name>ref-addresses</name>
+            <description>ref-addresses</description>
+            <property name="url" value="//localhost:9999/repository"/>
+          </properties-param>
+        </init-params>
+       </component-plugin>
+  </external-component-plugins>
+
+  <remove-configuration>org.exoplatform.services.scheduler.JobSchedulerService</remove-configuration>
+  <!--<import>jar:/conf/database-configuration.hsql.xml</import> -->
+</configuration>

Added: components/mop/trunk/core/src/test/resources/conf/standalone/jcr-config-sjdbc.xml
===================================================================
--- components/mop/trunk/core/src/test/resources/conf/standalone/jcr-config-sjdbc.xml	                        (rev 0)
+++ components/mop/trunk/core/src/test/resources/conf/standalone/jcr-config-sjdbc.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,331 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<repository-service default-repository="db1">
+  <repositories>
+    <repository name="db1" system-workspace="ws" default-workspace="ws">
+      <security-domain>exo-domain</security-domain>
+      <!-- access-control>optional</access-control -->
+      <!-- access-control>disable</access-control -->
+      <session-max-age>1h</session-max-age>
+      <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+      <workspaces>
+        <workspace name="ws">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcr" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/ws" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/ws" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1/ws" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+          <lock-manager>
+            <time-out>15m</time-out>
+            <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+              <properties>
+                <property name="path" value="target/temp/lock" />
+              </properties>
+            </persister>
+          </lock-manager>
+        </workspace>
+
+        <workspace name="ws1">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcr" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/ws1" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/ws1" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1/ws1" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+        </workspace>
+
+        <workspace name="ws2">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcr" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/ws2" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws2" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/ws2" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1/ws2" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+        </workspace>
+      </workspaces>
+    </repository>
+
+    <repository name="db1tck" system-workspace="ws" default-workspace="ws">
+      <security-domain>exo-domain</security-domain>
+      <!-- access-control>optional</access-control -->
+      <!-- access-control>disable</access-control -->
+      <session-max-age>1h</session-max-age>
+      <authentication-policy>org.exoplatform.services.jcr.impl.core.access.JAASAuthenticator</authentication-policy>
+      <workspaces>
+        <workspace name="ws">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcrtck" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/wstck" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/wstck" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+              <property name="root-permissions" value="any read;*:/admin read;*:/admin add_node;*:/admin set_property;*:/admin remove"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1tck/ws" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+          <lock-manager>
+            <time-out>15m</time-out>
+            <persister class="org.exoplatform.services.jcr.impl.core.lock.FileSystemLockPersister">
+              <properties>
+                <property name="path" value="target/temp/lock" />
+              </properties>
+            </persister>
+          </lock-manager>
+        </workspace>
+
+        <workspace name="ws1">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcrtck" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/ws1tck" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws1" class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/ws1tck" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+              <property name="root-permissions" value="any read;*:/admin read;*:/admin add_node;*:/admin set_property;*:/admin remove"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1tck/ws1" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+        </workspace>
+
+        <workspace name="ws2">
+          <container class="org.exoplatform.services.jcr.impl.storage.jdbc.JDBCWorkspaceDataContainer">
+            <properties>
+              <property name="source-name" value="jdbcjcrtck" />
+              <property name="dialect" value="hsqldb" />
+              <property name="multi-db" value="false" />
+              <property name="update-storage" value="false" />
+              <property name="max-buffer-size" value="200k" />
+              <property name="swap-directory" value="target/temp/swap/ws2tck" />
+            </properties>
+            <value-storages>
+              <value-storage id="ws2"
+                class="org.exoplatform.services.jcr.impl.storage.value.fs.TreeFileValueStorage">
+                <properties>
+                  <property name="path" value="target/temp/values/ws2tck" />
+                </properties>
+                <filters>
+                  <filter property-type="Binary" />
+                </filters>
+              </value-storage>
+            </value-storages>
+          </container>
+          <initializer class="org.exoplatform.services.jcr.impl.core.ScratchWorkspaceInitializer">
+            <properties>
+              <property name="root-nodetype" value="nt:unstructured"/>
+              <property name="root-permissions" value="any read;*:/admin read;*:/admin add_node;*:/admin set_property;*:/admin remove"/>
+            </properties>
+          </initializer>
+          <cache enabled="true" class="org.exoplatform.services.jcr.impl.dataflow.persistent.LinkedWorkspaceStorageCacheImpl">
+            <properties>
+              <property name="max-size" value="2k" />
+              <property name="live-time" value="20m" />
+            </properties>
+          </cache>
+          <query-handler class="org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex">
+            <properties>
+              <property name="index-dir" value="target/temp/index/db1/ws2tck" />
+              <property name="synonymprovider-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.PropertiesSynonymProvider" />
+              <property name="synonymprovider-config-path" value="../../synonyms.properties" />
+              <property name="support-highlighting" value="true" />
+              <property name="indexing-configuration-path" value="../../indexing-configuration.xml" />
+              <property name="query-class" value="org.exoplatform.services.jcr.impl.core.query.QueryImpl" />
+              <property name="spellchecker-class" value="org.exoplatform.services.jcr.impl.core.query.lucene.spell.LuceneSpellChecker$FiveSecondsRefreshInterval"/>
+            </properties>
+          </query-handler>
+        </workspace>
+      </workspaces>
+    </repository>
+  </repositories>
+</repository-service>

Added: components/mop/trunk/core/src/test/resources/indexing-configuration.xml
===================================================================
--- components/mop/trunk/core/src/test/resources/indexing-configuration.xml	                        (rev 0)
+++ components/mop/trunk/core/src/test/resources/indexing-configuration.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<!DOCTYPE configuration SYSTEM "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd">
+<configuration xmlns:jcr="http://www.jcp.org/jcr/1.0"
+               xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
+
+  <!--aggregate primaryType="nt:file">
+    <include>jcr:content</include>
+  </aggregate-->
+
+   <index-rule nodeType="nt:unstructured"
+              boost="2.0"
+              condition="ancestor::*/@priority = 'low'">
+   <property>Text</property>
+   </index-rule>
+
+   <index-rule nodeType="nt:unstructured"
+              boost="2.0"
+              condition="parent::indrootparent/@priority = 'low'">
+   <property>Text</property>
+   </index-rule>
+
+   <index-rule nodeType="nt:unstructured"
+              boost="2.0"
+              condition="indrootchild/@priority = 'gg'">
+   <property>Text</property>
+   </index-rule>
+
+</configuration>
+
+

Added: components/mop/trunk/core/src/test/resources/synonyms.properties
===================================================================
--- components/mop/trunk/core/src/test/resources/synonyms.properties	                        (rev 0)
+++ components/mop/trunk/core/src/test/resources/synonyms.properties	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,19 @@
+#  Licensed to the Apache Software Foundation (ASF) under one or more
+#  contributor license agreements.  See the NOTICE file distributed with
+#  this work for additional information regarding copyright ownership.
+#  The ASF licenses this file to You under the Apache License, Version 2.0
+#  (the "License"); you may not use this file except in compliance with
+#  the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+# this is a synonym definition file for PropertiesSynonymProvider
+ASF=Apache Software Foundation
+quick=fast
+sluggish=lazy
\ No newline at end of file

Added: components/mop/trunk/parent/pom.xml
===================================================================
--- components/mop/trunk/parent/pom.xml	                        (rev 0)
+++ components/mop/trunk/parent/pom.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,362 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <!--
+      <repositories> <repository> <id>exo-int</id> <name>exoplatform.org internal repository</name> <url>http://maven2.exoplatform.org/rest/maven2</url> <layout>default</layout> </repository>
+      </repositories>
+   -->
+
+   <modelVersion>4.0.0</modelVersion>
+
+   <!-- ****************** -->
+   <!-- Project Definition -->
+   <!-- ****************** -->
+
+   <parent>
+      <groupId>org.jboss</groupId>
+      <artifactId>jboss-parent</artifactId>
+      <version>5-beta-1</version>
+   </parent>
+
+   <groupId>org.gatein.mop</groupId>
+   <artifactId>mop.parent</artifactId>
+   <version>1.0.0-SNAPSHOT</version>
+   <packaging>pom</packaging>
+
+   <name>MOP Parent</name>
+   <description>Model Object for Portal Parent</description>
+   <url>http://www.exoplatform.com</url>
+
+   <organization>
+      <name>eXo Platform SAS</name>
+      <url>http://www.exoplatform.com</url>
+   </organization>
+
+   <licenses>
+      <license>
+         <name>LGPL, version 2.1</name>
+         <url>http://www.opensource.org/licenses/lgpl-license.php</url>
+      </license>
+   </licenses>
+
+   <scm>
+      <connection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/parent/</connection>
+      <developerConnection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/parent/</developerConnection>
+      <url>http://fisheye.exoplatform.org/browse/projects-internal/exorh/exo-portal/mop/trunk/parent/</url>
+   </scm>
+
+   <repositories>
+      <repository>
+         <id>jboss.com</id>
+         <url>http://repository.jboss.com/maven2</url>
+      </repository>
+   </repositories>
+   
+   <dependencies>
+
+      <dependency>
+         <groupId>org.slf4j</groupId>
+         <artifactId>slf4j-log4j12</artifactId>
+         <version>1.5.8</version>
+         <scope>test</scope>
+      </dependency>
+
+   </dependencies>
+
+   <properties>
+      <!-- Plugins versions are defined in properties to be reused in build and reporting parts if necessary -->
+      <clean.plugin.version>2.3</clean.plugin.version>
+      <buildnumber.plugin.version>1.0-beta-3</buildnumber.plugin.version>
+      <compiler.plugin.version>2.0.2</compiler.plugin.version>
+      <deploy.plugin.version>2.4</deploy.plugin.version>
+      <enforcer.plugin.version>1.0-beta-1</enforcer.plugin.version>
+      <install.plugin.version>2.3</install.plugin.version>
+      <jar.plugin.version>2.2</jar.plugin.version>
+      <javadoc.plugin.version>2.6</javadoc.plugin.version>
+      <release.plugin.version>2.0-beta-9</release.plugin.version>
+      <resources.plugin.version>2.3</resources.plugin.version>
+      <site.plugin.version>2.0.1</site.plugin.version>
+      <source.plugin.version>2.1</source.plugin.version>
+      <surefire.plugin.version>2.4.3</surefire.plugin.version>
+
+      <!-- Plugins settings -->
+
+      <!-- maven-compiler-plugin -->
+      <maven.compiler.target>1.5</maven.compiler.target>
+      <maven.compiler.source>1.5</maven.compiler.source>
+
+      <!-- maven-release-plugin -->
+      <useReleaseProfile>false</useReleaseProfile>
+      <arguments>-Prelease</arguments>
+   </properties>
+
+   <!-- **************** -->
+   <!-- Build Definition -->
+   <!-- **************** -->
+
+   <build>
+      <pluginManagement>
+         <!--  Plugins are sorted by shortname : clean, deploy, ... -->
+         <plugins>
+            <plugin>
+               <groupId>org.codehaus.mojo</groupId>
+               <artifactId>buildnumber-maven-plugin</artifactId>
+               <version>${buildnumber.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-clean-plugin</artifactId>
+               <version>${clean.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-compiler-plugin</artifactId>
+               <version>${compiler.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-deploy-plugin</artifactId>
+               <version>${deploy.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-enforcer-plugin</artifactId>
+               <version>${enforcer.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-install-plugin</artifactId>
+               <version>${install.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-jar-plugin</artifactId>
+               <version>${jar.plugin.version}</version>
+               <configuration>
+                  <archive>
+                     <manifest>
+                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                     </manifest>
+                  </archive>
+               </configuration>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-javadoc-plugin</artifactId>
+               <version>${javadoc.plugin.version}</version>
+               <configuration>
+                  <archive>
+                     <manifest>
+                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                     </manifest>
+                  </archive>
+               </configuration>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-release-plugin</artifactId>
+               <version>${release.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-resources-plugin</artifactId>
+               <version>${resources.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-site-plugin</artifactId>
+               <version>${site.plugin.version}</version>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-source-plugin</artifactId>
+               <version>${source.plugin.version}</version>
+               <configuration>
+                  <archive>
+                     <manifest>
+                        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                     </manifest>
+                  </archive>
+               </configuration>
+            </plugin>
+            <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-surefire-plugin</artifactId>
+               <version>${surefire.plugin.version}</version>
+            </plugin>
+         </plugins>
+      </pluginManagement>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-enforcer-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>enforce-java-version</id>
+                  <goals>
+                     <goal>enforce</goal>
+                  </goals>
+                  <configuration>
+                     <rules>
+                        <requireJavaVersion>
+                           <message>Even if deliveries are checked to be compatible with Java 5, MOP requires Java 6 to build.</message>
+                           <version>1.6</version>
+                        </requireJavaVersion>
+                     </rules>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+      </plugins>
+   </build>
+   <profiles>
+      <profile>
+         <id>release</id>
+         <repositories>
+            <!--  Used by animal-sniffer -->
+            <repository>
+               <id>maven2-repository.dev.java.net</id>
+               <name>Java.net Repository for Maven</name>
+               <url>http://download.java.net/maven/2/</url>
+            </repository>
+         </repositories>
+         <pluginRepositories>
+            <!--  Used by animal-sniffer -->
+            <pluginRepository>
+               <id>maven2-repository.dev.java.net</id>
+               <name>Java.net Repository for Maven</name>
+               <url>http://download.java.net/maven/2/</url>
+            </pluginRepository>
+         </pluginRepositories>
+         <build>
+            <pluginManagement>
+               <plugins>
+                  <plugin>
+                     <groupId>org.apache.maven.plugins</groupId>
+                     <artifactId>maven-jar-plugin</artifactId>
+                     <configuration>
+                        <archive>
+                           <!-- Additional entries in Manifest -->
+                           <manifestEntries>
+                              <SCM-Revision>${buildNumber}</SCM-Revision>
+                           </manifestEntries>
+                        </archive>
+                     </configuration>
+                  </plugin>
+                  <plugin>
+                     <groupId>org.apache.maven.plugins</groupId>
+                     <artifactId>maven-javadoc-plugin</artifactId>
+                     <configuration>
+                        <archive>
+                           <!-- Additional entries in Manifest -->
+                           <manifestEntries>
+                              <SCM-Revision>${buildNumber}</SCM-Revision>
+                           </manifestEntries>
+                        </archive>
+                     </configuration>
+                  </plugin>
+                  <plugin>
+                     <groupId>org.apache.maven.plugins</groupId>
+                     <artifactId>maven-source-plugin</artifactId>
+                     <configuration>
+                        <archive>
+                           <!-- Additional entries in Manifest -->
+                           <manifestEntries>
+                              <SCM-Revision>${buildNumber}</SCM-Revision>
+                           </manifestEntries>
+                        </archive>
+                     </configuration>
+                  </plugin>
+               </plugins>
+            </pluginManagement>
+            <plugins>
+               <plugin>
+                  <groupId>org.codehaus.mojo</groupId>
+                  <artifactId>buildnumber-maven-plugin</artifactId>
+                  <executions>
+                     <execution>
+                        <!-- Requires Maven 2.1+ -->
+                        <phase>prepare-package</phase>
+                        <goals>
+                           <goal>create</goal>
+                        </goals>
+                     </execution>
+                  </executions>
+               </plugin>
+               <plugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-javadoc-plugin</artifactId>
+                  <executions>
+                     <execution>
+                        <id>attach-javadocs</id>
+                        <goals>
+                           <goal>jar</goal>
+                        </goals>
+                     </execution>
+                  </executions>
+               </plugin>
+               <plugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-enforcer-plugin</artifactId>
+                  <executions>
+                     <execution>
+                        <id>enforce-maven-version</id>
+                        <goals>
+                           <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                           <rules>
+                              <requireMavenVersion>
+                                 <message>We are using some Maven 2.1+ features and only 2.2+ has the required stability. 2.2.1 is recommanded.</message>
+                                 <version>2.2.0</version>
+                              </requireMavenVersion>
+                           </rules>
+                        </configuration>
+                     </execution>
+                  </executions>
+               </plugin>
+               <plugin>
+                  <groupId>org.jvnet</groupId>
+                  <artifactId>animal-sniffer</artifactId>
+                  <version>1.2</version>
+                  <executions>
+                     <execution>
+                        <id>check-java-compatibility</id>
+                        <phase>compile</phase>
+                        <goals>
+                           <goal>check</goal>
+                        </goals>
+                        <configuration>
+                           <signature>
+                              <groupId>org.jvnet.animal-sniffer</groupId>
+                              <artifactId>java1.5</artifactId>
+                              <version>1.0</version>
+                           </signature>
+                        </configuration>
+                     </execution>
+                  </executions>
+               </plugin>
+            </plugins>
+         </build>
+      </profile>
+   </profiles>
+</project>

Added: components/mop/trunk/pom.xml
===================================================================
--- components/mop/trunk/pom.xml	                        (rev 0)
+++ components/mop/trunk/pom.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,67 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+
+   <!-- ****************** -->
+   <!-- Project Definition -->
+   <!-- ****************** -->
+
+   <groupId>org.gatein.mop</groupId>
+   <artifactId>mop.main</artifactId>
+   <version>1.0.0-SNAPSHOT</version>
+   <packaging>pom</packaging>
+
+   <name>MOP Main</name>
+
+   <url>http://www.exoplatform.com</url>
+   <description>Main of the Object Model for Portal</description>
+
+   <organization>
+      <name>eXo Platform SAS</name>
+      <url>http://www.exoplatform.com</url>
+   </organization>
+
+   <licenses>
+      <license>
+         <name>LGPL, version 2.1</name>
+         <url>http://www.opensource.org/licenses/lgpl-license.php</url>
+      </license>
+   </licenses>
+
+   <scm>
+      <connection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/</connection>
+      <developerConnection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/</developerConnection>
+      <url>http://fisheye.exoplatform.org/browse/projects-internal/exorh/exo-portal/mop/trunk/</url>
+   </scm>
+
+   <!-- **************** -->
+   <!-- Build Definition -->
+   <!-- **************** -->
+
+   <modules>
+      <module>parent</module>
+      <module>api</module>
+      <module>spi</module>
+      <module>core</module>
+   </modules>
+
+</project>

Added: components/mop/trunk/spi/pom.xml
===================================================================
--- components/mop/trunk/spi/pom.xml	                        (rev 0)
+++ components/mop/trunk/spi/pom.xml	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,60 @@
+<!--
+
+    Copyright (C) 2009 eXo Platform SAS.
+
+    This is free software; you can redistribute it and/or modify it
+    under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation; either version 2.1 of
+    the License, or (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this software; if not, write to the Free
+    Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+    02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <modelVersion>4.0.0</modelVersion>
+
+   <parent>
+      <groupId>org.gatein.mop</groupId>
+      <artifactId>mop.parent</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+      <relativePath>../parent/pom.xml</relativePath>
+   </parent>
+
+   <!-- ****************** -->
+   <!-- Project Definition -->
+   <!-- ****************** -->
+
+   <groupId>org.gatein.mop</groupId>
+   <artifactId>mop.spi</artifactId>
+   <version>1.0.0-SNAPSHOT</version>
+   <packaging>jar</packaging>
+
+   <name>MOP SPI</name>
+   <description>SPI of the Object Model for Portal</description>
+
+   <scm>
+      <connection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/spi/</connection>
+      <developerConnection>scm:svn:http://svn.exoplatform.org/projects/exorh/exo-portal/mop/trunk/spi/</developerConnection>
+      <url>http://fisheye.exoplatform.org/browse/projects-internal/exorh/exo-portal/mop/trunk/spi/</url>
+   </scm>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>org.gatein.mop</groupId>
+         <artifactId>mop.api</artifactId>
+         <version>1.0.0-SNAPSHOT</version>
+      </dependency>
+
+   </dependencies>
+
+</project>

Added: components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/ContentProvider.java
===================================================================
--- components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/ContentProvider.java	                        (rev 0)
+++ components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/ContentProvider.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.spi.content;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface ContentProvider<S> {
+
+  /**
+   * <p>Returns the state wrapper associated with the specified content or null if no relationship can be
+   * done with the specifiec content. When the <tt>GetState</tt> response is returned with a null state
+   * it means that the content is found but is stateless.</p>
+   *
+   * @param contentId the content id
+   * @return the content state
+   */
+  GetState getState(String contentId);
+
+  /**
+   * Combines several states into a single state representation.
+   *
+   * @param states the various states to combine
+   * @return the combined state
+   */
+  S combine(List<S> states);
+
+}

Added: components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/GetState.java
===================================================================
--- components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/GetState.java	                        (rev 0)
+++ components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/content/GetState.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.spi.content;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GetState<S> {
+
+  /** . */
+  private final S state;
+
+  public GetState(S state) {
+    this.state = state;
+  }
+
+  public S getState() {
+    return state;
+  }
+}

Added: components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/customization/CustomizationContextProvider.java
===================================================================
--- components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/customization/CustomizationContextProvider.java	                        (rev 0)
+++ components/mop/trunk/spi/src/main/java/org/gatein/mop/spi/customization/CustomizationContextProvider.java	2009-08-25 06:06:36 UTC (rev 47)
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.gatein.mop.spi.customization;
+
+import org.gatein.mop.api.content.CustomizationContext;
+
+/**
+ * Integration for customization context.
+ *
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface CustomizationContextProvider {
+
+  /**
+   * Resolves the provided customization context or returns null if no context can be resolved.
+   *
+   * @param contextId the context id
+   * @return the resolved context
+   */
+  CustomizationContext resolveContext(String contextId);
+
+}



More information about the gatein-commits mailing list