http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/BinarySpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/BinarySpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/BinarySpecification.java
new file mode 100644
index 0000000..07c5d99
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/BinarySpecification.java
@@ -0,0 +1,41 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Specification;
+
+/**
+ * Base binary Specification, used for AND and OR Specifications..
+ */
+public abstract class BinarySpecification
+    extends ExpressionSpecification
+{
+    protected final Iterable<Specification<Composite>> operands;
+
+    protected BinarySpecification( Iterable<Specification<Composite>> operands 
)
+    {
+        this.operands = operands;
+    }
+
+    public Iterable<Specification<Composite>> operands()
+    {
+        return operands;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ComparisonSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ComparisonSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ComparisonSpecification.java
new file mode 100644
index 0000000..f855054
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ComparisonSpecification.java
@@ -0,0 +1,76 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.property.Property;
+
+/**
+ * Base comparison Specification.
+ */
+public abstract class ComparisonSpecification<T>
+    extends ExpressionSpecification
+{
+    protected final PropertyFunction<T> property;
+    protected final T value;
+
+    public ComparisonSpecification( PropertyFunction<T> property, T value )
+    {
+        this.property = property;
+        this.value = value;
+    }
+
+    public PropertyFunction<T> property()
+    {
+        return property;
+    }
+
+    @Override
+    public final boolean satisfiedBy( Composite item )
+    {
+        try
+        {
+            Property<T> prop = property.map( item );
+
+            if( prop == null )
+            {
+                return false;
+            }
+
+            T propValue = prop.get();
+            if( propValue == null )
+            {
+                return false;
+            }
+
+            return compare( propValue );
+        }
+        catch( IllegalArgumentException e )
+        {
+            return false;
+        }
+    }
+
+    protected abstract boolean compare( T value );
+
+    public T value()
+    {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsAllSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsAllSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsAllSpecification.java
new file mode 100644
index 0000000..7ff3e1b
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsAllSpecification.java
@@ -0,0 +1,78 @@
+/*
+ * 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.query.grammar;
+
+import java.util.Collection;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Iterables;
+
+/**
+ * Contains All Specification.
+ */
+public class ContainsAllSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<? extends Collection<T>> collectionProperty;
+    private Iterable<T> valueCollection;
+
+    public ContainsAllSpecification( PropertyFunction<? extends Collection<T>> 
collectionProperty,
+                                     Iterable<T> valueCollection
+    )
+    {
+        this.collectionProperty = collectionProperty;
+        this.valueCollection = valueCollection;
+    }
+
+    public PropertyFunction<? extends Collection<T>> collectionProperty()
+    {
+        return collectionProperty;
+    }
+
+    public Iterable<T> containedValues()
+    {
+        return valueCollection;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Collection<T> collection = collectionProperty.map( item ).get();
+
+        if( collection == null )
+        {
+            return false;
+        }
+
+        for( T value : valueCollection )
+        {
+            if( !collection.contains( value ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return collectionProperty + " contains " + Iterables.toList( 
valueCollection );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsSpecification.java
new file mode 100644
index 0000000..ea049de
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ContainsSpecification.java
@@ -0,0 +1,67 @@
+/*
+ * 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.query.grammar;
+
+import java.util.Collection;
+import org.qi4j.api.composite.Composite;
+
+/**
+ * Contains Specification.
+ */
+public class ContainsSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<? extends Collection<T>> collectionProperty;
+    private T value;
+
+    public ContainsSpecification( PropertyFunction<? extends Collection<T>> 
collectionProperty, T value )
+    {
+        this.collectionProperty = collectionProperty;
+        this.value = value;
+    }
+
+    public PropertyFunction<? extends Collection<T>> collectionProperty()
+    {
+        return collectionProperty;
+    }
+
+    public T value()
+    {
+        return value;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Collection<T> collection = collectionProperty.map( item ).get();
+
+        if( collection == null )
+        {
+            return false;
+        }
+
+        return collection.contains( value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return collectionProperty + " contains " + value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/EqSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/EqSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/EqSpecification.java
new file mode 100644
index 0000000..b4c1d90
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/EqSpecification.java
@@ -0,0 +1,43 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Equals Specification.
+ */
+public class EqSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public EqSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    protected boolean compare( T value )
+    {
+        return value.equals( this.value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "=" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ExpressionSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ExpressionSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ExpressionSpecification.java
new file mode 100644
index 0000000..9886ca9
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ExpressionSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Specification;
+
+import static org.qi4j.functional.Iterables.append;
+import static org.qi4j.functional.Iterables.iterable;
+
+/**
+ * Base expression Specification.
+ */
+public abstract class ExpressionSpecification
+    implements Specification<Composite>
+{
+
+    @SuppressWarnings( "unchecked" )
+    public AndSpecification and( Specification<Composite> specification )
+    {
+        if( this instanceof AndSpecification )
+        {
+            return new AndSpecification( append( specification, ( 
(AndSpecification) this ).operands() ) );
+        }
+        else
+        {
+            return new AndSpecification( iterable( this, specification ) );
+        }
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public OrSpecification or( Specification<Composite> specification )
+    {
+        if( this instanceof OrSpecification )
+        {
+            return new OrSpecification( append( specification, ( 
(OrSpecification) this ).operands() ) );
+        }
+        else
+        {
+            return new OrSpecification( iterable( this, specification ) );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/GeSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/GeSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/GeSpecification.java
new file mode 100644
index 0000000..82e9e38
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/GeSpecification.java
@@ -0,0 +1,44 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Greater or equals Specification.
+ */
+public class GeSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public GeSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    protected boolean compare( T value )
+    {
+        return ( (Comparable) value ).compareTo( this.value ) >= 0;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + ">=" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/GtSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/GtSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/GtSpecification.java
new file mode 100644
index 0000000..883120b
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/GtSpecification.java
@@ -0,0 +1,44 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Greater than Specification.
+ */
+public class GtSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public GtSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    protected boolean compare( T value )
+    {
+        return ( (Comparable) value ).compareTo( this.value ) > 0;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + ">" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/LeSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/LeSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/LeSpecification.java
new file mode 100644
index 0000000..3715ffd
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/LeSpecification.java
@@ -0,0 +1,44 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Less or equals Specification.
+ */
+public class LeSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public LeSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    protected boolean compare( T value )
+    {
+        return ( (Comparable) value ).compareTo( this.value ) <= 0;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "<=" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/LtSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/LtSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/LtSpecification.java
new file mode 100644
index 0000000..6d3002a
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/LtSpecification.java
@@ -0,0 +1,44 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Lesser than Specification.
+ */
+public class LtSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public LtSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    protected boolean compare( T value )
+    {
+        return ( (Comparable) value ).compareTo( this.value ) < 0;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "<" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationContainsSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationContainsSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationContainsSpecification.java
new file mode 100644
index 0000000..d8a6b2e
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationContainsSpecification.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007-2011 Rickard Öberg.
+ * Copyright 2007-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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.composite.Composite;
+
+/**
+ * ManyAssociation Contains Specification.
+ */
+public class ManyAssociationContainsSpecification<T>
+    extends ExpressionSpecification
+{
+    private final ManyAssociationFunction<T> manyAssociationFunction;
+    private final T value;
+
+    public ManyAssociationContainsSpecification( ManyAssociationFunction<T> 
manyAssociationFunction, T value )
+    {
+        this.manyAssociationFunction = manyAssociationFunction;
+        this.value = value;
+    }
+
+    public ManyAssociationFunction<T> manyAssociation()
+    {
+        return manyAssociationFunction;
+    }
+
+    public T value()
+    {
+        return value;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        ManyAssociation<T> collection = manyAssociationFunction.map( item );
+        if( collection == null )
+        {
+            return false;
+        }
+        return collection.contains( value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return manyAssociationFunction + " contains:" + value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationFunction.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationFunction.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationFunction.java
new file mode 100644
index 0000000..e91cdeb
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/ManyAssociationFunction.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-2011 Rickard Öberg.
+ * Copyright 2007-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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.Proxy;
+import org.qi4j.api.association.AssociationStateHolder;
+import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.composite.CompositeInstance;
+import org.qi4j.functional.Function;
+
+/**
+ * Function to get Entity ManyAssociations.
+ */
+public class ManyAssociationFunction<T>
+    implements Function<Composite, ManyAssociation<T>>
+{
+    private final AssociationFunction<?> traversedAssociation;
+    private final ManyAssociationFunction<?> traversedManyAssociation;
+    private final NamedAssociationFunction<?> traversedNamedAssociation;
+    private final AccessibleObject accessor;
+
+    public ManyAssociationFunction( AssociationFunction<?> 
traversedAssociation,
+                                    ManyAssociationFunction<?> 
traversedManyAssociation,
+                                    NamedAssociationFunction<?> 
traversedNamedAssociation,
+                                    AccessibleObject accessor
+    )
+    {
+        this.traversedAssociation = traversedAssociation;
+        this.traversedManyAssociation = traversedManyAssociation;
+        this.traversedNamedAssociation = traversedNamedAssociation;
+        this.accessor = accessor;
+    }
+
+    public AssociationFunction<?> traversedAssociation()
+    {
+        return traversedAssociation;
+    }
+
+    public ManyAssociationFunction<?> traversedManyAssociation()
+    {
+        return traversedManyAssociation;
+    }
+
+    public NamedAssociationFunction<?> traversedNamedAssociation()
+    {
+        return traversedNamedAssociation;
+    }
+
+    public AccessibleObject accessor()
+    {
+        return accessor;
+    }
+
+    @Override
+    public ManyAssociation<T> map( Composite entity )
+    {
+        try
+        {
+            Object target = entity;
+            if( traversedAssociation != null )
+            {
+                target = traversedAssociation.map( entity ).get();
+            }
+            if( traversedManyAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse 
ManyAssociations" );
+            }
+            if( traversedNamedAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse 
NamedAssociations" );
+            }
+
+            CompositeInstance handler = (CompositeInstance) 
Proxy.getInvocationHandler( target );
+            return ( (AssociationStateHolder) handler.state() 
).manyAssociationFor( accessor );
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw e;
+        }
+        catch( Throwable e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        if( traversedAssociation != null )
+        {
+            return traversedAssociation.toString() + "." + ( (Member) accessor 
).getName();
+        }
+        else
+        {
+            return ( (Member) accessor ).getName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/MatchesSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/MatchesSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/MatchesSpecification.java
new file mode 100644
index 0000000..6cde577
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/MatchesSpecification.java
@@ -0,0 +1,93 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.property.Property;
+
+/**
+ * Regular expression match Specification.
+ */
+public class MatchesSpecification
+    extends ExpressionSpecification
+{
+    private PropertyFunction<String> property;
+    private Object value;
+
+    public MatchesSpecification( PropertyFunction<String> property, String 
regexp )
+    {
+        this.property = property;
+        this.value = regexp;
+    }
+
+    public MatchesSpecification( PropertyFunction<String> property, Variable 
variable )
+    {
+        this.property = property;
+        this.value = variable;
+    }
+
+    public PropertyFunction<String> property()
+    {
+        return property;
+    }
+
+    public Object value()
+    {
+        return value;
+    }
+
+    public String regexp()
+    {
+        return ( String ) value;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Property<String> prop = property.map( item );
+
+        if( prop == null )
+        {
+            return false;
+        }
+
+        String val = prop.get();
+
+        if( val == null )
+        {
+            return false;
+        }
+
+        return val.matches( ( String ) value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return new StringBuilder()
+            .append( "( " )
+            .append( property )
+            .append( " matches " )
+            .append( "\"" )
+            .append( value )
+            .append( "\"" )
+            .append( " )" )
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsNameSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsNameSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsNameSpecification.java
new file mode 100644
index 0000000..c20987e
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsNameSpecification.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2011-2012 Niclas Hedhman.
+ * Copyright 2014 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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import org.qi4j.api.association.NamedAssociation;
+import org.qi4j.api.composite.Composite;
+
+/**
+ * NamedAssociation Contains Specification.
+ */
+public class NamedAssociationContainsNameSpecification<T>
+    extends ExpressionSpecification
+{
+    private final NamedAssociationFunction<T> namedAssociationFunction;
+    private final String name;
+
+    public NamedAssociationContainsNameSpecification( 
NamedAssociationFunction<T> namedAssociationFunction, String name )
+    {
+        this.namedAssociationFunction = namedAssociationFunction;
+        this.name = name;
+    }
+
+    public NamedAssociationFunction<T> namedAssociation()
+    {
+        return namedAssociationFunction;
+    }
+
+    public String name()
+    {
+        return name;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        NamedAssociation<T> collection = namedAssociationFunction.map( item );
+        if( collection == null )
+        {
+            return false;
+        }
+        return collection.containsName( name );
+    }
+
+    @Override
+    public String toString()
+    {
+        return namedAssociationFunction + " contains name:" + name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsSpecification.java
new file mode 100644
index 0000000..22079aa
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationContainsSpecification.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2011-2012 Niclas Hedhman.
+ * Copyright 2014 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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import org.qi4j.api.association.NamedAssociation;
+import org.qi4j.api.composite.Composite;
+
+/**
+ * NamedAssociation Contains Specification.
+ */
+public class NamedAssociationContainsSpecification<T>
+    extends ExpressionSpecification
+{
+    private final NamedAssociationFunction<T> namedAssociationFunction;
+    private final T value;
+
+    public NamedAssociationContainsSpecification( NamedAssociationFunction<T> 
namedAssociationFunction, T value )
+    {
+        this.namedAssociationFunction = namedAssociationFunction;
+        this.value = value;
+    }
+
+    public NamedAssociationFunction<T> namedAssociation()
+    {
+        return namedAssociationFunction;
+    }
+
+    public T value()
+    {
+        return value;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        NamedAssociation<T> collection = namedAssociationFunction.map( item );
+        if( collection == null )
+        {
+            return false;
+        }
+        return collection.nameOf( value ) != null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return namedAssociationFunction + " contains:" + value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationFunction.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationFunction.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationFunction.java
new file mode 100644
index 0000000..3f7b8e3
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NamedAssociationFunction.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2011-2012 Niclas Hedhman.
+ * Copyright 2014 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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.Proxy;
+import org.qi4j.api.association.AssociationStateHolder;
+import org.qi4j.api.association.NamedAssociation;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.composite.CompositeInstance;
+import org.qi4j.functional.Function;
+
+/**
+ * Function to get Entity NamedAssociations.
+ */
+public class NamedAssociationFunction<T>
+    implements Function<Composite, NamedAssociation<T>>
+{
+    private final AssociationFunction<?> traversedAssociation;
+    private final ManyAssociationFunction<?> traversedManyAssociation;
+    private final NamedAssociationFunction<?> traversedNamedAssociation;
+    private final AccessibleObject accessor;
+
+    public NamedAssociationFunction( AssociationFunction<?> 
traversedAssociation,
+                                     ManyAssociationFunction<?> 
traversedManyAssociation,
+                                     NamedAssociationFunction<?> 
traversedNamedAssociation,
+                                     AccessibleObject accessor
+    )
+    {
+        this.traversedAssociation = traversedAssociation;
+        this.traversedManyAssociation = traversedManyAssociation;
+        this.traversedNamedAssociation = traversedNamedAssociation;
+        this.accessor = accessor;
+    }
+
+    public AssociationFunction<?> traversedAssociation()
+    {
+        return traversedAssociation;
+    }
+
+    public ManyAssociationFunction<?> traversedManyAssociation()
+    {
+        return traversedManyAssociation;
+    }
+
+    public NamedAssociationFunction<?> traversedNamedAssociation()
+    {
+        return traversedNamedAssociation;
+    }
+
+    public AccessibleObject accessor()
+    {
+        return accessor;
+    }
+
+    @Override
+    public NamedAssociation<T> map( Composite entity )
+    {
+        try
+        {
+            Object target = entity;
+            if( traversedAssociation != null )
+            {
+                target = traversedAssociation.map( entity ).get();
+            }
+            if( traversedManyAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse 
ManyAssociations" );
+            }
+            if( traversedNamedAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse 
NamedAssociations" );
+            }
+
+            CompositeInstance handler = (CompositeInstance) 
Proxy.getInvocationHandler( target );
+            return ( (AssociationStateHolder) handler.state() 
).namedAssociationFor( accessor );
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw e;
+        }
+        catch( Throwable e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        if( traversedAssociation != null )
+        {
+            return traversedAssociation.toString() + "." + ( (Member) accessor 
).getName();
+        }
+        else
+        {
+            return ( (Member) accessor ).getName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/NeSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/NeSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NeSpecification.java
new file mode 100644
index 0000000..e864184
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/NeSpecification.java
@@ -0,0 +1,43 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Not equals Specification.
+ */
+public class NeSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public NeSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    protected boolean compare( T value )
+    {
+        return !value.equals( this.value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "!=" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/NotSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/NotSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/NotSpecification.java
new file mode 100644
index 0000000..a85500d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/NotSpecification.java
@@ -0,0 +1,53 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Specification;
+import org.qi4j.functional.Specifications;
+
+/**
+ * NOT Specification.
+ */
+public class NotSpecification implements Specification<Composite>
+{
+    private Specification<Composite> operand;
+
+    public NotSpecification( Specification<Composite> operand )
+    {
+        this.operand = operand;
+    }
+
+    public Specification<Composite> operand()
+    {
+        return operand;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return Specifications.not( operand ).satisfiedBy( item );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "!" + operand.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/OrSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/OrSpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/OrSpecification.java
new file mode 100644
index 0000000..ac775d6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/OrSpecification.java
@@ -0,0 +1,56 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Specification;
+import org.qi4j.functional.Specifications;
+
+/**
+ * OR Specification.
+ */
+public class OrSpecification
+    extends BinarySpecification
+{
+
+    public OrSpecification( Iterable<Specification<Composite>> operands )
+    {
+        super( operands );
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return Specifications.or( operands ).satisfiedBy( item );
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder( "(" );
+        String or = "";
+        for( Specification<Composite> operand : operands )
+        {
+            sb.append( or ).append( operand );
+            or = " or ";
+        }
+        return sb.append( ")" ).toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/OrderBy.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/query/grammar/OrderBy.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/OrderBy.java
new file mode 100644
index 0000000..097171b
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/OrderBy.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Niclas Hedhman.
+ * Copyright 2008 Alin Dreghiciu.
+ *
+ * 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.query.grammar;
+
+/**
+ * Query sorting segment.
+ */
+public class OrderBy
+{
+    /**
+     * Order direction.
+     */
+    public enum Order
+    {
+        ASCENDING, DESCENDING
+    }
+
+    /**
+     * Order.
+     */
+    private final PropertyFunction<?> propertyReference;
+    /**
+     * Direction.
+     */
+    private final Order order;
+
+    /**
+     * Constructor.
+     *
+     * @param propertyReference property that determines the order; cannot be 
null
+     * @param order             direction
+     *
+     * @throws IllegalArgumentException - If property is null
+     */
+    public OrderBy( final PropertyFunction<?> propertyReference,
+                    final Order order
+    )
+    {
+        if( propertyReference == null )
+        {
+            throw new IllegalArgumentException( "Ordering property cannot be 
null" );
+        }
+        this.propertyReference = propertyReference;
+        this.order = order;
+    }
+
+    /**
+     * Getter.
+     *
+     * @return property; cannot be null
+     */
+    public PropertyFunction<?> property()
+    {
+        return propertyReference;
+    }
+
+    /**
+     * Getter.
+     *
+     * @return direction; cannot be null
+     */
+    public Order order()
+    {
+        return order;
+    }
+
+    @Override
+    public String toString()
+    {
+        return new StringBuilder()
+            .append( propertyReference )
+            .append( " " )
+            .append( order )
+            .toString();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyFunction.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyFunction.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyFunction.java
new file mode 100644
index 0000000..b3f4c37
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyFunction.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2007-2011 Rickard Öberg.
+ * Copyright 2007-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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.query.grammar;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import org.qi4j.api.association.Association;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.composite.CompositeInstance;
+import org.qi4j.api.property.GenericPropertyInfo;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.query.NotQueryableException;
+import org.qi4j.api.query.QueryExpressionException;
+import org.qi4j.api.util.Classes;
+import org.qi4j.functional.Function;
+
+import static org.qi4j.api.util.Classes.typeOf;
+
+/**
+ * Function to get Entity Properties.
+ */
+public class PropertyFunction<T>
+    implements Function<Composite, Property<T>>
+{
+    private final PropertyFunction<?> traversedProperty;
+    private final AssociationFunction<?> traversedAssociation;
+    private final ManyAssociationFunction<?> traversedManyAssociation;
+    private final NamedAssociationFunction<?> traversedNamedAssociation;
+    private final AccessibleObject accessor;
+
+    public PropertyFunction( PropertyFunction<?> traversedProperty,
+                             AssociationFunction<?> traversedAssociation,
+                             ManyAssociationFunction<?> 
traversedManyAssociation,
+                             NamedAssociationFunction<?> 
traversedNamedAssociation,
+                             AccessibleObject accessor
+    )
+    {
+        this.traversedProperty = traversedProperty;
+        this.traversedAssociation = traversedAssociation;
+        this.traversedManyAssociation = traversedManyAssociation;
+        this.traversedNamedAssociation = traversedNamedAssociation;
+        this.accessor = accessor;
+
+        // Verify that the property accessor is not marked as non queryable
+        NotQueryableException.throwIfNotQueryable( accessor );
+        // Verify that the property type itself (value composites) is not 
marked as non queryable
+
+        Type returnType = typeOf( accessor );
+        if( !Property.class.isAssignableFrom( Classes.RAW_CLASS.map( 
returnType ) ) )
+        {
+            throw new QueryExpressionException( "Not a property type:" + 
returnType );
+        }
+        Type propertyTypeAsType = GenericPropertyInfo.toPropertyType( 
returnType );
+        if( propertyTypeAsType instanceof ParameterizedType )
+        {
+            propertyTypeAsType = ( (ParameterizedType) propertyTypeAsType 
).getRawType();
+        }
+
+        if( !( propertyTypeAsType instanceof Class ) )
+        {
+            throw new QueryExpressionException( "Unsupported property type:" + 
propertyTypeAsType );
+        }
+        @SuppressWarnings( "unchecked" )
+        Class<T> type = (Class<T>) propertyTypeAsType;
+        NotQueryableException.throwIfNotQueryable( type );
+    }
+
+    public PropertyFunction<?> traversedProperty()
+    {
+        return traversedProperty;
+    }
+
+    public AssociationFunction<?> traversedAssociation()
+    {
+        return traversedAssociation;
+    }
+
+    public ManyAssociationFunction<?> traversedManyAssociation()
+    {
+        return traversedManyAssociation;
+    }
+
+    public NamedAssociationFunction<?> traversedNamedAssociation()
+    {
+        return traversedNamedAssociation;
+    }
+
+    public AccessibleObject accessor()
+    {
+        return accessor;
+    }
+
+    @Override
+    public Property<T> map( Composite entity )
+    {
+        try
+        {
+            Object target = entity;
+            if( traversedProperty != null )
+            {
+                Property<?> property = traversedProperty.map( entity );
+                if( property == null )
+                {
+                    return null;
+                }
+                target = property.get();
+            }
+            else if( traversedAssociation != null )
+            {
+                Association<?> association = traversedAssociation.map( entity 
);
+                if( association == null )
+                {
+                    return null;
+                }
+                target = association.get();
+            }
+            else if( traversedManyAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot evaluate a 
ManyAssociation" );
+            }
+            else if( traversedNamedAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot evaluate a 
NamedAssociation" );
+            }
+
+            if( target == null )
+            {
+                return null;
+            }
+
+            CompositeInstance handler = (CompositeInstance) 
Proxy.getInvocationHandler( target );
+            return handler.state().propertyFor( accessor );
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw e;
+        }
+        catch( Throwable e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        if( traversedProperty != null )
+        {
+            return traversedProperty.toString() + "." + ( (Member) accessor 
).getName();
+        }
+        else if( traversedAssociation != null )
+        {
+            return traversedAssociation.toString() + "." + ( (Member) accessor 
).getName();
+        }
+        else
+        {
+            return ( (Member) accessor ).getName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNotNullSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNotNullSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNotNullSpecification.java
new file mode 100644
index 0000000..c73afa8
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNotNullSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.property.Property;
+
+/**
+ * Property not null Specification.
+ */
+public class PropertyNotNullSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<T> property;
+
+    public PropertyNotNullSpecification( PropertyFunction<T> property )
+    {
+        this.property = property;
+    }
+
+    public PropertyFunction<T> property()
+    {
+        return property;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Property<T> prop = property.map( item );
+
+        if( prop == null )
+        {
+            return false;
+        }
+
+        return prop.get() != null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "is not null";
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNullSpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNullSpecification.java
 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNullSpecification.java
new file mode 100644
index 0000000..7f7908f
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyNullSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.property.Property;
+
+/**
+ * Property null Specification.
+ */
+public class PropertyNullSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<T> property;
+
+    public PropertyNullSpecification( PropertyFunction<T> property )
+    {
+        this.property = property;
+    }
+
+    public PropertyFunction<T> property()
+    {
+        return property;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Property<T> prop = property.map( item );
+
+        if( prop == null )
+        {
+            return true;
+        }
+
+        return prop.get() == null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "is null";
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyReference.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyReference.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyReference.java
new file mode 100644
index 0000000..7b865de
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/PropertyReference.java
@@ -0,0 +1,31 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.property.Property;
+import org.qi4j.functional.Function;
+
+/**
+ * Property Reference.
+ */
+public interface PropertyReference
+{
+    <T> Function<Composite, Property<T>> reference();
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/QuerySpecification.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/query/grammar/QuerySpecification.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/QuerySpecification.java
new file mode 100644
index 0000000..3c033d7
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/QuerySpecification.java
@@ -0,0 +1,71 @@
+/*
+ * 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.query.grammar;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Specification;
+
+/**
+ * This should be used when doing native queries, such as SQL, SPARQL or 
similar. EntityFinders can choose
+ * what type of query languages they can understand by checking the language 
property of a QuerySpecification
+ */
+public class QuerySpecification
+    implements Specification<Composite>
+{
+    public static boolean isQueryLanguage( String language, 
Specification<Composite> specification )
+    {
+        if( !( specification instanceof QuerySpecification ) )
+        {
+            return false;
+        }
+
+        return ( (QuerySpecification) specification ).language().equals( 
language );
+    }
+
+    private String language;
+    private String query;
+
+    public QuerySpecification( String language, String query )
+    {
+        this.language = language;
+        this.query = query;
+    }
+
+    public String language()
+    {
+        return language;
+    }
+
+    public String query()
+    {
+        return query;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return language + ":" + query;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/Variable.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/query/grammar/Variable.java 
b/core/api/src/main/java/org/qi4j/api/query/grammar/Variable.java
new file mode 100644
index 0000000..205347b
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/Variable.java
@@ -0,0 +1,43 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Query Variable name.
+ */
+public class Variable
+{
+    private String name;
+
+    public Variable( String name )
+    {
+        this.name = name;
+    }
+
+    public String variableName()
+    {
+        return name;
+    }
+
+    @Override
+    public String toString()
+    {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/grammar/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/query/grammar/package.html 
b/core/api/src/main/java/org/qi4j/api/query/grammar/package.html
new file mode 100644
index 0000000..e0b80f6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/grammar/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>Query Grammar.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/query/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/query/package.html 
b/core/api/src/main/java/org/qi4j/api/query/package.html
new file mode 100644
index 0000000..27e4455
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/query/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>Query API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/Availability.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/service/Availability.java 
b/core/api/src/main/java/org/qi4j/api/service/Availability.java
new file mode 100644
index 0000000..3905a1d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/Availability.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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.service;
+
+/**
+ * Services can implement this interface in order to allow Zest to ask
+ * it whether it is currently available for use or not. This is accessed
+ * by clients through the ServiceReference of the service. Services that do not
+ * implement this are always considered to be available.
+ */
+public interface Availability
+{
+    /**
+     * Implementations should return true if the underlying service is 
currently available for use.
+     *
+     * Reasons why a service might not be available is either if it has been 
configured not to be (see
+     * the Enabled interface), or if an underlying resource is currently 
unavailable.
+     *
+     * @return true if the service is available, false otherwise.
+     */
+    boolean isAvailable();
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/DuplicateServiceIdentityException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/service/DuplicateServiceIdentityException.java
 
b/core/api/src/main/java/org/qi4j/api/service/DuplicateServiceIdentityException.java
new file mode 100644
index 0000000..fffa42a
--- /dev/null
+++ 
b/core/api/src/main/java/org/qi4j/api/service/DuplicateServiceIdentityException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.service;
+
+import org.qi4j.api.common.InvalidApplicationException;
+
+/**
+ * Thrown when a duplicate service identity is detected.
+ */
+public class DuplicateServiceIdentityException
+    extends InvalidApplicationException
+{
+    public DuplicateServiceIdentityException( String string )
+    {
+        super( string );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/IdentityDescriptor.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/service/IdentityDescriptor.java 
b/core/api/src/main/java/org/qi4j/api/service/IdentityDescriptor.java
new file mode 100644
index 0000000..13e0ee5
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/IdentityDescriptor.java
@@ -0,0 +1,27 @@
+/*
+ * 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.service;
+
+/**
+ * Identity Descriptor.
+ */
+public interface IdentityDescriptor
+{
+    String identity();
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ImportedServiceDescriptor.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/service/ImportedServiceDescriptor.java 
b/core/api/src/main/java/org/qi4j/api/service/ImportedServiceDescriptor.java
new file mode 100644
index 0000000..6590049
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ImportedServiceDescriptor.java
@@ -0,0 +1,28 @@
+/*
+ * 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.service;
+
+import org.qi4j.api.composite.ModelDescriptor;
+
+/**
+ * {@code ServiceDescriptor} provides meta information of a service.
+ */
+public interface ImportedServiceDescriptor
+    extends ModelDescriptor, IdentityDescriptor
+{
+    Class<? extends ServiceImporter> serviceImporter();
+
+    Class<?> type();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/NoSuchServiceException.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/service/NoSuchServiceException.java 
b/core/api/src/main/java/org/qi4j/api/service/NoSuchServiceException.java
new file mode 100644
index 0000000..9ce08ae
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/NoSuchServiceException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 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.service;
+
+import org.qi4j.api.composite.NoSuchCompositeException;
+
+/**
+ * Thrown when no visible service of the requested type is found.
+ */
+public class NoSuchServiceException extends NoSuchCompositeException
+{
+    public NoSuchServiceException( String typeName, String moduleName )
+    {
+        super( "ServiceComposite", typeName, moduleName );
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ServiceActivation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/service/ServiceActivation.java 
b/core/api/src/main/java/org/qi4j/api/service/ServiceActivation.java
new file mode 100644
index 0000000..87a7cad
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ServiceActivation.java
@@ -0,0 +1,67 @@
+/*
+ * 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.service;
+
+import org.qi4j.api.activation.Activators;
+
+/**
+ * Convenience interface for simple Service Activation.
+ *
+ * Let your ServiceComposite extends ServiceActivation and implement it in one 
of its Mixins.
+ * A corresponding Activator is automatically registered.
+ */
+@Activators( ServiceActivation.ServiceActivator.class )
+public interface ServiceActivation
+{
+
+    /**
+     * Called after ServiceComposite Activation.
+     */
+    void activateService()
+        throws Exception;
+
+    /**
+     * Called before ServiceComposite Passivation.
+     */
+    void passivateService()
+        throws Exception;
+
+    /**
+     * Service Activator.
+     */
+    class ServiceActivator
+        extends ServiceActivatorAdapter<ServiceActivation>
+    {
+
+        @Override
+        public void afterActivation( ServiceReference<ServiceActivation> 
activated )
+            throws Exception
+        {
+            activated.get().activateService();
+        }
+
+        @Override
+        public void beforePassivation( ServiceReference<ServiceActivation> 
passivating )
+            throws Exception
+        {
+            passivating.get().passivateService();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ServiceActivatorAdapter.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/qi4j/api/service/ServiceActivatorAdapter.java 
b/core/api/src/main/java/org/qi4j/api/service/ServiceActivatorAdapter.java
new file mode 100644
index 0000000..966226e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ServiceActivatorAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 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.service;
+
+import org.qi4j.api.activation.Activator;
+
+/**
+ * Adapter for Service Activator.
+ *
+ * @param <ServiceType> Type of the service.
+ */
+public class ServiceActivatorAdapter<ServiceType>
+    implements Activator<ServiceReference<ServiceType>>
+{
+    /**
+     * Called before Service activation.
+     * @param activating Activating Service
+     */
+    @Override
+    public void beforeActivation( ServiceReference<ServiceType> activating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after Service activation.
+     * @param activated Activated Service
+     */
+    @Override
+    public void afterActivation( ServiceReference<ServiceType> activated )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called before Service passivation.
+     * @param passivating Passivating Service
+     */
+    @Override
+    public void beforePassivation( ServiceReference<ServiceType> passivating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after Service passivation.
+     * @param passivated Passivated Service
+     */
+    @Override
+    public void afterPassivation( ServiceReference<ServiceType> passivated )
+        throws Exception
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ServiceComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/service/ServiceComposite.java 
b/core/api/src/main/java/org/qi4j/api/service/ServiceComposite.java
new file mode 100644
index 0000000..f27b994
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ServiceComposite.java
@@ -0,0 +1,27 @@
+/*
+ * 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.service;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.entity.Identity;
+
+/**
+ * All Composites being used to implement Services
+ * must extend this interface.
+ */
+public interface ServiceComposite
+    extends Identity, Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ServiceDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/service/ServiceDescriptor.java 
b/core/api/src/main/java/org/qi4j/api/service/ServiceDescriptor.java
new file mode 100644
index 0000000..d6a55ee
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ServiceDescriptor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.service;
+
+import org.qi4j.api.composite.CompositeDescriptor;
+import org.qi4j.api.composite.StatefulCompositeDescriptor;
+
+/**
+ * {@code ServiceDescriptor} provides meta informations of a service.
+ */
+public interface ServiceDescriptor
+    extends CompositeDescriptor, IdentityDescriptor, 
StatefulCompositeDescriptor
+{
+    boolean isInstantiateOnStartup();
+
+    <T> Class<T> configurationType();
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/service/ServiceFinder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/service/ServiceFinder.java 
b/core/api/src/main/java/org/qi4j/api/service/ServiceFinder.java
new file mode 100644
index 0000000..3ffb213
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/service/ServiceFinder.java
@@ -0,0 +1,87 @@
+/*
+ * 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.service;
+
+import java.lang.reflect.Type;
+
+/**
+ * Interface used to query for ServiceReferences.
+ * <p>
+ * Each ServiceFinder is
+ * obtained from a specific Module, and the lookup rules are the following:
+ * </p>
+ * <ol>
+ * <li>First look in the same Module as the ServiceFinder</li>
+ * <li>Then look in the same Layer as the ServiceFinder. Any Services declared
+ * with Visibility Layer and Application should be included</li>
+ * <li>Then look in the used Layers. Any Services declared with Visibility 
Application
+ * should be included</li>
+ * </ol>
+ * <p>
+ * Both native Zest services and imported services are considered, with 
preference to native services.
+ * </p>
+ */
+public interface ServiceFinder
+{
+    /**
+     * Find a ServiceReference that implements the given type.
+     *
+     * @param serviceType the type that the Service must implement
+     *
+     * @return a ServiceReference if one is found
+     *
+     * @throws NoSuchServiceException if no service of serviceType is found
+     */
+    <T> ServiceReference<T> findService( Class<T> serviceType )
+        throws NoSuchServiceException;
+
+    /**
+     * Find a ServiceReference that implements the given type.
+     *
+     * @param serviceType the type that the Service must implement
+     *
+     * @return a ServiceReference if one is found
+     *
+     * @throws NoSuchServiceException if no service of serviceType is found
+     */
+    <T> ServiceReference<T> findService( Type serviceType )
+        throws NoSuchServiceException;
+
+    /**
+     * Find ServiceReferences that implements the given type.
+     * <p>
+     * The order of the references is such that Services more local to the 
querying
+     * Module is earlier in the list.
+     * </p>
+     *
+     * @param serviceType the type that the Services must implement
+     *
+     * @return an iterable of ServiceReferences for the given type. It is 
empty if none exist
+     */
+    <T> Iterable<ServiceReference<T>> findServices( Class<T> serviceType );
+
+    /**
+     * Find ServiceReferences that implements the given type.
+     * <p>
+     * The order of the references is such that Services more local to the 
querying
+     * Module is earlier in the list.
+     * </p>
+     *
+     * @param serviceType the type that the Services must implement
+     *
+     * @return an iterable of ServiceReferences for the given type. It is 
empty if none exist
+     */
+    <T> Iterable<ServiceReference<T>> findServices( Type serviceType );
+}

Reply via email to