You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/07/31 04:47:59 UTC

[40/51] [abbrv] [partial] zest-java git commit: Revert "First round of changes to move to org.apache.zest namespace."

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java
new file mode 100644
index 0000000..3562c6e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011, Rickard Öberg.
+ * Copyright (c) 2012, Niclas Hedhman.
+ *
+ * Licensed 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.
+ *
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Listener for ActivationEvent events
+ */
+public interface ActivationEventListener
+{
+    void onEvent( ActivationEvent event )
+        throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java
new file mode 100644
index 0000000..41e3b5e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ActivationEventListenerRegistration.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, Rickard Öberg.
+ * Copyright (c) 2012, Niclas Hedhman.
+ *
+ * Licensed 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.
+ *
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Use this to register listeners for ActivationEvents.
+ *
+ * This is implemented by Application, Layer, Module, for example.
+ */
+public interface ActivationEventListenerRegistration
+{
+    /**
+     * @param listener will be notified when Activation events occur
+     */
+    void registerActivationEventListener( ActivationEventListener listener );
+
+    /**
+     * @param listener will not be notified when Activation events occur anymore
+     */
+    void deregisterActivationEventListener( ActivationEventListener listener );
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java b/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java
new file mode 100644
index 0000000..30d06be
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ActivationException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 Niclas Hedhman.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Thrown when unable to activate.
+ */
+public class ActivationException extends Exception
+{
+    private static final long serialVersionUID = 1L;
+    public ActivationException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/Activator.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/Activator.java b/core/api/src/main/java/org/qi4j/api/activation/Activator.java
new file mode 100644
index 0000000..2cba184
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/Activator.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012 Paul Merlin.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Assemble Activators to hook Services Activation.
+ *
+ * @param <ActivateeType> Type of the activatee.
+ *
+ * @see ActivatorAdapter
+ * @see org.qi4j.api.service.ServiceActivation
+ */
+public interface Activator<ActivateeType>
+{
+
+    /**
+     * Called before activatee activation.
+     */
+    void beforeActivation( ActivateeType activating )
+        throws Exception;
+
+    /**
+     * Called after activatee activation.
+     */
+    void afterActivation( ActivateeType activated )
+        throws Exception;
+
+    /**
+     * Called before activatee passivation.
+     */
+    void beforePassivation( ActivateeType passivating )
+        throws Exception;
+
+    /**
+     * Called after activatee passivation.
+     */
+    void afterPassivation( ActivateeType passivated )
+        throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java b/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java
new file mode 100644
index 0000000..59652b9
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ActivatorAdapter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 Paul Merlin.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Adapter for Activator.
+ * <p>If you are thinking about Service activation, see {@link org.qi4j.api.service.ServiceActivatorAdapter}.</p>
+ *
+ * @param <ActivateeType> Type of the activatee.
+ */
+public class ActivatorAdapter<ActivateeType>
+    implements Activator<ActivateeType>
+{
+    /**
+     * Called before activatee activation.
+     * @param activating Activating activatee
+     */
+    @Override
+    public void beforeActivation( ActivateeType activating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after activatee activation.
+     * @param activated Activating activatee
+     */
+    @Override
+    public void afterActivation( ActivateeType activated )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called before activatee passivation.
+     * @param passivating Passivating activatee
+     */
+    @Override
+    public void beforePassivation( ActivateeType passivating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after activatee passivation.
+     * @param passivated Passivated activatee
+     */
+    @Override
+    public void afterPassivation( ActivateeType passivated )
+        throws Exception
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java b/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java
new file mode 100644
index 0000000..bfe3fee
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ActivatorDescriptor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.activation;
+
+/**
+ * Activator Descriptor.
+ */
+public interface ActivatorDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/Activators.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/Activators.java b/core/api/src/main/java/org/qi4j/api/activation/Activators.java
new file mode 100644
index 0000000..8d0f7e6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/Activators.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Paul Merlin.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is used in ServiceComposites to declare Activator implementation classes.
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( ElementType.TYPE )
+@Documented
+public @interface Activators
+{
+
+    /**
+     * @return Activator implementation classes.
+     */
+    Class<? extends Activator<?>>[] value();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java b/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java
new file mode 100644
index 0000000..62b1f67
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/ApplicationPassivationThread.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2013 Paul Merlin.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+import java.io.PrintStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.qi4j.api.structure.Application;
+
+/**
+ * Application Passivation Thread to use as a Shutdown Hook.
+ * <pre>Runtime.getRuntime().addShutdownHook( new ApplicationPassivationThread( application ) );</pre>
+ * <p>Constructors to control where errors are logged are provided. They support PrintStream (STDOUT/STDERR) and SLF4J
+ * Loggers. Defaults to STDERR.</p>
+ */
+public final class ApplicationPassivationThread
+    extends Thread
+{
+    /**
+     * Create a new Application Passivation Thread that output errors to STDERR.
+     * @param application The Application to passivate
+     */
+    public ApplicationPassivationThread( final Application application )
+    {
+        this( application, null, null );
+    }
+
+    /**
+     * Create a new Application Passivation Thread that output errors to a Logger.
+     * @param application The Application to passivate
+     * @param logger Logger for errors
+     */
+    public ApplicationPassivationThread( Application application, Logger logger )
+    {
+        this( application, null, logger );
+    }
+
+    /**
+     * Create a new Application Passivation Thread that output errors to a PrintStream.
+     * @param application The Application to passivate
+     * @param output PrintStream for errors
+     */
+    public ApplicationPassivationThread( Application application, PrintStream output )
+    {
+        this( application, output, null );
+    }
+
+    private ApplicationPassivationThread( Application application, PrintStream output, Logger logger )
+    {
+        super( new ApplicationPassivation( application, output, logger ),
+               application.name() + " Passivation Thread" );
+    }
+
+    private static class ApplicationPassivation
+        implements Runnable
+    {
+
+        private final Application application;
+        private final PrintStream output;
+        private final Logger logger;
+
+        private ApplicationPassivation( Application application, PrintStream output, Logger logger )
+        {
+            this.application = application;
+            this.output = output;
+            this.logger = logger;
+        }
+
+        @Override
+        public void run()
+        {
+            try
+            {
+                application.passivate();
+            }
+            catch( PassivationException ex )
+            {
+                String message = application.name() + " " + ex.getMessage();
+                if( logger != null )
+                {
+                    logger.log( Level.SEVERE, message, ex );
+                }
+                else if( output != null )
+                {
+                    output.println( message );
+                    ex.printStackTrace( output );
+                }
+                else
+                {
+                    ex.printStackTrace();
+                }
+            }
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java b/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java
new file mode 100644
index 0000000..c3f33fe
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/PassivationException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Niclas Hedhman.
+ * Copyright 2013 Paul Merlin.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.activation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Thrown when unable to passivate.
+ *
+ * Printed StackTrace contains all causes in order as suppressed exceptions.
+ */
+public final class PassivationException
+    extends Exception
+{
+
+    private static final long serialVersionUID = 1L;
+    private final List<Exception> causes;
+
+    /**
+     * Create new PassivationException.
+     * @param exceptions All exceptions encountered during passivation, in order
+     */
+    public PassivationException( Collection<Exception> exceptions )
+    {
+        super( "Passivation Exception - [has " + exceptions.size() + " cause(s)]" );
+        for( Throwable cause : exceptions )
+        {
+            addSuppressed( cause );
+        }
+        this.causes = new ArrayList<>( exceptions );
+    }
+
+    /**
+     * @return All exceptions encountered during passivation, in order
+     */
+    public List<Exception> causes()
+    {
+        return causes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/activation/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/activation/package.html b/core/api/src/main/java/org/qi4j/api/activation/package.html
new file mode 100644
index 0000000..47b333a
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/activation/package.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+<html>
+    <body>
+        <h2>Activation API.</h2>
+        <p>
+            The Activation API package contains types used by client code to integrate with the Zest™ Runtime activation
+            mechanism. In assembly, client code can easily listen to Structure (Application, Layers and Modules) and
+            Services activation events, or, declare Structure and Service Activators.
+        </p>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java b/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java
new file mode 100644
index 0000000..60afce2
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AbstractAssociation.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+/**
+ * Base interface for all associations.
+ */
+public interface AbstractAssociation
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/Association.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/Association.java b/core/api/src/main/java/org/qi4j/api/association/Association.java
new file mode 100644
index 0000000..acd406f
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/Association.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * Association to a single EntityComposite.
+ */
+public interface Association<T> extends AbstractAssociation
+{
+    /**
+     * Get the associated entity.
+     *
+     * @return the associated entity
+     */
+    T get();
+
+    /**
+     * Set the associated entity.
+     *
+     * @param associated the entity
+     *
+     * @throws IllegalArgumentException thrown if the entity is not a valid reference for this association
+     * @throws IllegalStateException    thrown if association is immutable
+     */
+    void set( T associated )
+        throws IllegalArgumentException, IllegalStateException;
+
+    /**
+     * @return the the reference of the associated entity.
+     */
+    EntityReference reference();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java b/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java
new file mode 100644
index 0000000..9f7576a
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationDescriptor.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Type;
+import org.qi4j.api.common.QualifiedName;
+import org.qi4j.api.structure.MetaInfoHolder;
+
+/**
+ * Association Descriptor.
+ */
+public interface AssociationDescriptor extends MetaInfoHolder
+{
+    /**
+     * Get the qualified name of the association. This is constructed by
+     * concatenating the name of the declaring interface with the name
+     * of the method, using ":" as separator.
+     * <p>
+     * Example:
+     * </p>
+     * <p>
+     * com.somecompany.MyInterface with association method
+     * </p>
+     * <pre><code>
+     * Association&lt;String&gt; someAssociation();
+     * </code></pre>
+     * will have the qualified name:
+     * <pre><code>
+     * com.somecompany.MyInterface:someAssociation
+     * </code></pre>
+     *
+     * @return the qualified name of the association
+     */
+    QualifiedName qualifiedName();
+
+    /**
+     * Get the type of the associated Entities
+     *
+     * @return the type of the associated Entities
+     */
+    Type type();
+
+    boolean isImmutable();
+
+    boolean isAggregated();
+
+    AccessibleObject accessor();
+
+    boolean queryable();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java
new file mode 100644
index 0000000..ac26de3
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationMixin.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import org.qi4j.api.common.AppliesTo;
+import org.qi4j.api.common.AppliesToFilter;
+import org.qi4j.api.injection.scope.State;
+
+/**
+ * Generic mixin for associations.
+ */
+@AppliesTo( { AssociationMixin.AssociationFilter.class } )
+public final class AssociationMixin
+    implements InvocationHandler
+{
+    @State
+    private AssociationStateHolder associations;
+
+    @Override
+    public Object invoke( Object proxy, Method method, Object[] args )
+        throws Throwable
+    {
+        return associations.associationFor( method );
+    }
+
+    /**
+     * Associations generic mixin AppliesToFilter.
+     */
+    public static class AssociationFilter
+        implements AppliesToFilter
+    {
+        @Override
+        public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> modifierClass )
+        {
+            return Association.class.isAssignableFrom( method.getReturnType() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java b/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java
new file mode 100644
index 0000000..83c04a4
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationStateDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2008-2011, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.association;
+
+import org.qi4j.api.common.QualifiedName;
+import org.qi4j.api.composite.StateDescriptor;
+
+/**
+ * Associations State Descriptor.
+ */
+public interface AssociationStateDescriptor extends StateDescriptor
+{
+    AssociationDescriptor getAssociationByName( String name )
+        throws IllegalArgumentException;
+
+    AssociationDescriptor getAssociationByQualifiedName( QualifiedName name )
+        throws IllegalArgumentException;
+
+    AssociationDescriptor getManyAssociationByName( String name )
+        throws IllegalArgumentException;
+
+    AssociationDescriptor getManyAssociationByQualifiedName( QualifiedName name )
+        throws IllegalArgumentException;
+
+    AssociationDescriptor getNamedAssociationByName( String name )
+        throws IllegalArgumentException;
+
+    AssociationDescriptor getNamedAssociationByQualifiedName( QualifiedName name )
+        throws IllegalArgumentException;
+
+    Iterable<? extends AssociationDescriptor> associations();
+
+    Iterable<? extends AssociationDescriptor> manyAssociations();
+
+    Iterable<? extends AssociationDescriptor> namedAssociations();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java b/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java
new file mode 100644
index 0000000..e33ff7f
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationStateHolder.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.association;
+
+import java.lang.reflect.AccessibleObject;
+import org.qi4j.api.property.StateHolder;
+
+/**
+ * This represents the state of a entity (properties+associations).
+ */
+public interface AssociationStateHolder
+    extends StateHolder
+{
+    /**
+     * Get an association for a specific accessor method
+     *
+     * @param associationMethod for the association
+     *
+     * @return the association
+     */
+    <T> Association<T> associationFor( AccessibleObject associationMethod );
+
+    /**
+     * Get all associations
+     *
+     * @return iterable of associations
+     */
+    Iterable<? extends Association<?>> allAssociations();
+
+    /**
+     * Get a many-association for a specific accessor method
+     *
+     * @param manyassociationMethod for the many-association
+     *
+     * @return the association
+     */
+    <T> ManyAssociation<T> manyAssociationFor( AccessibleObject manyassociationMethod );
+
+    /**
+     * Get all ManyAssociations
+     *
+     * @return iterable of many-associations
+     */
+    Iterable<? extends ManyAssociation<?>> allManyAssociations();
+
+    /**
+     * Get a named-association for a specific accessor method
+     *
+     * @param namedassociationMethod for the named-association
+     *
+     * @return the association
+     */
+    <T> NamedAssociation<T> namedAssociationFor( AccessibleObject namedassociationMethod );
+
+    /**
+     * Get all NmaedAssociations
+     *
+     * @return iterable of named-associations
+     */
+    Iterable<? extends NamedAssociation<?>> allNamedAssociations();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
new file mode 100644
index 0000000..68777b3
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/AssociationWrapper.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+package org.qi4j.api.association;
+
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * If you want to catch getting and setting association, then create a GenericConcern
+ * that wraps the Zest-supplied Association instance with AssociationWrappers. Override
+ * get() and/or set() to perform your custom code.
+ */
+public class AssociationWrapper
+    implements Association<Object>
+{
+    protected Association<Object> next;
+
+    public AssociationWrapper( Association<Object> next )
+    {
+        this.next = next;
+    }
+
+    public Association<Object> next()
+    {
+        return next;
+    }
+
+    @Override
+    public Object get()
+    {
+        return next.get();
+    }
+
+    @Override
+    public void set( Object associated )
+        throws IllegalArgumentException
+    {
+        next.set( associated );
+    }
+
+    @Override
+    public EntityReference reference()
+    {
+        return next.reference();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return next.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        return next.equals( obj );
+    }
+
+    @Override
+    public String toString()
+    {
+        return next.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java b/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java
new file mode 100644
index 0000000..7173547
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/GenericAssociationInfo.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Niclas Hedhman. All rights Reserved.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.association;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+import static org.qi4j.api.util.Classes.typeOf;
+
+/**
+ * Generic Association info.
+ */
+public final class GenericAssociationInfo
+{
+    public static Type associationTypeOf( AccessibleObject accessor )
+    {
+        return toAssociationType( typeOf( accessor ) );
+    }
+
+    public static Type toAssociationType( Type methodReturnType )
+    {
+        if( methodReturnType instanceof ParameterizedType )
+        {
+            ParameterizedType parameterizedType = (ParameterizedType) methodReturnType;
+            if( AbstractAssociation.class.isAssignableFrom( (Class<?>) parameterizedType.getRawType() ) )
+            {
+                return parameterizedType.getActualTypeArguments()[ 0 ];
+            }
+        }
+
+        Type[] interfaces = ( (Class<?>) methodReturnType ).getGenericInterfaces();
+        for( Type anInterface : interfaces )
+        {
+            Type associationType = toAssociationType( anInterface );
+            if( associationType != null )
+            {
+                return associationType;
+            }
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
new file mode 100644
index 0000000..37d7211
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/ManyAssociation.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+import java.util.List;
+import java.util.Set;
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * Association to a collection of entities.
+ */
+public interface ManyAssociation<T> extends Iterable<T>, AbstractAssociation
+{
+    /**
+     * Returns the number of references in this association.
+     * @return the number of references in this association.
+     */
+    int count();
+
+    boolean contains( T entity );
+
+    boolean add( int i, T entity );
+
+    boolean add( T entity );
+
+    boolean remove( T entity );
+
+    T get( int i );
+
+    List<T> toList();
+
+    Set<T> toSet();
+
+    /**
+     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * @return the references to the associated entities.
+     */
+    Iterable<EntityReference> references();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java
new file mode 100644
index 0000000..5b2177d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationMixin.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.association;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import org.qi4j.api.common.AppliesTo;
+import org.qi4j.api.common.AppliesToFilter;
+import org.qi4j.api.injection.scope.State;
+
+/**
+ * Generic mixin for associations.
+ */
+@AppliesTo( { ManyAssociationMixin.AssociationFilter.class } )
+public final class ManyAssociationMixin
+    implements InvocationHandler
+{
+    @State
+    private AssociationStateHolder associations;
+
+    @Override
+    public Object invoke( Object proxy, Method method, Object[] args )
+        throws Throwable
+    {
+        return associations.manyAssociationFor( method );
+    }
+
+    /**
+     * ManyAssociations generic mixin AppliesToFilter.
+     */
+    public static class AssociationFilter
+        implements AppliesToFilter
+    {
+        @Override
+        public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> modifierClass )
+        {
+            return ManyAssociation.class.isAssignableFrom( method.getReturnType() );
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
new file mode 100644
index 0000000..aee7804
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/ManyAssociationWrapper.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+package org.qi4j.api.association;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * If you want to catch calls to ManyAssociations, then create a GenericConcern
+ * that wraps the Zest-supplied ManyAssociation instance with ManyAssociationWrappers. Override
+ * methods to perform your custom code.
+ */
+public class ManyAssociationWrapper
+    implements ManyAssociation<Object>
+{
+    protected ManyAssociation<Object> next;
+
+    public ManyAssociationWrapper( ManyAssociation<Object> next )
+    {
+        this.next = next;
+    }
+
+    public ManyAssociation<Object> next()
+    {
+        return next;
+    }
+
+    @Override
+    public int count()
+    {
+        return next.count();
+    }
+
+    @Override
+    public boolean contains( Object entity )
+    {
+        return next.contains( entity );
+    }
+
+    @Override
+    public boolean add( int i, Object entity )
+    {
+        return next.add( i, entity );
+    }
+
+    @Override
+    public boolean add( Object entity )
+    {
+        return next.add( entity );
+    }
+
+    @Override
+    public boolean remove( Object entity )
+    {
+        return next.remove( entity );
+    }
+
+    @Override
+    public Object get( int i )
+    {
+        return next.get( i );
+    }
+
+    @Override
+    public List<Object> toList()
+    {
+        return next.toList();
+    }
+
+    @Override
+    public Set<Object> toSet()
+    {
+        return next.toSet();
+    }
+
+    @Override
+    public Iterable<EntityReference> references()
+    {
+        return next.references();
+    }
+
+    @Override
+    public Iterator<Object> iterator()
+    {
+        return next.iterator();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return next.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        return next.equals( obj );
+    }
+
+    @Override
+    public String toString()
+    {
+        return next.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
new file mode 100644
index 0000000..61c9c9a
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociation.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011-2012, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.association;
+
+import java.util.Map;
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * Association to named Entities.
+ * The Iterable&lt;String&gt; returns the names in the association set.
+ * @param <T> Parameterized associatee type
+ */
+public interface NamedAssociation<T>
+    extends Iterable<String>, AbstractAssociation
+{
+    /**
+     * @return The number of named associations in this NamedAssociation.
+     */
+    int count();
+
+    /**
+     * Checks if there is an association with the given name.
+     * @param name The name of the association we are checking if it exists.
+     * @return true if it exists, false otherwise
+     */
+    boolean containsName( String name );
+
+    /**
+     * Adds a named assocation.
+     * @param name The name of the association.
+     * @param entity The entity for this named association.
+     * @return true if putted, false otherwise
+     */
+    boolean put( String name, T entity );
+
+    /**
+     * Remove a named association.
+     * @param name The name of the association.
+     * @return true if removed, false otherwise
+     */
+    boolean remove( String name );
+
+    /**
+     * Retrieves a named association.
+     * @param name The name of the association.
+     * @return The entity that has previously been associated.
+     */
+    T get( String name );
+
+    /**
+     * Checks if the entity is present.
+     * Note that this is potentially a very slow operation, depending on the size of the NamedAssociation.
+     * @param entity The entity to look for.
+     * @return The name of the entity if found, otherwise null.
+     */
+    String nameOf( T entity );
+
+    /**
+     * @return A fully populated Map with the content of this NamedAssociation.
+     */
+    Map<String, T> toMap();
+
+    /**
+     * Returns an unmodifiable Iterable of the references to the associated entities.
+     * @return the references to the associated entities.
+     */
+    Iterable<EntityReference> references();
+
+    /** Returns the EntityReference for the Association with the given name.
+     *
+     * @param name The name of the association to return the EntityReference for
+     * @return The EntityReference of the association.
+     */
+    EntityReference referenceOf( String name );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java
new file mode 100644
index 0000000..d612ed6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationMixin.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011-2012, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.association;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import org.qi4j.api.common.AppliesTo;
+import org.qi4j.api.common.AppliesToFilter;
+import org.qi4j.api.injection.scope.State;
+
+/**
+ * Generic mixin for NamedAssociations.
+ */
+@AppliesTo( NamedAssociationMixin.AssociationFilter.class )
+public final class NamedAssociationMixin
+    implements InvocationHandler
+{
+    @State
+    private AssociationStateHolder associations;
+
+    @Override
+    public Object invoke( Object proxy, Method method, Object[] args )
+        throws Throwable
+    {
+        return associations.namedAssociationFor( method );
+    }
+
+    /**
+     * NamedAssociations generic mixin AppliesToFilter.
+     */
+    public static class AssociationFilter
+        implements AppliesToFilter
+    {
+        @Override
+        public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> modifierClass )
+        {
+            return NamedAssociation.class.isAssignableFrom( method.getReturnType() );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
new file mode 100644
index 0000000..814644a
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/NamedAssociationWrapper.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011-2012, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. All Rights Reserved.
+ *
+ * Licensed  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. 
+ */
+package org.qi4j.api.association;
+
+import java.util.Iterator;
+import java.util.Map;
+import org.qi4j.api.entity.EntityReference;
+
+/**
+ * If you want to catch calls to NamedAssociations, then create a GenericConcern
+ * that wraps the Zest-supplied NamedAssociations instance with NamedAssociationsWrapper. Override
+ * methods to perform your custom code.
+ */
+public class NamedAssociationWrapper
+    implements NamedAssociation<Object>
+{
+    protected NamedAssociation<Object> next;
+
+    public NamedAssociationWrapper( NamedAssociation<Object> next )
+    {
+        this.next = next;
+    }
+
+    public NamedAssociation<Object> next()
+    {
+        return next;
+    }
+
+    @Override
+    public Iterator<String> iterator()
+    {
+        return next.iterator();
+    }
+
+    @Override
+    public int count()
+    {
+        return next.count();
+    }
+
+    @Override
+    public boolean containsName( String name )
+    {
+        return next.containsName( name );
+    }
+
+    @Override
+    public boolean put( String name, Object entity )
+    {
+        return next.put( name, entity );
+    }
+
+    @Override
+    public boolean remove( String name )
+    {
+        return next.remove( name );
+    }
+
+    @Override
+    public Object get( String name )
+    {
+        return next.get( name );
+    }
+
+    @Override
+    public String nameOf( Object entity )
+    {
+        return next.nameOf( entity );
+    }
+
+    @Override
+    public Map<String, Object> toMap()
+    {
+        return next.toMap();
+    }
+
+    @Override
+    public Iterable<EntityReference> references()
+    {
+        return next.references();
+    }
+
+    @Override
+    public EntityReference referenceOf( String name )
+    {
+        return next.referenceOf( name );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return next.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object obj )
+    {
+        return next.equals( obj );
+    }
+
+    @Override
+    public String toString()
+    {
+        return next.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/association/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/association/package.html b/core/api/src/main/java/org/qi4j/api/association/package.html
new file mode 100644
index 0000000..cf48596
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/association/package.html
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<html>
+    <body>
+        <h2>Association API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java b/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java
new file mode 100644
index 0000000..ccfc286
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/cache/CacheOptions.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Niclas Hedhman.
+ *
+ * Licensed  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.
+ */
+package org.qi4j.api.cache;
+
+/**
+ * CacheOptions is a metaInfo class for the Cache system for Entity persistence.
+ * CacheOptions should be assigned to the Usecase of the UnitOfWork, to give hint on caching to entity stores.
+ * See {@link org.qi4j.api.usecase.UsecaseBuilder} on how to set the metaInfo on Usecases.
+ */
+public final class CacheOptions
+{
+    public static final CacheOptions ALWAYS = new CacheOptions( true, true, true );
+    public static final CacheOptions NEVER = new CacheOptions( false, false, false );
+
+    private final boolean cacheOnRead;
+    private final boolean cacheOnWrite;
+    private final boolean cacheOnNew;
+
+    /**
+     * Constructor for CacheOptions.
+     *
+     * @param cacheOnRead  if true, give the hint to the Cache system that it may not be a good idea to cache the
+     *                     read values. This is useful when it is known that the read will be over a large set and
+     *                     shouldn't affect the existing cached entities. For instance, when traversing the EntityStore
+     *                     this option is set to false.
+     * @param cacheOnWrite if true, give the hint to the Cache system that it may not be a good idea to cache the
+     *                     entity when the value is updated. If this is false, the cache should be emptied from any
+     *                     cached entity instead of updated. There are few cases when this is useful, and if this is
+     *                     false, it makes sense that the <i>cacheOnRead</i> is also false.
+     * @param cacheOnNew   if true, give the hint to the Cache system that it may not be a good idea to cache a newly
+     *                     created Entity, as it is not likely to be read in the near future. This is useful when
+     *                     batch inserts are being made.
+     */
+    public CacheOptions( boolean cacheOnRead, boolean cacheOnWrite, boolean cacheOnNew )
+    {
+        this.cacheOnRead = cacheOnRead;
+        this.cacheOnWrite = cacheOnWrite;
+        this.cacheOnNew = cacheOnNew;
+    }
+
+    /**
+     * @return if true, give the hint to the Cache system that it may not be a good idea to cache the
+     *         read values. This is useful when it is known that the read will be over a large set and
+     *         shouldn't affect the existing cached entities. For instance, when traversing the EntityStore
+     */
+    public boolean cacheOnRead()
+    {
+        return cacheOnRead;
+    }
+
+    /**
+     * @return if true, give the hint to the Cache system that it may not be a good idea to cache the
+     *         entity when the value is updated. If this is false, the cache should be emptied from any
+     *         cached entity instead of updated. There are few cases when this is useful, and if this is
+     *         false, it makes sense that the <i>cacheOnRead</i> is also false.
+     */
+    public boolean cacheOnWrite()
+    {
+        return cacheOnWrite;
+    }
+
+    /**
+     * @return if true, give the hint to the Cache system that it may not be a good idea to cache a newly
+     *         created Entity, as it is not likely to be read in the near future. This is useful when
+     *         batch inserts are being made.
+     */
+    public boolean cacheOnNew()
+    {
+        return cacheOnNew;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/cache/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/cache/package.html b/core/api/src/main/java/org/qi4j/api/cache/package.html
new file mode 100644
index 0000000..a62da34
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/cache/package.html
@@ -0,0 +1,40 @@
+<!--
+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.
+-->
+<html>
+    <body>
+        <h2>Cache API.</h2>
+        <p>
+            The Cache API/SPI is an extension point for Entity Store caching.
+        </p>
+        <p>
+            The API part is only to allow caching options to be passed to the underlying extension in a uniform and
+            standard way. CacheOptions are to be passed as meta info on the optional Cache extension that is specified
+            during assembly phase. Example;
+        </p>
+<pre><code>
+public void assemble( ModuleAssembly module )
+{
+    CacheOptions options = new CacheOptions( true, true, false );
+    module.addServices( EhCacheService.class ).setMetaInfo( options );
+}
+</code></pre>
+        <p>
+            Not all EntityStore implementations use the Cache extension, so check the implementation details of the
+            EntityStore whether the cache extension can bring any benefits or not.
+        </p>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java b/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java
new file mode 100644
index 0000000..b23f204
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/AppliesTo.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
+ * 
+ * Licensed 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.
+ */
+
+package org.qi4j.api.common;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Fragments that implement InvocationHandler and which should only be applied to methods that have a particular
+ * annotation or implement a known interface should use this annotation.
+ * <p>
+ * &#64;AppliesTo can specify one of;
+ * </p>
+ * <ul>
+ * <li>An annotation,</li>
+ * <li>An interface,</li>
+ * <li>An AppliesToFilter implementation.</li>
+ * </ul>
+ * <p>
+ * Example with annotation:
+ * </p>
+ * <pre><code>
+ *
+ * &#64;AppliesTo( Sessional.class )   // Tells Zest to apply this concern on methods with &#64;Sessional annotation
+ * public class SessionConcern extends GenericConcern
+ * {
+ *     public Object invoke( Object proxy, Method method, Object[] args )
+ *         throws Throwable
+ *     {
+ *         ... do session stuff ...
+ *     }
+ * }
+ *
+ * &#64;Retention( RetentionPolicy.RUNTIME )
+ * &#64;Target( ElementType.METHOD )
+ * &#64;Documented
+ * &#64;Inherited
+ * public @interface Sessional
+ * {
+ * }
+ *
+ * public class MyMixin
+ *     implements My
+ * {
+ *     &#64;Sessional
+ *     public void doSomethingSessional()
+ *     {
+ *        // ... do your logic wrapped in a session
+ *     }
+ *
+ *     public void doSomethingWithoutSession()
+ *     {
+ *        // ... do stuff that are not wrapped in session.
+ *     }
+ * }
+ *
+ * public interface My
+ * {
+ *     void doSomethingSessional();
+ *
+ *     void doSomethingWithoutSession();
+ * }
+ *
+ * &#64;Concerns( SessionConcern.class )
+ * &#64;Mixins( MyMixin.class )
+ * public interface MyComposite extends My, TransientComposite
+ * {}
+ * </code></pre>
+ * <p>
+ * The doSomethingWithoutSession method do not have the &#64;Sessional annotation, therefore the SessionConcern will
+ * not be placed into the call sequence of these methods, and
+ * vice-versa. The &#64;Sessional annotation can be placed either on the interface method or the implementation
+ * method, depending on whether it is a contract or implementation detail.
+ * </p>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.TYPE, ElementType.METHOD } )
+@Documented
+public @interface AppliesTo
+{
+    /**
+     * List of interfaces, annotations or AppliesToFilter
+     * implementation classes.
+     * If one of them matches the current element it will be
+     * accepted, so this list can be considered an "or".
+     *
+     * @return array of classes or interfaces to be used by the filter
+     */
+    Class<?>[] value();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java b/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java
new file mode 100644
index 0000000..f356cf4
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/AppliesToFilter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.common;
+
+import java.lang.reflect.Method;
+
+/**
+ * Implementations of this interface can be specified in the &#64;AppliesTo.
+ * <p>
+ * AppliesTo filters are one of the driving technologies in Zest. They allow you to apply fragments (Mixins,
+ * Concerns, SideEffects), often generic ones, depending on the context that they are evaluated under. This
+ * mechanism is heavily used internally in Zest to achieve many other features.
+ * </p>
+ * <p>
+ * The starting point is the basic use of AppliesToFilter, where the &#64;AppliesTo annotation is given an
+ * AppliesToFilter implementation as an argument, for instance at a Mixin implementation;
+ * </p>
+ * <pre><code>
+ * &#64;AppliesTo( MyAppliesToFilter.class )
+ * public class SomeMixin
+ *     implements InvocationHandler
+ * {
+ *
+ * }
+ *
+ * public class MyAppliesToFilter
+ *     implements AppliesToFilter
+ * {
+ *     public boolean appliesTo( Method method, Class&lt;?&gt; mixin, Class&lt;?&gt; compositeType, Class&lt;?&gt; fragmentClass )
+ *     {
+ *         return method.getName().startsWith( "my" );
+ *     }
+ * }
+ * </code></pre>
+ * <p>
+ * In the case above, the generic mixin will only be applied to the methods that that is defined by the
+ * AppliesToFilter. This is the primary way to define limits on the application of generic fragments, since
+ * especially mixins are rarely applied to all methods.
+ * </p>
+ */
+public interface AppliesToFilter
+{
+    /**
+     * This is an internal AppliesToFilter which is assigned if no other AppliesToFilters are found for a given
+     * fragment.
+     * <p>
+     * There is no reason for user code to use this AppliesToFilter directly, and should be perceived as an
+     * internal class in Zest.
+     * </p>
+     */
+    AppliesToFilter ALWAYS = new AppliesToFilter()
+    {
+        @Override
+        public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass )
+        {
+            return true;
+        }
+    };
+
+    /**
+     * Check if the Fragment should be applied or not. Will be call when applied to Mixins, Concerns, SideEffects.
+     *
+     * @param method        method that is invoked
+     * @param mixin         mixin implementation for the method
+     * @param compositeType composite type
+     * @param fragmentClass fragment that is being applies
+     *
+     * @return true if the filter passes, otherwise false
+     */
+    boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java b/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java
new file mode 100644
index 0000000..9957e63
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/ConstructionException.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+package org.qi4j.api.common;
+
+/**
+ * Thrown when a Fragment or object could not be instantiated.
+ * This includes, but not be limited to;
+ * <ul>
+ * <li>private constructor.</li>
+ * <li>abstract class for Constraints.</li>
+ * <li>interface instead of a class.</li>
+ * <li>useful constructor missing.</li>
+ * <li>exception thrown in the constructor.</li>
+ * <li>Subclassing of org.qi4j.api.property.Property</li>
+ * </ul>
+ * <p>
+ * See the nested exception for additional details.
+ * </p>
+ */
+public class ConstructionException
+    extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    public ConstructionException()
+    {
+    }
+
+    public ConstructionException( String message )
+    {
+        super( message );
+    }
+
+    public ConstructionException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public ConstructionException( Throwable cause )
+    {
+        super( cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java b/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java
new file mode 100644
index 0000000..5769fad
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/InvalidApplicationException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.common;
+
+/**
+ * Thrown when an application is considered to not be constructed properly.
+ * This happens primarily when client code tries to instantiate Composites
+ * and objects which have not been registered in the ModuleAssembly.
+ */
+public class InvalidApplicationException
+    extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    public InvalidApplicationException( String string )
+    {
+        super( string );
+    }
+
+    public InvalidApplicationException( String string, Throwable cause )
+    {
+        super( string, cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java b/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java
new file mode 100644
index 0000000..b746711
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/MetaInfo.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+
+package org.qi4j.api.common;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.qi4j.api.concern.Concerns;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.sideeffect.SideEffects;
+import org.qi4j.api.util.Classes;
+
+import static java.util.Arrays.asList;
+import static org.qi4j.api.util.Classes.typesOf;
+
+/**
+ * Used to declare and access meta-info.
+ * <p>
+ * <strong>This is effectively an internal class and should not be used directly.</strong>
+ * </p>
+ * <p>
+ * MetaInfo can be set on composites during the assembly phase, a.k.a the bootstrap
+ * process. MetaInfo is any additional data that one wishes to associate at the 'class level' instead of instance
+ * level of a composite declaration.
+ * </p>
+ * <p>
+ * To set the MetaInfo on a Composite, call the {@code setMetaInfo()} methods on the various composite declaration
+ * types, such as;
+ * </p>
+ * <pre><code>
+ * public void assemble( ModuleAssembly module )
+ *     throws AssemblyException
+ * {
+ *     Map&lt;String,String&gt; properties = ...;
+ *     module.services( MyService.class ).setMetaInfo( properties );
+ * }
+ * </code></pre>
+ * <p>
+ * which can later be retrieved by calling the {@code metaInfo()} method on the composite itself. For the example
+ * above that would be;
+ * </p>
+ * <pre><code>
+ * &#64;Mixins(MyServiceMixin.class)
+ * public interface MyService extends ServiceComposite
+ * {
+ *
+ * }
+ *
+ * public abstract class MyServiceMixin
+ *     implements MyService
+ * {
+ *     private Properties props;
+ *
+ *     public MyServiceMixin()
+ *     {
+ *         props = metaInfo( Map.class );
+ *     }
+ * }
+ * </code></pre>
+ */
+public final class MetaInfo
+{
+    private final static Collection<Class> ignored;
+
+    static
+    {
+        ignored = new HashSet<Class>( 4, 0.8f ); // Optimize size used.
+        ignored.addAll( asList( Mixins.class, Concerns.class, SideEffects.class ) );
+    }
+
+    private final Map<Class<?>, Object> metaInfoMap;
+
+    public MetaInfo()
+    {
+        metaInfoMap = new LinkedHashMap<Class<?>, Object>();
+    }
+
+    public MetaInfo( MetaInfo metaInfo )
+    {
+        metaInfoMap = new LinkedHashMap<Class<?>, Object>();
+        metaInfoMap.putAll( metaInfo.metaInfoMap );
+    }
+
+    public void set( Object metaInfo )
+    {
+        if( metaInfo instanceof Annotation )
+        {
+            Annotation annotation = (Annotation) metaInfo;
+            metaInfoMap.put( annotation.annotationType(), metaInfo );
+        }
+        else
+        {
+            Class<?> metaInfoclass = metaInfo.getClass();
+            Iterable<Type> types = typesOf( metaInfoclass );
+            for( Type type : types )
+            {
+                metaInfoMap.put( Classes.RAW_CLASS.map( type ), metaInfo );
+            }
+        }
+    }
+
+    public <T> T get( Class<T> metaInfoType )
+    {
+        return metaInfoType.cast( metaInfoMap.get( metaInfoType ) );
+    }
+
+    public <T> void add( Class<T> infoType, T info )
+    {
+        metaInfoMap.put( infoType, info );
+    }
+
+    public MetaInfo withAnnotations( AnnotatedElement annotatedElement )
+    {
+        for( Annotation annotation : annotatedElement.getAnnotations() )
+        {
+            if( !ignored.contains( annotation.annotationType() )
+                && get( annotation.annotationType() ) == null )
+            {
+                set( annotation );
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public String toString()
+    {
+        return metaInfoMap.toString();
+    }
+
+    public void remove( Class serviceFinderClass )
+    {
+        metaInfoMap.remove( serviceFinderClass );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/Optional.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/Optional.java b/core/api/src/main/java/org/qi4j/api/common/Optional.java
new file mode 100644
index 0000000..3a070c3
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/Optional.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed 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.
+ *
+ */
+package org.qi4j.api.common;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to denote that something is optional.
+ * <ul>
+ * <li>
+ * If applied to a method parameter, then the value is allowed to be null. Default
+ * is that method parameters have to be non-null.
+ * </li>
+ * <li>
+ * If applied to a Property declaration, then the value may be null after construction of
+ * the instance, or may be set to null at a later time.
+ * </li>
+ * <li>
+ * If applied to an injected member field, it is allowed tha none get injected. For instance, an <code>&#64;Optional
+ * &#64;Service</code> would allow a service to not have been declared and the field will be null.
+ * </li>
+ * </ul>
+ * <p>
+ * Optionality is not the default in Zest, and if injections, property values and parameters in methods are not
+ * non-null, the Zest runtime will throw an {@link org.qi4j.api.constraint.ConstraintViolationException}, indicating
+ * which field/property/parameter in which composite and mixin the problem has been detected.
+ * </p>
+ * <p>
+ * Example;
+ * </p>
+ * <pre><code>
+ * &#64;Optional &#64;Service
+ * MyService service;   // If no MyService instance is declared and visible to this service injection point
+ *                      // the 'service' field will be null.
+ *
+ * &#64;Service
+ * YourService other;   // If no YourService instance is declared and visible to this service injection point
+ *                      // the Zest runtime will throw a ConstraintViolationException.
+ *
+ * </code></pre>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD } )
+@Documented
+public @interface Optional
+{
+}
\ No newline at end of file