You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2015/04/21 13:50:16 UTC

[04/18] zest-sandbox git commit: Move Qi4j related projects in a `qi4j/` subfolder

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/properties/PropertiesMixinTest.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/properties/PropertiesMixinTest.java b/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/properties/PropertiesMixinTest.java
new file mode 100644
index 0000000..8ca4dee
--- /dev/null
+++ b/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/properties/PropertiesMixinTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2007 Alin Dreghiciu. 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.library.beans.properties;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.qi4j.api.composite.TransientBuilder;
+import org.qi4j.api.composite.TransientComposite;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.test.AbstractQi4jTest;
+
+import java.util.Iterator;
+
+public class PropertiesMixinTest extends AbstractQi4jTest
+{
+    private SampleJavaBean m_proxy;
+
+    public void assemble( ModuleAssembly aModule ) throws AssemblyException
+    {
+        aModule.transients( SampleJavaBeanComposite.class );
+    }
+
+    @Override
+    @Before
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        TransientBuilder<SampleJavaBeanComposite> builder = module.newTransientBuilder( SampleJavaBeanComposite.class );
+        m_proxy = builder.newInstance();
+    }
+
+    @Test
+    public void setAndGetFoo()
+    {
+        m_proxy.setFoo( "aValue" );
+        assertEquals( "aValue", m_proxy.getFoo() );
+    }
+
+    @Test
+    public void setAndGet()
+    {
+        m_proxy.set( "aValue" );
+        assertEquals( "aValue", m_proxy.get() );
+    }
+
+    @Test
+    public void getFooWithoutSetFoo()
+    {
+        assertEquals( null, m_proxy.getFoo() );
+    }
+
+    @Test
+    public void iterateBarAfterAddBar()
+    {
+        m_proxy.addBar( "aValue" );
+        Iterator<String> iterator = m_proxy.barIterator();
+        assertNotNull( "iterator should not be null", iterator );
+        assertEquals( "iterator has a value", true, iterator.hasNext() );
+        assertEquals( "iterator content", "aValue", iterator.next() );
+    }
+
+    @Test
+    public void iterateAfterAdd()
+    {
+        m_proxy.add( "aValue" );
+        Iterator<String> iterator = m_proxy.iterator();
+        assertNotNull( "iterator should not be null", iterator );
+        assertEquals( "iterator has a value", true, iterator.hasNext() );
+        assertEquals( "iterator content", "aValue", iterator.next() );
+    }
+
+    @Test
+    public void iterateBarAfterAddAndRemoveBar()
+    {
+        m_proxy.addBar( "aValue" );
+        m_proxy.removeBar( "aValue" );
+        Iterator<String> iterator = m_proxy.barIterator();
+        assertNotNull( iterator );
+        assertFalse( iterator.hasNext() );
+    }
+
+    @Test
+    public void iterateAfterAddAndRemove()
+    {
+        m_proxy.add( "aValue" );
+        m_proxy.remove( "aValue" );
+        Iterator<String> iterator = m_proxy.iterator();
+        assertNotNull( iterator );
+        assertFalse( iterator.hasNext() );
+    }
+
+    @Test
+    public void removeBarWithoutAddBar()
+    {
+        m_proxy.removeBar( "aValue" );
+    }
+
+    @Test
+    public void removeWithoutAdd()
+    {
+        m_proxy.remove( "aValue" );
+    }
+
+    @Test
+    public void iterateBarWithoutAddBar()
+    {
+        Iterator<String> iterator = m_proxy.barIterator();
+        assertNotNull( "iterator not supposed to be null", iterator );
+        assertFalse( iterator.hasNext() );
+    }
+
+    @Test
+    public void iterateWithoutAdd()
+    {
+        Iterator<String> iterator = m_proxy.barIterator();
+        assertNotNull( "iterator not supposed to be null", iterator );
+        assertFalse( iterator.hasNext() );
+    }
+
+    @Test
+    public void addFooAndGetFoo()
+    {
+        m_proxy.addFoo( "aValue" );
+        assertNull( "getter supposed to be null", m_proxy.getFoo() );
+    }
+
+    @Test
+    public void addFooAndSetFoo()
+    {
+        m_proxy.addFoo( "addValue" );
+        m_proxy.setFoo( "setValue" );
+    }
+
+    @Test
+    public void setFooAndAddFoo()
+    {
+        m_proxy.setFoo( "setValue" );
+        m_proxy.addFoo( "addValue" );
+    }
+
+    @Test
+    public void setFooAndRemoveFoo()
+    {
+        m_proxy.setFoo( "aValue" );
+        m_proxy.removeFoo( "aValue" );
+        assertEquals( "aValue", m_proxy.getFoo() );
+    }
+
+    @Test
+    public void setFooAndIterateFoo()
+    {
+        m_proxy.setFoo( "aValue" );
+        Iterator<String> iterator = m_proxy.fooIterator();
+        assertNotNull( "iterator not supposed to be null", iterator );
+        assertFalse( iterator.hasNext() );
+    }
+
+    @Test
+    public void setValidAndIsValid()
+    {
+        m_proxy.setValid( true );
+        assertTrue( m_proxy.isValid() );
+    }
+
+    @Test
+    public void setTestedAndHasTested()
+    {
+        m_proxy.setTested( true );
+        assertTrue( m_proxy.hasTested() );
+    }
+
+    @Mixins( PropertiesMixin.class )
+    public static interface SampleJavaBeanComposite extends SampleJavaBean, TransientComposite
+    {
+    }
+
+    public static interface SampleJavaBean
+    {
+        public String getFoo();
+
+        public void setFoo( String value );
+
+        public String get();
+
+        public void set( String value );
+
+        public void addFoo( String value );
+
+        public void removeFoo( String value );
+
+        public Iterator<String> fooIterator();
+
+        public void addBar( String value );
+
+        public void removeBar( String value );
+
+        public Iterator<String> barIterator();
+
+        public void add( String value );
+
+        public void remove( String value );
+
+        public Iterator<String> iterator();
+
+        public boolean isValid();
+
+        public void setValid( boolean value );
+
+        public boolean hasTested();
+
+        public void setTested( boolean value );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/support/JavabeanBackedTest.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/support/JavabeanBackedTest.java b/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/support/JavabeanBackedTest.java
new file mode 100644
index 0000000..e1ed9a8
--- /dev/null
+++ b/qi4j/libraries/beans/src/test/java/org/qi4j/library/beans/support/JavabeanBackedTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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.library.beans.support;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.junit.Ignore;
+import org.qi4j.api.common.Optional;
+import org.qi4j.api.composite.TransientComposite;
+import org.qi4j.api.composite.TransientBuilder;
+import org.qi4j.api.association.Association;
+import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.property.Property;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.test.AbstractQi4jTest;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class JavabeanBackedTest extends AbstractQi4jTest
+{
+
+    public void assemble( ModuleAssembly module ) throws AssemblyException
+    {
+        module.transients( PersonComposite.class, CountryComposite.class, CityComposite.class );
+    }
+
+    @Test
+    @Ignore
+    public void givenPersonPojoWhenDataIsOkThenExpectCorrectResult()
+        throws Exception
+    {
+        CountryPojo malaysia = new CountryPojo( "Malaysia" );
+        Set<CityPojo> cities = new HashSet<CityPojo>();
+        CityPojo kl = new CityPojo( "Kuala Lumpur", malaysia );
+        cities.add( kl );
+        CityPojo jb = new CityPojo( "Johor Bahru", malaysia );
+        cities.add( jb );
+        CityPojo penang = new CityPojo( "Penang", malaysia );
+        cities.add( penang );
+        CityPojo kk = new CityPojo( "Kota Kinabalu", malaysia );
+        cities.add( kk );
+        malaysia.setCities( cities );
+
+        List<PersonPojo> friendsNiclas = new ArrayList<PersonPojo>();
+        List<PersonPojo> friendsMakas = new ArrayList<PersonPojo>();
+        List<PersonPojo> friendsEdward = new ArrayList<PersonPojo>();
+        PersonPojo niclasPojo = new PersonPojo( "Niclas Hedhman", kl, friendsNiclas );
+        PersonPojo makasPojo = new PersonPojo( "Makas Lau", kl, friendsMakas );
+        PersonPojo edwardPojo = new PersonPojo( "Edward Yakop", kl, friendsEdward );
+        friendsEdward.add( makasPojo );
+        friendsEdward.add( niclasPojo );
+        friendsMakas.add( edwardPojo );
+        friendsMakas.add( niclasPojo );
+        friendsNiclas.add( makasPojo );
+        friendsNiclas.add( edwardPojo );
+
+        TransientBuilder<Person> builder = module.newTransientBuilder( Person.class );
+        builder.use( niclasPojo );
+        Person niclas = builder.newInstance();
+        Property<String> stringProperty = niclas.name();
+        assertEquals( "Name match.", "Niclas Hedhman", stringProperty.get() );
+        Property<City> cityProperty = niclas.city();
+        City cityValue = cityProperty.get();
+        Association<Country> countryAssociation = cityValue.country();
+        Country country = countryAssociation.get();
+        assertEquals( "Country match.", "Malaysia", country.name().get() );
+        ManyAssociation citylist = country.cities();
+        for( Object aCitylist : citylist )
+        {
+            City city = (City) aCitylist;
+            String name = city.name().get();
+            assertTrue( name.equals( "Kuala Lumpur" ) ||
+                        name.equals( "Johor Bahru" ) ||
+                        name.equals( "Kota Kinabalu" ) ||
+                        name.equals( "Penang" )
+            );
+        }
+        assertEquals( 4, country.cities().count() );
+    }
+
+
+    public interface PersonComposite extends Person, JavabeanSupport, TransientComposite
+    {
+    }
+
+    public interface Person
+    {
+        @Optional Property<String> name();
+
+        @Optional Property<City> city();
+
+        ManyAssociation<Person> friends();
+    }
+
+    public interface CityComposite extends City, JavabeanSupport, TransientComposite
+    {
+    }
+
+    public interface CountryComposite extends Country, JavabeanSupport, TransientComposite
+    {
+    }
+
+    public interface City
+    {
+        @Optional Property<String> name();
+
+        @Optional Association<Country> country();
+    }
+
+    public interface Country
+    {
+        @Optional Property<String> name();
+
+        ManyAssociation<City> cities();
+    }
+
+    public class PersonPojo
+    {
+        private String name;
+        private CityPojo city;
+        private List<PersonPojo> friends;
+
+        public PersonPojo( String name, CityPojo city, List<PersonPojo> friends )
+        {
+            this.name = name;
+            this.city = city;
+            this.friends = friends;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public CityPojo getCity()
+        {
+            return city;
+        }
+
+        public List<PersonPojo> getFriends()
+        {
+            return friends;
+        }
+    }
+
+    public class CountryPojo
+    {
+        private String countryName;
+        private Set<CityPojo> cities;
+
+        public CountryPojo( String countryName )
+        {
+            this.countryName = countryName;
+        }
+
+        public String getName()
+        {
+            return countryName;
+        }
+
+        public Set<CityPojo> getCities()
+        {
+            return cities;
+        }
+
+        public void setCities( Set<CityPojo> cities )
+        {
+            this.cities = cities;
+        }
+    }
+
+    public class CityPojo
+    {
+        private final String name;
+        private final CountryPojo country;
+
+        public CityPojo( String name, CountryPojo country )
+        {
+            this.name = name;
+            this.country = country;
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public CountryPojo getCountry()
+        {
+            return country;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/pom.xml
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/pom.xml b/qi4j/libraries/entityproxy/pom.xml
new file mode 100644
index 0000000..e046310
--- /dev/null
+++ b/qi4j/libraries/entityproxy/pom.xml
@@ -0,0 +1,45 @@
+<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.qi4j.sandbox</groupId>
+    <artifactId>qi4j-sandbox-libraries</artifactId>
+    <version>0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.qi4j.sandbox</groupId>
+  <artifactId>org.qi4j.library.entityproxy</artifactId>
+  <name>Qi4j Library - Entityproxy</name>
+  <description>This library provides easy way to wrap your entities with transient composites so that qi4j-agnostic code may handle them without worrying about unit of work.</description>
+  <dependencies>
+  	<dependency>
+  		<groupId>org.qi4j.core</groupId>
+  		<artifactId>org.qi4j.core.api</artifactId>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.qi4j.library</groupId>
+  		<artifactId>org.qi4j.library.constraints</artifactId>
+        <version>${version.qi4j}</version>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.qi4j.core</groupId>
+  		<artifactId>org.qi4j.core.testsupport</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.qi4j.core</groupId>
+  		<artifactId>org.qi4j.core.runtime</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  </dependencies>
+
+  <build>
+   <plugins>
+     <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+   </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxy.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxy.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxy.java
new file mode 100644
index 0000000..f212b63
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxy.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.concern.Concerns;
+import org.qi4j.api.injection.scope.Structure;
+import org.qi4j.api.injection.scope.This;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.property.Immutable;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.unitofwork.UnitOfWorkFactory;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkConcern;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation.Propagation;
+
+@Mixins({
+    EntityProxy.EntityProxyMixin.class
+})
+@Concerns({
+    UnitOfWorkConcern.class
+})
+public interface EntityProxy
+{
+
+    String getEntityID();
+
+    Class<?> getCommonClass();
+
+    <EntityType> EntityType getEntity( Class<EntityType> entityClass );
+
+    public interface EntityProxyState
+    {
+        @Immutable
+        Property<String> entityID();
+
+        @Immutable
+        Property<Class<?>> commonClass();
+    }
+
+    public abstract class EntityProxyMixin
+        implements EntityProxy
+    {
+
+        @This
+        private EntityProxyState _state;
+
+        @This
+        private EntityProxy _meAsProxy;
+
+        @Structure private UnitOfWorkFactory _uowf;
+
+        @Override
+        public String getEntityID()
+        {
+            return this._state.entityID().get();
+        }
+
+        @Override
+        public Class<?> getCommonClass()
+        {
+            return this._state.commonClass().get();
+        }
+
+        @Override
+        @UnitOfWorkPropagation(Propagation.REQUIRED)
+        public <EntityType> EntityType getEntity( Class<EntityType> entityClass )
+        {
+            return this._uowf.currentUnitOfWork().get( entityClass, this._meAsProxy.getEntityID() );
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxyHelper.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxyHelper.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxyHelper.java
new file mode 100644
index 0000000..5376bee
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/EntityProxyHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.concern.Concerns;
+import org.qi4j.api.injection.scope.Structure;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.service.ServiceComposite;
+import org.qi4j.api.unitofwork.UnitOfWorkFactory;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkConcern;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation.Propagation;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+public interface EntityProxyHelper
+{
+
+    public <EType, ReturnType> ReturnType getEntity( Class<ReturnType> entityClass, EType proxyOrEntity );
+
+    public <PType, ReturnType> ReturnType getProxy( Class<ReturnType> proxyClass, PType proxyOrEntity );
+
+    @Mixins({EntityProxyHelperMixin.class})
+    @Concerns({UnitOfWorkConcern.class})
+    public interface EntityProxyHelperService extends EntityProxyHelper, ServiceComposite
+    {
+
+    }
+
+    public abstract class EntityProxyHelperMixin
+        implements EntityProxyHelper
+    {
+        @Structure private UnitOfWorkFactory _uowf;
+
+
+        @Override
+        @UnitOfWorkPropagation(Propagation.REQUIRED)
+        public <EType, ReturnType> ReturnType getEntity( Class<ReturnType> entityClass, EType proxyOrEntity )
+        {
+            return proxyOrEntity instanceof EntityProxy ? ((EntityProxy) proxyOrEntity).getEntity( entityClass )
+                : entityClass.cast( this._uowf.currentUnitOfWork().get( proxyOrEntity ));
+        }
+
+        @Override
+        @UnitOfWorkPropagation(Propagation.REQUIRED)
+        public <PType, ReturnType> ReturnType getProxy( Class<ReturnType> proxyClass, PType proxyOrEntity )
+        {
+            return proxyOrEntity instanceof ProxyableEntity ? ((ProxyableEntity) this._uowf.currentUnitOfWork().get( proxyOrEntity )).getProxy( proxyClass )
+                : proxyClass.cast( proxyOrEntity );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/MutualType.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/MutualType.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/MutualType.java
new file mode 100644
index 0000000..d00a7b7
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/MutualType.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+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;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Documented
+public @interface MutualType
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/NoCommonClassFoundException.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/NoCommonClassFoundException.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/NoCommonClassFoundException.java
new file mode 100644
index 0000000..32bd185
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/NoCommonClassFoundException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+public class NoCommonClassFoundException extends RuntimeException
+{
+   public NoCommonClassFoundException(String message)
+   {
+      super(message);
+   }
+
+   public NoCommonClassFoundException(String message, Throwable cause)
+   {
+      super(message, cause);
+   }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/ProxyableEntity.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/ProxyableEntity.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/ProxyableEntity.java
new file mode 100644
index 0000000..38ce038
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/ProxyableEntity.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.composite.TransientBuilder;
+import org.qi4j.api.composite.TransientBuilderFactory;
+import org.qi4j.api.entity.EntityComposite;
+import org.qi4j.api.entity.Lifecycle;
+import org.qi4j.api.entity.LifecycleException;
+import org.qi4j.api.injection.scope.Service;
+import org.qi4j.api.injection.scope.Structure;
+import org.qi4j.api.injection.scope.This;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.unitofwork.UnitOfWorkCallback;
+import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
+import org.qi4j.api.unitofwork.UnitOfWorkFactory;
+import org.qi4j.library.entityproxy.internal.EntityProxyCache;
+
+@Mixins({ProxyableEntity.ProxyableEntityMixin.class})
+public interface ProxyableEntity
+{
+   <ProxyType> ProxyType getProxy(Class<ProxyType> proxyClass);
+
+   public abstract class ProxyableEntityMixin
+   implements ProxyableEntity, Lifecycle
+{
+
+   @Service
+   private EntityProxyCache _proxyUtils;
+
+   @Structure
+   private UnitOfWorkFactory _uowf;
+
+   @This
+   private EntityComposite _meAsEntityComposite;
+
+   @Structure private TransientBuilderFactory _tbf;
+
+   @Override
+   public <ProxyType> ProxyType getProxy( Class<ProxyType> proxyClass )
+   {
+       String id = this._meAsEntityComposite.identity().get();
+       EntityProxy proxy = this._proxyUtils.getFromCache( id );
+       if (proxy == null)
+       {
+           proxy = this.createProxy( proxyClass );
+           this._proxyUtils.storeToCache( proxy );
+       }
+       ProxyType result = proxyClass.cast( proxy );
+       return result;
+   }
+
+   private <ProxyType> EntityProxy createProxy(Class<ProxyType> proxyClass)
+   {
+      TransientBuilder<ProxyType> builder = this._tbf.newTransientBuilder(proxyClass);
+      EntityProxy.EntityProxyState state = builder.prototypeFor(EntityProxy.EntityProxyState.class);
+      Class<?> commonClass = this.doGetCommonType(proxyClass);
+      if (commonClass == null)
+      {
+         throw new NoCommonClassFoundException("Did not find common class for entity of type: " + this._meAsEntityComposite.getClass().getName() + " [proxyClass: " + proxyClass.getName() + "].");
+      }
+      state.commonClass().set(commonClass);
+      state.entityID().set(this._meAsEntityComposite.identity().get());
+
+      return EntityProxy.class.cast( builder.newInstance() );
+   }
+
+   private Class<?> doGetCommonType(Class<?> clazz)
+   {
+      Class<?> result = null;
+      MutualType commonType = clazz.getAnnotation(MutualType.class);
+      if (commonType == null)
+      {
+         for (Class<?> sInterface : clazz.getInterfaces())
+         {
+            result = this.doGetCommonType(sInterface);
+            if (result != null)
+            {
+               break;
+            }
+         }
+
+         if (result == null && clazz.getSuperclass() != null)
+         {
+            result = this.doGetCommonType(clazz.getSuperclass());
+         }
+      }
+      else
+      {
+          result = clazz;
+      }
+
+      return result;
+   }
+
+   @Override
+   public void create()
+       throws LifecycleException
+   {
+
+   }
+
+   @Override
+   public void remove()
+       throws LifecycleException
+   {
+
+       final String id = this._meAsEntityComposite.identity().get();
+       this._uowf.currentUnitOfWork().addUnitOfWorkCallback( new UnitOfWorkCallback()
+       {
+
+           @Override
+           public void beforeCompletion()
+               throws UnitOfWorkCompletionException
+           {
+               // Nothing.
+           }
+
+           @Override
+           public void afterCompletion( UnitOfWorkStatus status )
+           {
+               if( status == UnitOfWorkStatus.COMPLETED )
+               {
+                   _proxyUtils.removeFromCache( id );
+               }
+           }
+       } );
+
+   }
+}
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/assembling/EntityProxyAssembler.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/assembling/EntityProxyAssembler.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/assembling/EntityProxyAssembler.java
new file mode 100644
index 0000000..8681ff5
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/assembling/EntityProxyAssembler.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy.assembling;
+
+import org.qi4j.api.common.Visibility;
+import org.qi4j.bootstrap.Assembler;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.library.entityproxy.EntityProxyHelper.EntityProxyHelperService;
+import org.qi4j.library.entityproxy.internal.EntityProxyCacheService;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+public class EntityProxyAssembler implements Assembler
+{
+
+    public EntityProxyAssembler()
+    {
+
+    }
+
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.addServices( EntityProxyCacheService.class, EntityProxyHelperService.class).visibleIn( Visibility.application );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCache.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCache.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCache.java
new file mode 100644
index 0000000..c2e84a7
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCache.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy.internal;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.qi4j.api.service.ServiceActivation;
+import org.qi4j.library.constraints.annotation.GreaterThan;
+import org.qi4j.library.entityproxy.EntityProxy;
+
+public interface EntityProxyCache extends ServiceActivation
+{
+    public EntityProxy getFromCache(String entityID);
+
+    public void storeToCache(EntityProxy proxy);
+
+    public void removeFromCache(String entityID);
+
+    public Integer getMaxCacheSize();
+
+    public Integer getCurrentCacheSize();
+
+    public void setMaxCacheSize(@GreaterThan(0) Integer newSize);
+
+   public abstract class EntityProxyUtilsMixin implements EntityProxyCache
+   {
+
+      private static final Integer DEFAULT_MAX_PROXIES = 1000;
+
+      private Map<String, EntityProxy> _entityProxyMapping;
+
+      private Integer _maxProxies;
+
+      @Override
+      public void activateService() throws Exception
+      {
+         this._maxProxies = DEFAULT_MAX_PROXIES;
+         this._entityProxyMapping = new LinkedHashMap<String, EntityProxy>(this._maxProxies);
+      }
+
+      @Override
+      public void passivateService() throws Exception
+      {
+      }
+
+      @Override
+      public Integer getCurrentCacheSize()
+      {
+          return this._entityProxyMapping.size();
+      }
+
+      @Override
+      public EntityProxy getFromCache( String entityID )
+      {
+          return this._entityProxyMapping.get( entityID );
+      }
+      @Override
+      public Integer getMaxCacheSize()
+      {
+          return this._maxProxies;
+      }
+
+      @Override
+      public void removeFromCache( String entityID )
+      {
+          this._entityProxyMapping.remove( entityID );
+      }
+
+      @Override
+      public void setMaxCacheSize( Integer newSize )
+      {
+          this._maxProxies = newSize;
+          while (this._entityProxyMapping.size() > this._maxProxies)
+          {
+              this.removeEldestProxy();
+          }
+      }
+
+      @Override
+      public void storeToCache( EntityProxy proxy )
+      {
+          synchronized( this._entityProxyMapping )
+          {
+              if (this._entityProxyMapping.size() == this._maxProxies)
+              {
+                  this.removeEldestProxy();
+              }
+              this._entityProxyMapping.put( proxy.getEntityID(), proxy );
+          }
+      }
+
+      private void removeEldestProxy()
+      {
+          this._entityProxyMapping.remove( this._entityProxyMapping.keySet().iterator().next() );
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCacheService.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCacheService.java b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCacheService.java
new file mode 100644
index 0000000..cd2ab00
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/main/java/org/qi4j/library/entityproxy/internal/EntityProxyCacheService.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy.internal;
+
+import org.qi4j.api.concern.Concerns;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.service.ServiceComposite;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkConcern;
+
+@Mixins({
+   EntityProxyCache.EntityProxyUtilsMixin.class
+   })
+@Concerns({
+   UnitOfWorkConcern.class
+   })
+public interface EntityProxyCacheService extends EntityProxyCache, ServiceComposite
+{
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityProxyTest.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityProxyTest.java b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityProxyTest.java
new file mode 100644
index 0000000..2563be2
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityProxyTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.qi4j.api.unitofwork.ConcurrentEntityModificationException;
+import org.qi4j.api.unitofwork.UnitOfWork;
+import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.library.entityproxy.EntityWithMutualType.EntityCompositeWithMutualType;
+import org.qi4j.library.entityproxy.EntityWithMutualType.EntityProxyWithMutualType;
+import org.qi4j.library.entityproxy.MissingMutualTypeEntity.MissingMutualTypeEntityComposite;
+import org.qi4j.library.entityproxy.MissingMutualTypeEntity.MissingMutualTypeEntityProxy;
+import org.qi4j.library.entityproxy.assembling.EntityProxyAssembler;
+import org.qi4j.test.AbstractQi4jTest;
+import org.qi4j.test.EntityTestAssembler;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+public class EntityProxyTest extends AbstractQi4jTest
+{
+
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.entities( EntityCompositeWithMutualType.class, MissingMutualTypeEntityComposite.class );
+        module.transients( EntityProxyWithMutualType.class, MissingMutualTypeEntityProxy.class );
+
+        EntityProxyAssembler eAss = new EntityProxyAssembler();
+        eAss.assemble( module );
+
+        new EntityTestAssembler().assemble( module );
+    }
+
+    private <EntityType> EntityType createEntity(Class<EntityType> entityClass) throws ConcurrentEntityModificationException, UnitOfWorkCompletionException
+    {
+        UnitOfWork uow = module.newUnitOfWork();
+        EntityType result = uow.newEntity( entityClass );
+        uow.complete();
+        return result;
+    }
+
+    @Test
+    public void getEntityProxyTest() throws Exception
+    {
+        EntityWithMutualType entity = this.createEntity( EntityCompositeWithMutualType.class );
+
+        UnitOfWork uow = module.newUnitOfWork();
+        EntityWithMutualType proxy = ((ProxyableEntity)uow.get( entity )).getProxy( EntityWithMutualType.class );
+        uow.complete();
+
+        Assert.assertNotNull( "The proxy must be non-null.", proxy );
+    }
+
+    @Test
+    public void getProxyableEntity() throws Exception
+    {
+        EntityWithMutualType entity = this.createEntity( EntityCompositeWithMutualType.class );
+
+        UnitOfWork uow = module.newUnitOfWork();
+        EntityWithMutualType proxy = ((ProxyableEntity)uow.get( entity )).getProxy( EntityWithMutualType.class );
+        uow.complete();
+
+        entity = ((EntityProxy)proxy).getEntity( EntityWithMutualType.class );
+
+        uow = module.newUnitOfWork();
+        try
+        {
+            Assert.assertNotNull( "The proxy must point to existing entity.", uow.get(entity) );
+        } finally
+        {
+            uow.discard();
+        }
+    }
+
+    @Test(expected = NoCommonClassFoundException.class)
+    public void testMissingMutualType() throws Exception
+    {
+        MissingMutualTypeEntity entity = this.createEntity( MissingMutualTypeEntity.class );
+
+        UnitOfWork uow = module.newUnitOfWork();
+        try
+        {
+            MissingMutualTypeEntity proxy = ((ProxyableEntity)uow.get( entity )).getProxy( MissingMutualTypeEntity.class );
+        } finally
+        {
+            uow.complete();
+        }
+    }
+
+    @Test
+    public void changesMustPropagateToEntityTest() throws Exception
+    {
+        EntityWithMutualType entity = this.createEntity( EntityCompositeWithMutualType.class );
+
+        UnitOfWork uow = module.newUnitOfWork();
+        EntityWithMutualType proxy = ((ProxyableEntity)uow.get( entity )).getProxy( EntityWithMutualType.class );
+        uow.complete();
+
+        proxy.setMyString( "TestString" );
+
+        uow = module.newUnitOfWork();
+        try
+        {
+            Assert.assertEquals( "The change must go down to entity.", "TestString", uow.get( entity ).getMyString() );
+        } finally
+        {
+            uow.discard();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityWithMutualType.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityWithMutualType.java b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityWithMutualType.java
new file mode 100644
index 0000000..3d6be5b
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/EntityWithMutualType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.composite.TransientComposite;
+import org.qi4j.api.entity.EntityComposite;
+import org.qi4j.api.mixin.Mixins;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+@MutualType
+public interface EntityWithMutualType extends SomeRole
+{
+
+    public interface EntityCompositeWithMutualType extends EntityWithMutualType, ProxyableEntity, EntityComposite
+    {
+
+    }
+
+    @Mixins({ SomeRole.SomeRoleProxyMixin.class })
+    public interface EntityProxyWithMutualType extends EntityWithMutualType, EntityProxy, TransientComposite
+    {
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/MissingMutualTypeEntity.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/MissingMutualTypeEntity.java b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/MissingMutualTypeEntity.java
new file mode 100644
index 0000000..3bb3f9a
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/MissingMutualTypeEntity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.composite.TransientComposite;
+import org.qi4j.api.entity.EntityComposite;
+import org.qi4j.api.mixin.Mixins;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+public interface MissingMutualTypeEntity extends SomeRole
+{
+
+    public interface MissingMutualTypeEntityComposite extends MissingMutualTypeEntity, ProxyableEntity, EntityComposite
+    {
+
+    }
+
+    @Mixins({ SomeRole.SomeRoleProxyMixin.class })
+    public interface MissingMutualTypeEntityProxy extends MissingMutualTypeEntity, EntityProxy, TransientComposite
+    {
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/SomeRole.java
----------------------------------------------------------------------
diff --git a/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/SomeRole.java b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/SomeRole.java
new file mode 100644
index 0000000..8c1e18b
--- /dev/null
+++ b/qi4j/libraries/entityproxy/src/test/java/org/qi4j/library/entityproxy/SomeRole.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010, Stanislav Muhametsin. 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.library.entityproxy;
+
+import org.qi4j.api.common.Optional;
+import org.qi4j.api.injection.scope.This;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation;
+import org.qi4j.api.unitofwork.concern.UnitOfWorkPropagation.Propagation;
+
+/**
+ *
+ * @author Stanislav Muhametsin
+ */
+@Mixins({
+    SomeRole.SomeRoleMixin.class
+})
+public interface SomeRole
+{
+
+    public String getMyString();
+
+    public void setMyString(String str);
+
+    public interface SomeRoleState
+    {
+        @Optional
+        Property<String> myString();
+    }
+
+    public class SomeRoleMixin implements SomeRole
+    {
+
+        @This private SomeRoleState _state;
+
+        @Override
+        public String getMyString()
+        {
+            return this._state.myString().get();
+        }
+
+        @Override
+        public void setMyString( String str )
+        {
+            this._state.myString().set( str );
+        }
+
+    }
+
+    // The reason why proxy mixins are not generic is that sometimes, for example, entity may return the value of @This-injected variable,
+    // which is not instance of ProxyableEntity, but still an entity. Then a full control is needed.
+    public class SomeRoleProxyMixin implements SomeRole
+    {
+        @This private EntityProxy _proxy;
+
+        @Override
+        @UnitOfWorkPropagation(Propagation.REQUIRED)
+        public String getMyString()
+        {
+            return this._proxy.getEntity( SomeRole.class ).getMyString();
+        }
+
+        @Override
+        @UnitOfWorkPropagation(Propagation.REQUIRED)
+        public void setMyString( String str )
+        {
+            this._proxy.getEntity( SomeRole.class ).setMyString( str );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/dev-status.xml
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/dev-status.xml b/qi4j/libraries/exception/dev-status.xml
new file mode 100644
index 0000000..1e523b4
--- /dev/null
+++ b/qi4j/libraries/exception/dev-status.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<module xmlns="http://www.qi4j.org/schemas/2008/dev-status/1">
+  <status>
+    <codebase>early</codebase>
+    <!--none,early,beta,stable,mature-->
+    <documentation>none</documentation>
+    <!-- none, brief, good, complete -->
+    <unittests>none</unittests>
+    <!-- none, some, good, complete -->
+  </status>
+  <licenses>
+    <license>ALv2</license>
+  </licenses>
+</module>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/licenses/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/licenses/.svn/all-wcprops b/qi4j/libraries/exception/licenses/.svn/all-wcprops
new file mode 100644
index 0000000..34b9b1c
--- /dev/null
+++ b/qi4j/libraries/exception/licenses/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/repos/ops4j/!svn/ver/12441/projects/qi4j/libraries/exception/licenses
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/licenses/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/licenses/.svn/entries b/qi4j/libraries/exception/licenses/.svn/entries
new file mode 100644
index 0000000..21f4838
--- /dev/null
+++ b/qi4j/libraries/exception/licenses/.svn/entries
@@ -0,0 +1,28 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/licenses
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-07-26T12:42:38.335187Z
+12441
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/licenses/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/licenses/.svn/format b/qi4j/libraries/exception/licenses/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/licenses/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/pom.xml
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/pom.xml b/qi4j/libraries/exception/pom.xml
new file mode 100644
index 0000000..14c30db
--- /dev/null
+++ b/qi4j/libraries/exception/pom.xml
@@ -0,0 +1,37 @@
+<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.qi4j.sandbox</groupId>
+    <artifactId>qi4j-sandbox-libraries</artifactId>
+    <version>0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.qi4j.library</groupId>
+  <artifactId>org.qi4j.library.exception</artifactId>
+  <name>Qi4j Library - Exception Handling</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.qi4j.core</groupId>
+      <artifactId>org.qi4j.core.api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.qi4j.core</groupId>
+      <artifactId>org.qi4j.core.spi</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.qi4j.core</groupId>
+      <artifactId>org.qi4j.core.bootstrap</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.qi4j.core</groupId>
+      <artifactId>org.qi4j.core.testsupport</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/.svn/all-wcprops b/qi4j/libraries/exception/src/.svn/all-wcprops
new file mode 100644
index 0000000..292a7a7
--- /dev/null
+++ b/qi4j/libraries/exception/src/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/.svn/entries b/qi4j/libraries/exception/src/.svn/entries
new file mode 100644
index 0000000..bd80ce2
--- /dev/null
+++ b/qi4j/libraries/exception/src/.svn/entries
@@ -0,0 +1,34 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+test
+dir
+
+main
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/.svn/format b/qi4j/libraries/exception/src/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/.svn/all-wcprops b/qi4j/libraries/exception/src/main/.svn/all-wcprops
new file mode 100644
index 0000000..b2f265e
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/.svn/entries b/qi4j/libraries/exception/src/main/.svn/entries
new file mode 100644
index 0000000..3597cb3
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/.svn/entries
@@ -0,0 +1,31 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+java
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/.svn/format b/qi4j/libraries/exception/src/main/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/.svn/all-wcprops b/qi4j/libraries/exception/src/main/java/.svn/all-wcprops
new file mode 100644
index 0000000..0046ee9
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/.svn/entries b/qi4j/libraries/exception/src/main/java/.svn/entries
new file mode 100644
index 0000000..3099041
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/.svn/entries
@@ -0,0 +1,31 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main/java
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+org
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/.svn/format b/qi4j/libraries/exception/src/main/java/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/.svn/all-wcprops b/qi4j/libraries/exception/src/main/java/org/.svn/all-wcprops
new file mode 100644
index 0000000..b966086
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/.svn/entries b/qi4j/libraries/exception/src/main/java/org/.svn/entries
new file mode 100644
index 0000000..5c5182b
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/.svn/entries
@@ -0,0 +1,31 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main/java/org
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+qi4j
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/.svn/format b/qi4j/libraries/exception/src/main/java/org/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/all-wcprops b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/all-wcprops
new file mode 100644
index 0000000..e4b389d
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/entries b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/entries
new file mode 100644
index 0000000..af9b8aa
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/entries
@@ -0,0 +1,31 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main/java/org/qi4j
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+library
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/format b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/all-wcprops b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/all-wcprops
new file mode 100644
index 0000000..a29b0c2
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 92
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/entries b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/entries
new file mode 100644
index 0000000..5cf1ff0
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/entries
@@ -0,0 +1,31 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+exception
+dir
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/format b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/all-wcprops
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/all-wcprops b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/all-wcprops
new file mode 100644
index 0000000..accc3af
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/all-wcprops
@@ -0,0 +1,65 @@
+K 25
+svn:wc:ra_dav:version-url
+V 102
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception
+END
+ExceptionHandlingNotificationConcern.java
+K 25
+svn:wc:ra_dav:version-url
+V 144
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ExceptionHandlingNotificationConcern.java
+END
+ExceptionHandling.java
+K 25
+svn:wc:ra_dav:version-url
+V 125
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ExceptionHandling.java
+END
+ExceptionObservable.java
+K 25
+svn:wc:ra_dav:version-url
+V 127
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ExceptionObservable.java
+END
+ExceptionObserver.java
+K 25
+svn:wc:ra_dav:version-url
+V 125
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ExceptionObserver.java
+END
+SystemErrExceptionHandlingMixin.java
+K 25
+svn:wc:ra_dav:version-url
+V 139
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/SystemErrExceptionHandlingMixin.java
+END
+ExceptionObservableMixin.java
+K 25
+svn:wc:ra_dav:version-url
+V 132
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ExceptionObservableMixin.java
+END
+ObservableExceptionHandlingService.java
+K 25
+svn:wc:ra_dav:version-url
+V 142
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/ObservableExceptionHandlingService.java
+END
+DelegatingExceptionObserver.java
+K 25
+svn:wc:ra_dav:version-url
+V 135
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/DelegatingExceptionObserver.java
+END
+NullExceptionHandling.java
+K 25
+svn:wc:ra_dav:version-url
+V 129
+/repos/ops4j/!svn/ver/12464/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/NullExceptionHandling.java
+END
+SimpleExceptionHandlingService.java
+K 25
+svn:wc:ra_dav:version-url
+V 138
+/repos/ops4j/!svn/ver/13742/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/SimpleExceptionHandlingService.java
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/entries
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/entries b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/entries
new file mode 100644
index 0000000..0b0f918
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/entries
@@ -0,0 +1,158 @@
+8
+
+dir
+14719
+https://scm.ops4j.org/repos/ops4j/projects/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception
+https://scm.ops4j.org/repos/ops4j
+
+
+
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+9b982a3c-3ae5-0310-a4bc-d9a3335569bd
+
+ExceptionHandlingNotificationConcern.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+73ff824c08ee67ed5f1ba4a3d3850d29
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+has-props
+
+ExceptionHandling.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+763b3886feab2bd18cf7baae5806d466
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+ExceptionObservable.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+b1c2bf9efeba4f6be16d052cfa9d577a
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+ExceptionObserver.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+ace5fa42fc4f338d1a5c506cb8459e32
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+SystemErrExceptionHandlingMixin.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+b5584d5522869f417f76f2f151a3e234
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+ExceptionObservableMixin.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+092661c2003fdd452b397d20514dd5fd
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+has-props
+
+ObservableExceptionHandlingService.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+672d78d16ff53bf03b05638ab48ca377
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+has-props
+
+DelegatingExceptionObserver.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+eae1c8abb25bab16da660f6cef9afdeb
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+NullExceptionHandling.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+122ff5432a8e2b5d607160747dc193eb
+2008-07-30T03:59:42.341738Z
+12464
+niclas@hedhman.org
+has-props
+
+SimpleExceptionHandlingService.java
+file
+
+
+
+
+2009-04-05T04:16:42.000000Z
+98d295d244112f3da0bf768fe6f7be96
+2008-12-16T11:13:26.017490Z
+13742
+niclas@hedhman.org
+has-props
+

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/format
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/format b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/format
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/format
@@ -0,0 +1 @@
+8

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/DelegatingExceptionObserver.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/DelegatingExceptionObserver.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/DelegatingExceptionObserver.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/DelegatingExceptionObserver.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandling.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandling.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandling.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandling.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandlingNotificationConcern.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandlingNotificationConcern.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandlingNotificationConcern.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionHandlingNotificationConcern.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservable.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservable.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservable.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservable.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservableMixin.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservableMixin.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservableMixin.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObservableMixin.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObserver.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObserver.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObserver.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ExceptionObserver.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/NullExceptionHandling.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/NullExceptionHandling.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/NullExceptionHandling.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/NullExceptionHandling.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ObservableExceptionHandlingService.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ObservableExceptionHandlingService.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ObservableExceptionHandlingService.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/ObservableExceptionHandlingService.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SimpleExceptionHandlingService.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SimpleExceptionHandlingService.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SimpleExceptionHandlingService.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SimpleExceptionHandlingService.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SystemErrExceptionHandlingMixin.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SystemErrExceptionHandlingMixin.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SystemErrExceptionHandlingMixin.java.svn-base
new file mode 100644
index 0000000..bdbd305
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/prop-base/SystemErrExceptionHandlingMixin.java.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:eol-style
+V 6
+native
+END

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/DelegatingExceptionObserver.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/DelegatingExceptionObserver.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/DelegatingExceptionObserver.java.svn-base
new file mode 100644
index 0000000..903b5d6
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/DelegatingExceptionObserver.java.svn-base
@@ -0,0 +1,85 @@
+/*
+ * 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.library.exception;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+public class DelegatingExceptionObserver
+    implements ExceptionObserver
+{
+    private LinkedList<ExceptionObserver> observers;
+
+    public DelegatingExceptionObserver( ExceptionObserver existing )
+    {
+        observers = new LinkedList<ExceptionObserver>();
+        observers.add( existing );
+    }
+
+    public void notify( String message, Object source, Throwable exception )
+    {
+        Iterator<ExceptionObserver> iterator;
+        synchronized( this )
+        {
+            iterator = observers.iterator();
+        }
+        while( iterator.hasNext() )
+        {
+            ExceptionObserver observer = iterator.next();
+            try
+            {
+                observer.notify( message, source, exception );
+            }
+            catch( Throwable e )
+            {
+                System.err.println( "WARNING: ExceptionObserver " + observer + " threw an exception. See below." );
+                e.printStackTrace( System.err );
+            }
+        }
+    }
+
+    void addExceptionObserver( ExceptionObserver observer )
+    {
+        synchronized( this )
+        {
+            LinkedList<ExceptionObserver> clone = new LinkedList<ExceptionObserver>();
+            clone.addAll( observers );
+            clone.add( observer );
+            observers = clone;
+        }
+    }
+
+    ExceptionObserver removeExceptionObserver( ExceptionObserver observer )
+    {
+        synchronized( this )
+        {
+            LinkedList<ExceptionObserver> clone = new LinkedList<ExceptionObserver>();
+            clone.addAll( observers );
+            clone.remove( observer );
+            if( observers.size() == 1 )
+            {
+                ExceptionObserver last = observers.removeFirst();
+                observers = null;
+                return last;
+            }
+            observers = clone;
+            return this;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandling.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandling.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandling.java.svn-base
new file mode 100644
index 0000000..016e8cd
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandling.java.svn-base
@@ -0,0 +1,23 @@
+/*
+ * 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.library.exception;
+
+public interface ExceptionHandling
+{
+    void exceptionOccurred( String message, Object location, Throwable exception );
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandlingNotificationConcern.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandlingNotificationConcern.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandlingNotificationConcern.java.svn-base
new file mode 100644
index 0000000..428d6fa
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionHandlingNotificationConcern.java.svn-base
@@ -0,0 +1,41 @@
+/*
+ * 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.library.exception;
+
+import org.qi4j.api.injection.scope.This;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.concern.ConcernOf;
+import org.qi4j.api.mixin.Mixins;
+
+@Mixins( ExceptionObservableMixin.class )
+public class ExceptionHandlingNotificationConcern extends ConcernOf<ExceptionHandling>
+    implements ExceptionHandling
+{
+    @This private Property<ExceptionObserver> observer;
+
+    public void exceptionOccurred( String message, Object location, Throwable exception )
+    {
+        ExceptionObserver current;
+        synchronized( this )
+        {
+            current = observer.get();
+        }
+        current.notify( message, location, exception );
+        next.exceptionOccurred( message, location, exception );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-sandbox/blob/d4dd9c17/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionObservable.java.svn-base
----------------------------------------------------------------------
diff --git a/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionObservable.java.svn-base b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionObservable.java.svn-base
new file mode 100644
index 0000000..7009895
--- /dev/null
+++ b/qi4j/libraries/exception/src/main/java/org/qi4j/library/exception/.svn/text-base/ExceptionObservable.java.svn-base
@@ -0,0 +1,25 @@
+/*
+ * 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.library.exception;
+
+public interface ExceptionObservable
+{
+    void addExceptionObserver( ExceptionObserver observer );
+
+    void removeExceptionObserver( ExceptionObserver observer );
+}